commit
43e8c49dcc
7 changed files with 52 additions and 2 deletions
|
@ -10,3 +10,5 @@ LBRY_WEB_API=https://api.lbry.tv
|
||||||
LBRY_WEB_STREAMING_API=https://cdn.lbryplayer.xyz
|
LBRY_WEB_STREAMING_API=https://cdn.lbryplayer.xyz
|
||||||
WELCOME_VERSION=1.0
|
WELCOME_VERSION=1.0
|
||||||
DEFAULT_LANGUAGE=en
|
DEFAULT_LANGUAGE=en
|
||||||
|
MATOMO_URL=https://analytics.lbry.com/
|
||||||
|
MATOMO_ID=6
|
||||||
|
|
|
@ -12,6 +12,8 @@ const config = {
|
||||||
LBRY_WEB_STREAMING_API: process.env.LBRY_WEB_STREAMING_API, //cdn.lbryplayer.xyz',
|
LBRY_WEB_STREAMING_API: process.env.LBRY_WEB_STREAMING_API, //cdn.lbryplayer.xyz',
|
||||||
WELCOME_VERSION: process.env.WELCOME_VERSION,
|
WELCOME_VERSION: process.env.WELCOME_VERSION,
|
||||||
DEFAULT_LANGUAGE: process.env.DEFAULT_LANGUAGE,
|
DEFAULT_LANGUAGE: process.env.DEFAULT_LANGUAGE,
|
||||||
|
MATOMO_URL: process.env.MATOMO_URL,
|
||||||
|
MATOMO_ID: process.env.MATOMO_ID,
|
||||||
LOGO_TITLE: process.env.LOGO_TITLE,
|
LOGO_TITLE: process.env.LOGO_TITLE,
|
||||||
PINNED_URI_1: process.env.PINNED_URI_1,
|
PINNED_URI_1: process.env.PINNED_URI_1,
|
||||||
PINNED_LABEL_1: process.env.PINNED_LABEL_1,
|
PINNED_LABEL_1: process.env.PINNED_LABEL_1,
|
||||||
|
|
|
@ -67,6 +67,7 @@
|
||||||
"@babel/preset-flow": "^7.0.0",
|
"@babel/preset-flow": "^7.0.0",
|
||||||
"@babel/preset-react": "^7.0.0",
|
"@babel/preset-react": "^7.0.0",
|
||||||
"@babel/register": "^7.0.0",
|
"@babel/register": "^7.0.0",
|
||||||
|
"@datapunt/matomo-tracker-js": "^0.1.4",
|
||||||
"@exponent/electron-cookies": "^2.0.0",
|
"@exponent/electron-cookies": "^2.0.0",
|
||||||
"@hot-loader/react-dom": "^16.8",
|
"@hot-loader/react-dom": "^16.8",
|
||||||
"@lbry/components": "^4.2.2",
|
"@lbry/components": "^4.2.2",
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import ReactGA from 'react-ga';
|
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 { history } from './store';
|
import { history } from './store';
|
||||||
import { SDK_API_PATH } from './index';
|
import { SDK_API_PATH } from './index';
|
||||||
// @if TARGET='app'
|
// @if TARGET='app'
|
||||||
|
@ -9,6 +10,7 @@ import Native from 'native';
|
||||||
import ElectronCookies from '@exponent/electron-cookies';
|
import ElectronCookies from '@exponent/electron-cookies';
|
||||||
import { generateInitialUrl } from 'util/url';
|
import { generateInitialUrl } from 'util/url';
|
||||||
// @endif
|
// @endif
|
||||||
|
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;
|
||||||
|
@ -38,7 +40,7 @@ type Analytics = {
|
||||||
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,
|
||||||
tagFollowEvent: (string, boolean, string) => void,
|
tagFollowEvent: (string, boolean, ?string) => void,
|
||||||
videoStartEvent: (string, number) => void,
|
videoStartEvent: (string, number) => void,
|
||||||
videoBufferEvent: (string, number) => void,
|
videoBufferEvent: (string, number) => void,
|
||||||
emailProvidedEvent: () => void,
|
emailProvidedEvent: () => void,
|
||||||
|
@ -93,6 +95,11 @@ const analytics: Analytics = {
|
||||||
if (thirdPartyAnalyticsEnabled) {
|
if (thirdPartyAnalyticsEnabled) {
|
||||||
ReactGA.pageview(path, [SECOND_TRACKER_NAME]);
|
ReactGA.pageview(path, [SECOND_TRACKER_NAME]);
|
||||||
}
|
}
|
||||||
|
if (internalAnalyticsEnabled) {
|
||||||
|
MatomoInstance.trackPageView({
|
||||||
|
href: `${path}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
setUser: userId => {
|
setUser: userId => {
|
||||||
if (thirdPartyAnalyticsEnabled && userId) {
|
if (thirdPartyAnalyticsEnabled && userId) {
|
||||||
|
@ -185,41 +192,52 @@ const analytics: Analytics = {
|
||||||
videoStartEvent: (claimId, duration) => {
|
videoStartEvent: (claimId, duration) => {
|
||||||
sendGaTimingEvent('Media', 'TimeToStart', duration, claimId);
|
sendGaTimingEvent('Media', 'TimeToStart', duration, claimId);
|
||||||
sendPromMetric('time_to_start', duration);
|
sendPromMetric('time_to_start', duration);
|
||||||
|
sendMatomoEvent('Media', 'TimeToStart', claimId, duration);
|
||||||
},
|
},
|
||||||
videoBufferEvent: (claimId, currentTime) => {
|
videoBufferEvent: (claimId, currentTime) => {
|
||||||
sendGaTimingEvent('Media', 'BufferTimestamp', currentTime * 1000, claimId);
|
sendGaTimingEvent('Media', 'BufferTimestamp', currentTime * 1000, claimId);
|
||||||
sendPromMetric('buffer');
|
sendPromMetric('buffer');
|
||||||
|
sendMatomoEvent('Media', 'BufferTimestamp', claimId, currentTime * 1000);
|
||||||
},
|
},
|
||||||
tagFollowEvent: (tag, following, location) => {
|
tagFollowEvent: (tag, following) => {
|
||||||
sendGaEvent(following ? 'Tag-Follow' : 'Tag-Unfollow', tag);
|
sendGaEvent(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);
|
sendGaEvent(blocked ? 'Channel-Hidden' : 'Channel-Unhidden', uri);
|
||||||
|
sendMatomoEvent(blocked ? 'Channel-Hidden' : 'Channel-Unhidden', uri);
|
||||||
},
|
},
|
||||||
emailProvidedEvent: () => {
|
emailProvidedEvent: () => {
|
||||||
sendGaEvent('Engagement', 'Email-Provided');
|
sendGaEvent('Engagement', 'Email-Provided');
|
||||||
|
sendMatomoEvent('Engagement', 'Email-Provided');
|
||||||
},
|
},
|
||||||
emailVerifiedEvent: () => {
|
emailVerifiedEvent: () => {
|
||||||
sendGaEvent('Engagement', 'Email-Verified');
|
sendGaEvent('Engagement', 'Email-Verified');
|
||||||
|
sendMatomoEvent('Engagement', 'Email-Verified');
|
||||||
},
|
},
|
||||||
rewardEligibleEvent: () => {
|
rewardEligibleEvent: () => {
|
||||||
sendGaEvent('Engagement', 'Reward-Eligible');
|
sendGaEvent('Engagement', 'Reward-Eligible');
|
||||||
|
sendMatomoEvent('Engagement', 'Reward-Eligible');
|
||||||
},
|
},
|
||||||
openUrlEvent: (url: string) => {
|
openUrlEvent: (url: string) => {
|
||||||
sendGaEvent('Engagement', 'Open-Url', url);
|
sendGaEvent('Engagement', 'Open-Url', url);
|
||||||
|
sendMatomoEvent('Engagement', 'Open-Url', url);
|
||||||
},
|
},
|
||||||
trendingAlgorithmEvent: (trendingAlgorithm: string) => {
|
trendingAlgorithmEvent: (trendingAlgorithm: string) => {
|
||||||
sendGaEvent('Engagement', 'Trending-Algorithm', trendingAlgorithm);
|
sendGaEvent('Engagement', 'Trending-Algorithm', trendingAlgorithm);
|
||||||
},
|
},
|
||||||
startupEvent: () => {
|
startupEvent: () => {
|
||||||
sendGaEvent('Startup', 'Startup');
|
sendGaEvent('Startup', 'Startup');
|
||||||
|
sendMatomoEvent('Startup', 'Startup');
|
||||||
},
|
},
|
||||||
readyEvent: (timeToReady: number) => {
|
readyEvent: (timeToReady: number) => {
|
||||||
sendGaEvent('Startup', 'App-Ready');
|
sendGaEvent('Startup', 'App-Ready');
|
||||||
sendGaTimingEvent('Startup', 'App-Ready', timeToReady);
|
sendGaTimingEvent('Startup', 'App-Ready', timeToReady);
|
||||||
|
sendMatomoEvent('Startup', 'App-Ready', 'Time', timeToReady);
|
||||||
},
|
},
|
||||||
purchaseEvent: (purchaseInt: number) => {
|
purchaseEvent: (purchaseInt: number) => {
|
||||||
sendGaEvent('Purchase', 'Purchase-Complete', undefined, purchaseInt);
|
sendGaEvent('Purchase', 'Purchase-Complete', undefined, purchaseInt);
|
||||||
|
sendMatomoEvent('Purchase', 'Purchase-Complete', 'someLabel', purchaseInt);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -237,6 +255,13 @@ function sendGaEvent(category, action, label, value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sendMatomoEvent(category, action, name, value) {
|
||||||
|
if (internalAnalyticsEnabled) {
|
||||||
|
const event = { category, action, name, value };
|
||||||
|
MatomoInstance.trackEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function sendGaTimingEvent(category: string, action: string, timeInMs: number, label?: string) {
|
function sendGaTimingEvent(category: string, action: string, timeInMs: number, label?: string) {
|
||||||
if (thirdPartyAnalyticsEnabled && isProduction) {
|
if (thirdPartyAnalyticsEnabled && isProduction) {
|
||||||
ReactGA.timing(
|
ReactGA.timing(
|
||||||
|
@ -285,6 +310,16 @@ if (!IS_WEB) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MatomoInstance = new MatomoTracker({
|
||||||
|
urlBase: MATOMO_URL,
|
||||||
|
siteId: MATOMO_ID, // optional, default value: `1`
|
||||||
|
// heartBeat: { // optional, enabled by default
|
||||||
|
// active: true, // optional, default value: true
|
||||||
|
// seconds: 10 // optional, default value: `15
|
||||||
|
// },
|
||||||
|
// linkTracking: false // optional, default value: true
|
||||||
|
});
|
||||||
|
|
||||||
ReactGA.initialize(gaTrackers, {
|
ReactGA.initialize(gaTrackers, {
|
||||||
testMode: process.env.NODE_ENV !== 'production',
|
testMode: process.env.NODE_ENV !== 'production',
|
||||||
cookieDomain: 'auto',
|
cookieDomain: 'auto',
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { Form, FormField } from 'component/common/form';
|
||||||
import Tag from 'component/tag';
|
import Tag from 'component/tag';
|
||||||
import { setUnion, setDifference } from 'util/set-operations';
|
import { setUnion, setDifference } from 'util/set-operations';
|
||||||
import I18nMessage from 'component/i18nMessage';
|
import I18nMessage from 'component/i18nMessage';
|
||||||
|
import analytics from 'analytics';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
tagsPassedIn: Array<Tag>,
|
tagsPassedIn: Array<Tag>,
|
||||||
|
@ -120,7 +121,9 @@ export default function TagsSearch(props: Props) {
|
||||||
if (onSelect) {
|
if (onSelect) {
|
||||||
onSelect([{ name: tag }]);
|
onSelect([{ name: tag }]);
|
||||||
} else {
|
} else {
|
||||||
|
const wasFollowing = followedTags.map(t => t.name).includes(tag);
|
||||||
doToggleTagFollowDesktop(tag);
|
doToggleTagFollowDesktop(tag);
|
||||||
|
analytics.tagFollowEvent(tag, !wasFollowing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -10,6 +10,8 @@ LBRY_WEB_API=https://api.lbry.tv
|
||||||
LBRY_WEB_STREAMING_API=https://cdn.lbryplayer.xyz
|
LBRY_WEB_STREAMING_API=https://cdn.lbryplayer.xyz
|
||||||
WELCOME_VERSION=1.0
|
WELCOME_VERSION=1.0
|
||||||
DEFAULT_LANGUAGE=en
|
DEFAULT_LANGUAGE=en
|
||||||
|
MATOMO_URL=https://analytics.lbry.com/
|
||||||
|
MATOMO_ID=3
|
||||||
# If true, supply copy example to homepage.js in
|
# If true, supply copy example to homepage.js in
|
||||||
CUSTOM_HOMEPAGE=false
|
CUSTOM_HOMEPAGE=false
|
||||||
# Add up to 2 sidebar links:
|
# Add up to 2 sidebar links:
|
||||||
|
|
|
@ -803,6 +803,11 @@
|
||||||
lodash "^4.17.13"
|
lodash "^4.17.13"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
|
"@datapunt/matomo-tracker-js@^0.1.4":
|
||||||
|
version "0.1.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@datapunt/matomo-tracker-js/-/matomo-tracker-js-0.1.4.tgz#1226f0964d2c062bf9392e9c2fd89838262b10df"
|
||||||
|
integrity sha512-bi8/guszgciSNLJQIFgph27AzkiCF1DmLBxtmJE3CsLxfc0aTgI2vMg3EFoLv13Mu8HLaCs27Z7vbttlD6jp5w==
|
||||||
|
|
||||||
"@develar/schema-utils@~2.1.0":
|
"@develar/schema-utils@~2.1.0":
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@develar/schema-utils/-/schema-utils-2.1.0.tgz#eceb1695bfbed6f6bb84666d5d3abe5e1fd54e17"
|
resolved "https://registry.yarnpkg.com/@develar/schema-utils/-/schema-utils-2.1.0.tgz#eceb1695bfbed6f6bb84666d5d3abe5e1fd54e17"
|
||||||
|
|
Loading…
Reference in a new issue