strip ga calls #4305
6 changed files with 18 additions and 113 deletions
|
@ -159,7 +159,6 @@
|
||||||
"react-confetti": "^4.0.1",
|
"react-confetti": "^4.0.1",
|
||||||
"react-dom": "^16.8.2",
|
"react-dom": "^16.8.2",
|
||||||
"react-draggable": "^3.3.0",
|
"react-draggable": "^3.3.0",
|
||||||
"react-ga": "^2.5.7",
|
|
||||||
"react-google-recaptcha": "^2.0.1",
|
"react-google-recaptcha": "^2.0.1",
|
||||||
"react-hot-loader": "^4.11.1",
|
"react-hot-loader": "^4.11.1",
|
||||||
"react-modal": "^3.1.7",
|
"react-modal": "^3.1.7",
|
||||||
|
|
|
@ -1197,5 +1197,9 @@
|
||||||
"lbry.tv Premium - 1 month": "lbry.tv Premium - 1 month",
|
"lbry.tv Premium - 1 month": "lbry.tv Premium - 1 month",
|
||||||
"We will refund no questions asked within 30 days.": "We will refund no questions asked within 30 days.",
|
"We will refund no questions asked within 30 days.": "We will refund no questions asked within 30 days.",
|
||||||
"Your Wallet": "Your Wallet",
|
"Your Wallet": "Your Wallet",
|
||||||
"This file may have been streamed, moved or deleted": "This file may have been streamed, moved or deleted"
|
"This file may have been streamed, moved or deleted": "This file may have been streamed, moved or deleted",
|
||||||
|
"LBRY takes privacy and choice seriously. Just a few questions before you enter the land of content freedom. ": "LBRY takes privacy and choice seriously. Just a few questions before you enter the land of content freedom. ",
|
||||||
|
"Sending information to third parties (e.g. Google Analytics or Mixpanel) allows us to use detailed\n analytical reports to improve all aspects of LBRY.": "Sending information to third parties (e.g. Google Analytics or Mixpanel) allows us to use detailed\n analytical reports to improve all aspects of LBRY.",
|
||||||
|
"Sharing information with LBRY, Inc. allows us to report to publishers how their content is doing, as\n well as track basic usage and performance. This is the minimum required to earn rewards from LBRY, Inc.": "Sharing information with LBRY, Inc. allows us to report to publishers how their content is doing, as\n well as track basic usage and performance. This is the minimum required to earn rewards from LBRY, Inc.",
|
||||||
|
"No information will be sent directly to LBRY, Inc. or third-parties about your usage. Note that as\n peer-to-peer software, your IP address and potentially other system information can be sent to other\n users, though this information is not stored permanently.": "No information will be sent directly to LBRY, Inc. or third-parties about your usage. Note that as\n peer-to-peer software, your IP address and potentially other system information can be sent to other\n users, though this information is not stored permanently."
|
||||||
}
|
}
|
||||||
|
|
101
ui/analytics.js
101
ui/analytics.js
|
@ -1,6 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import ReactGA from 'react-ga';
|
|
||||||
import * as Sentry from '@sentry/browser';
|
import * as Sentry from '@sentry/browser';
|
||||||
import MatomoTracker from '@datapunt/matomo-tracker-js';
|
import MatomoTracker from '@datapunt/matomo-tracker-js';
|
||||||
import { history } from './store';
|
import { history } from './store';
|
||||||
|
@ -14,10 +13,6 @@ import { MATOMO_ID, MATOMO_URL } from 'config';
|
||||||
|
|
||||||
const isProduction = process.env.NODE_ENV === 'production';
|
const isProduction = process.env.NODE_ENV === 'production';
|
||||||
const devInternalApis = process.env.LBRY_API_URL;
|
const devInternalApis = process.env.LBRY_API_URL;
|
||||||
const LBRY_TV_MINUS_PIRATE_BAY_UA_ID = 'UA-60403362-16';
|
|
||||||
const LBRY_TV_UA_ID = 'UA-60403362-12';
|
|
||||||
const DESKTOP_UA_ID = 'UA-60403362-13';
|
|
||||||
const SECOND_TRACKER_NAME = 'tracker2';
|
|
||||||
|
|
||||||
export const SHARE_INTERNAL = 'shareInternal';
|
export const SHARE_INTERNAL = 'shareInternal';
|
||||||
const SHARE_THIRD_PARTY = 'shareThirdParty';
|
const SHARE_THIRD_PARTY = 'shareThirdParty';
|
||||||
|
@ -36,7 +31,6 @@ type Analytics = {
|
||||||
pageView: string => void,
|
pageView: string => void,
|
||||||
setUser: Object => void,
|
setUser: Object => void,
|
||||||
toggleInternal: (boolean, ?boolean) => void,
|
toggleInternal: (boolean, ?boolean) => void,
|
||||||
toggleThirdParty: (boolean, ?boolean) => void,
|
|
||||||
apiLogView: (string, string, string, ?number, ?() => void) => Promise<any>,
|
apiLogView: (string, string, string, ?number, ?() => void) => Promise<any>,
|
||||||
apiLogPublish: (ChannelClaim | StreamClaim) => void,
|
apiLogPublish: (ChannelClaim | StreamClaim) => void,
|
||||||
apiSyncTags: ({}) => void,
|
apiSyncTags: ({}) => void,
|
||||||
|
@ -60,10 +54,10 @@ type LogPublishParams = {
|
||||||
};
|
};
|
||||||
|
|
||||||
let internalAnalyticsEnabled: boolean = IS_WEB || false;
|
let internalAnalyticsEnabled: boolean = IS_WEB || false;
|
||||||
let thirdPartyAnalyticsEnabled: boolean = IS_WEB || false;
|
// let thirdPartyAnalyticsEnabled: boolean = IS_WEB || false;
|
||||||
// @if TARGET='app'
|
// @if TARGET='app'
|
||||||
if (window.localStorage.getItem(SHARE_INTERNAL) === 'true') internalAnalyticsEnabled = true;
|
if (window.localStorage.getItem(SHARE_INTERNAL) === 'true') internalAnalyticsEnabled = true;
|
||||||
if (window.localStorage.getItem(SHARE_THIRD_PARTY) === 'true') thirdPartyAnalyticsEnabled = true;
|
// if (window.localStorage.getItem(SHARE_THIRD_PARTY) === 'true') thirdPartyAnalyticsEnabled = true;
|
||||||
// @endif
|
// @endif
|
||||||
|
|
||||||
const analytics: Analytics = {
|
const analytics: Analytics = {
|
||||||
|
@ -92,9 +86,6 @@ const analytics: Analytics = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
pageView: path => {
|
pageView: path => {
|
||||||
if (thirdPartyAnalyticsEnabled) {
|
|
||||||
ReactGA.pageview(path, [SECOND_TRACKER_NAME]);
|
|
||||||
}
|
|
||||||
if (internalAnalyticsEnabled) {
|
if (internalAnalyticsEnabled) {
|
||||||
MatomoInstance.trackPageView({
|
MatomoInstance.trackPageView({
|
||||||
href: `${path}`,
|
href: `${path}`,
|
||||||
|
@ -102,14 +93,11 @@ const analytics: Analytics = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setUser: userId => {
|
setUser: userId => {
|
||||||
if (thirdPartyAnalyticsEnabled && userId) {
|
// SEND USERID TO MATOMO?
|
||||||
ReactGA.set({
|
if (internalAnalyticsEnabled && userId) {
|
||||||
userId,
|
|
||||||
});
|
|
||||||
|
|
||||||
// @if TARGET='app'
|
// @if TARGET='app'
|
||||||
Native.getAppVersionInfo().then(({ localVersion }) => {
|
Native.getAppVersionInfo().then(({ localVersion }) => {
|
||||||
sendGaEvent('Desktop-Version', localVersion);
|
sendMatomoEvent('Version', 'Desktop-Version', localVersion);
|
||||||
});
|
});
|
||||||
// @endif
|
// @endif
|
||||||
}
|
}
|
||||||
|
@ -125,7 +113,7 @@ const analytics: Analytics = {
|
||||||
toggleThirdParty: (enabled: boolean): void => {
|
toggleThirdParty: (enabled: boolean): void => {
|
||||||
// Always collect analytics on lbry.tv
|
// Always collect analytics on lbry.tv
|
||||||
// @if TARGET='app'
|
// @if TARGET='app'
|
||||||
thirdPartyAnalyticsEnabled = enabled;
|
// thirdPartyAnalyticsEnabled = enabled;
|
||||||
window.localStorage.setItem(SHARE_THIRD_PARTY, enabled);
|
window.localStorage.setItem(SHARE_THIRD_PARTY, enabled);
|
||||||
// @endif
|
// @endif
|
||||||
},
|
},
|
||||||
|
@ -190,71 +178,45 @@ const analytics: Analytics = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
videoStartEvent: (claimId, duration) => {
|
videoStartEvent: (claimId, duration) => {
|
||||||
sendGaTimingEvent('Media', 'TimeToStart', duration, claimId);
|
|
||||||
sendPromMetric('time_to_start', duration);
|
sendPromMetric('time_to_start', duration);
|
||||||
sendMatomoEvent('Media', 'TimeToStart', claimId, duration);
|
sendMatomoEvent('Media', 'TimeToStart', claimId, duration);
|
||||||
},
|
},
|
||||||
videoBufferEvent: (claimId, currentTime) => {
|
videoBufferEvent: (claimId, currentTime) => {
|
||||||
sendGaTimingEvent('Media', 'BufferTimestamp', currentTime * 1000, claimId);
|
|
||||||
sendPromMetric('buffer');
|
sendPromMetric('buffer');
|
||||||
sendMatomoEvent('Media', 'BufferTimestamp', claimId, currentTime * 1000);
|
sendMatomoEvent('Media', 'BufferTimestamp', claimId, currentTime * 1000);
|
||||||
},
|
},
|
||||||
tagFollowEvent: (tag, following) => {
|
tagFollowEvent: (tag, following) => {
|
||||||
sendGaEvent(following ? 'Tag-Follow' : 'Tag-Unfollow', tag);
|
|
||||||
sendMatomoEvent('Tag', following ? 'Tag-Follow' : 'Tag-Unfollow', tag);
|
sendMatomoEvent('Tag', following ? 'Tag-Follow' : 'Tag-Unfollow', tag);
|
||||||
},
|
},
|
||||||
channelBlockEvent: (uri, blocked, location) => {
|
channelBlockEvent: (uri, blocked, location) => {
|
||||||
sendGaEvent(blocked ? 'Channel-Hidden' : 'Channel-Unhidden', uri);
|
|
||||||
sendMatomoEvent(blocked ? 'Channel-Hidden' : 'Channel-Unhidden', uri);
|
sendMatomoEvent(blocked ? 'Channel-Hidden' : 'Channel-Unhidden', uri);
|
||||||
},
|
},
|
||||||
emailProvidedEvent: () => {
|
emailProvidedEvent: () => {
|
||||||
sendGaEvent('Engagement', 'Email-Provided');
|
|
||||||
sendMatomoEvent('Engagement', 'Email-Provided');
|
sendMatomoEvent('Engagement', 'Email-Provided');
|
||||||
},
|
},
|
||||||
emailVerifiedEvent: () => {
|
emailVerifiedEvent: () => {
|
||||||
sendGaEvent('Engagement', 'Email-Verified');
|
|
||||||
sendMatomoEvent('Engagement', 'Email-Verified');
|
sendMatomoEvent('Engagement', 'Email-Verified');
|
||||||
},
|
},
|
||||||
rewardEligibleEvent: () => {
|
rewardEligibleEvent: () => {
|
||||||
sendGaEvent('Engagement', 'Reward-Eligible');
|
|
||||||
sendMatomoEvent('Engagement', 'Reward-Eligible');
|
sendMatomoEvent('Engagement', 'Reward-Eligible');
|
||||||
},
|
},
|
||||||
openUrlEvent: (url: string) => {
|
openUrlEvent: (url: string) => {
|
||||||
sendGaEvent('Engagement', 'Open-Url', url);
|
|
||||||
sendMatomoEvent('Engagement', 'Open-Url', url);
|
sendMatomoEvent('Engagement', 'Open-Url', url);
|
||||||
},
|
},
|
||||||
trendingAlgorithmEvent: (trendingAlgorithm: string) => {
|
trendingAlgorithmEvent: (trendingAlgorithm: string) => {
|
||||||
sendGaEvent('Engagement', 'Trending-Algorithm', trendingAlgorithm);
|
sendMatomoEvent('Engagement', 'Trending-Algorithm', trendingAlgorithm);
|
||||||
},
|
},
|
||||||
startupEvent: () => {
|
startupEvent: () => {
|
||||||
sendGaEvent('Startup', 'Startup');
|
|
||||||
sendMatomoEvent('Startup', 'Startup');
|
sendMatomoEvent('Startup', 'Startup');
|
||||||
},
|
},
|
||||||
readyEvent: (timeToReady: number) => {
|
readyEvent: (timeToReady: number) => {
|
||||||
sendGaEvent('Startup', 'App-Ready');
|
|
||||||
sendGaTimingEvent('Startup', 'App-Ready', timeToReady);
|
|
||||||
sendMatomoEvent('Startup', 'App-Ready', 'Time', timeToReady);
|
sendMatomoEvent('Startup', 'App-Ready', 'Time', timeToReady);
|
||||||
},
|
},
|
||||||
purchaseEvent: (purchaseInt: number) => {
|
purchaseEvent: (purchaseInt: number) => {
|
||||||
sendGaEvent('Purchase', 'Purchase-Complete', undefined, purchaseInt);
|
|
||||||
sendMatomoEvent('Purchase', 'Purchase-Complete', 'someLabel', purchaseInt);
|
sendMatomoEvent('Purchase', 'Purchase-Complete', 'someLabel', purchaseInt);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function sendGaEvent(category, action, label, value) {
|
|
||||||
if (thirdPartyAnalyticsEnabled && isProduction) {
|
|
||||||
ReactGA.event(
|
|
||||||
{
|
|
||||||
category,
|
|
||||||
action,
|
|
||||||
...(label ? { label } : {}),
|
|
||||||
...(value ? { value } : {}),
|
|
||||||
},
|
|
||||||
[SECOND_TRACKER_NAME]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendMatomoEvent(category, action, name, value) {
|
function sendMatomoEvent(category, action, name, value) {
|
||||||
if (internalAnalyticsEnabled) {
|
if (internalAnalyticsEnabled) {
|
||||||
const event = { category, action, name, value };
|
const event = { category, action, name, value };
|
||||||
|
@ -262,20 +224,6 @@ function sendMatomoEvent(category, action, name, value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendGaTimingEvent(category: string, action: string, timeInMs: number, label?: string) {
|
|
||||||
if (thirdPartyAnalyticsEnabled && isProduction) {
|
|
||||||
ReactGA.timing(
|
|
||||||
{
|
|
||||||
category,
|
|
||||||
variable: action,
|
|
||||||
value: timeInMs,
|
|
||||||
...(label ? { label } : {}),
|
|
||||||
},
|
|
||||||
[SECOND_TRACKER_NAME]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendPromMetric(name: string, value?: number) {
|
function sendPromMetric(name: string, value?: number) {
|
||||||
if (IS_WEB) {
|
if (IS_WEB) {
|
||||||
let url = new URL(SDK_API_PATH + '/metric/ui');
|
let url = new URL(SDK_API_PATH + '/metric/ui');
|
||||||
|
@ -285,31 +233,6 @@ function sendPromMetric(name: string, value?: number) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let gaTrackers = [];
|
|
||||||
|
|
||||||
if (!IS_WEB) {
|
|
||||||
gaTrackers.push({
|
|
||||||
trackingId: DESKTOP_UA_ID,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
gaTrackers.push({
|
|
||||||
trackingId: LBRY_TV_UA_ID,
|
|
||||||
});
|
|
||||||
|
|
||||||
const { search } = window.location;
|
|
||||||
const urlParams = new URLSearchParams(search);
|
|
||||||
const isPirateBayUser = urlParams.get('utm_source') === 'PB';
|
|
||||||
|
|
||||||
if (!isPirateBayUser) {
|
|
||||||
gaTrackers.push({
|
|
||||||
trackingId: LBRY_TV_MINUS_PIRATE_BAY_UA_ID,
|
|
||||||
gaOptions: {
|
|
||||||
name: SECOND_TRACKER_NAME,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const MatomoInstance = new MatomoTracker({
|
const MatomoInstance = new MatomoTracker({
|
||||||
urlBase: MATOMO_URL,
|
urlBase: MATOMO_URL,
|
||||||
siteId: MATOMO_ID, // optional, default value: `1`
|
siteId: MATOMO_ID, // optional, default value: `1`
|
||||||
|
@ -320,14 +243,6 @@ const MatomoInstance = new MatomoTracker({
|
||||||
// linkTracking: false // optional, default value: true
|
// linkTracking: false // optional, default value: true
|
||||||
});
|
});
|
||||||
|
|
||||||
ReactGA.initialize(gaTrackers, {
|
|
||||||
testMode: process.env.NODE_ENV !== 'production',
|
|
||||||
cookieDomain: 'auto',
|
|
||||||
siteSpeedSampleRate: 100,
|
|
||||||
// un-comment to see events as they are sent to google
|
|
||||||
// debug: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Manually call the first page view
|
// Manually call the first page view
|
||||||
// React Router doesn't include this on `history.listen`
|
// React Router doesn't include this on `history.listen`
|
||||||
// @if TARGET='web'
|
// @if TARGET='web'
|
||||||
|
@ -335,8 +250,6 @@ analytics.pageView(window.location.pathname + window.location.search);
|
||||||
// @endif
|
// @endif
|
||||||
|
|
||||||
// @if TARGET='app'
|
// @if TARGET='app'
|
||||||
ReactGA.set({ checkProtocolTask: null });
|
|
||||||
ReactGA.set({ location: 'https://lbry.tv' });
|
|
||||||
analytics.pageView(
|
analytics.pageView(
|
||||||
window.location.pathname.split('.html')[1] + window.location.search || generateInitialUrl(window.location.hash)
|
window.location.pathname.split('.html')[1] + window.location.search || generateInitialUrl(window.location.hash)
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,7 +5,6 @@ import Icon from 'component/common/icon';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { NavLink } from 'react-router-dom';
|
import { NavLink } from 'react-router-dom';
|
||||||
import { formatLbryUrlForWeb } from 'util/url';
|
import { formatLbryUrlForWeb } from 'util/url';
|
||||||
import { OutboundLink } from 'react-ga';
|
|
||||||
import * as PAGES from 'constants/pages';
|
import * as PAGES from 'constants/pages';
|
||||||
import useCombinedRefs from 'effects/use-combined-refs';
|
import useCombinedRefs from 'effects/use-combined-refs';
|
||||||
|
|
||||||
|
@ -129,19 +128,12 @@ const Button = forwardRef<any, {}>((props: Props, ref: any) => {
|
||||||
{iconRight && <Icon icon={iconRight} iconColor={iconColor} size={size} />}
|
{iconRight && <Icon icon={iconRight} iconColor={iconColor} size={size} />}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
// TODO: replace the below with an outbound link tracker for matomo
|
||||||
if (href) {
|
if (href) {
|
||||||
return (
|
return (
|
||||||
<OutboundLink
|
<a href={href} className={combinedClassName}>
|
||||||
eventLabel="outboundClick"
|
|
||||||
to={href}
|
|
||||||
target="_blank"
|
|
||||||
className={combinedClassName}
|
|
||||||
onClick={onClick}
|
|
||||||
{...otherProps}
|
|
||||||
>
|
|
||||||
{content}
|
{content}
|
||||||
</OutboundLink>
|
</a>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,14 @@ import { Form } from 'component/common/form-components/form';
|
||||||
import { withRouter } from 'react-router-dom';
|
import { withRouter } from 'react-router-dom';
|
||||||
// $FlowFixMe cannot resolve ...
|
// $FlowFixMe cannot resolve ...
|
||||||
import image from 'static/img/unlocklbry.svg';
|
import image from 'static/img/unlocklbry.svg';
|
||||||
|
import { WELCOME_VERSION } from 'config';
|
||||||
|
|
||||||
const FREE = 'free';
|
const FREE = 'free';
|
||||||
const LIMITED = 'limited';
|
const LIMITED = 'limited';
|
||||||
const NONE = 'none';
|
const NONE = 'none';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
setWelcomeVersion: () => void,
|
setWelcomeVersion: number => void,
|
||||||
signOut: () => void,
|
signOut: () => void,
|
||||||
setShareDataInternal: boolean => void,
|
setShareDataInternal: boolean => void,
|
||||||
setShareDataThirdParty: boolean => void,
|
setShareDataThirdParty: boolean => void,
|
||||||
|
@ -37,7 +38,7 @@ function PrivacyAgreement(props: Props) {
|
||||||
setShareDataInternal(false);
|
setShareDataInternal(false);
|
||||||
setShareDataThirdParty(false);
|
setShareDataThirdParty(false);
|
||||||
}
|
}
|
||||||
setWelcomeVersion();
|
setWelcomeVersion(WELCOME_VERSION);
|
||||||
history.replace(`/`);
|
history.replace(`/`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8693,10 +8693,6 @@ react-draggable@^3.3.0:
|
||||||
classnames "^2.2.5"
|
classnames "^2.2.5"
|
||||||
prop-types "^15.6.0"
|
prop-types "^15.6.0"
|
||||||
|
|
||||||
react-ga@^2.5.7:
|
|
||||||
version "2.7.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/react-ga/-/react-ga-2.7.0.tgz#24328f157f31e8cffbf4de74a3396536679d8d7c"
|
|
||||||
|
|
||||||
react-google-recaptcha@^2.0.1:
|
react-google-recaptcha@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-google-recaptcha/-/react-google-recaptcha-2.0.1.tgz#3276b29659493f7ca2a5b7739f6c239293cdf1d8"
|
resolved "https://registry.yarnpkg.com/react-google-recaptcha/-/react-google-recaptcha-2.0.1.tgz#3276b29659493f7ca2a5b7739f6c239293cdf1d8"
|
||||||
|
|
Loading…
Reference in a new issue