@24i/bigscreen-sdk 1.0.7-alpha.2159-1 → 1.0.7-alpha.2161
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -1
- package/packages/analytics/README.md +65 -0
- package/packages/analytics/src/A.ts +51 -0
- package/packages/analytics/src/Analytics.ts +114 -0
- package/packages/analytics/src/analyticsOnScroll.ts +11 -0
- package/packages/analytics/src/clients/ConsoleAnalytics/ConsoleAnalytics.ts +12 -0
- package/packages/analytics/src/clients/ConsoleAnalytics/index.ts +1 -0
- package/packages/analytics/src/clients/GoogleAnalytics/GoogleAnalytics.ts +84 -0
- package/packages/analytics/src/clients/GoogleAnalytics/constants.ts +40 -0
- package/packages/analytics/src/clients/GoogleAnalytics/index.ts +1 -0
- package/packages/analytics/src/clients/GoogleAnalytics/interface.ts +10 -0
- package/packages/analytics/src/clients/GoogleAnalytics/mapPayload.ts +76 -0
- package/packages/analytics/src/constants.ts +56 -0
- package/packages/analytics/src/index.ts +3 -0
- package/packages/analytics/src/interface.ts +82 -0
- package/packages/create-package/dist/createPackage.js +0 -66
- package/packages/create-package/dist/createPackage.js.map +0 -1
- package/packages/create-package/dist/index.js +0 -5
- package/packages/create-package/dist/index.js.map +0 -1
- package/packages/create-package/dist/questionnaire/questions.js +0 -35
- package/packages/create-package/dist/questionnaire/questions.js.map +0 -1
- package/packages/create-package/dist/settings/Settings.js +0 -10
- package/packages/create-package/dist/settings/Settings.js.map +0 -1
- package/packages/create-package/dist/types.js +0 -3
- package/packages/create-package/dist/types.js.map +0 -1
- package/packages/rnv-build-engine/dist/src/constants/buildSchemes.js +0 -14
- package/packages/rnv-build-engine/dist/src/constants/index.js +0 -7
- package/packages/rnv-build-engine/dist/src/constants/platforms.js +0 -14
- package/packages/rnv-build-engine/dist/src/engine.js +0 -94
- package/packages/rnv-build-engine/dist/src/index.js +0 -26
- package/packages/rnv-build-engine/dist/src/resolvers/index.js +0 -29
- package/packages/rnv-build-engine/dist/src/resolvers/resolveBaseUrl.js +0 -31
- package/packages/rnv-build-engine/dist/src/resolvers/resolveBuildFileExtension.js +0 -12
- package/packages/rnv-build-engine/dist/src/resolvers/resolveBuildFileName.js +0 -36
- package/packages/rnv-build-engine/dist/src/resolvers/resolveBuildVersion.js +0 -42
- package/packages/rnv-build-engine/dist/src/resolvers/resolveBuildVersionOffset.js +0 -34
- package/packages/rnv-build-engine/dist/src/resolvers/resolveDeployLocations.js +0 -79
- package/packages/rnv-build-engine/dist/src/resolvers/resolveGenericRnvConfig.js +0 -47
- package/packages/rnv-build-engine/dist/src/resolvers/resolveHbbtvDeployConfig.js +0 -13
- package/packages/rnv-build-engine/dist/src/resolvers/resolveHbbtvDeployUrl.js +0 -11
- package/packages/rnv-build-engine/dist/src/resolvers/resolveHbbtvRemoteBuildDirRelativePath.js +0 -24
- package/packages/rnv-build-engine/dist/src/resolvers/resolveSupportedPlatforms.js +0 -5
- package/packages/rnv-build-engine/dist/src/resolvers/resolveUsedFlavours.js +0 -23
- package/packages/rnv-build-engine/dist/src/resolvers/resolveZippedPlatformBuildsRelativeFilePath.js +0 -14
- package/packages/rnv-build-engine/dist/src/scripts/buildAllWithScheme.js +0 -25
- package/packages/rnv-build-engine/dist/src/scripts/generateDeployUrls/formatTableDataSpaces.js +0 -30
- package/packages/rnv-build-engine/dist/src/scripts/generateDeployUrls/generateDeployUrls.js +0 -90
- package/packages/rnv-build-engine/dist/src/scripts/generateDeployUrls/index.js +0 -4
- package/packages/rnv-build-engine/dist/src/scripts/generateDeployUrls/makeTableDataByScheme.js +0 -63
- package/packages/rnv-build-engine/dist/src/scripts/gitReleaser/afterVersionBump.js +0 -18
- package/packages/rnv-build-engine/dist/src/scripts/gitReleaser/beforeVersionBump.js +0 -12
- package/packages/rnv-build-engine/dist/src/scripts/gitReleaser/checkReleaseNotes.js +0 -16
- package/packages/rnv-build-engine/dist/src/scripts/gitReleaser/pushRelease.js +0 -31
- package/packages/rnv-build-engine/dist/src/scripts/gitReleaser/pushReleaseCandidate.js +0 -6
- package/packages/rnv-build-engine/dist/src/scripts/gitReleaser/pushReleaseNotes.js +0 -37
- package/packages/rnv-build-engine/dist/src/scripts/release/deleteSourceMaps.js +0 -11
- package/packages/rnv-build-engine/dist/src/scripts/release/deployToAppCenter.js +0 -83
- package/packages/rnv-build-engine/dist/src/scripts/release/githubRelease.js +0 -128
- package/packages/rnv-build-engine/dist/src/scripts/release/notifySlack/generateWebhoook.js +0 -66
- package/packages/rnv-build-engine/dist/src/scripts/release/notifySlack/makePayload.js +0 -92
- package/packages/rnv-build-engine/dist/src/scripts/release/notifySlack/notifySlack.js +0 -44
- package/packages/rnv-build-engine/dist/src/scripts/release/notifySlack/slackBlockKitBuilder.js +0 -39
- package/packages/rnv-build-engine/dist/src/scripts/release/sentryRelease.js +0 -85
- package/packages/rnv-build-engine/dist/src/scripts/release/urlsMarkdown.js +0 -62
- package/packages/rnv-build-engine/dist/src/scripts/releaseAllWithScheme.js +0 -79
- package/packages/rnv-build-engine/dist/src/scripts/utils/cmdUtils.js +0 -12
- package/packages/rnv-build-engine/dist/src/scripts/utils/fsUtils.js +0 -33
- package/packages/rnv-build-engine/dist/src/scripts/utils/generateIcons.js +0 -29
- package/packages/rnv-build-engine/dist/src/scripts/utils/gitUtils.js +0 -78
- package/packages/rnv-build-engine/dist/src/scripts/utils/index.js +0 -27
- package/packages/rnv-build-engine/dist/src/scripts/utils/stringUtils.js +0 -5
- package/packages/rnv-build-engine/dist/src/sdks/index.js +0 -42
- package/packages/rnv-build-engine/dist/src/sdks/sdk-tizen/index.js +0 -13
- package/packages/rnv-build-engine/dist/src/sdks/sdk-tizen/sdkTizen.js +0 -240
- package/packages/rnv-build-engine/dist/src/sdks/sdk-utils/index.js +0 -14
- package/packages/rnv-build-engine/dist/src/sdks/sdk-utils/registerSdkPath.js +0 -14
- package/packages/rnv-build-engine/dist/src/sdks/sdk-utils/sdk-installer/index.js +0 -5
- package/packages/rnv-build-engine/dist/src/sdks/sdk-utils/sdk-installer/sdkInstaller.js +0 -39
- package/packages/rnv-build-engine/dist/src/sdks/sdk-utils/sdk-installer/services/clean.js +0 -11
- package/packages/rnv-build-engine/dist/src/sdks/sdk-utils/sdk-installer/services/download.js +0 -74
- package/packages/rnv-build-engine/dist/src/sdks/sdk-utils/sdk-installer/services/index.js +0 -11
- package/packages/rnv-build-engine/dist/src/sdks/sdk-utils/sdk-installer/services/install.js +0 -23
- package/packages/rnv-build-engine/dist/src/sdks/sdk-utils/sdk-installer/services/unzip.js +0 -12
- package/packages/rnv-build-engine/dist/src/sdks/sdk-webos/index.js +0 -13
- package/packages/rnv-build-engine/dist/src/sdks/sdk-webos/sdkWebos.js +0 -135
- package/packages/rnv-build-engine/dist/src/sdks/sdk-webpack/index.js +0 -13
- package/packages/rnv-build-engine/dist/src/sdks/sdk-webpack/sdkWebpack.js +0 -32
- package/packages/rnv-build-engine/dist/src/sdks/sdk-xbox/index.js +0 -13
- package/packages/rnv-build-engine/dist/src/sdks/sdk-xbox/sdkXbox.js +0 -222
- package/packages/rnv-build-engine/dist/src/tasks/deploy/aswS3/aws.js +0 -22
- package/packages/rnv-build-engine/dist/src/tasks/deploy/aswS3/deployS3.js +0 -71
- package/packages/rnv-build-engine/dist/src/tasks/deploy/hbbtv/deployHbbtv.js +0 -94
- package/packages/rnv-build-engine/dist/src/tasks/engineTasks.js +0 -22
- package/packages/rnv-build-engine/dist/src/tasks/task.rnv.build.js +0 -99
- package/packages/rnv-build-engine/dist/src/tasks/task.rnv.configure.js +0 -45
- package/packages/rnv-build-engine/dist/src/tasks/task.rnv.configureSoft.js +0 -31
- package/packages/rnv-build-engine/dist/src/tasks/task.rnv.deploy.js +0 -40
- package/packages/rnv-build-engine/dist/src/tasks/task.rnv.hooks.run.js +0 -71
- package/packages/rnv-build-engine/dist/src/tasks/task.rnv.package.js +0 -19
- package/packages/rnv-build-engine/dist/src/tasks/task.rnv.project.configure.js +0 -116
- package/packages/rnv-build-engine/dist/src/tasks/task.rnv.start.js +0 -72
- package/packages/rnv-build-engine/dist/src/types/c.js +0 -2
- package/packages/rnv-build-engine/dist/src/types/constants.js +0 -2
- package/packages/rnv-build-engine/dist/src/types/index.js +0 -2
- package/packages/rnv-build-engine/dist/src/utils/forEachSupportedPlatformFlavour.js +0 -24
- package/packages/rnv-build-engine/dist/src/utils/generatePngSpriteMap.js +0 -78
- package/packages/rnv-build-engine/dist/src/utils/generateSvgSpriteMap.js +0 -113
- package/packages/rnv-build-engine/dist/src/utils/mergeSvgAndPngIcons.js +0 -61
- package/packages/rnv-build-engine/dist/src/utils/replaceRelevantStringsInConfig/index.js +0 -5
- package/packages/rnv-build-engine/dist/src/utils/replaceRelevantStringsInConfig/replaceRelevantStringsInConfig.js +0 -31
- package/packages/rnv-build-engine/dist/src/utils/replaceRelevantStringsInConfig/replaceTemplateString.js +0 -40
- package/packages/rnv-build-engine/dist/src/utils/zipBuildsByPlatforms.js +0 -61
- package/packages/rnv-build-engine/dist/templates/platforms/_shared/template.js +0 -110
- package/packages/rnv-build-engine/dist/templates/platforms/_shared/utils/extendSass.js +0 -29
- package/packages/rnv-build-engine/dist/templates/platforms/_shared/utils/joinStrings.js +0 -5
- package/packages/rnv-build-engine/dist/templates/platforms/_shared/webpack.base.js +0 -239
- package/packages/rnv-build-engine/dist/templates/platforms/entone/webpack.config.dev.js +0 -63
- package/packages/rnv-build-engine/dist/templates/platforms/entone/webpack.config.prod.js +0 -58
- package/packages/rnv-build-engine/dist/templates/platforms/hbbtv/webpack.config.dev.js +0 -80
- package/packages/rnv-build-engine/dist/templates/platforms/hbbtv/webpack.config.prod.js +0 -75
- package/packages/rnv-build-engine/dist/templates/platforms/kreatv/webpack.config.dev.js +0 -63
- package/packages/rnv-build-engine/dist/templates/platforms/kreatv/webpack.config.prod.js +0 -58
- package/packages/rnv-build-engine/dist/templates/platforms/saphi/webpack.config.dev.js +0 -63
- package/packages/rnv-build-engine/dist/templates/platforms/saphi/webpack.config.prod.js +0 -58
- package/packages/rnv-build-engine/dist/templates/platforms/tizen/project/.project +0 -24
- package/packages/rnv-build-engine/dist/templates/platforms/tizen/project/.tproject +0 -12
- package/packages/rnv-build-engine/dist/templates/platforms/tizen/project/config.xml +0 -17
- package/packages/rnv-build-engine/dist/templates/platforms/tizen/webpack.config.dev.js +0 -64
- package/packages/rnv-build-engine/dist/templates/platforms/tizen/webpack.config.prod.js +0 -58
- package/packages/rnv-build-engine/dist/templates/platforms/webos/project/.project +0 -35
- package/packages/rnv-build-engine/dist/templates/platforms/webos/project/appinfo.json +0 -19
- package/packages/rnv-build-engine/dist/templates/platforms/webos/webpack.config.dev.js +0 -65
- package/packages/rnv-build-engine/dist/templates/platforms/webos/webpack.config.prod.js +0 -58
- package/packages/rnv-build-engine/dist/templates/platforms/webtv/webpack.config.dev.js +0 -63
- package/packages/rnv-build-engine/dist/templates/platforms/webtv/webpack.config.prod.js +0 -58
- package/packages/rnv-build-engine/dist/templates/platforms/xbox/webpack.config.dev.js +0 -64
- package/packages/rnv-build-engine/dist/templates/platforms/xbox/webpack.config.prod.js +0 -58
- package/packages/sdk-installer/dist/index.js +0 -5
- package/packages/sdk-installer/dist/sdkInstaller.js +0 -38
- package/packages/sdk-installer/dist/services/clean.js +0 -11
- package/packages/sdk-installer/dist/services/download.js +0 -55
- package/packages/sdk-installer/dist/services/index.js +0 -11
- package/packages/sdk-installer/dist/services/install.js +0 -24
- package/packages/sdk-installer/dist/services/unzip.js +0 -12
- package/packages/sdk-installer/dist/types/index.d.ts +0 -1
- package/packages/sdk-installer/dist/types/sdkInstaller.d.ts +0 -7
- package/packages/sdk-installer/dist/types/services/clean.d.ts +0 -2
- package/packages/sdk-installer/dist/types/services/download.d.ts +0 -2
- package/packages/sdk-installer/dist/types/services/index.d.ts +0 -4
- package/packages/sdk-installer/dist/types/services/install.d.ts +0 -2
- package/packages/sdk-installer/dist/types/services/unzip.d.ts +0 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@24i/bigscreen-sdk",
|
|
3
|
-
"version": "1.0.7-alpha.
|
|
3
|
+
"version": "1.0.7-alpha.2161",
|
|
4
4
|
"description": "SmartApps BIGscreen SDK monorepo",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"@24i/player-base": "6.10.0",
|
|
41
41
|
"@24i/smartapps-datalayer": "3.0.3",
|
|
42
42
|
"@sentry/browser": "^7.12.1",
|
|
43
|
+
"@types/gtag.js": "^0.0.12",
|
|
43
44
|
"@types/prop-types": "^15.7.5",
|
|
44
45
|
"@types/scheduler": "^0.16.2",
|
|
45
46
|
"csstype": "^3.1.1",
|
|
@@ -80,6 +81,10 @@
|
|
|
80
81
|
},
|
|
81
82
|
"exports": {
|
|
82
83
|
"./adobe-heartbeat": "./packages/adobe-heartbeat/src/index.ts",
|
|
84
|
+
"./analytics/interface": "./packages/analytics/src/interface.ts",
|
|
85
|
+
"./analytics/ConsoleAnalytics": "./packages/analytics/src/clients/ConsoleAnalytics/index.ts",
|
|
86
|
+
"./analytics/GoogleAnalytics": "./packages/analytics/src/clients/GoogleAnalytics/index.ts",
|
|
87
|
+
"./analytics": "./packages/analytics/src/index.ts",
|
|
83
88
|
"./animations/mock": "./packages/animations/src/__mocks__/JSAnimations.ts",
|
|
84
89
|
"./animations": "./packages/animations/src/index.ts",
|
|
85
90
|
"./announcement-banner": "./packages/announcement-banner/src/index.ts",
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: README
|
|
3
|
+
title: Analytics
|
|
4
|
+
hide_title: true
|
|
5
|
+
sidebar_label: Analytics
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Analytics
|
|
9
|
+
This package contains general implementation of analytics and implementation for these clients:
|
|
10
|
+
- ConsoleAnalytics - debugging analytics that dump triggers to the console.
|
|
11
|
+
|
|
12
|
+
## analytics
|
|
13
|
+
Single instance `analytics` is a general manager for analytics clients. It provides a unified
|
|
14
|
+
interface for use by the app without it needing to know any specific analytics client implementation.
|
|
15
|
+
It also adds some general app info to each trigger call (e.g. resolution, language, etc.)
|
|
16
|
+
|
|
17
|
+
## A
|
|
18
|
+
`A` is a shorthand utility function to simplify sending analytics information. It allows setting
|
|
19
|
+
a basic payload that is sent with each trigger call and shallowly merged with trigger payload.
|
|
20
|
+
Trigger payload can override values inside this basic payload.
|
|
21
|
+
|
|
22
|
+
### Usage
|
|
23
|
+
```typescript
|
|
24
|
+
import { A } from '@24i/bigscreen-sdk/analytics';
|
|
25
|
+
|
|
26
|
+
class DetailScene {
|
|
27
|
+
a = A.of({ sceneType: SceneType.DETAIL });
|
|
28
|
+
|
|
29
|
+
activate(params: RouteParams) {
|
|
30
|
+
this.a.addToPayload({
|
|
31
|
+
sceneId: `/detail/${params.assetType}/${params.id}`,
|
|
32
|
+
sceneName: `Detail - ${data.type} - [unknown]`,
|
|
33
|
+
asset: undefined,
|
|
34
|
+
});
|
|
35
|
+
// ...
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async loadAndRenderData() {
|
|
39
|
+
this.a('buffering_start');
|
|
40
|
+
const data = await dataProvider();
|
|
41
|
+
this.a.addToPayload({
|
|
42
|
+
sceneName: `Detail - ${data.type} - ${data.name}`,
|
|
43
|
+
asset: data,
|
|
44
|
+
});
|
|
45
|
+
this.a('buffering_stop');
|
|
46
|
+
// render
|
|
47
|
+
this.a('screen_view');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
It is better to store shorthand `a` function inside the component instance. Some scenes can be
|
|
52
|
+
instantiated multiple times by the router (e.g. Browse in WL). Therefore it cannot use a single
|
|
53
|
+
instance from a local `./analytics'` import for example.
|
|
54
|
+
|
|
55
|
+
## Clients
|
|
56
|
+
Analytics client is the integration to the specific analytics provider (e.g. Google Analytics).
|
|
57
|
+
It needs to implement `AnalyticsClient` interface and register its instance to receive the events.
|
|
58
|
+
|
|
59
|
+
Clients have to opt-in to events they wish to listen to. This can be done by listing all events or by
|
|
60
|
+
using a regular expression.
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
analytics.addClient(new GoogleAnalytics(), ['screen_view', 'buffering_start', 'buffering_stop']);
|
|
64
|
+
analytics.addClient(new ConsoleAnalytics(), /.*/);
|
|
65
|
+
```
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { analytics } from './Analytics';
|
|
2
|
+
import { AnalyticsEventsMap, AnalyticsEventsNames, AnyPayload, AFunction } from './interface';
|
|
3
|
+
|
|
4
|
+
interface PrivateAFunction extends AFunction {
|
|
5
|
+
payload: AnyPayload,
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class A {
|
|
9
|
+
/**
|
|
10
|
+
* Creates an analytics 'a' function for easy triggering of events.
|
|
11
|
+
* @param payload basic payload that is added to each payload of the returned
|
|
12
|
+
* function call.
|
|
13
|
+
* @returns a function for triggering analytics events
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // Creates a function and sets the basic payload.
|
|
17
|
+
* const a = A.of({ sceneType: 'HOME', sceneId: 'home' });
|
|
18
|
+
*
|
|
19
|
+
* // Sends 'screen_view' event with the basic payload.
|
|
20
|
+
* a('screen_view');
|
|
21
|
+
*
|
|
22
|
+
* // Sends 'buffering_stop' with shallow merge of the basic payload and { asset } object.
|
|
23
|
+
* a('buffering_stop', { asset });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
static of(payload: AnyPayload) {
|
|
27
|
+
const a: PrivateAFunction = (<
|
|
28
|
+
EventName extends AnalyticsEventsNames,
|
|
29
|
+
P extends Partial<Parameters<AnalyticsEventsMap[EventName]>[0]>,
|
|
30
|
+
>(eventName: EventName, eventPayload: P) => {
|
|
31
|
+
analytics.triggerEvent(eventName, {
|
|
32
|
+
...a.payload,
|
|
33
|
+
...eventPayload,
|
|
34
|
+
} as unknown as Parameters<AnalyticsEventsMap[EventName]>[0]);
|
|
35
|
+
}) as unknown as PrivateAFunction;
|
|
36
|
+
a.payload = payload;
|
|
37
|
+
a.addToPayload = (extendedPayload: AnyPayload) => {
|
|
38
|
+
a.payload = {
|
|
39
|
+
...a.payload,
|
|
40
|
+
...extendedPayload,
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
a.setPayload = (newPayload: AnyPayload) => {
|
|
44
|
+
a.payload = newPayload;
|
|
45
|
+
};
|
|
46
|
+
a.clearPayload = () => {
|
|
47
|
+
a.payload = {};
|
|
48
|
+
};
|
|
49
|
+
return a as AFunction;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { EventsManager } from '@24i/bigscreen-sdk/events-manager';
|
|
2
|
+
import { i18n } from '@24i/bigscreen-sdk/i18n';
|
|
3
|
+
import type {
|
|
4
|
+
AnalyticsEventsMap,
|
|
5
|
+
AnalyticsEventsNames,
|
|
6
|
+
AnalyticsClient,
|
|
7
|
+
GeneralAppData,
|
|
8
|
+
AppInfo,
|
|
9
|
+
UserInfo,
|
|
10
|
+
} from './interface';
|
|
11
|
+
import { EVENT_NAMES, ONLY_ONCE_EVENTS, UNREPEATABLE_EVENTS } from './constants';
|
|
12
|
+
|
|
13
|
+
class Analytics {
|
|
14
|
+
private events = new EventsManager<AnalyticsEventsMap>();
|
|
15
|
+
|
|
16
|
+
private onlyOnceAlreadySent: string[] = [];
|
|
17
|
+
|
|
18
|
+
private lastPayloadForEvent: Partial<Record<AnalyticsEventsNames, string>> = {};
|
|
19
|
+
|
|
20
|
+
private clients: Record<string, {
|
|
21
|
+
client: AnalyticsClient
|
|
22
|
+
registeredEvents: Partial<Record<AnalyticsEventsNames, Function>>,
|
|
23
|
+
}> = {};
|
|
24
|
+
|
|
25
|
+
private generalAppData: Partial<GeneralAppData> = {
|
|
26
|
+
language: i18n.getLanguage(),
|
|
27
|
+
resolution: `${window.innerWidth}x${window.innerHeight}`,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
private appInfo: Partial<AppInfo> = {};
|
|
31
|
+
|
|
32
|
+
private userInfo: Partial<UserInfo> = {};
|
|
33
|
+
|
|
34
|
+
constructor() {
|
|
35
|
+
i18n.addEventListener('languagechange', this.onLanguageChange);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
addClient(client: AnalyticsClient, events: AnalyticsEventsNames[] | RegExp) {
|
|
39
|
+
if (this.clients[client.name]) {
|
|
40
|
+
throw new Error(`${client.name} analytics client is already registered.`);
|
|
41
|
+
}
|
|
42
|
+
const eventsToRegister = Array.isArray(events)
|
|
43
|
+
? events
|
|
44
|
+
: EVENT_NAMES.filter(events.test.bind(events));
|
|
45
|
+
const registeredEvents: Partial<Record<AnalyticsEventsNames, Function>> = {};
|
|
46
|
+
eventsToRegister.forEach((eventName) => {
|
|
47
|
+
const listener = (payload: any) => {
|
|
48
|
+
client.onEvent(eventName, payload);
|
|
49
|
+
};
|
|
50
|
+
this.events.addEventListener(eventName, listener);
|
|
51
|
+
registeredEvents[eventName] = listener;
|
|
52
|
+
});
|
|
53
|
+
this.clients[client.name] = {
|
|
54
|
+
client: client,
|
|
55
|
+
registeredEvents,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
removeClient(client: AnalyticsClient) {
|
|
60
|
+
if (this.clients[client.name]) {
|
|
61
|
+
const { registeredEvents } = this.clients[client.name];
|
|
62
|
+
Object.keys(registeredEvents).forEach((eventName) => {
|
|
63
|
+
// @ts-ignore - specific payload typing
|
|
64
|
+
this.events.removeEventListener(eventName, registeredEvents[eventName]!);
|
|
65
|
+
});
|
|
66
|
+
delete this.clients[client.name];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
triggerEvent<Event extends AnalyticsEventsNames>(
|
|
71
|
+
event: Event,
|
|
72
|
+
triggerPayload: Parameters<AnalyticsEventsMap[Event]>[0] = undefined,
|
|
73
|
+
) {
|
|
74
|
+
const fullPayload = {
|
|
75
|
+
...this.generalAppData,
|
|
76
|
+
...this.appInfo,
|
|
77
|
+
...this.userInfo,
|
|
78
|
+
...triggerPayload,
|
|
79
|
+
};
|
|
80
|
+
if (ONLY_ONCE_EVENTS.includes(event)) {
|
|
81
|
+
const serializedPayload = `${event} - ${JSON.stringify(fullPayload)}`;
|
|
82
|
+
if (this.onlyOnceAlreadySent.includes(serializedPayload)) return;
|
|
83
|
+
this.onlyOnceAlreadySent.push(serializedPayload);
|
|
84
|
+
}
|
|
85
|
+
if (UNREPEATABLE_EVENTS.includes(event)) {
|
|
86
|
+
const serializedPayload = JSON.stringify(fullPayload);
|
|
87
|
+
if (this.lastPayloadForEvent[event] === serializedPayload) return;
|
|
88
|
+
this.lastPayloadForEvent[event] = serializedPayload;
|
|
89
|
+
}
|
|
90
|
+
this.tryFillUpMissingData();
|
|
91
|
+
// @ts-ignore - payload typing
|
|
92
|
+
this.events.triggerEvent(event, fullPayload);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
setAppInfo(data: Partial<AppInfo>) {
|
|
96
|
+
this.appInfo = data;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
setUserInfo(data: Partial<UserInfo>) {
|
|
100
|
+
this.userInfo = data;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private onLanguageChange = () => {
|
|
104
|
+
this.generalAppData.language = i18n.getLanguage();
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
private tryFillUpMissingData() {
|
|
108
|
+
if (!this.generalAppData.language) {
|
|
109
|
+
this.generalAppData.language = i18n.getLanguage();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export const analytics = new Analytics();
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AFunction } from './interface';
|
|
2
|
+
|
|
3
|
+
export const analyticsOnScroll = (a: AFunction, itemsTotal: number) => (_: any, index: number) => {
|
|
4
|
+
const percent = (index + 1) / itemsTotal;
|
|
5
|
+
/* eslint-disable no-magic-numbers */
|
|
6
|
+
if (percent >= 0.9) a('scroll_90');
|
|
7
|
+
else if (percent >= 0.75) a('scroll_75');
|
|
8
|
+
else if (percent >= 0.50) a('scroll_50');
|
|
9
|
+
else if (percent >= 0.25) a('scroll_25');
|
|
10
|
+
/* eslint-enable no-magic-numbers */
|
|
11
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AnalyticsClient } from '../../interface';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Simple debugging client that dumps all triggers to the console.
|
|
5
|
+
*/
|
|
6
|
+
export class ConsoleAnalytics implements AnalyticsClient {
|
|
7
|
+
name = 'ConsoleAnalytics';
|
|
8
|
+
|
|
9
|
+
onEvent(eventName: string, payload: any) {
|
|
10
|
+
console.info('CA: ', eventName, payload);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ConsoleAnalytics } from './ConsoleAnalytics';
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Storage } from '@24i/bigscreen-sdk/storage';
|
|
2
|
+
import { debounce } from '@24i/bigscreen-sdk/utils/debounce';
|
|
3
|
+
import { generateUuid } from '@24i/bigscreen-sdk/utils/generateUuid';
|
|
4
|
+
import type { AnalyticsClient, AnalyticsEventsMap } from '../../interface';
|
|
5
|
+
import { mapPayload } from './mapPayload';
|
|
6
|
+
import { TRIGGER_NAME_TO_GA_EVENTS } from './constants';
|
|
7
|
+
import { GAEventsNames } from './interface';
|
|
8
|
+
|
|
9
|
+
const SEND_DEBOUNCE_MS = 5000;
|
|
10
|
+
const MAX_QUEUE_LENGTH = 10;
|
|
11
|
+
|
|
12
|
+
const GA_CLIENT_ID = 'GA_client_id';
|
|
13
|
+
|
|
14
|
+
const getGAUrl = (id: string, secret: string) => (
|
|
15
|
+
// You can use the following URL for debugging if the events are not getting collected.
|
|
16
|
+
// `https://www.google-analytics.com/debug/mp/collect?measurement_id=${id}&api_secret=${secret}`
|
|
17
|
+
`https://www.google-analytics.com/mp/collect?measurement_id=${id}&api_secret=${secret}`
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
export class GoogleAnalytics implements AnalyticsClient {
|
|
21
|
+
name = 'GoogleAnalytics';
|
|
22
|
+
|
|
23
|
+
clientId = '';
|
|
24
|
+
|
|
25
|
+
sessionId = generateUuid();
|
|
26
|
+
|
|
27
|
+
a24iOperational = false;
|
|
28
|
+
|
|
29
|
+
eventsQueue: { name: GAEventsNames, params: Record<string, any> }[] = [];
|
|
30
|
+
|
|
31
|
+
constructor(private id: string, private secret: string) {
|
|
32
|
+
this.init();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async init() {
|
|
36
|
+
this.clientId = await Storage.getItem(GA_CLIENT_ID) ?? '';
|
|
37
|
+
if (!this.clientId) {
|
|
38
|
+
this.clientId = generateUuid();
|
|
39
|
+
await Storage.setItem(GA_CLIENT_ID, this.clientId);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
onEvent<Event extends keyof AnalyticsEventsMap>(
|
|
44
|
+
triggerName: Event,
|
|
45
|
+
payload: Parameters<AnalyticsEventsMap[Event]>,
|
|
46
|
+
): void {
|
|
47
|
+
const events = TRIGGER_NAME_TO_GA_EVENTS[triggerName];
|
|
48
|
+
events.forEach(async (event) => {
|
|
49
|
+
if (event === 'a24i_operational' && !this.shouldContinueWithA24iOperational()) return;
|
|
50
|
+
const gtagPayload = mapPayload(event, triggerName, this.sessionId, payload);
|
|
51
|
+
this.send(event, gtagPayload);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private send(name: GAEventsNames, params: Record<string, any>) {
|
|
56
|
+
this.eventsQueue.push({ name, params });
|
|
57
|
+
if (this.eventsQueue.length >= MAX_QUEUE_LENGTH) {
|
|
58
|
+
this.sendQueue();
|
|
59
|
+
} else {
|
|
60
|
+
this.sendQueueWithDelay();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private sendQueue = () => {
|
|
65
|
+
const body = JSON.stringify({
|
|
66
|
+
client_id: this.clientId,
|
|
67
|
+
events: this.eventsQueue,
|
|
68
|
+
});
|
|
69
|
+
this.eventsQueue.length = 0;
|
|
70
|
+
try {
|
|
71
|
+
fetch(getGAUrl(this.id, this.secret), { method: 'POST', body });
|
|
72
|
+
} catch (e) {
|
|
73
|
+
// Effort to send was made.
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
private sendQueueWithDelay = debounce(this.sendQueue, SEND_DEBOUNCE_MS);
|
|
78
|
+
|
|
79
|
+
private shouldContinueWithA24iOperational() {
|
|
80
|
+
const { a24iOperational } = this;
|
|
81
|
+
if (!a24iOperational) this.a24iOperational = true;
|
|
82
|
+
return !a24iOperational;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { AnalyticsEventsNames } from '../../interface';
|
|
2
|
+
import { GAEventsNames } from './interface';
|
|
3
|
+
|
|
4
|
+
export const TRIGGER_NAME_TO_GA_EVENTS: Record<AnalyticsEventsNames, GAEventsNames[]> = {
|
|
5
|
+
// App
|
|
6
|
+
'app_close': ['app_close', 'video_progress'],
|
|
7
|
+
|
|
8
|
+
// Data loading / Player buffering
|
|
9
|
+
'buffering_start': ['buffering_start'],
|
|
10
|
+
'buffering_stop': ['buffering_start'],
|
|
11
|
+
|
|
12
|
+
// Heartbeat
|
|
13
|
+
'heartbeat_5': ['a24i_content'],
|
|
14
|
+
|
|
15
|
+
// Playback
|
|
16
|
+
'playback_10': ['video_progress'],
|
|
17
|
+
'playback_25': ['video_progress'],
|
|
18
|
+
'playback_50': ['video_progress'],
|
|
19
|
+
'playback_75': ['video_progress'],
|
|
20
|
+
'playback_90': ['video_progress'],
|
|
21
|
+
'playback_pause': ['video_progress'],
|
|
22
|
+
'playback_start': ['video_start'],
|
|
23
|
+
'playback_stop': ['video_progress'],
|
|
24
|
+
|
|
25
|
+
// Player
|
|
26
|
+
'player_close': ['a24i_content', 'video_progress'],
|
|
27
|
+
'player_open': ['a24i_content'],
|
|
28
|
+
|
|
29
|
+
// Scenes
|
|
30
|
+
'screen_view': [
|
|
31
|
+
'page_view',
|
|
32
|
+
'a24i_operational',
|
|
33
|
+
],
|
|
34
|
+
|
|
35
|
+
// Scrolling in scene
|
|
36
|
+
'scroll_25': ['scroll'],
|
|
37
|
+
'scroll_50': ['scroll'],
|
|
38
|
+
'scroll_75': ['scroll'],
|
|
39
|
+
'scroll_90': ['scroll'],
|
|
40
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { GoogleAnalytics } from './GoogleAnalytics';
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AnalyticsEventsNames,
|
|
3
|
+
GeneralAppData,
|
|
4
|
+
SceneInfo,
|
|
5
|
+
AppInfo,
|
|
6
|
+
UserInfo,
|
|
7
|
+
} from '../../interface';
|
|
8
|
+
import type { GAEventsNames } from './interface';
|
|
9
|
+
|
|
10
|
+
const MILI_TO_MICRO = 10;
|
|
11
|
+
|
|
12
|
+
const camelToSnake = (name: string) => (
|
|
13
|
+
name.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`)
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const addKeyIfExists = <T extends string>(
|
|
17
|
+
keyName: T,
|
|
18
|
+
payload: { [key in typeof keyName]?: any },
|
|
19
|
+
gtagPayload: Record<string, any>,
|
|
20
|
+
) => {
|
|
21
|
+
if (payload[keyName]) gtagPayload[camelToSnake(keyName)] = payload[keyName];
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const mapGeneralData = (payload: Partial<GeneralAppData>) => {
|
|
25
|
+
const gtagPayloadGeneralData: Partial<GeneralAppData> = {};
|
|
26
|
+
addKeyIfExists('language', payload, gtagPayloadGeneralData);
|
|
27
|
+
addKeyIfExists('resolution', payload, gtagPayloadGeneralData);
|
|
28
|
+
return gtagPayloadGeneralData;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const mapSceneInfo = (payload: Partial<SceneInfo>) => {
|
|
32
|
+
const gtagPayloadSceneInfo: Partial<SceneInfo> = {};
|
|
33
|
+
addKeyIfExists('sceneId', payload, gtagPayloadSceneInfo);
|
|
34
|
+
addKeyIfExists('sceneType', payload, gtagPayloadSceneInfo);
|
|
35
|
+
addKeyIfExists('sceneName', payload, gtagPayloadSceneInfo);
|
|
36
|
+
return gtagPayloadSceneInfo;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const mapAppData = (payload: Partial<AppInfo>) => {
|
|
40
|
+
const gtagPayloadAppInfo: Partial<AppInfo> = {};
|
|
41
|
+
addKeyIfExists('applicationId', payload, gtagPayloadAppInfo);
|
|
42
|
+
addKeyIfExists('serviceId', payload, gtagPayloadAppInfo);
|
|
43
|
+
return gtagPayloadAppInfo;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const mapUserData = (payload: Partial<UserInfo>) => {
|
|
47
|
+
const gtagPayloadUserInfo: Partial<UserInfo> = {};
|
|
48
|
+
addKeyIfExists('userId', payload, gtagPayloadUserInfo);
|
|
49
|
+
return gtagPayloadUserInfo;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const mapPayload = (
|
|
53
|
+
eventName: GAEventsNames,
|
|
54
|
+
triggerName: AnalyticsEventsNames,
|
|
55
|
+
sessionId: string,
|
|
56
|
+
payload: Record<string, any>,
|
|
57
|
+
) => {
|
|
58
|
+
let gtagPayload: Record<string, any> = {
|
|
59
|
+
session_id: sessionId,
|
|
60
|
+
event_trigger: triggerName,
|
|
61
|
+
timestamp_micros: Date.now() * MILI_TO_MICRO,
|
|
62
|
+
...mapGeneralData(payload),
|
|
63
|
+
...mapAppData(payload),
|
|
64
|
+
...mapUserData(payload),
|
|
65
|
+
};
|
|
66
|
+
if (eventName === 'page_view' || eventName === 'buffering_start') {
|
|
67
|
+
gtagPayload = {
|
|
68
|
+
...gtagPayload,
|
|
69
|
+
...mapSceneInfo(payload),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (eventName === 'scroll') {
|
|
73
|
+
gtagPayload.percent_scroll = parseInt(triggerName.split('_')[1], 10);
|
|
74
|
+
}
|
|
75
|
+
return gtagPayload;
|
|
76
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { AnalyticsEventsNames } from './interface';
|
|
2
|
+
|
|
3
|
+
export const EVENT_NAMES = [
|
|
4
|
+
// App
|
|
5
|
+
'app_close',
|
|
6
|
+
|
|
7
|
+
// Data loading / Player buffering
|
|
8
|
+
'buffering_start',
|
|
9
|
+
'buffering_stop',
|
|
10
|
+
|
|
11
|
+
// Heartbeat
|
|
12
|
+
'heartbeat_5',
|
|
13
|
+
|
|
14
|
+
// Playback
|
|
15
|
+
'playback_10',
|
|
16
|
+
'playback_25',
|
|
17
|
+
'playback_50',
|
|
18
|
+
'playback_75',
|
|
19
|
+
'playback_90',
|
|
20
|
+
'playback_pause',
|
|
21
|
+
'playback_start',
|
|
22
|
+
'playback_stop',
|
|
23
|
+
|
|
24
|
+
// Player
|
|
25
|
+
'player_close',
|
|
26
|
+
'player_open',
|
|
27
|
+
|
|
28
|
+
// Scenes
|
|
29
|
+
'screen_view',
|
|
30
|
+
|
|
31
|
+
// Scrolling in scene
|
|
32
|
+
'scroll_25',
|
|
33
|
+
'scroll_50',
|
|
34
|
+
'scroll_75',
|
|
35
|
+
'scroll_90',
|
|
36
|
+
] as const;
|
|
37
|
+
|
|
38
|
+
export const ONLY_ONCE_EVENTS: AnalyticsEventsNames[] = [
|
|
39
|
+
// Playback
|
|
40
|
+
'playback_10',
|
|
41
|
+
'playback_25',
|
|
42
|
+
'playback_50',
|
|
43
|
+
'playback_75',
|
|
44
|
+
'playback_90',
|
|
45
|
+
|
|
46
|
+
// Scrolling in scene
|
|
47
|
+
'scroll_25',
|
|
48
|
+
'scroll_50',
|
|
49
|
+
'scroll_75',
|
|
50
|
+
'scroll_90',
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
export const UNREPEATABLE_EVENTS: AnalyticsEventsNames[] = [
|
|
54
|
+
// Scenes
|
|
55
|
+
'screen_view',
|
|
56
|
+
];
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export type SceneInfo = {
|
|
2
|
+
sceneId: string,
|
|
3
|
+
sceneType: string,
|
|
4
|
+
sceneName: string,
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export type AppInfo = {
|
|
8
|
+
applicationId: string,
|
|
9
|
+
serviceId: string,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type UserInfo = {
|
|
13
|
+
userId: string,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type GeneralAppData = {
|
|
17
|
+
language: string,
|
|
18
|
+
resolution: string,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* List of all tracked events.
|
|
23
|
+
*/
|
|
24
|
+
export type AnalyticsEventsMap = {
|
|
25
|
+
// App
|
|
26
|
+
'app_close': (payload: void) => void,
|
|
27
|
+
|
|
28
|
+
// Data loading / Player buffering
|
|
29
|
+
'buffering_start': (payload: SceneInfo) => void,
|
|
30
|
+
'buffering_stop': (payload: SceneInfo) => void,
|
|
31
|
+
|
|
32
|
+
// Heartbeat
|
|
33
|
+
'heartbeat_5': (payload: void) => void,
|
|
34
|
+
|
|
35
|
+
// Playback
|
|
36
|
+
'playback_10': (payload: void) => void,
|
|
37
|
+
'playback_25': (payload: void) => void,
|
|
38
|
+
'playback_50': (payload: void) => void,
|
|
39
|
+
'playback_75': (payload: void) => void,
|
|
40
|
+
'playback_90': (payload: void) => void,
|
|
41
|
+
'playback_pause': (payload: void) => void,
|
|
42
|
+
'playback_start': (payload: void) => void,
|
|
43
|
+
'playback_stop': (payload: void) => void,
|
|
44
|
+
|
|
45
|
+
// Player
|
|
46
|
+
'player_close': (payload: void) => void,
|
|
47
|
+
'player_open': (payload: void) => void,
|
|
48
|
+
|
|
49
|
+
// Scenes
|
|
50
|
+
'screen_view': (payload: SceneInfo) => void,
|
|
51
|
+
|
|
52
|
+
// Scrolling in scene
|
|
53
|
+
'scroll_25': (payload: SceneInfo) => void,
|
|
54
|
+
'scroll_50': (payload: SceneInfo) => void,
|
|
55
|
+
'scroll_75': (payload: SceneInfo) => void,
|
|
56
|
+
'scroll_90': (payload: SceneInfo) => void,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export type AnalyticsEventsNames = keyof AnalyticsEventsMap;
|
|
60
|
+
|
|
61
|
+
export interface AnalyticsClient {
|
|
62
|
+
name: string,
|
|
63
|
+
onEvent<Event extends keyof AnalyticsEventsMap>(
|
|
64
|
+
eventName: Event,
|
|
65
|
+
payload: Parameters<AnalyticsEventsMap[Event]>,
|
|
66
|
+
): void;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export type AnyPayload = Record<string, any>;
|
|
70
|
+
|
|
71
|
+
export interface AFunction {
|
|
72
|
+
<
|
|
73
|
+
EventName extends AnalyticsEventsNames,
|
|
74
|
+
P extends Partial<Parameters<AnalyticsEventsMap[EventName]>[0]>,
|
|
75
|
+
>(eventName: EventName, payload?: P): void,
|
|
76
|
+
|
|
77
|
+
addToPayload(payload: AnyPayload): void,
|
|
78
|
+
|
|
79
|
+
setPayload(payload: AnyPayload): void,
|
|
80
|
+
|
|
81
|
+
clearPayload(): void,
|
|
82
|
+
}
|