@applicaster/zapp-react-native-utils 15.0.0-alpha.4153840309 → 15.0.0-alpha.4200413542

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 (125) hide show
  1. package/actionsExecutor/ActionExecutorContext.tsx +3 -6
  2. package/actionsExecutor/feedDecorator.ts +6 -6
  3. package/adsUtils/__tests__/createVMAP.test.ts +419 -0
  4. package/adsUtils/index.ts +2 -2
  5. package/analyticsUtils/README.md +1 -1
  6. package/analyticsUtils/analyticsMapper.ts +10 -2
  7. package/appDataUtils/__tests__/urlScheme.test.ts +678 -0
  8. package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +0 -188
  9. package/appUtils/HooksManager/__tests__/hooksManager.test.js +16 -2
  10. package/appUtils/HooksManager/index.ts +10 -10
  11. package/appUtils/RiverFocusManager/{index.js → index.ts} +25 -18
  12. package/appUtils/accessibilityManager/__tests__/utils.test.ts +360 -0
  13. package/appUtils/accessibilityManager/const.ts +4 -0
  14. package/appUtils/accessibilityManager/utils.ts +25 -5
  15. package/appUtils/contextKeysManager/__tests__/getKeys/failure.test.ts +7 -2
  16. package/appUtils/contextKeysManager/__tests__/getKeys/success.test.ts +48 -0
  17. package/appUtils/contextKeysManager/contextResolver.ts +51 -22
  18. package/appUtils/contextKeysManager/index.ts +65 -10
  19. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +3 -0
  20. package/appUtils/focusManager/index.ios.ts +43 -4
  21. package/appUtils/focusManagerAux/utils/index.ios.ts +122 -0
  22. package/appUtils/focusManagerAux/utils/index.ts +1 -1
  23. package/appUtils/focusManagerAux/utils/utils.ios.ts +199 -3
  24. package/appUtils/keyCodes/keys/keys.web.ts +1 -4
  25. package/appUtils/orientationHelper.ts +2 -4
  26. package/appUtils/platform/platformUtils.ts +1 -1
  27. package/appUtils/playerManager/player.ts +4 -0
  28. package/appUtils/playerManager/playerNative.ts +29 -16
  29. package/appUtils/playerManager/usePlayerState.tsx +14 -2
  30. package/cloudEventsUtils/__tests__/index.test.ts +529 -0
  31. package/cloudEventsUtils/index.ts +65 -1
  32. package/configurationUtils/__tests__/imageSrcFromMediaItem.test.ts +38 -0
  33. package/configurationUtils/__tests__/manifestKeyParser.test.ts +26 -26
  34. package/configurationUtils/index.ts +17 -11
  35. package/dateUtils/__tests__/dayjs.test.ts +330 -0
  36. package/enumUtils/__tests__/getEnumKeyByEnumValue.test.ts +207 -0
  37. package/errorUtils/__tests__/GeneralError.test.ts +97 -0
  38. package/errorUtils/__tests__/HttpStatusCode.test.ts +344 -0
  39. package/errorUtils/__tests__/MissingPluginError.test.ts +113 -0
  40. package/errorUtils/__tests__/NetworkError.test.ts +202 -0
  41. package/errorUtils/__tests__/getParsedResponse.test.ts +188 -0
  42. package/errorUtils/__tests__/invariant.test.ts +112 -0
  43. package/focusManager/aux/index.ts +1 -1
  44. package/headersUtils/__tests__/headersUtils.test.js +11 -1
  45. package/headersUtils/index.ts +2 -1
  46. package/manifestUtils/defaultManifestConfigurations/player.js +125 -11
  47. package/manifestUtils/platformIsTV.js +13 -0
  48. package/manifestUtils/tvAction/container/index.js +1 -1
  49. package/navigationUtils/index.ts +15 -5
  50. package/numberUtils/__tests__/toNumber.test.ts +12 -0
  51. package/numberUtils/__tests__/toPositiveNumber.test.ts +165 -0
  52. package/numberUtils/index.ts +19 -1
  53. package/package.json +4 -4
  54. package/pluginUtils/index.ts +4 -0
  55. package/reactHooks/advertising/index.ts +2 -2
  56. package/reactHooks/analytics/__tests__/useSendAnalyticsOnPress.test.ts +537 -0
  57. package/reactHooks/app/__tests__/useAppState.test.ts +1 -1
  58. package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
  59. package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +1 -2
  60. package/reactHooks/cell-click/__tests__/index.test.js +1 -3
  61. package/reactHooks/configuration/__tests__/index.test.tsx +1 -1
  62. package/reactHooks/connection/__tests__/index.test.js +1 -1
  63. package/reactHooks/debugging/__tests__/index.test.js +4 -4
  64. package/reactHooks/dev/__tests__/useReRenderLog.test.ts +188 -0
  65. package/reactHooks/device/useIsTablet.tsx +14 -19
  66. package/reactHooks/device/useMemoizedIsTablet.ts +3 -3
  67. package/reactHooks/events/index.ts +20 -0
  68. package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +32 -23
  69. package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +19 -19
  70. package/reactHooks/feed/__tests__/useEntryScreenId.test.tsx +4 -1
  71. package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +42 -30
  72. package/reactHooks/feed/__tests__/useFeedRefresh.test.tsx +1 -1
  73. package/reactHooks/feed/__tests__/{useInflatedUrl.test.ts → useInflatedUrl.test.tsx} +62 -7
  74. package/reactHooks/feed/useEntryScreenId.ts +2 -2
  75. package/reactHooks/feed/useInflatedUrl.ts +43 -17
  76. package/reactHooks/flatList/useLoadNextPageIfNeeded.ts +13 -16
  77. package/reactHooks/hookModal/hooks/useHookModalScreenData.ts +12 -8
  78. package/reactHooks/index.ts +2 -0
  79. package/reactHooks/layout/__tests__/index.test.tsx +1 -1
  80. package/reactHooks/layout/__tests__/useLayoutVersion.test.tsx +1 -1
  81. package/reactHooks/layout/useDimensions/__tests__/{useDimensions.test.ts → useDimensions.test.tsx} +105 -25
  82. package/reactHooks/layout/useDimensions/useDimensions.ts +2 -2
  83. package/reactHooks/navigation/__tests__/index.test.tsx +40 -9
  84. package/reactHooks/navigation/index.ts +27 -11
  85. package/reactHooks/navigation/useRoute.ts +11 -7
  86. package/reactHooks/player/TVSeekControlller/TVSeekController.ts +27 -10
  87. package/reactHooks/player/__tests__/useAutoSeek._test.tsx +1 -1
  88. package/reactHooks/player/__tests__/useTapSeek._test.ts +1 -1
  89. package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +1 -1
  90. package/reactHooks/resolvers/__tests__/useComponentResolver.test.tsx +1 -1
  91. package/reactHooks/resolvers/useCellResolver.ts +6 -2
  92. package/reactHooks/resolvers/useComponentResolver.ts +8 -2
  93. package/reactHooks/screen/__tests__/useCurrentScreenData.test.tsx +2 -2
  94. package/reactHooks/screen/__tests__/useScreenBackgroundColor.test.tsx +1 -1
  95. package/reactHooks/screen/__tests__/useScreenData.test.tsx +1 -1
  96. package/reactHooks/screen/__tests__/useTargetScreenData.test.tsx +12 -4
  97. package/reactHooks/screen/useTargetScreenData.ts +4 -2
  98. package/reactHooks/state/useRefWithInitialValue.ts +10 -0
  99. package/reactHooks/state/useRivers.ts +1 -1
  100. package/reactHooks/ui/__tests__/useFadeOutWhenBlurred.test.ts +580 -0
  101. package/reactHooks/usePluginConfiguration.ts +2 -2
  102. package/reactHooks/utils/__tests__/index.test.js +1 -1
  103. package/rectUtils/__tests__/index.test.ts +549 -0
  104. package/rectUtils/index.ts +2 -2
  105. package/screenPickerUtils/__tests__/index.test.ts +333 -0
  106. package/screenState/__tests__/index.test.ts +1 -1
  107. package/searchUtils/const.ts +7 -0
  108. package/searchUtils/index.ts +3 -0
  109. package/services/storageServiceSync.web.ts +1 -1
  110. package/stringUtils/index.ts +1 -1
  111. package/testUtils/index.tsx +30 -21
  112. package/time/__tests__/BackgroundTimer.test.ts +156 -0
  113. package/time/__tests__/Timer.test.ts +236 -0
  114. package/typeGuards/__tests__/isString.test.ts +21 -0
  115. package/typeGuards/index.ts +4 -0
  116. package/utils/__tests__/mergeRight.test.ts +48 -0
  117. package/utils/__tests__/selectors.test.ts +124 -0
  118. package/utils/index.ts +13 -0
  119. package/utils/mergeRight.ts +5 -0
  120. package/utils/path.ts +6 -3
  121. package/utils/pathOr.ts +5 -1
  122. package/utils/selectors.ts +46 -0
  123. package/zappFrameworkUtils/HookCallback/callbackNavigationAction.ts +34 -11
  124. package/zappFrameworkUtils/HookCallback/hookCallbackManifestExtensions.config.js +1 -1
  125. package/reactHooks/componentsMap/index.ts +0 -55
