@applicaster/zapp-react-native-utils 12.0.0-alpha.4043183114 → 12.0.0-alpha.4155487673

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 (43) hide show
  1. package/analyticsUtils/AnalyticPlayerListener.ts +141 -0
  2. package/analyticsUtils/PlayerAnalyticsManager.ts +90 -0
  3. package/analyticsUtils/{analyticsTracker.ts → playerAnalyticsTracker.ts} +19 -10
  4. package/appUtils/HooksManager/{Hook.ts → Hook.js} +11 -17
  5. package/appUtils/HooksManager/{constants.ts → constants.js} +1 -1
  6. package/appUtils/HooksManager/{index.ts → index.js} +109 -98
  7. package/appUtils/RiverFocusManager/index.js +12 -17
  8. package/appUtils/accessibilityManager/hooks.ts +16 -7
  9. package/appUtils/accessibilityManager/index.ts +42 -26
  10. package/appUtils/focusManager/treeDataStructure/Tree/index.js +3 -2
  11. package/appUtils/focusManager/treeDataStructure/Utils/index.js +3 -1
  12. package/appUtils/{index.ts → index.js} +1 -1
  13. package/appUtils/keyCodes/{index.ts → index.js} +0 -2
  14. package/appUtils/keyCodes/{keys/keyEventMapper.ts → keys.android.js} +19 -0
  15. package/appUtils/keyCodes/keys.ios.js +46 -0
  16. package/appUtils/platform/platformUtils.ts +14 -0
  17. package/appUtils/playerManager/index.ts +9 -27
  18. package/appUtils/playerManager/playerNative.ts +1 -1
  19. package/cellUtils/index.ts +38 -5
  20. package/domUtils/{cookieManager.ts → cookieManager.js} +2 -1
  21. package/functionUtils/index.ts +11 -15
  22. package/index.d.ts +15 -0
  23. package/modalState/index.ts +5 -1
  24. package/navigationUtils/index.ts +5 -14
  25. package/numberUtils/__tests__/toNumber.test.ts +2 -2
  26. package/package.json +2 -2
  27. package/playerUtils/imaScriptDom.ts +59 -0
  28. package/reactHooks/debugging/__tests__/index.test.js +81 -11
  29. package/reactHooks/navigation/index.ts +4 -7
  30. package/reactHooks/resolvers/useCellResolver.ts +5 -1
  31. package/reactUtils/index.ts +15 -2
  32. package/appUtils/HooksManager/types.ts +0 -93
  33. package/appUtils/keyCodes/keys/index.ts +0 -3
  34. package/appUtils/keyCodes/keys/keys.android.ts +0 -18
  35. package/appUtils/keyCodes/keys/keys.ios.ts +0 -25
  36. package/appUtils/keyCodes/keys/keys.ts +0 -15
  37. /package/appUtils/HooksManager/{logger.ts → logger.js} +0 -0
  38. /package/appUtils/{directionHelper.ts → directionHelper.js} +0 -0
  39. /package/appUtils/keyCodes/{androidTVKeys.ts → androidTVKeys.js} +0 -0
  40. /package/appUtils/keyCodes/{keys/keys.web.ts → keys.web.js} +0 -0
  41. /package/appUtils/keyCodes/{keys/keysByPlatform.ts → keysByPlatform.js} +0 -0
  42. /package/appUtils/{localizationsHelper.ts → localizationsHelper.js} +0 -0
  43. /package/domUtils/{logger.ts → logger.js} +0 -0
