@24i/bigscreen-sdk 1.0.34-alpha.2570 → 1.0.34-beta.1

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.
Files changed (24) hide show
  1. package/.vscode/settings.json +0 -1
  2. package/package.json +2 -2
  3. package/packages/analytics/src/clients/TealiumAnalytics/TealiumAnalytics.ts +15 -24
  4. package/packages/analytics/src/clients/TealiumAnalytics/constants.ts +12 -13
  5. package/packages/analytics/src/clients/TealiumAnalytics/index.ts +0 -1
  6. package/packages/analytics/src/clients/TealiumAnalytics/interface.ts +0 -2
  7. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapBase.ts +1 -0
  8. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapPlayerClose.ts +24 -9
  9. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapPlayerOpen.ts +24 -9
  10. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearchFailed.ts +7 -2
  11. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearchSuccess.ts +7 -2
  12. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoPause.ts +24 -9
  13. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoProgress.ts +18 -6
  14. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoResume.ts +24 -9
  15. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoStart.ts +24 -9
  16. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoStop.ts +24 -9
  17. package/packages/analytics/src/clients/TealiumAnalytics/types.ts +26 -43
  18. package/packages/driver-base/src/DeviceBase.ts +0 -34
  19. package/packages/player-ui/src/PauseButton.tsx +0 -8
  20. package/packages/router/src/utils.ts +1 -1
  21. package/packages/analytics/src/clients/TealiumAnalytics/mappers/__mocks__/mediaPayload.ts +0 -40
  22. package/packages/analytics/src/clients/TealiumAnalytics/mappers/helper.ts +0 -21
  23. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapAppError.ts +0 -14
  24. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearch.ts +0 -18
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "cSpell.words": [
3
- "MEDIAPAYLOAD",
4
3
  "Tealium"
5
4
  ]
6
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@24i/bigscreen-sdk",
3
- "version": "1.0.34-alpha.2570",
3
+ "version": "1.0.34-beta.1",
4
4
  "description": "SmartApps BIGscreen SDK monorepo",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "homepage": "https://github.com/24i/smartapps-bigscreen-sdk#readme",