@@ -0,0 +1,188 @@
1
+ import { getParsedResponse } from "../index";
2
+ import { RESPONSES } from "../errorCodes";
3
+
4
+ describe("getParsedResponse", () => {
5
+ it("should parse error with response status code from response.data", () => {
6
+ const err = {
7
+ response: {
8
+ data: {
9
+ statusCode: 404,
10
+ message: "Resource not found",
11
+ },
12
+ config: {
13
+ url: "https://api.example.com/data",
14
+ params: { id: 123 },
15
+ },
16
+ },
17
+ name: "AxiosError",
18
+ context: { userId: "user123" },
19
+ };
20
+
21
+ const result = getParsedResponse(err);
22
+
23
+ expect(result.message).toBe("Error: Resource not found");
24
+ expect(result.data.statusCode).toBe("404");
25
+ expect(result.data.url).toBe("https://api.example.com/data");
26
+ expect(result.data.params).toEqual({ id: 123 });
27
+ expect(result.data.context).toEqual({ userId: "user123" });
28
+ expect(result.data.name).toBe("AxiosError");
29
+ expect(result.jsOnly).toBe(false);
30
+ expect(result.exception).toBe(result.message);
31
+ });
32
+
33
+ it("should parse error with response status code from response.status", () => {
34
+ const err = {
35
+ response: {
36
+ status: 500,
37
+ config: {
38
+ url: "https://api.example.com/data",
39
+ },
40
+ },
41
+ };
42
+
43
+ const result = getParsedResponse(err);
44
+
45
+ expect(result.message).toBe(`Error: ${RESPONSES[500]}`);
46
+ expect(result.data.statusCode).toBe("500");
47
+ });
48
+
49
+ it("should handle error with request but no response", () => {
50
+ const err = {
51
+ request: {},
52
+ message: "Network timeout",
53
+ config: {
54
+ url: "https://api.example.com/data",
55
+ params: { test: "value" },
56
+ },
57
+ name: "NetworkError",
58
+ context: { app: "test" },
59
+ };
60
+
61
+ const result = getParsedResponse(err);
62
+
63
+ expect(result.message).toBe("Error: Network timeout");
64
+ expect(result.data.url).toBe("https://api.example.com/data");
65
+ expect(result.data.params).toEqual({ test: "value" });
66
+ expect(result.data.name).toBe("NetworkError");
67
+ expect(result.data.context).toEqual({ app: "test" });
68
+ expect(result.jsOnly).toBe(false);
69
+ });
70
+
71
+ it("should handle error with request but no response and no message", () => {
72
+ const err = {
73
+ request: {},
74
+ config: {
75
+ url: "https://api.example.com/data",
76
+ },
77
+ };
78
+
79
+ const result = getParsedResponse(err);
80
+
81
+ expect(result.message).toBe(`Error: ${RESPONSES.noResponse}`);
82
+ });
83
+
84
+ it("should handle error with neither response nor request", () => {
85
+ const err = {
86
+ message: "Failed to set up request",
87
+ config: {
88
+ url: "https://api.example.com/data",
89
+ },
90
+ };
91
+
92
+ const result = getParsedResponse(err);
93
+
94
+ expect(result.message).toBe("Error: Failed to set up request");
95
+ });
96
+
97
+ it("should handle error with neither response nor request and no message", () => {
98
+ const err = {
99
+ config: {
100
+ url: "https://api.example.com/data",
101
+ },
102
+ };
103
+
104
+ const result = getParsedResponse(err);
105
+
106
+ expect(result.message).toBe(`Error: ${RESPONSES.unknown}`);
107
+ });
108
+
109
+ it("should handle null error", () => {
110
+ const err = null;
111
+
112
+ const result = getParsedResponse(err);
113
+
114
+ expect(result.message).toBe(`Error: ${RESPONSES.unknown}`);
115
+
116
+ expect(result.data).toEqual({
117
+ context: undefined,
118
+ name: undefined,
119
+ params: undefined,
120
+ url: undefined,
121
+ });
122
+ });
123
+
124
+ it("should handle undefined error", () => {
125
+ const err = undefined;
126
+
127
+ const result = getParsedResponse(err);
128
+
129
+ expect(result.message).toBe(`Error: ${RESPONSES.unknown}`);
130
+ });
131
+
132
+ it("should extract params from err.config when response is not present", () => {
133
+ const err = {
134
+ request: {},
135
+ message: "Request failed",
136
+ config: {
137
+ url: "https://api.example.com/data",
138
+ params: { key: "value" },
139
+ },
140
+ };
141
+
142
+ const result = getParsedResponse(err);
143
+
144
+ expect(result.data.params).toEqual({ key: "value" });
145
+ expect(result.data.url).toBe("https://api.example.com/data");
146
+ });
147
+
148
+ it("should prioritize response config over error config", () => {
149
+ const err = {
150
+ response: {
151
+ status: 404,
152
+ config: {
153
+ url: "https://api.example.com/response-url",
154
+ params: { from: "response" },
155
+ },
156
+ },
157
+ config: {
158
+ url: "https://api.example.com/error-url",
159
+ params: { from: "error" },
160
+ },
161
+ };
162
+
163
+ const result = getParsedResponse(err);
164
+
165
+ expect(result.data.url).toBe("https://api.example.com/response-url");
166
+ expect(result.data.params).toEqual({ from: "response" });
167
+ });
168
+
169
+ it("should handle response with custom status codes", () => {
170
+ const err = {
171
+ response: {
172
+ data: {
173
+ statusCode: 418,
174
+ message: "I'm a teapot",
175
+ },
176
+ status: 418,
177
+ config: {
178
+ url: "https://api.example.com/coffee",
179
+ },
180
+ },
181
+ };
182
+
183
+ const result = getParsedResponse(err);
184
+
185
+ expect(result.message).toBe("Error: I'm a teapot");
186
+ expect(result.data.statusCode).toBe("418");
187
+ });
188
+ });
@@ -0,0 +1,112 @@
1
+ import { invariant } from "../index";
2
+
3
+ // Mock __DEV__ global
4
+ declare global {
5
+ var __DEV__: boolean;
6
+ }
7
+
8
+ describe("invariant", () => {
9
+ const originalDev = global.__DEV__;
10
+
11
+ afterEach(() => {
12
+ global.__DEV__ = originalDev;
13
+ });
14
+
15
+ describe("in development mode", () => {
16
+ beforeEach(() => {
17
+ global.__DEV__ = true;
18
+ });
19
+
20
+ it("should not throw when condition is true", () => {
21
+ expect(() => {
22
+ invariant(true, "This should not throw");
23
+ }).not.toThrow();
24
+ });
25
+
26
+ it("should throw when condition is false", () => {
27
+ expect(() => {
28
+ invariant(false, "This should throw");
29
+ }).toThrow("This should throw");
30
+ });
31
+
32
+ it("should throw with correct error message", () => {
33
+ const errorMessage = "Custom error message";
34
+
35
+ expect(() => {
36
+ invariant(false, errorMessage);
37
+ }).toThrow(errorMessage);
38
+ });
39
+
40
+ it("should not throw when condition is truthy value", () => {
41
+ expect(() => {
42
+ invariant(1 as any, "Should not throw");
43
+ }).not.toThrow();
44
+
45
+ expect(() => {
46
+ invariant("string" as any, "Should not throw");
47
+ }).not.toThrow();
48
+
49
+ expect(() => {
50
+ invariant({} as any, "Should not throw");
51
+ }).not.toThrow();
52
+
53
+ expect(() => {
54
+ invariant([] as any, "Should not throw");
55
+ }).not.toThrow();
56
+ });
57
+
58
+ it("should throw when condition is falsy value", () => {
59
+ expect(() => {
60
+ invariant(0 as any, "Should throw for 0");
61
+ }).toThrow("Should throw for 0");
62
+
63
+ expect(() => {
64
+ invariant("" as any, "Should throw for empty string");
65
+ }).toThrow("Should throw for empty string");
66
+
67
+ expect(() => {
68
+ invariant(null as any, "Should throw for null");
69
+ }).toThrow("Should throw for null");
70
+
71
+ expect(() => {
72
+ invariant(undefined as any, "Should throw for undefined");
73
+ }).toThrow("Should throw for undefined");
74
+
75
+ expect(() => {
76
+ invariant(NaN as any, "Should throw for NaN");
77
+ }).toThrow("Should throw for NaN");
78
+ });
79
+ });
80
+
81
+ describe("in production mode", () => {
82
+ beforeEach(() => {
83
+ global.__DEV__ = false;
84
+ });
85
+
86
+ it("should not throw when condition is true", () => {
87
+ expect(() => {
88
+ invariant(true, "This should not throw");
89
+ }).not.toThrow();
90
+ });
91
+
92
+ it("should not throw when condition is false", () => {
93
+ expect(() => {
94
+ invariant(false, "This should not throw in production");
95
+ }).not.toThrow();
96
+ });
97
+
98
+ it("should not throw for any condition", () => {
99
+ expect(() => {
100
+ invariant(0 as any, "Should not throw in production");
101
+ }).not.toThrow();
102
+
103
+ expect(() => {
104
+ invariant(null as any, "Should not throw in production");
105
+ }).not.toThrow();
106
+
107
+ expect(() => {
108
+ invariant(undefined as any, "Should not throw in production");
109
+ }).not.toThrow();
110
+ });
111
+ });
112
+ });
@@ -49,7 +49,7 @@ export const findSelectedMenuId = (
49
49
  ) => {
50
50
  const sectionName = QUICK_BRICK_NAVBAR_SECTIONS[sectionKey];
51
51
 
52
- return pathOr(
52
+ return pathOr<string | undefined>(
53
53
  undefined,
54
54
  ["children", index, "id"],
55
55
  focusableTree.find(sectionName)
@@ -1,6 +1,15 @@
1
1
  import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
2
2
  import { getAppDataHeaders } from "../index";
3
3
 
4
+ const mockUILanguage = "en-US";
5
+
6
+ jest.mock(
7
+ "@applicaster/zapp-react-native-utils/appUtils/localizationsHelper",
8
+ () => ({
9
+ getUILanguage: jest.fn(() => mockUILanguage),
10
+ })
11
+ );
12
+
4
13
  describe("getAppDataHeaders", () => {
5
14
  const mockAppData = {
6
15
  riversConfigurationId: "test-layout",
@@ -25,7 +34,7 @@ describe("getAppDataHeaders", () => {
25
34
  const expectedHeaders = {
26
35
  "x-applicaster-layout-id": mockAppData.riversConfigurationId,
27
36
  "x-applicaster-screen-id": screenId,
28
- "x-applicaster-language-code": mockAppData.languageCode,
37
+ "x-applicaster-language-code": mockUILanguage,
29
38
  "x-applicaster-version-number": mockAppData.version_name,
30
39
  "x-applicaster-platform": mockAppData.platform,
31
40
  "x-applicaster-country-code": mockAppData.countryCode,
@@ -33,6 +42,7 @@ describe("getAppDataHeaders", () => {
33
42
  mockAppData.signedDeviceInfoToken,
34
43
  "x-applicaster-device-make": mockAppData.deviceMake,
35
44
  "x-applicaster-device-model": mockAppData.deviceModel,
45
+ "x-applicaster-uuid": undefined,
36
46
  };
37
47
 
38
48
  const headers = getAppDataHeaders(screenId);
@@ -1,6 +1,7 @@
1
1
  import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
2
2
  import { getPlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
3
3
  import { utilsLogger } from "../logger";
4
+ import { getUILanguage } from "../localizationUtils";
4
5
 
5
6
  const logger = utilsLogger.addSubsystem("headersUtils");
6
7
 
@@ -21,7 +22,7 @@ export const getAppDataHeaders = (screenId: string) => {
21
22
  "x-applicaster-layout-id":
22
23
  appData.riversConfigurationId || appData.rivers_configuration_id,
23
24
  "x-applicaster-screen-id": screenId,
24
- "x-applicaster-language-code": appData.languageCode,
25
+ "x-applicaster-language-code": getUILanguage(),
25
26
  "x-applicaster-version-number": appData.version_name || appData.versionName,
26
27
  "x-applicaster-platform": (platform || appData.platform).toLowerCase(),
27
28
  "x-applicaster-country-code": appData.countryCode,
@@ -331,10 +331,53 @@ function getPlayerConfiguration({ platform, version }) {
331
331
  label_tooltip: "Hint for skip intro button accessibility",
332
332
  type: "text_input",
333
333
  },
334
+ {
335
+ type: "text_input",
336
+ label: "Text Tracks Label",
337
+ key: "text_tracks_label",
338
+ initial_value: "Subtitles",
339
+ label_tooltip: "Label for the text tracks list",
340
+ },
341
+ {
342
+ type: "text_input",
343
+ label: "Audio Tracks Label",
344
+ key: "audio_tracks_label",
345
+ initial_value: "Audio",
346
+ label_tooltip: "Label for the audio tracks list",
347
+ },
348
+ {
349
+ type: "text_input",
350
+ label: "Off Track Label",
351
+ key: "off_track_label",
352
+ initial_value: "Off",
353
+ label_tooltip: "Label for the 'Off' option in text tracks list",
354
+ },
355
+ {
356
+ type: "text_input",
357
+ label: "Default Track Label",
358
+ key: "default_track_label",
359
+ initial_value: "Default",
360
+ label_tooltip:
361
+ "Label for the 'Default' audio track in audio tracks list",
362
+ },
334
363
  ],
335
364
  };
336
365
 
337
366
  if (isTV(platform)) {
367
+ localizations.fields.push({
368
+ key: "back_to_live_label",
369
+ label: "Back to live label",
370
+ initial_value: "Back To Live",
371
+ type: "text_input",
372
+ });
373
+
374
+ localizations.fields.push({
375
+ key: "start_over_label",
376
+ label: "Start over label",
377
+ initial_value: "Start Over",
378
+ type: "text_input",
379
+ });
380
+
338
381
  styles.fields.push(
339
382
  fieldsGroup("Always Show Scrub Bar & Timestamp", "", [
340
383
  {
@@ -447,7 +490,7 @@ function getPlayerConfiguration({ platform, version }) {
447
490
  ),
448
491
  fieldsGroup(
449
492
  "Skip Button",
450
- "This section allows you to configure the skip button styles for tv",
493
+ "This section allows you to configure the skip button behaviour",
451
494
  [
452
495
  {
453
496
  type: "switch",
@@ -464,6 +507,12 @@ function getPlayerConfiguration({ platform, version }) {
464
507
  label: "Persistent Button Toggle",
465
508
  initial_value: true,
466
509
  },
510
+ ]
511
+ ),
512
+ fieldsGroup(
513
+ "Labeled Button Style",
514
+ "This section allows you to configure the labeled button styles",
515
+ [
467
516
  {
468
517
  type: "color_picker_rgba",
469
518
  label_tooltip: "",
@@ -619,7 +668,61 @@ function getPlayerConfiguration({ platform, version }) {
619
668
  );
620
669
  }
621
670
 
671
+ if (isTV(platform)) {
672
+ general.fields.push(
673
+ {
674
+ key: "liveSeekingEnabled",
675
+ label: "Live Seeking Enabled",
676
+ initial_value: false,
677
+ type: "switch",
678
+ label_tooltip: "Enable Live Seek",
679
+ },
680
+ {
681
+ key: "minimumAllowedSeekableDurationInSeconds",
682
+ label: "Minimum allowed seekable duration in seconds",
683
+ initial_value: 300,
684
+ type: "number_input",
685
+ label_tooltip:
686
+ "If duration less than this value, player will disable 'liveSeekingEnabled' value",
687
+ },
688
+ {
689
+ key: "live_image",
690
+ label: "Live badge",
691
+ type: "uploader",
692
+ label_tooltip: "Override default live badge / icon",
693
+ },
694
+ {
695
+ key: "live_width",
696
+ label: "Live badge width",
697
+ type: "number_input",
698
+ initial_value: 85,
699
+ },
700
+ {
701
+ key: "live_height",
702
+ label: "Live badge height",
703
+ type: "number_input",
704
+ initial_value: 50,
705
+ }
706
+ );
707
+ }
708
+
622
709
  if (isMobile(platform)) {
710
+ localizations.fields.push(
711
+ {
712
+ type: "text_input",
713
+ label: "Restrict playback on mobile networks alert title",
714
+ key: "mobile_connection_restricted_alert_title",
715
+ initial_value: "Restricted Connection Type",
716
+ },
717
+ {
718
+ type: "text_input",
719
+ label: "Restrict playback on mobile networks alert message",
720
+ key: "mobile_connection_restricted_alert_message",
721
+ initial_value:
722
+ "This content can only be viewed over a Wi-Fi or LAN network.",
723
+ }
724
+ );
725
+
623
726
  general.fields.push(
624
727
  {
625
728
  section: "Default Timestamp Type",
@@ -1142,40 +1245,35 @@ function getPlayerConfiguration({ platform, version }) {
1142
1245
  label: "Playback Speed 0.8x",
1143
1246
  type: "uploader",
1144
1247
  label_tooltip: "Playback Speed 0.8x",
1145
- initial_value:
1146
- "data:image/png;base64,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",
1248
+ initial_value: null,
1147
1249
  },
1148
1250
  {
1149
1251
  key: "speed_1",
1150
1252
  label: "Playback Speed 1x",
1151
1253
  type: "uploader",
1152
1254
  label_tooltip: "Playback Speed 1x",
1153
- initial_value:
1154
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAYAAAA5ZDbSAAAACXBIWXMAACE4AAAhOAFFljFgAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAI4SURBVHgB7dzhcRJBGIDhT8cCkg6SDmIHsQNLiBUYKwAqUCtIC5ZACVqBdIAdxN3JMSLecXcE8Tt5npkdJlxyf97ZcLcLRAAAAAAAAAAAAAAAAAAAAAAAAADAMb2IiViv17fl4aGMq45fub68vFwFv3kVyZWwF+VhVsZ9MFrqwANmLT1SBm5mbQ37NniWl5FMifu+PHwPcY8izQwuYa/iadbeBkeTaQbfxf64P8r4GoyS7l90h89lXJfxLRgl+23Sqox35f52WX8o/8aDcTLP4EUZrzdxOUzGGbws40MJ6/X2CDIFrhdRNeyn4GjSBBb275jKVTQHEvg/d/aB69Lo+sljGR/jADvnmEUiZx242a2qr/0XzVP35bmHkeeY7Zxj3pw3hXOfwTctz90NjdzEnbccuo0kzj1w1712b+Q9cfed9+TOOnCzSrboONwZuSfuopz3SyRx9hdZJcY8RkQeELfr2D/hNimGR55a3Cr9m+5OpcZpdqvabnNq5HpBdtPx5ynjVmbwlp6ZPLm4lcA7eiLvSh23ErjFwMjp41YCd3t85vEUBG7Rc7W8Mc+27txG4B0D426kjyzwlp64y47nU0cWuDFgEeNNdF94pY0scAxfoeq5uk4Z2Yb/yOXHqUW24X/A2vKAyGk+OGfDv13vIsaBy5onZ8P/T4NXqPZEtuGfwdaG/yp+vfF+HiNsRV5tnSPNhv9kvoSlaj75f9F2zBewAAAAAAAAAAAAAAAAAAAAAAAAwHT8BNhH51wNSx95AAAAAElFTkSuQmCC",
1255
+ initial_value: null,
1155
1256
  },
1156
1257
  {
1157
1258
  key: "speed_1_2",
1158
1259
  label: "Playback Speed 1.2x",
1159
1260
  type: "uploader",
1160
1261
  label_tooltip: "Playback Speed 1.2x",
1161
- initial_value:
1162
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAYAAAA5ZDbSAAAACXBIWXMAACE4AAAhOAFFljFgAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAUjSURBVHgB7d3bUeNIFAbgA7Xv2EUCmgiWjWBNBAwRYCKYdQQrIliIYEUEw0awymDIYDQBUFC8g+eccWsulPomteTu1v9VdZlSGyP0W1KrWxciAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgPgc0Mw8Pj4u+KUt4mm5XDaUqVED5oX5gV/ea6o3vGDvaQI8Hyt+ueAir4XmbTIvNZebnAIfJWBeoCf88g/tFqjOKS/ImkbE8/FezUdBfu5o9wVsKHGHFJBs/rjIAv1E5nBHpebjX/7xI/mHK+SL8Zk/429K3G8UiNoMykItaI/UPvZ/Lic0XMmfR7wmX1GiBq/BP621slAL2j9Z60KE25KQ/6JEDdoHD9jHieD7YJ6fNe22IjpPXG5p16Bq1DT5MpyReZciv/eO5/eJEtN7E63C/Wh5myyQBU1Hu888ODi42263lx0h1Vyu1ZdDvqxd8yvTZC0uKTFDNtGm4GQhbrjc0ERUy73QVNeLxeLctAZyXcUv56R3QQkK2or+9oGHhxXtNmfXNK2Voe6SHKhdxq2muuAvUUGJCRlww+X06Ojock/7qj810+89j2fvDHUFJSZUwLIp/mPsjgsL3S7jC/mZpHdtKkOPg2VhbPYcbEuOVbs2rw35mbJROLohAdeqYRKFgF+ywlCX3GFS7010xiMwZ5rpzVSDIyEFb0WnTLWS1111fHRQU4IQ8K+0vWCvr69J9kcjYEWNHK001c5jxNIvz2XLpfdolIyEtZ/x/Pw8qIMFAdP3ExNKTXVDjl2UqruzHZgoaDdQ4RWyGuZct5/x8vJSqRGyXmYfMC88WUNMvW6nHh03q45pziG/Cdf2uU5mHbAKtzK8xfesjloz3RqyIVzRu/U+24Adwr3y7U+XfgFujOn6srUhW8K9GnJIOsuAHcMtqYfj4+O1T8gO4ZY0wOwCdgj3duhCdQ157HDFrAJ2DHdNATiELCcmrjX1QcIVswl4ynBblpB1540FC1fMImB1nFsZ3hI83JYl5LeChiuyD1jt70yt4dHCbTmGHDxckXXAKtzS8JbRw23xYMXW8hZbfb+/S5mKKVxLa7nl3a3pItiVDaGpoTs5NVf6YeW8qjuP300t3FbwKymiDLgrIJ4m3XXWfuGEwpX/p6slHTTk6AJWIzJlR5UsDDnR/tTwu7ZwGy6Vuo6qF9dTg1w6MR4eHireN3cNBwYLOcY1+MxQt5Khs661WF0/VJJZQbtrqPpquLyzvcm1h0pa1xwyjRlyjI0s29jnief0Sfl2P/r2XfuKMWDbeczRnvimdi9rTbX2ONch5N5f3hgDrgx1N8u4r/BbaaZbOzEsIRfUU3QBq0aMXEvUvKmS1m/s1+nWHdOce6gMIffeao3dyJJj10ZTp5v+beCcN0s17farsk9uHFqvFenPqAjFuPVQ813wjx/UJO+TBiRk/gz5Oxfq7w0a8AcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANif7B8Q/dOlJHI7iEJNvlcl+8tCsg5Y3R/Ldm1QuUz46aI2ud9lx+XCr1HubhOLLNdgh6eQdjn3uZNPKnIN+DP5XzQtl6ha77+Rmuw20eoOOgX5K4bcfSdWOe6Dh9yMJYobuYSUY8BDnj2Y1XMLRY4BD7lJS3LPJrTJMeAht1lK7tmENmhF/4BWdEI25C/L3qwsA1YdFj6BXcX0LOSQcu+LLvnF1g258b2XVUrmMppUcvmdfhznNlz+43Kd+2jSV0z9PFgMpokeAAAAAElFTkSuQmCC",
1262
+ initial_value: null,
1163
1263
  },
1164
1264
  {
1165
1265
  key: "speed_1_5",
1166
1266
  label: "Playback Speed 1.5x",
1167
1267
  type: "uploader",
1168
1268
  label_tooltip: "Playback Speed 1.5x",
1169
- initial_value:
1170
- "data:image/png;base64,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",
1269
+ initial_value: null,
1171
1270
  },
1172
1271
  {
1173
1272
  key: "speed_2",
1174
1273
  label: "Playback Speed 2x",
1175
1274
  type: "uploader",
1176
1275
  label_tooltip: "Playback Speed 2x",
1177
- initial_value:
1178
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAYAAAA5ZDbSAAAACXBIWXMAACE4AAAhOAFFljFgAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAQnSURBVHgB7d2PUdRAFMfxh2MBUIGxArECjwqECjwqUCowV4FYgdABVCAdSAekg7ME35pFgnOb3ZDAvmy+n5lMGJLL3dzvkuyfZCMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2LMnM7Hdbvd11p2ag4ODRtDLdMAa6kpnH3U61qkKrHbrp0sN/EbwiMmAfbBfdVrJMI1OZxr0leAvcwFruC7YWsY515DPBLYC1nC/6eyLTONCQz6VhXslRvg9d6pwnbX/wSyaiT1Yg6h0dhdZzZ1Xr6U9zzqHOn2QtgDW52jJhS8rAf/Q2Tqw2JWQT0JVIv/j+CnhUvaNvvZIFip7wL5+uw0sbqTdA5vINiqd/ZK2fryLbuLgtyyQhXPwYc+yTUpjhl/ne88qK1koCwGvQgs0uAtJ17duJQtlIeDQYfVWBojs6fuyUK8lP1c63hXmlOfMRZ5/newBT1WF0YJW37m8kYUy09Axgb6ABx3uSzKb7sI+vqrlqknVjsXJ9WC/HRlTpZpiG1MqZQ92zZxVYNmlJPBNpdv2z6c1cfrXjdrG1Ga/B+sX+Vln54HFV7onnUh8GytpW8O6BnVWBFrjTnJ3Xc56D/YFq1C47hCZ2mW46/y99qGlfI5QU+uhZDbbgDtt0CFJrWBeqBAWDTnSjn4jmc0y4E64oQYMF+65JPJVtU1gcTDkSLgbC71YszsHJ/QeuWuz1vK0bdfSFth2eXROTgi3FgNmFXBCuLf6xb6Xce9RSyTkuYTrzOmyWVdg6Tssu/Po0RT1z0jIjYR/YKbCdWYR8EuG23nPWsIh72IuXMd8wDnC7bx3LWkhmwzXsX7he7ZwO5+hlv6QzYbrmK0mWQjXezNyeVZW72wwEW6ktNxl9hpsc3uwfqmfZF7hOsnNmi/NVMA+3AsJh9tI24CfM9ybwP9Nhmzpzob7cEMaSbiEdoLPEWvEcH3Lg5s1c7Fy4Xss3PueoUaeKKVdeEgL1ZBmzZwsXPi+kv5eoUnoF74X+Rx9N77trArNIWQLh+hKMtOgjmVguI7/f9/h+lgyK+miuzGqwP+jjRiRkOnwN2JXh39yC1VPyFeSGQHLvwKYu3bLBd1IOwxELQP49U//28atZGahkFXJC9wcNvA+JwAAAAAAAAAAAAAAAAAAAAAAAIxWxIjvffytMW5M6e4ziO+fOTxkRNpZKjrgyGDh92oNeSOFKvbuQj9Ef8qQwrVft0hF7sEa2FpnQwdDyT78/nMoNeA7GT40RKMBv5XCFHeI9oO6VDJc5V9blBLPwWPGxcg+psbUSgx4X55uzGtNKjHgMcMcPvfItS+uxIDHDHySfdCUqVGKfkApekZSn3jWVWRrVpEB+waLIYFtSh1mqfS26FriD9U4G/KUtLlZSm9SrdM7eajnNjpd63Reem/SH2FDq35f8ateAAAAAElFTkSuQmCC",
1276
+ initial_value: null,
1179
1277
  },
1180
1278
  {
1181
1279
  key: "sleep_timer",
@@ -3429,6 +3527,22 @@ function getPlayerConfiguration({ platform, version }) {
3429
3527
  label_tooltip:
3430
3528
  "This field allows you to override the player configuration / initialization options. i.e. html5: { vhs: { limitRenditionByPlayerDimensions: false } } Please ensure your configuration matches the player you are targeting, and that it is a valid json. See config options here: https://videojs.com/guides/options/",
3431
3529
  },
3530
+ {
3531
+ key: "advanced_player_styles",
3532
+ label: "Advanced Player Styles",
3533
+ type: "text_input",
3534
+ multiline: true,
3535
+ initial_value: `.vjs-text-track-cue {
3536
+ inset: unset !important;
3537
+ top: 94% !important;
3538
+ bottom: 0 !important;
3539
+ left: 0 !important;
3540
+ right: 0 !important;
3541
+ width: 100% !important;
3542
+ }`,
3543
+ label_tooltip:
3544
+ "This field allows you to inject custom CSS styles to override default player styles. The styles will be injected into the document head and can be used to customize the appearance of the player. Leave empty to use only default styles.",
3545
+ },
3432
3546
  {
3433
3547
  key: "use_dashjs_player",
3434
3548
  label: "Use Enhanced Player for DASH streams",
@@ -0,0 +1,13 @@
1
+ function platformIsTV(platform) {
2
+ return [
3
+ "tvos_for_quickbrick",
4
+ "android_tv_for_quickbrick",
5
+ "amazon_fire_tv_for_quickbrick",
6
+ "lg_tv",
7
+ "samsung_tv",
8
+ "web",
9
+ "vizio",
10
+ ].includes(platform);
11
+ }
12
+
13
+ module.exports = { platformIsTV };
@@ -38,7 +38,7 @@ function tvActionButtonsContainer({ label, description, defaults }) {
38
38
  generateFieldsFromDefaultsWithoutPrefixedLabel(
39
39
  label,
40
40
  defaults,
41
- tvActionButtonContainerFields(defaults["position"])
41
+ tvActionButtonContainerFields(defaults.position)
42
42
  )
43
43
  );
44
44
 
@@ -5,7 +5,8 @@ import { layoutV2TypeMatcher } from "./layoutV2TypeMatcher";
5
5
  import { HOOKS_EVENTS } from "../appUtils/HooksManager/constants";
6
6
  import { HooksManager } from "../appUtils/HooksManager";
7
7
  import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
8
- import { HookModalContextT } from "@applicaster/zapp-react-native-ui-components/Contexts/ZappHookModalContext";
8
+
9
+ import { zappHookModalStore } from "@applicaster/zapp-react-native-ui-components/Contexts/ZappHookModalContext";
9
10
  import { logger } from "@applicaster/zapp-react-native-utils/logger";
10
11
  import {
11
12
  isGeneralPlugin,
@@ -15,6 +16,8 @@ import {
15
16
  } from "./itemTypeMatchers";
16
17
  import { RootState } from "@applicaster/zapp-react-native-redux/store";
17
18
 
19
+ import { pick } from "@applicaster/zapp-react-native-utils/utils";
20
+
18
21
  type PathAttribute = {
19
22
  screenType: string;
20
23
  screenId: string;
@@ -403,15 +406,22 @@ export const mapContentTypesToRivers = (
403
406
  };
404
407
 
405
408
  export const runZappHooksForEntry = async (
406
- entry: HookPluginProps["payload"],
407
- {
409
+ entry: HookPluginProps["payload"]
410
+ ): Promise<{ success: boolean; payload: ZappEntry }> => {
411
+ const {
408
412
  setState,
409
413
  resetState,
410
414
  setIsHooksExecutionInProgress,
411
415
  setIsPresentingFullScreen,
412
416
  setIsRunningInBackground,
413
- }: Partial<HookModalContextT>
414
- ): Promise<{ success: boolean; payload: ZappEntry }> => {
417
+ } = pick(zappHookModalStore.getState(), [
418
+ "setState",
419
+ "resetState",
420
+ "setIsHooksExecutionInProgress",
421
+ "setIsPresentingFullScreen",
422
+ "setIsRunningInBackground",
423
+ ]);
424
+
415
425
  resetState?.();
416
426
 
417
427
  let success;
@@ -11,6 +11,16 @@ describe("toNumber", () => {
11
11
  });
12
12
  });
13
13
 
14
+ it("return number if input is BigInt", () => {
15
+ const inputs = [5n, -5n];
16
+ expect.assertions(inputs.length);
17
+
18
+ inputs.forEach((input) => {
19
+ const output = toNumber(input);
20
+ expect(output).toBe(Number(input));
21
+ });
22
+ });
23
+
14
24
  it("return number if input is string as number", () => {
15
25
  const inputs = ["-1", "0", "1", "100", "0.2"];
16
26
  expect.assertions(inputs.length);
@@ -32,6 +42,8 @@ describe("toNumber", () => {
32
42
  { test: 1 },
33
43
  [],
34
44
  [1],
45
+ "5n",
46
+ "-5n",
35
47
  ];
36
48
 
37
49
  expect.assertions(inputs.length);