@@ -324,13 +324,7 @@ export function getPathAttributes({
324
324
  * @param {object} rivers
325
325
  * @returns {object}
326
326
  */
327
- export function getRiverFromRoute({
328
- route,
329
- rivers,
330
- }: {
331
- route: string;
332
- rivers: Record<string, ZappRiver>;
333
- }) {
327
+ export function getRiverFromRoute({ route, rivers }) {
334
328
  if (!route) {
335
329
  return null;
336
330
  }
@@ -443,7 +437,7 @@ export const runZappHooksForEntry = async (
443
437
 
444
438
  let success;
445
439
  let payload;
446
- const rivers: Record<string, ZappRiver> = appStore.get("rivers");
440
+ const rivers = appStore.get("rivers");
447
441
  const plugins = appStore.get("plugins");
448
442
  const appData = appStore.get("appData");
449
443
 
@@ -498,16 +492,13 @@ export const runZappHooksForEntry = async (
498
492
  payload = _payload;
499
493
  };
500
494
 
501
- const hooksManager = HooksManager(hooksOptions);
502
-
503
- hooksManager.subscriber
495
+ HooksManager(hooksOptions)
504
496
  .on(HOOKS_EVENTS.PRESENT_SCREEN_HOOK, handleHookPresent)
505
497
  .on(HOOKS_EVENTS.START_BACKGROUND_HOOK, handleBackgroundHook)
506
498
  .on(HOOKS_EVENTS.ERROR, onFinished(false))
507
499
  .on(HOOKS_EVENTS.CANCEL, onFinished(false))
508
- .on(HOOKS_EVENTS.COMPLETE, onFinished(true));
509
-
510
- hooksManager.handleHooks(entry);
500
+ .on(HOOKS_EVENTS.COMPLETE, onFinished(true))
501
+ .handleHooks(entry);
511
502
 
512
503
  // eslint-disable-next-line no-unmodified-loop-condition
513
504
  while (success === undefined) {
@@ -2,7 +2,7 @@ import { toNumber } from "..";
2
2
 
3
3
  describe("toNumber", () => {
4
4
  it("return number if input is number", () => {
5
- const inputs = [-1, 0, 1, 100];
5
+ const inputs = [-1, 0, 1, 100, 0.2];
6
6
  expect.assertions(inputs.length);
7
7
 
8
8
  inputs.forEach((input) => {
@@ -12,7 +12,7 @@ describe("toNumber", () => {
12
12
  });
13
13
 
14
14
  it("return number if input is string as number", () => {
15
- const inputs = ["-1", "0", "1", "100"];
15
+ const inputs = ["-1", "0", "1", "100", "0.2"];
16
16
  expect.assertions(inputs.length);
17
17
 
18
18
  inputs.forEach((input) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-utils",
3
- "version": "12.0.0-alpha.4043183114",
3
+ "version": "12.0.0-alpha.4155487673",
4
4
  "description": "Applicaster Zapp React Native utilities package",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "homepage": "https://github.com/applicaster/quickbrick#readme",
30
30
  "dependencies": {
31
- "@applicaster/applicaster-types": "12.0.0-alpha.4043183114",
31
+ "@applicaster/applicaster-types": "12.0.0-alpha.4155487673",
32
32
  "buffer": "^5.2.1",
33
33
  "camelize": "^1.0.0",
34
34
  "create-react-context": "^0.2.3",
@@ -0,0 +1,59 @@
1
+ import { createLogger } from "../logger";
2
+
3
+ export const logger = createLogger({
4
+ category: "ImaDomUtils",
5
+ subsystem: "Player/ImaDomUtils",
6
+ });
7
+
8
+ const { log_debug, log_error, log_verbose } = logger;
9
+
10
+ const removeElement = (node) => {
11
+ if (node) {
12
+ const parentNode = node.parentNode;
13
+
14
+ if (parentNode) {
15
+ parentNode.removeChild(node);
16
+ }
17
+ }
18
+ };
19
+
20
+ // TODO: This should probably be loaded to root of project before player init
21
+ export const loadIMAScript = async () => {
22
+ return new Promise((resolve) => {
23
+ // If ima script is already loaded, resolve
24
+ const imaScript = document.getElementById("ima-script");
25
+
26
+ if (imaScript) {
27
+ log_verbose("loadIMAScript: IMA script already loaded");
28
+
29
+ return resolve(true);
30
+ }
31
+
32
+ const script = document.createElement("script");
33
+
34
+ if (__DEV__) {
35
+ script.src = "https://imasdk.googleapis.com/js/sdkloader/ima3_debug.js";
36
+ } else {
37
+ script.src = "https://imasdk.googleapis.com/js/sdkloader/ima3.js";
38
+ }
39
+
40
+ script.async = true;
41
+ script.id = "ima-script";
42
+
43
+ script.onload = () => {
44
+ removeElement(script);
45
+ log_debug("loadIMAScript: Loaded ima script", script.src);
46
+ resolve(true);
47
+ };
48
+
49
+ script.onerror = (_e) => {
50
+ removeElement(script);
51
+ log_error("loadIMAScript: Failed to load ima script", script.src);
52
+ resolve(false);
53
+ };
54
+
55
+ if (document.head) {
56
+ document.head.appendChild(script);
57
+ }
58
+ });
59
+ };
@@ -4,38 +4,77 @@ import {
4
4
  timers,
5
5
  } from "@applicaster/zapp-react-native-utils/reactHooks/debugging";
6
6
 
7
- jest.useFakeTimers();
8
-
9
7
  describe("Debug utils", () => {
8
+ let performanceNowMock;
9
+
10
+ beforeEach(() => {
11
+ jest.useFakeTimers();
12
+ // Clear the timers object
13
+ Object.keys(timers).forEach((key) => delete timers[key]);
14
+
15
+ // Mock performance.now()
16
+ // eslint-disable-next-line no-undef
17
+ performanceNowMock = jest.spyOn(performance, "now");
18
+ performanceNowMock.mockReturnValue(0); // Initial value
19
+ });
20
+
21
+ afterEach(() => {
22
+ jest.useRealTimers();
23
+ jest.restoreAllMocks();
24
+ performanceNowMock.mockRestore();
25
+ });
26
+
10
27
  describe("Unit Test: time", () => {
11
28
  it("should create new timer if timer with a label does not exist", () => {
29
+ performanceNowMock.mockReturnValue(1000);
12
30
  time("timer1");
13
31
  expect(timers["timer1"]).toBeDefined();
32
+ expect(timers["timer1"].startTime).toBe(1000);
14
33
  });
15
34
 
16
35
  it("should update start time of timer if timer with a label exists", () => {
36
+ // First call to time()
37
+ performanceNowMock.mockReturnValue(1000);
38
+ time("timer1");
17
39
  const previousStartTime = timers["timer1"].startTime;
18
- jest.advanceTimersByTime(1000);
40
+
41
+ // Second call to time()
42
+ performanceNowMock.mockReturnValue(2000);
19
43
  time("timer1");
20
44
  const currentStartTime = timers["timer1"].startTime;
21
- expect(previousStartTime).not.toEqual(currentStartTime);
45
+
46
+ expect(previousStartTime).toBe(1000);
47
+ expect(currentStartTime).toBe(2000);
22
48
  });
23
49
  });
24
50
 
25
51
  describe("Unit Test: timeEnd", () => {
26
- beforeEach(() => jest.resetAllMocks());
52
+ beforeEach(() => {
53
+ jest.spyOn(console, "log").mockImplementation(() => {});
54
+ });
27
55
 
28
56
  it("should log elapsed time", () => {
29
57
  const logSpy = jest.spyOn(console, "log");
30
58
 
59
+ performanceNowMock.mockReturnValue(1000);
60
+ time("timer1");
61
+
62
+ performanceNowMock.mockReturnValue(2000);
31
63
  timeEnd("timer1");
32
64
 
33
- expect(logSpy).toHaveBeenCalled();
65
+ expect(logSpy).toHaveBeenCalledWith(
66
+ "timer1: 1000.000ms 2",
67
+ expect.any(Object)
68
+ );
34
69
  });
35
70
 
36
71
  it("should not log elapsed time if accumulative: true in settings", () => {
37
72
  const logSpy = jest.spyOn(console, "log");
38
73
 
74
+ performanceNowMock.mockReturnValue(1000);
75
+ time("timer1");
76
+
77
+ performanceNowMock.mockReturnValue(2000);
39
78
  timeEnd("timer1", { accumulative: true });
40
79
 
41
80
  expect(logSpy).not.toHaveBeenCalled();
@@ -43,21 +82,52 @@ describe("Debug utils", () => {
43
82
  });
44
83
 
45
84
  describe("Integration Test: time and timeEnd", () => {
46
- beforeEach(() => jest.resetAllMocks());
85
+ beforeEach(() => {
86
+ jest.spyOn(console, "log").mockImplementation(() => {});
87
+ });
47
88
 
48
89
  it("should log elapsed time on timeEnd call", () => {
49
90
  const logSpy = jest.spyOn(console, "log");
91
+
92
+ performanceNowMock.mockReturnValue(1000);
50
93
  time("timer1");
94
+
95
+ performanceNowMock.mockReturnValue(2000);
51
96
  timeEnd("timer1");
52
- expect(logSpy).toHaveBeenCalled();
97
+
98
+ expect(logSpy).toHaveBeenCalledWith(
99
+ "timer1: 1000.000ms 2",
100
+ expect.objectContaining({
101
+ label: "timer1",
102
+ settings: undefined,
103
+ })
104
+ );
53
105
  });
54
106
 
55
- it("should log total and average time on timeEnd call without accumulative option", () => {
107
+ it("should log total and average time when accumulative timing is complete", () => {
56
108
  const logSpy = jest.spyOn(console, "log");
109
+
110
+ // First timing
111
+ performanceNowMock.mockReturnValue(1000);
57
112
  time("timer2");
113
+
114
+ performanceNowMock.mockReturnValue(2000);
58
115
  timeEnd("timer2", { accumulative: true });
59
- timeEnd("timer2");
60
- expect(logSpy).toHaveBeenCalled();
116
+
117
+ // Second timing
118
+ performanceNowMock.mockReturnValue(3000);
119
+ time("timer2");
120
+
121
+ performanceNowMock.mockReturnValue(5000);
122
+ timeEnd("timer2"); // This will log because timer is accumulative (callCount > 1)
123
+
124
+ expect(logSpy).toHaveBeenCalledWith(
125
+ "timer2: 2000.000ms 2",
126
+ expect.objectContaining({
127
+ label: "timer2",
128
+ settings: undefined,
129
+ })
130
+ );
61
131
  });
62
132
  });
63
133
  });
@@ -320,19 +320,16 @@ export const useZappHooksForEntry = (
320
320
  callbacks?.handleHookComplete?.(props);
321
321
  };
322
322
 
323
- const hookManager = HooksManager(hooksOptions);
324
-
325
- hookManager.subscriber
323
+ const hookManager = HooksManager(hooksOptions)
326
324
  .on(HOOKS_EVENTS.PRESENT_SCREEN_HOOK, handleHookPresent)
327
325
  .on(HOOKS_EVENTS.ERROR, handleHookError)
328
326
  .on(HOOKS_EVENTS.CANCEL, handleHookCancel)
329
327
  .on(HOOKS_EVENTS.START_BACKGROUND_HOOK, handleBackgroundHook)
330
- .on(HOOKS_EVENTS.COMPLETE, handleHookComplete);
331
-
332
- hookManager.handleHooks(entry);
328
+ .on(HOOKS_EVENTS.COMPLETE, handleHookComplete)
329
+ .handleHooks(entry);
333
330
 
334
331
  return () => {
335
- hookManager.subscriber
332
+ hookManager
336
333
  .removeHandler(HOOKS_EVENTS.PRESENT_SCREEN_HOOK, handleHookPresent)
337
334
  .removeHandler(HOOKS_EVENTS.ERROR, handleHookError)
338
335
  .removeHandler(HOOKS_EVENTS.CANCEL, handleHookCancel)
@@ -48,7 +48,11 @@ export function useCellResolver({
48
48
  ...cellResolverOptions
49
49
  }: Props) {
50
50
  let _component = Object.assign({}, component);
51
- const { width, height } = useDimensions("screen");
51
+
52
+ const { width, height } = useDimensions("screen", {
53
+ updateForInactiveScreens: false,
54
+ });
55
+
52
56
  const { plugins, cellStyles } = usePickFromState(["plugins", "cellStyles"]);
53
57
  const isRTL = useIsRTL();
54
58
 
@@ -109,6 +109,20 @@ export const isTvOSPlatform = () => getPlatform() === "tvos";
109
109
 
110
110
  export const isAndroidTVPlatform = () => getPlatform() === "android_tv";
111
111
 
112
+ declare global {
113
+ interface Window {
114
+ VIZIO?: {
115
+ Chromevox: {
116
+ play: (text: string) => void;
117
+ };
118
+ exitApplication: () => void;
119
+ setClosedCaptionHandler: (
120
+ callback: (isCCEnabled: boolean) => void
121
+ ) => void;
122
+ };
123
+ }
124
+ }
125
+
112
126
  /**
113
127
  * Platforms found in userAgent string, please note that simulators
114
128
  * might not have the same agents that the devices have
@@ -138,8 +152,7 @@ export const hasTizen = typeof window?.tizen !== "undefined";
138
152
  */
139
153
  export const hasWebOS = typeof window?.webOS !== "undefined";
140
154
 
141
- export const getUserAgent = () =>
142
- window?.navigator?.userAgent || global?.navigator?.userAgent;
155
+ export const getUserAgent = () => window?.navigator?.userAgent;
143
156
 
144
157
  export const isLgPlatform = () => {
145
158
  const userAgent = getUserAgent();
@@ -1,93 +0,0 @@
1
- import { SubscriberObj } from "../../functionUtils";
2
- import { HOOKS_EVENTS } from "./constants";
3
-
4
- export interface HookConfiguration {}
5
-
6
- export interface HookModule {
7
- ModalContainer: React.ComponentType<any>;
8
- Component: React.ComponentType<any>;
9
- presentFullScreen: boolean;
10
- run: (
11
- arg0: unknown,
12
- callback: () => void,
13
- configuration: HookConfiguration
14
- ) => void;
15
- configuration: HookConfiguration;
16
- isFlowBlocker: () => boolean;
17
- skipHook: boolean;
18
- setSkipHook: (skipHook: boolean) => void;
19
- shouldSkipHook: () => boolean;
20
- runInBackground: (
21
- arg0: unknown,
22
- callback: () => void,
23
- hookPlugin: Hook,
24
- presentUI: boolean
25
- ) => void;
26
- }
27
-
28
- export type HookManagerArgs = {
29
- rivers: Record<string, ZappRiver>;
30
- plugins: ZappPlugin[];
31
- targetScreen: ZappRiver;
32
- startUpHooksData?: {
33
- startUpHooks?: unknown[] | "in_process";
34
- setStartUpHooks?: (arg0: string) => void;
35
- };
36
- };
37
-
38
- export interface HookManager {
39
- subscriber: SubscriberObj;
40
- presentScreenHook: (
41
- hook: Hook,
42
- payload: unknown,
43
- callback: (...any) => void
44
- ) => void;
45
- executeHook: (
46
- hook: Hook,
47
- payload: unknown,
48
- callback: (...any) => void
49
- ) => void;
50
- handleHooks: (payload: unknown) => void;
51
- runInBackground: (
52
- hook: Hook,
53
- payload: unknown,
54
- callback: (...any) => void,
55
- presentUI: boolean
56
- ) => void;
57
- }
58
-
59
- export type HookIniObj = {
60
- hook: HookModule & {
61
- module: HookModule;
62
- general: unknown;
63
- screen_id?: string;
64
- identifier?: string;
65
- weight?: number | string;
66
- };
67
- hooks: Hook<any>[];
68
- manager: HookManager;
69
- };
70
-
71
- export interface Hook<T extends HookModule = HookModule> {
72
- manager: HookManager;
73
- lastHook: boolean;
74
- state: number;
75
- module: T;
76
- screen_id: string;
77
- identifier: string;
78
- configuration: T["configuration"];
79
- setStateAndNotify(
80
- event: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS],
81
- opts: {
82
- error?: typeof Error;
83
- route?: string;
84
- hookPlugin: Hook<T>;
85
- payload: unknown;
86
- }
87
- );
88
- general?: {
89
- transition_type: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS];
90
- allow_screen_plugin_presentation: boolean;
91
- is_flow_blocker: boolean;
92
- };
93
- }
@@ -1,3 +0,0 @@
1
- export * from "./keys";
2
-
3
- export { keyEventMapper } from "./keyEventMapper";
@@ -1,18 +0,0 @@
1
- export const KEYS = {
2
- Enter: { code: "Enter", keyCode: 13 },
3
- EnterKeyboard: { code: "EnterKeyboard", keyCode: 66 },
4
- Back: { code: "Back", keyCode: 8 },
5
- Space: { code: "Space", keyCode: 32 },
6
- m: { code: "m", keyCode: 77 },
7
- ArrowLeft: { code: "ArrowLeft", keyCode: 37 },
8
- ArrowUp: { code: "ArrowUp", keyCode: 38 },
9
- ArrowRight: { code: "ArrowRight", keyCode: 39 },
10
- ArrowDown: { code: "ArrowDown", keyCode: 40 },
11
- };
12
-
13
- export const ARROW_KEYS = [
14
- KEYS.ArrowUp,
15
- KEYS.ArrowLeft,
16
- KEYS.ArrowDown,
17
- KEYS.ArrowRight,
18
- ];
@@ -1,25 +0,0 @@
1
- export const KEYS = {
2
- Enter: { code: "Enter", keyCode: 13 },
3
- Space: { code: "Space", keyCode: 32 },
4
- m: { code: "m", keyCode: 77 },
5
- ArrowLeft: { code: "ArrowLeft", keyCode: 37 },
6
- ArrowUp: { code: "ArrowUp", keyCode: 38 },
7
- ArrowRight: { code: "ArrowRight", keyCode: 39 },
8
- ArrowDown: { code: "ArrowDown", keyCode: 40 },
9
- Back: { code: "Backspace", keyCode: 8 },
10
- Play: { code: "PlayPause", keyCode: 179 },
11
- Pause: { code: "Pause", keyCode: 179 },
12
- Forward: { code: "Forward", keyCode: 176 },
13
- Rewind: { code: "Rewind", keyCode: 177 },
14
- VolumeUp: { code: "VolumeUp", keyCode: 175 },
15
- VolumeDown: { code: "VolumeDown", keyCode: 174 },
16
- ToggleMute: { code: "VolumeMute", keyCode: 173 },
17
- Stop: { code: "Q", keyCode: 81 },
18
- };
19
-
20
- export const ARROW_KEYS = [
21
- KEYS.ArrowUp,
22
- KEYS.ArrowLeft,
23
- KEYS.ArrowDown,
24
- KEYS.ArrowRight,
25
- ];
@@ -1,15 +0,0 @@
1
- // dummy file to make sure the folder structure is created
2
- export const KEYS: Record<string, { code: string; keyCode: number }> = {
3
- ArrowLeft: { code: "ArrowLeft", keyCode: -1 },
4
- ArrowUp: { code: "ArrowUp", keyCode: -1 },
5
- ArrowRight: { code: "ArrowRight", keyCode: -1 },
6
- ArrowDown: { code: "ArrowDown", keyCode: -1 },
7
- Back: { code: "Back", keyCode: -1 },
8
- };
9
-
10
- export const ARROW_KEYS = [
11
- KEYS.ArrowUp,
12
- KEYS.ArrowLeft,
13
- KEYS.ArrowDown,
14
- KEYS.ArrowRight,
15
- ];
File without changes
File without changes