39
39
  "dependencies": {
40
- "@24i/appstage-shared-analytics": "1.0.20-alpha.70",
40
+ "@24i/appstage-shared-analytics": "1.0.19",
41
41
  "@24i/appstage-shared-events-manager": "1.0.11",
42
42
  "@24i/appstage-shared-perf-utils": "1.0.11",
43
43
  "@24i/bigscreen-players-engine-base": "3.0.2",
@@ -14,12 +14,9 @@ import type { AnalyticsClient, AnyPayload } from '../../interface';
14
14
  import type {
15
15
  BaseResult,
16
16
  Payload,
17
- TealiumAnalyticsOptions,
18
- UtagWindow,
17
+ TealiumAnalyticsConfiguration,
19
18
  } from './types';
20
19
 
21
- declare const window: Window & UtagWindow;
22
-
23
20
  // eslint-disable-next-line no-magic-numbers
24
21
  const SESSION_TIMEOUT = 30 * MINUTE_IN_MS;
25
22
 
@@ -43,26 +40,28 @@ export class TealiumAnalytics implements AnalyticsClient {
43
40
 
44
41
  constantPayload: BaseResult = DEFAULT_PAYLOAD;
45
42
 
43
+ baseURL = '';
44
+
46
45
  sessionTimeout = createTimeout();
47
46
 
48
47
  isSessionActive = false;
49
48
 
50
49
  sessionStartSent = false;
51
50
 
52
- constructor(private config: TealiumAnalyticsOptions, private appVersion: string = '') {
51
+ constructor(private config: TealiumAnalyticsConfiguration, private appVersion: string = '') {
53
52
  this.init();
54
53
  }
55
54
 
56
55
  async init() {
57
56
  // Typically set "noview" flag to true for Single Page Apps (SPAs)
58
- window.utag_cfg_ovrd = { noview: true };
59
- window.utag_data = {};
57
+ (window as any).utag_cfg_ovrd = { noview: true };
58
+ (window as any).utag_data = {};
60
59
  this.loadScript();
61
60
  this.prepareDatasetPayload();
62
61
  }
63
62
 
64
63
  prepareDatasetPayload() {
65
- const { entity, language } = this.config;
64
+ const { entity, language } = this.config.options;
66
65
  this.constantPayload = {
67
66
  language,
68
67
  language_service: `${entity} ${language}`,
@@ -94,7 +93,7 @@ export class TealiumAnalytics implements AnalyticsClient {
94
93
  }
95
94
 
96
95
  loadScript() {
97
- const { account, profile, environment } = this.config;
96
+ const { account, profile, environment } = this.config.options;
98
97
  const url = `//tags.tiqcdn.com/utag/${account}/${profile}/${environment}/utag.js`;
99
98
 
100
99
  const script = document.createElement('script');
@@ -105,22 +104,16 @@ export class TealiumAnalytics implements AnalyticsClient {
105
104
  console.log('Tealium was loaded.');
106
105
  await this.startSession();
107
106
  }, false);
108
- const scriptElements = document.getElementsByTagName('script');
109
- if (scriptElements.length > 0) {
110
- const scriptElement = scriptElements[0];
111
- scriptElement.parentNode!.insertBefore(script, scriptElement);
112
- } else {
113
- document.body.appendChild(script);
114
- }
107
+ const t = document.getElementsByTagName('script')[0];
108
+ t.parentNode!.insertBefore(script, t);
115
109
  }
116
110
 
117
- track(tealiumEvent: string, payload?: AnyPayload) {
118
- if (window.utag === undefined) {
111
+ track(tealiumEvent: string, data?: any) {
112
+ if ((window as any).utag === undefined) {
119
113
  console.warn('Tealium is not available');
120
114
  return;
121
115
  }
122
- window.utag_data = this.constantPayload;
123
- window.utag!.track(tealiumEvent, payload);
116
+ (window as any).utag.track(tealiumEvent, data);
124
117
  }
125
118
 
126
119
  view(payload?: AnyPayload) {
@@ -147,10 +140,8 @@ export class TealiumAnalytics implements AnalyticsClient {
147
140
  ...this.constantPayload,
148
141
  ...payload,
149
142
  } as unknown as Payload);
150
- if ((eventBody as unknown as AnyPayload).track_event_type === 'view') {
151
- this.view(eventBody as Payload);
152
- } else {
153
- this.link(eventBody as Payload);
143
+ if (eventBody) {
144
+ (window as any).utag.track(payload.app_events, eventBody);
154
145
  }
155
146
  } catch (e) {
156
147
  console.warn(`[${this.name}] Error onEvent: `, e);
@@ -16,15 +16,15 @@ export const TEALIUM_TRIGGERS = [
16
16
  // Scenes
17
17
  AnalyticsTriggers.SCENE_VIEW,
18
18
 
19
- // Search
20
- AnalyticsTriggers.SEARCH,
19
+ // Data loading / Player buffering
20
+ AnalyticsTriggers.BUFFERING_START,
21
+ AnalyticsTriggers.BUFFERING_STOP,
21
22
 
22
23
  // Playback
23
24
  AnalyticsTriggers.PLAYBACK_10,
24
25
  AnalyticsTriggers.PLAYBACK_50,
25
26
  AnalyticsTriggers.PLAYBACK_90,
26
27
  AnalyticsTriggers.PLAYBACK_PAUSE,
27
- AnalyticsTriggers.PLAYBACK_UNPAUSE,
28
28
  AnalyticsTriggers.PLAYBACK_START,
29
29
  AnalyticsTriggers.PLAYBACK_STOP,
30
30
 
@@ -32,22 +32,26 @@ export const TEALIUM_TRIGGERS = [
32
32
  AnalyticsTriggers.PLAYER_CLOSE,
33
33
  AnalyticsTriggers.PLAYER_OPEN,
34
34
 
35
+ // Scrolling in scene
36
+ AnalyticsTriggers.SCROLL_25,
37
+ AnalyticsTriggers.SCROLL_50,
38
+ AnalyticsTriggers.SCROLL_75,
39
+ AnalyticsTriggers.SCROLL_90,
40
+
35
41
  // Favorites
36
42
  AnalyticsTriggers.FAVORITE_ADD,
37
43
  AnalyticsTriggers.FAVORITE_REMOVE,
38
44
 
39
45
  AnalyticsTriggers.SELECT_CONTENT,
40
- AnalyticsTriggers.SEARCH_SUCCESS,
41
- AnalyticsTriggers.SEARCH_FAILED,
46
+ 'playback_unpause',
42
47
  ];
43
48
 
44
- export const AppEvents: { [key: string]: string } = {
49
+ export const AppEvents = {
45
50
  [AnalyticsTriggers.PLAYBACK_10]: 'media_milestone_10_video',
46
51
  [AnalyticsTriggers.PLAYBACK_50]: 'media_milestone_50_video',
47
52
  [AnalyticsTriggers.PLAYBACK_90]: 'media_milestone_90_video',
48
53
  [AnalyticsTriggers.PLAYBACK_STOP]: 'video_stop',
49
54
  [AnalyticsTriggers.PLAYBACK_PAUSE]: 'video_pause',
50
- [AnalyticsTriggers.PLAYBACK_UNPAUSE]: 'video_resume',
51
55
  [AnalyticsTriggers.PLAYBACK_START]: 'video_play',
52
56
  [AnalyticsTriggers.PLAYER_OPEN]: 'player_x',
53
57
  [AnalyticsTriggers.PLAYER_CLOSE]: 'player_x',
@@ -55,9 +59,7 @@ export const AppEvents: { [key: string]: string } = {
55
59
  [AnalyticsTriggers.FAVORITE_REMOVE]: 'subscribe_to_fav',
56
60
  [AnalyticsTriggers.APP_ERROR]: 'app_events',
57
61
  [AnalyticsTriggers.SELECT_CONTENT]: 'app_events',
58
- [AnalyticsTriggers.SEARCH_SUCCESS]: 'search_success',
59
- [AnalyticsTriggers.SEARCH_FAILED]: 'search_fail',
60
- unpause: 'video_resume',
62
+ [AnalyticsTriggers.SEARCH]: 'search_success',
61
63
  };
62
64
 
63
65
  export enum EVENTS {
@@ -73,7 +75,6 @@ export enum EVENTS {
73
75
  SEARCH_FAILED = 'search_failed',
74
76
  FAVORITE_ADD = 'favorite_add',
75
77
  FAVORITE_REMOVE = 'favorite_remove',
76
- APP_ERROR = 'app_error',
77
78
  }
78
79
 
79
80
  export enum TrackEventType {
@@ -87,13 +88,11 @@ export const TRIGGER_NAME_TO_TEALIUM_EVENTS: { [K in AnalyticsTriggers]?: EVENTS
87
88
  [AnalyticsTriggers.PLAYBACK_50]: [EVENTS.VIDEO_PROGRESS],
88
89
  [AnalyticsTriggers.PLAYBACK_90]: [EVENTS.VIDEO_PROGRESS],
89
90
  [AnalyticsTriggers.PLAYBACK_PAUSE]: [EVENTS.VIDEO_PAUSE],
90
- [AnalyticsTriggers.PLAYBACK_UNPAUSE]: [EVENTS.VIDEO_UNPAUSE],
91
91
  [AnalyticsTriggers.PLAYBACK_START]: [EVENTS.VIDEO_START],
92
92
  [AnalyticsTriggers.PLAYBACK_STOP]: [EVENTS.VIDEO_STOP],
93
93
  [AnalyticsTriggers.PLAYER_CLOSE]: [EVENTS.PLAYER_CLOSE],
94
94
  [AnalyticsTriggers.PLAYER_OPEN]: [EVENTS.PLAYER_OPEN],
95
95
  [AnalyticsTriggers.APP_CLOSE]: [EVENTS.VIDEO_STOP, EVENTS.PLAYER_CLOSE],
96
- [AnalyticsTriggers.APP_ERROR]: [EVENTS.APP_ERROR],
97
96
  [AnalyticsTriggers.FAVORITE_ADD]: [EVENTS.FAVORITE_ADD],
98
97
  [AnalyticsTriggers.FAVORITE_REMOVE]: [EVENTS.FAVORITE_REMOVE],
99
98
  [AnalyticsTriggers.SEARCH]: [EVENTS.SEARCH_SUCCESS, EVENTS.SEARCH_FAILED],
@@ -1,3 +1,2 @@
1
1
  export { TealiumAnalytics } from './TealiumAnalytics';
2
2
  export { TEALIUM_TRIGGERS } from './constants';
3
- export { TealiumAnalyticsOptions, TealiumAnalyticsConfiguration } from './types';
@@ -14,7 +14,6 @@ import { mapVideoResume } from './mappers/mapVideoResume';
14
14
  import { mapSearchSuccess } from './mappers/mapSearchSuccess';
15
15
  import { mapSearchFailed } from './mappers/mapSearchFailed';
16
16
  import { EventMappingFunction } from './types';
17
- import { mapAppError } from './mappers/mapAppError';
18
17
 
19
18
  export const EVENTS_MAPPING: Record<EVENTS, EventMappingFunction> = {
20
19
  [EVENTS.SCENE_VIEW]: mapSceneView,
@@ -29,5 +28,4 @@ export const EVENTS_MAPPING: Record<EVENTS, EventMappingFunction> = {
29
28
  [EVENTS.VIDEO_UNPAUSE]: mapVideoResume,
30
29
  [EVENTS.SEARCH_SUCCESS]: mapSearchSuccess,
31
30
  [EVENTS.SEARCH_FAILED]: mapSearchFailed,
32
- [EVENTS.APP_ERROR]: mapAppError,
33
31
  };
@@ -0,0 +1 @@
1
+ export const mapBase = () => ({});
@@ -1,15 +1,30 @@
1
1
  import { AnalyticsTriggers } from '@24i/appstage-shared-analytics';
2
+ import { SECOND_IN_MS } from '@24i/bigscreen-sdk/utils';
2
3
  import { Payload, VideoResult } from '../types';
3
- import { AppEvents, TrackEventType } from '../constants';
4
- import { mapMediaPayload } from './helper';
4
+ import { AppEvents, HUNDRED_PERCENT, TrackEventType } from '../constants';
5
5
 
6
6
  export const mapPlayerClose = (
7
7
  triggerName: AnalyticsTriggers,
8
8
  payload: Payload,
9
- ): VideoResult => ({
10
- app_events: AppEvents.player_close,
11
- event_trigger: triggerName,
12
- track_event_type: TrackEventType.ACTIVITY,
13
- video_event: AppEvents.player_close,
14
- ...(mapMediaPayload(payload)),
15
- });
9
+ ): VideoResult => {
10
+ const { asset, duration = 0 } = payload;
11
+ const progressPercent = Number(triggerName.split('_')[1]);
12
+ const assetDuration = duration / SECOND_IN_MS || asset?.duration || 0;
13
+ const progressInSeconds = Math.round((assetDuration * progressPercent) / HUNDRED_PERCENT);
14
+ return {
15
+ app_events: AppEvents.player_close,
16
+ event_trigger: triggerName,
17
+ track_event_type: TrackEventType.ACTIVITY,
18
+ video_name: asset?.label || '',
19
+ video_length: assetDuration,
20
+ video_event: AppEvents.playback_start,
21
+ video_position: progressInSeconds,
22
+ media_type: 'vod',
23
+ canonical_url: '',
24
+ video_series_title: '',
25
+ byline: 'N/A',
26
+ pub_date: asset?.year || '',
27
+ article_uid: '',
28
+ tags: '',
29
+ };
30
+ };
@@ -1,15 +1,30 @@
1
1
  import { AnalyticsTriggers } from '@24i/appstage-shared-analytics';
2
+ import { SECOND_IN_MS } from '@24i/bigscreen-sdk/utils';
2
3
  import { Payload, VideoResult } from '../types';
3
- import { AppEvents, TrackEventType } from '../constants';
4
- import { mapMediaPayload } from './helper';
4
+ import { AppEvents, HUNDRED_PERCENT, TrackEventType } from '../constants';
5
5
 
6
6
  export const mapPlayerOpen = (
7
7
  triggerName: AnalyticsTriggers,
8
8
  payload: Payload,
9
- ): VideoResult => ({
10
- app_events: AppEvents.player_open,
11
- event_trigger: triggerName,
12
- track_event_type: TrackEventType.ACTIVITY,
13
- video_event: AppEvents.player_open,
14
- ...(mapMediaPayload(payload)),
15
- });
9
+ ): VideoResult => {
10
+ const { asset, duration = 0 } = payload;
11
+ const progressPercent = Number(triggerName.split('_')[1]);
12
+ const assetDuration = duration / SECOND_IN_MS || asset?.duration || 0;
13
+ const progressInSeconds = Math.round((assetDuration * progressPercent) / HUNDRED_PERCENT);
14
+ return {
15
+ app_events: AppEvents.player_open,
16
+ event_trigger: triggerName,
17
+ track_event_type: TrackEventType.ACTIVITY,
18
+ video_name: asset?.label || '',
19
+ video_length: assetDuration,
20
+ video_event: AppEvents.playback_start,
21
+ video_position: progressInSeconds,
22
+ media_type: 'vod',
23
+ canonical_url: '',
24
+ video_series_title: '',
25
+ byline: 'N/A',
26
+ pub_date: asset?.year || '',
27
+ article_uid: '',
28
+ tags: '',
29
+ };
30
+ };
@@ -1,8 +1,13 @@
1
1
  import { AnalyticsTriggers } from '@24i/appstage-shared-analytics';
2
2
  import { Payload, SearchResult } from '../types';
3
- import { mapSearch } from './mapSearch';
3
+ import { AppEvents, TrackEventType } from '../constants';
4
4
 
5
5
  export const mapSearchFailed = (
6
6
  triggerName: AnalyticsTriggers,
7
7
  payload: Payload,
8
- ): SearchResult => (mapSearch(triggerName, payload));
8
+ ): SearchResult => ({
9
+ app_events: AppEvents.search,
10
+ event_trigger: triggerName,
11
+ track_event_type: TrackEventType.ACTIVITY,
12
+ search_keyword: payload.search,
13
+ });
@@ -1,8 +1,13 @@
1
1
  import { AnalyticsTriggers } from '@24i/appstage-shared-analytics';
2
2
  import { Payload, SearchResult } from '../types';
3
- import { mapSearch } from './mapSearch';
3
+ import { AppEvents, TrackEventType } from '../constants';
4
4
 
5
5
  export const mapSearchSuccess = (
6
6
  triggerName: AnalyticsTriggers,
7
7
  payload: Payload,
8
- ): SearchResult => (mapSearch(triggerName, payload));
8
+ ): SearchResult => ({
9
+ app_events: AppEvents.search,
10
+ event_trigger: triggerName,
11
+ track_event_type: TrackEventType.ACTIVITY,
12
+ search_keyword: payload.search,
13
+ });
@@ -1,15 +1,30 @@
1
1
  import { AnalyticsTriggers } from '@24i/appstage-shared-analytics';
2
+ import { SECOND_IN_MS } from '@24i/bigscreen-sdk/utils';
2
3
  import { Payload, VideoResult } from '../types';
3
- import { AppEvents, TrackEventType } from '../constants';
4
- import { mapMediaPayload } from './helper';
4
+ import { AppEvents, HUNDRED_PERCENT, TrackEventType } from '../constants';
5
5
 
6
6
  export const mapVideoPause = (
7
7
  triggerName: AnalyticsTriggers,
8
8
  payload: Payload,
9
- ): VideoResult => ({
10
- app_events: AppEvents.playback_pause,
11
- event_trigger: triggerName,
12
- track_event_type: TrackEventType.ACTIVITY,
13
- video_event: AppEvents.playback_pause,
14
- ...(mapMediaPayload(payload)),
15
- });
9
+ ): VideoResult => {
10
+ const { asset, duration = 0 } = payload;
11
+ const progressPercent = Number(triggerName.split('_')[1]);
12
+ const assetDuration = duration / SECOND_IN_MS || asset?.duration || 0;
13
+ const progressInSeconds = Math.round((assetDuration * progressPercent) / HUNDRED_PERCENT);
14
+ return {
15
+ app_events: AppEvents.playback_pause,
16
+ event_trigger: triggerName,
17
+ track_event_type: TrackEventType.ACTIVITY,
18
+ video_name: asset?.label || '',
19
+ video_length: assetDuration,
20
+ video_event: AppEvents.playback_pause,
21
+ video_position: progressInSeconds,
22
+ media_type: 'vod',
23
+ canonical_url: '',
24
+ video_series_title: '',
25
+ byline: 'N/A',
26
+ pub_date: asset?.year || '',
27
+ article_uid: '',
28
+ tags: '',
29
+ };
30
+ };
@@ -1,18 +1,30 @@
1
1
  import { AnalyticsTriggers } from '@24i/appstage-shared-analytics';
2
+ import { SECOND_IN_MS } from '@24i/bigscreen-sdk/utils';
2
3
  import { Payload, VideoResult } from '../types';
3
- import { AppEvents, TrackEventType } from '../constants';
4
- import { mapMediaPayload } from './helper';
4
+ import { AppEvents, HUNDRED_PERCENT, TrackEventType } from '../constants';
5
5
 
6
6
  export const mapVideoProgress = (
7
7
  triggerName: AnalyticsTriggers,
8
8
  payload: Payload,
9
9
  ): VideoResult => {
10
- const appEvent = AppEvents[triggerName.toLowerCase()];
10
+ const { asset, duration = 0 } = payload;
11
+ const progressPercent = Number(triggerName.split('_')[1]);
12
+ const assetDuration = duration / SECOND_IN_MS || asset?.duration || 0;
13
+ const progressInSeconds = Math.round((assetDuration * progressPercent) / HUNDRED_PERCENT);
11
14
  return {
12
- app_events: appEvent,
15
+ app_events: AppEvents.playback_10,
13
16
  event_trigger: triggerName,
14
17
  track_event_type: TrackEventType.ACTIVITY,
15
- video_event: appEvent,
16
- ...(mapMediaPayload(payload)),
18
+ video_name: asset?.label || '',
19
+ video_length: assetDuration,
20
+ video_event: AppEvents.playback_10,
21
+ video_position: progressInSeconds,
22
+ media_type: 'vod',
23
+ canonical_url: '',
24
+ video_series_title: '',
25
+ byline: 'N/A',
26
+ pub_date: asset?.year || '',
27
+ article_uid: '',
28
+ tags: '',
17
29
  };
18
30
  };
@@ -1,15 +1,30 @@
1
1
  import { AnalyticsTriggers } from '@24i/appstage-shared-analytics';
2
+ import { SECOND_IN_MS } from '@24i/bigscreen-sdk/utils';
2
3
  import { Payload, VideoResult } from '../types';
3
- import { AppEvents, TrackEventType } from '../constants';
4
- import { mapMediaPayload } from './helper';
4
+ import { AppEvents, HUNDRED_PERCENT, TrackEventType } from '../constants';
5
5
 
6
6
  export const mapVideoResume = (
7
7
  triggerName: AnalyticsTriggers,
8
8
  payload: Payload,
9
- ): VideoResult => ({
10
- app_events: AppEvents.unpause,
11
- event_trigger: triggerName,
12
- track_event_type: TrackEventType.ACTIVITY,
13
- video_event: AppEvents.unpause,
14
- ...(mapMediaPayload(payload)),
15
- });
9
+ ): VideoResult => {
10
+ const { asset, duration = 0 } = payload;
11
+ const progressPercent = Number(triggerName.split('_')[1]);
12
+ const assetDuration = duration / SECOND_IN_MS || asset?.duration || 0;
13
+ const progressInSeconds = Math.round((assetDuration * progressPercent) / HUNDRED_PERCENT);
14
+ return {
15
+ app_events: AppEvents.playback_pause,
16
+ event_trigger: triggerName,
17
+ track_event_type: TrackEventType.ACTIVITY,
18
+ video_name: asset?.label || '',
19
+ video_length: assetDuration,
20
+ video_event: AppEvents.playback_pause,
21
+ video_position: progressInSeconds,
22
+ media_type: 'vod',
23
+ canonical_url: '',
24
+ video_series_title: '',
25
+ byline: 'N/A',
26
+ pub_date: asset?.year || '',
27
+ article_uid: '',
28
+ tags: '',
29
+ };
30
+ };
@@ -1,15 +1,30 @@
1
1
  import { AnalyticsTriggers } from '@24i/appstage-shared-analytics';
2
+ import { SECOND_IN_MS } from '@24i/bigscreen-sdk/utils';
2
3
  import { Payload, VideoResult } from '../types';
3
- import { AppEvents, TrackEventType } from '../constants';
4
- import { mapMediaPayload } from './helper';
4
+ import { AppEvents, HUNDRED_PERCENT, TrackEventType } from '../constants';
5
5
 
6
6
  export const mapVideoStart = (
7
7
  triggerName: AnalyticsTriggers,
8
8
  payload: Payload,
9
- ): VideoResult => ({
10
- app_events: AppEvents.playback_start,
11
- event_trigger: triggerName,
12
- track_event_type: TrackEventType.ACTIVITY,
13
- video_event: AppEvents.playback_start,
14
- ...(mapMediaPayload(payload)),
15
- });
9
+ ): VideoResult => {
10
+ const { asset, duration = 0 } = payload;
11
+ const progressPercent = Number(triggerName.split('_')[1]);
12
+ const assetDuration = duration / SECOND_IN_MS || asset?.duration || 0;
13
+ const progressInSeconds = Math.round((assetDuration * progressPercent) / HUNDRED_PERCENT);
14
+ return {
15
+ app_events: AppEvents.playback_start,
16
+ event_trigger: triggerName,
17
+ track_event_type: TrackEventType.ACTIVITY,
18
+ video_name: asset?.label || '',
19
+ video_length: assetDuration,
20
+ video_event: AppEvents.playback_start,
21
+ video_position: progressInSeconds,
22
+ media_type: 'vod',
23
+ canonical_url: '',
24
+ video_series_title: '',
25
+ byline: 'N/A',
26
+ pub_date: asset?.year || '',
27
+ article_uid: '',
28
+ tags: '',
29
+ };
30
+ };
@@ -1,15 +1,30 @@
1
1
  import { AnalyticsTriggers } from '@24i/appstage-shared-analytics';
2
+ import { SECOND_IN_MS } from '@24i/bigscreen-sdk/utils';
2
3
  import { Payload, VideoResult } from '../types';
3
- import { AppEvents, TrackEventType } from '../constants';
4
- import { mapMediaPayload } from './helper';
4
+ import { AppEvents, HUNDRED_PERCENT, TrackEventType } from '../constants';
5
5
 
6
6
  export const mapVideoStop = (
7
7
  triggerName: AnalyticsTriggers,
8
8
  payload: Payload,
9
- ): VideoResult => ({
10
- app_events: AppEvents.playback_stop,
11
- event_trigger: triggerName,
12
- track_event_type: TrackEventType.ACTIVITY,
13
- video_event: AppEvents.playback_stop,
14
- ...(mapMediaPayload(payload)),
15
- });
9
+ ): VideoResult => {
10
+ const { asset, duration = 0 } = payload;
11
+ const progressPercent = Number(triggerName.split('_')[1]);
12
+ const assetDuration = duration / SECOND_IN_MS || asset?.duration || 0;
13
+ const progressInSeconds = Math.round((assetDuration * progressPercent) / HUNDRED_PERCENT);
14
+ return {
15
+ app_events: AppEvents.playback_stop,
16
+ event_trigger: triggerName,
17
+ track_event_type: TrackEventType.ACTIVITY,
18
+ video_name: asset?.label || '',
19
+ video_length: assetDuration,
20
+ video_event: AppEvents.playback_stop,
21
+ video_position: progressInSeconds,
22
+ media_type: 'vod',
23
+ canonical_url: '',
24
+ video_series_title: '',
25
+ byline: 'N/A',
26
+ pub_date: asset?.year || '',
27
+ article_uid: '',
28
+ tags: '',
29
+ };
30
+ };
@@ -1,16 +1,7 @@
1
+ import { Asset } from '@24i/smartapps-datalayer/models';
1
2
  import { AnalyticsTriggers } from '@24i/appstage-shared-analytics';
2
3
  import type { AnyPayload, UserInfo, AppInfo } from '../../interface';
3
4
 
4
- export interface UtagWindow {
5
- utag_cfg_ovrd?: {
6
- noview: boolean;
7
- };
8
- utag_data?: {};
9
- utag?: {
10
- track: (eventName: string, payload?: AnyPayload) => {};
11
- }
12
- }
13
-
14
5
  export type TealiumAnalyticsOptions = {
15
6
  account: string, // e.g: 'bbg'
16
7
  profile: string, // e.g: 'main'
@@ -29,21 +20,20 @@ export type TealiumAnalyticsConfiguration = {
29
20
  options: TealiumAnalyticsOptions,
30
21
  };
31
22
 
32
- export interface CorePayload {
33
- app_id: string;
34
- app_type: string;
35
- message?: string;
23
+ interface ScreenParams {
24
+ screen: string;
25
+ screenName: string;
26
+ id: string;
27
+ asset: Asset;
36
28
  }
37
- export interface MediaPayload {
38
- title: string;
39
- externalId: string;
40
- contentType: string;
41
- currentTime: number;
42
- duration: number;
43
- percent: number;
44
- assetId: string;
45
- provider: string,
46
- url: string;
29
+ export interface CorePayload {
30
+ timestamp?: number;
31
+ params?: ScreenParams;
32
+ asset?: Asset;
33
+ source?: string;
34
+ duration?: number;
35
+ id?: string;
36
+ percentOfPlayback?: number;
47
37
  }
48
38
 
49
39
  export interface SessionInfo {
@@ -66,17 +56,10 @@ export interface SceneInfo {
66
56
  }
67
57
 
68
58
  export interface SearchInfo {
69
- searchTerm?: string,
70
- searchSuccess?: boolean,
59
+ search: string,
71
60
  }
72
61
 
73
- export type Payload = CorePayload &
74
- SceneInfo &
75
- SessionInfo &
76
- MediaPayload &
77
- UserInfo &
78
- AppInfo &
79
- SearchInfo;
62
+ export type Payload = CorePayload & SceneInfo & SessionInfo & UserInfo & AppInfo & SearchInfo;
80
63
 
81
64
  export type EventBody = AnyPayload;
82
65
 
@@ -102,8 +85,6 @@ export type CoreResult = {
102
85
  event_trigger: string,
103
86
  track_event_type: string,
104
87
  app_events?: string,
105
- video_event?: string,
106
- message?: string,
107
88
  };
108
89
 
109
90
  export type SceneViewResult = CoreResult & {
@@ -113,21 +94,20 @@ export type SceneViewResult = CoreResult & {
113
94
  categories: string,
114
95
  };
115
96
 
116
- export type MediaResult = {
97
+ export type VideoResult = CoreResult & {
117
98
  video_name: string,
118
99
  video_length: number,
100
+ video_event: string,
119
101
  video_position: number,
120
102
  media_type: string,
121
103
  canonical_url: string,
122
- video_series_title?: string,
123
- byline?: string,
124
- pub_date?: string,
125
- article_uid?: string,
126
- tags?: string,
104
+ video_series_title: string,
105
+ byline: string,
106
+ pub_date: string,
107
+ article_uid: string,
108
+ tags: string,
127
109
  };
128
110
 
129
- export type VideoResult = CoreResult & MediaResult;
130
-
131
111
  export type PlayerOpenResult = CoreResult & {
132
112
  thing_id: string;
133
113
  source_page: string;
@@ -137,3 +117,6 @@ export type PlayerOpenResult = CoreResult & {
137
117
  export type SearchResult = CoreResult & {
138
118
  search_keyword?: string;
139
119
  };
120
+
121
+ export type VideoStopResult = VideoResult;
122
+ export type PlayerCloseResult = VideoResult;
@@ -1,5 +1,4 @@
1
1
  import { Storage } from '@24i/bigscreen-sdk/storage';
2
- import { config } from '@24i/bigscreen-sdk/runtime-config';
3
2
  import { generateUuid } from '@24i/bigscreen-sdk/utils/generateUuid';
4
3
  import { EventsManager, IEvents, EventMapType } from '@24i/bigscreen-sdk/events-manager';
5
4
  import { isRtl } from '@24i/bigscreen-sdk/i18n';
@@ -17,10 +16,6 @@ import { LEFT, RIGHT, UP, DOWN, ENTER, BACK, ESC } from './KeyMap';
17
16
 
18
17
  export const STORAGE_UUID_KEY = '__UUID__';
19
18
 
20
- const DEFAULT_POLLING_INTERVAL = 15000;
21
-
22
- const CHECKED_URL = 'http://www.google-analytics.com/__utm.gif';
23
-
24
19
  export abstract class DeviceBase<
25
20
  CustomEventMap extends EventMapType = {},
26
21
  EventMap extends EventMapType = DeviceEventMap & CustomEventMap,
@@ -46,8 +41,6 @@ export abstract class DeviceBase<
46
41
 
47
42
  screenSize: ScreenSize = 'unknown';
48
43
 
49
- pollingInterval: number = DEFAULT_POLLING_INTERVAL;
50
-
51
44
  // MARK: Initialization
52
45
 
53
46
  /**
@@ -72,39 +65,12 @@ export abstract class DeviceBase<
72
65
  async internalInit() {
73
66
  if (!this.initializer) {
74
67
  this.initializer = this.initDevice();
75
- this.checkNetworkConnection();
76
68
  await this.initializer;
77
69
  return this.initializer;
78
70
  }
79
71
  return this.initializer;
80
72
  }
81
73
 
82
- doOnlineCheck = () => {
83
- const tester = new Image();
84
- tester.onload = this.connectionFound;
85
- tester.onerror = this.connectionNotFound;
86
- tester.src = `${CHECKED_URL}?ts=${Date.now()}`;
87
- };
88
-
89
- connectionFound = () => {
90
- this.triggerEvent('networkchange',
91
- { isConnected: true } as any);
92
- };
93
-
94
- connectionNotFound = () => {
95
- this.triggerEvent('networkchange',
96
- { isConnected: false } as any);
97
- };
98
-
99
- checkNetworkConnection() {
100
- const networkConfig: any = config.get('network.checkConnection');
101
- this.pollingInterval = Number(networkConfig?.pollingInterval);
102
- window.setInterval(
103
- this.doOnlineCheck,
104
- this.pollingInterval || DEFAULT_POLLING_INTERVAL,
105
- );
106
- }
107
-
108
74
  // MARK: Interface implemented by individual platform-specific drivers
109
75
 
110
76
  abstract initDevice(): Promise<void>;
@@ -8,8 +8,6 @@ type Props = PlayerUICommonProps;
8
8
  export class PauseButton extends Component<Props> implements IFocusable {
9
9
  button = createRef<PlayerInteractable>();
10
10
 
11
- isPaused = false;
12
-
13
11
  static defaultProps = {
14
12
  className: '',
15
13
  };
@@ -33,16 +31,10 @@ export class PauseButton extends Component<Props> implements IFocusable {
33
31
 
34
32
  onPlaying = () => {
35
33
  this.button.current!.show();
36
- if (this.isPaused) {
37
- const { ui } = this.props;
38
- ui.getPlayer().triggerEvent('unpause');
39
- }
40
- this.isPaused = false;
41
34
  };
42
35
 
43
36
  onPause = () => {
44
37
  this.button.current!.hide();
45
- this.isPaused = true;
46
38
  };
47
39
 
48
40
  focus(options?: FocusOptions) {
@@ -6,7 +6,7 @@ export const isPathVisible = (hash: string, regexpPath?: RegExp) => (
6
6
 
7
7
  export const getCurrentHash = () => window.location.href.split('#')[1] || '';
8
8
 
9
- const PARAM = '([a-zA-Z0-9+-=.:%_()\\[\\]{}]+)';
9
+ const PARAM = '([a-zA-Z0-9-=.:%_()\\[\\]{}]+)';
10
10
 
11
11
  export const pathToRegExp = (path: string) => {
12
12
  const regexpParts: string[] = [];
@@ -1,40 +0,0 @@
1
- import { Payload } from '../../types';
2
-
3
- export const MEDIA_PAYLOAD: Payload = {
4
- duration: 120,
5
- currentTime: 60,
6
- title: 'Test Video',
7
- url: 'https://example.com/video',
8
- contentType: 'video/mp4',
9
- externalId: '',
10
- percent: 2,
11
- provider: 'provider',
12
- assetId: '12345',
13
- app_id: 'app_id',
14
- app_type: 'app_type',
15
- sceneName: '',
16
- sceneId: '',
17
- sceneType: '',
18
- sessionId: 1,
19
- sessionNumber: 1,
20
- userId: '10',
21
- userProfileId: 'a1',
22
- applicationId: 'app',
23
- appVersion: 'v1.0',
24
- deviceId: 'ott',
25
- deviceType: 'smarttv',
26
- searchTerm: '',
27
- };
28
-
29
- export const TEALIUM_MEDIA_PAYLOAD = {
30
- article_uid: '12345',
31
- byline: 'N/A',
32
- canonical_url: 'https://example.com/video',
33
- media_type: 'video/mp4',
34
- pub_date: '',
35
- tags: '',
36
- video_length: 120,
37
- video_name: 'Test Video',
38
- video_position: 60,
39
- video_series_title: '',
40
- };
@@ -1,21 +0,0 @@
1
- import { Payload, MediaResult } from '../types';
2
-
3
- export const mapMediaPayload = (
4
- payload: Payload,
5
- ): MediaResult => {
6
- const {
7
- duration, currentTime, title, url, contentType, assetId,
8
- } = payload;
9
- return {
10
- video_name: title || '',
11
- video_length: duration,
12
- video_position: currentTime,
13
- media_type: contentType,
14
- canonical_url: url,
15
- video_series_title: '',
16
- byline: 'N/A',
17
- pub_date: '',
18
- article_uid: assetId,
19
- tags: '',
20
- };
21
- };
@@ -1,14 +0,0 @@
1
- import { AnalyticsTriggers } from '@24i/appstage-shared-analytics';
2
- import { CoreResult, Payload } from '../types';
3
- import { AppEvents, TrackEventType } from '../constants';
4
-
5
- export const mapAppError = (
6
- triggerName: AnalyticsTriggers,
7
- payload: Payload,
8
- ): CoreResult => ({
9
- app_events: AppEvents.app_error,
10
- event_trigger: triggerName,
11
- track_event_type: TrackEventType.ACTIVITY,
12
- video_event: AppEvents.app_error,
13
- message: payload.message,
14
- });
@@ -1,18 +0,0 @@
1
- import { AnalyticsTriggers } from '@24i/appstage-shared-analytics';
2
- import { Payload, SearchResult } from '../types';
3
- import { AppEvents, TrackEventType } from '../constants';
4
-
5
- export const mapSearch = (
6
- triggerName: AnalyticsTriggers,
7
- payload: Payload,
8
- ): SearchResult => {
9
- const searchEventName = payload.searchSuccess
10
- ? AnalyticsTriggers.SEARCH_SUCCESS
11
- : AnalyticsTriggers.SEARCH_FAILED;
12
- return {
13
- app_events: AppEvents[searchEventName],
14
- event_trigger: searchEventName,
15
- track_event_type: TrackEventType.ACTIVITY,
16
- search_keyword: payload.searchTerm,
17
- };
18
- };