@applicaster/zapp-react-native-utils 15.0.0-alpha.1966607451 → 15.0.0-alpha.2060204268

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 (87) hide show
  1. package/adsUtils/__tests__/createVMAP.test.ts +419 -0
  2. package/analyticsUtils/analyticsMapper.ts +10 -2
  3. package/appDataUtils/__tests__/urlScheme.test.ts +678 -0
  4. package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +0 -188
  5. package/appUtils/HooksManager/__tests__/hooksManager.test.js +16 -2
  6. package/appUtils/RiverFocusManager/{index.js → index.ts} +25 -18
  7. package/appUtils/contextKeysManager/__tests__/getKeys/failure.test.ts +7 -2
  8. package/appUtils/contextKeysManager/__tests__/getKeys/success.test.ts +48 -0
  9. package/appUtils/contextKeysManager/contextResolver.ts +51 -22
  10. package/appUtils/contextKeysManager/index.ts +65 -10
  11. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +3 -0
  12. package/appUtils/focusManager/index.ios.ts +35 -2
  13. package/appUtils/focusManagerAux/utils/index.ios.ts +122 -0
  14. package/appUtils/focusManagerAux/utils/utils.ios.ts +55 -1
  15. package/cloudEventsUtils/__tests__/index.test.ts +529 -0
  16. package/cloudEventsUtils/index.ts +65 -1
  17. package/configurationUtils/__tests__/imageSrcFromMediaItem.test.ts +38 -0
  18. package/configurationUtils/index.ts +17 -11
  19. package/dateUtils/__tests__/dayjs.test.ts +330 -0
  20. package/enumUtils/__tests__/getEnumKeyByEnumValue.test.ts +207 -0
  21. package/errorUtils/__tests__/GeneralError.test.ts +97 -0
  22. package/errorUtils/__tests__/HttpStatusCode.test.ts +344 -0
  23. package/errorUtils/__tests__/MissingPluginError.test.ts +113 -0
  24. package/errorUtils/__tests__/NetworkError.test.ts +202 -0
  25. package/errorUtils/__tests__/getParsedResponse.test.ts +188 -0
  26. package/errorUtils/__tests__/invariant.test.ts +112 -0
  27. package/headersUtils/__tests__/headersUtils.test.js +11 -1
  28. package/headersUtils/index.ts +2 -1
  29. package/manifestUtils/defaultManifestConfigurations/player.js +52 -7
  30. package/manifestUtils/platformIsTV.js +13 -0
  31. package/navigationUtils/index.ts +15 -5
  32. package/numberUtils/__tests__/toNumber.test.ts +12 -0
  33. package/numberUtils/__tests__/toPositiveNumber.test.ts +165 -0
  34. package/numberUtils/index.ts +19 -1
  35. package/package.json +4 -4
  36. package/reactHooks/analytics/__tests__/useSendAnalyticsOnPress.test.ts +537 -0
  37. package/reactHooks/app/__tests__/useAppState.test.ts +1 -1
  38. package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
  39. package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +1 -2
  40. package/reactHooks/cell-click/__tests__/index.test.js +1 -3
  41. package/reactHooks/configuration/__tests__/index.test.tsx +1 -1
  42. package/reactHooks/connection/__tests__/index.test.js +1 -1
  43. package/reactHooks/dev/__tests__/useReRenderLog.test.ts +188 -0
  44. package/reactHooks/device/useIsTablet.tsx +14 -19
  45. package/reactHooks/events/index.ts +20 -0
  46. package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +32 -23
  47. package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +19 -19
  48. package/reactHooks/feed/__tests__/useEntryScreenId.test.tsx +1 -1
  49. package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +42 -30
  50. package/reactHooks/feed/__tests__/useFeedRefresh.test.tsx +1 -1
  51. package/reactHooks/feed/__tests__/useInflatedUrl.test.tsx +1 -1
  52. package/reactHooks/hookModal/hooks/useHookModalScreenData.ts +12 -8
  53. package/reactHooks/index.ts +2 -0
  54. package/reactHooks/layout/__tests__/index.test.tsx +1 -1
  55. package/reactHooks/layout/__tests__/useLayoutVersion.test.tsx +1 -1
  56. package/reactHooks/navigation/__tests__/index.test.tsx +40 -9
  57. package/reactHooks/navigation/index.ts +19 -4
  58. package/reactHooks/navigation/useRoute.ts +3 -1
  59. package/reactHooks/player/__tests__/useAutoSeek._test.tsx +1 -1
  60. package/reactHooks/player/__tests__/useTapSeek._test.ts +1 -1
  61. package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +1 -1
  62. package/reactHooks/resolvers/__tests__/useComponentResolver.test.tsx +1 -1
  63. package/reactHooks/screen/__tests__/useCurrentScreenData.test.tsx +2 -2
  64. package/reactHooks/screen/__tests__/useScreenBackgroundColor.test.tsx +1 -1
  65. package/reactHooks/screen/__tests__/useScreenData.test.tsx +1 -1
  66. package/reactHooks/screen/__tests__/useTargetScreenData.test.tsx +2 -2
  67. package/reactHooks/state/useRefWithInitialValue.ts +10 -0
  68. package/reactHooks/ui/__tests__/useFadeOutWhenBlurred.test.ts +580 -0
  69. package/reactHooks/utils/__tests__/index.test.js +1 -1
  70. package/rectUtils/__tests__/index.test.ts +549 -0
  71. package/rectUtils/index.ts +2 -2
  72. package/screenPickerUtils/__tests__/index.test.ts +333 -0
  73. package/screenState/__tests__/index.test.ts +1 -1
  74. package/screenUtils/index.ts +3 -0
  75. package/searchUtils/const.ts +7 -0
  76. package/searchUtils/index.ts +3 -0
  77. package/services/storageServiceSync.web.ts +1 -1
  78. package/stringUtils/index.ts +1 -1
  79. package/testUtils/index.tsx +1 -1
  80. package/time/__tests__/BackgroundTimer.test.ts +156 -0
  81. package/time/__tests__/Timer.test.ts +236 -0
  82. package/typeGuards/__tests__/isString.test.ts +21 -0
  83. package/typeGuards/index.ts +4 -0
  84. package/utils/__tests__/mergeRight.test.ts +48 -0
  85. package/utils/index.ts +3 -0
  86. package/utils/mergeRight.ts +5 -0
  87. package/reactHooks/componentsMap/index.ts +0 -55
@@ -331,6 +331,35 @@ 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
 
@@ -678,6 +707,22 @@ function getPlayerConfiguration({ platform, version }) {
678
707
  }
679
708
 
680
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
+
681
726
  general.fields.push(
682
727
  {
683
728
  section: "Default Timestamp Type",
@@ -1196,49 +1241,49 @@ function getPlayerConfiguration({ platform, version }) {
1196
1241
  "Upload Assets Folder Zip File, expected format: pip_play, pip_pause, pip_seek_forward, pip_seek_backward",
1197
1242
  },
1198
1243
  {
1199
- key: "image_speed_0_8",
1244
+ key: "speed_0_8",
1200
1245
  label: "Playback Speed 0.8x",
1201
1246
  type: "uploader",
1202
1247
  label_tooltip: "Playback Speed 0.8x",
1203
1248
  initial_value: null,
1204
1249
  },
1205
1250
  {
1206
- key: "image_speed_1",
1251
+ key: "speed_1",
1207
1252
  label: "Playback Speed 1x",
1208
1253
  type: "uploader",
1209
1254
  label_tooltip: "Playback Speed 1x",
1210
1255
  initial_value: null,
1211
1256
  },
1212
1257
  {
1213
- key: "image_speed_1_2",
1258
+ key: "speed_1_2",
1214
1259
  label: "Playback Speed 1.2x",
1215
1260
  type: "uploader",
1216
1261
  label_tooltip: "Playback Speed 1.2x",
1217
1262
  initial_value: null,
1218
1263
  },
1219
1264
  {
1220
- key: "image_speed_1_5",
1265
+ key: "speed_1_5",
1221
1266
  label: "Playback Speed 1.5x",
1222
1267
  type: "uploader",
1223
1268
  label_tooltip: "Playback Speed 1.5x",
1224
1269
  initial_value: null,
1225
1270
  },
1226
1271
  {
1227
- key: "image_speed_2",
1272
+ key: "speed_2",
1228
1273
  label: "Playback Speed 2x",
1229
1274
  type: "uploader",
1230
1275
  label_tooltip: "Playback Speed 2x",
1231
1276
  initial_value: null,
1232
1277
  },
1233
1278
  {
1234
- key: "image_sleep_timer",
1279
+ key: "sleep_timer",
1235
1280
  label: "Sleep Timer Default",
1236
1281
  type: "uploader",
1237
1282
  label_tooltip: "Sleep Timer Default",
1238
1283
  initial_value: null,
1239
1284
  },
1240
1285
  {
1241
- key: "image_sleep_timer_active",
1286
+ key: "sleep_timer_active",
1242
1287
  label: "Sleep Timer Active",
1243
1288
  type: "uploader",
1244
1289
  label_tooltip: "Sleep Timer Active",
@@ -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 };
@@ -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);
@@ -0,0 +1,165 @@
1
+ import { toPositiveNumber } from "..";
2
+
3
+ describe("toPositiveNumber", () => {
4
+ describe("valid positive numbers", () => {
5
+ it("returns the number for positive integers", () => {
6
+ expect(toPositiveNumber(5)).toBe(5);
7
+ expect(toPositiveNumber(1000)).toBe(1000);
8
+ });
9
+
10
+ it("returns the number for positive floats", () => {
11
+ expect(toPositiveNumber(0.1)).toBe(0.1);
12
+ expect(toPositiveNumber(3.14159)).toBe(3.14159);
13
+ });
14
+
15
+ it("returns the number for very small positive numbers", () => {
16
+ expect(toPositiveNumber(1e-300)).toBe(1e-300);
17
+ });
18
+
19
+ it("returns the number for very large positive numbers", () => {
20
+ expect(toPositiveNumber(1e300)).toBe(1e300);
21
+ });
22
+
23
+ it("returns Infinity for positive infinity", () => {
24
+ expect(toPositiveNumber(Infinity)).toBe(Infinity);
25
+ });
26
+
27
+ it("converts valid positive strings to numbers", () => {
28
+ expect(toPositiveNumber("5")).toBe(5);
29
+ expect(toPositiveNumber("3.14")).toBe(3.14);
30
+ expect(toPositiveNumber(" 100 ")).toBe(100);
31
+ });
32
+
33
+ it("converts boolean true to undefined", () => {
34
+ expect(toPositiveNumber(true)).toBeUndefined();
35
+ });
36
+
37
+ it("converts single-element arrays to undefined", () => {
38
+ expect(toPositiveNumber([5])).toBeUndefined();
39
+ expect(toPositiveNumber(["10"])).toBeUndefined();
40
+ });
41
+ });
42
+
43
+ describe("invalid cases (return undefined)", () => {
44
+ describe("zero values", () => {
45
+ it("returns undefined for zero", () => {
46
+ expect(toPositiveNumber(0)).toBeUndefined();
47
+ expect(toPositiveNumber(-0)).toBeUndefined();
48
+ });
49
+
50
+ it("returns undefined for string zero", () => {
51
+ expect(toPositiveNumber("0")).toBeUndefined();
52
+ expect(toPositiveNumber(" 0 ")).toBeUndefined();
53
+ });
54
+
55
+ it("returns undefined for boolean false", () => {
56
+ expect(toPositiveNumber(false)).toBeUndefined();
57
+ });
58
+
59
+ it("returns undefined for empty arrays", () => {
60
+ expect(toPositiveNumber([])).toBeUndefined();
61
+ });
62
+
63
+ it("returns undefined for empty strings", () => {
64
+ expect(toPositiveNumber("")).toBeUndefined();
65
+ expect(toPositiveNumber(" ")).toBeUndefined();
66
+ });
67
+ });
68
+
69
+ describe("negative values", () => {
70
+ it("returns undefined for negative numbers", () => {
71
+ expect(toPositiveNumber(-5)).toBeUndefined();
72
+ expect(toPositiveNumber(-0.1)).toBeUndefined();
73
+ });
74
+
75
+ it("returns undefined for negative strings", () => {
76
+ expect(toPositiveNumber("-5")).toBeUndefined();
77
+ expect(toPositiveNumber(" -10 ")).toBeUndefined();
78
+ });
79
+
80
+ it("returns undefined for negative infinity", () => {
81
+ expect(toPositiveNumber(-Infinity)).toBeUndefined();
82
+ });
83
+ });
84
+
85
+ describe("non-convertible values", () => {
86
+ it("returns undefined for null", () => {
87
+ expect(toPositiveNumber(null)).toBeUndefined();
88
+ });
89
+
90
+ it("returns undefined for undefined", () => {
91
+ expect(toPositiveNumber(undefined)).toBeUndefined();
92
+ });
93
+
94
+ it("returns undefined for objects", () => {
95
+ expect(toPositiveNumber({})).toBeUndefined();
96
+ expect(toPositiveNumber({ a: 1 })).toBeUndefined();
97
+ });
98
+
99
+ it("returns undefined for multi-element arrays", () => {
100
+ expect(toPositiveNumber([1, 2])).toBeUndefined();
101
+ expect(toPositiveNumber(["a", "b"])).toBeUndefined();
102
+ });
103
+
104
+ it("returns undefined for non-numeric strings", () => {
105
+ expect(toPositiveNumber("abc")).toBeUndefined();
106
+ expect(toPositiveNumber("5px")).toBeUndefined();
107
+ expect(toPositiveNumber("123.45.67")).toBeUndefined();
108
+ });
109
+
110
+ it("returns undefined for NaN", () => {
111
+ expect(toPositiveNumber(NaN)).toBeUndefined();
112
+ expect(toPositiveNumber(Number("abc"))).toBeUndefined();
113
+ });
114
+ });
115
+ });
116
+
117
+ describe("special cases", () => {
118
+ it("handles exponential notation correctly", () => {
119
+ expect(toPositiveNumber("1e5")).toBe(100000);
120
+ expect(toPositiveNumber("1e-5")).toBe(0.00001);
121
+ expect(toPositiveNumber("-1e5")).toBeUndefined();
122
+ });
123
+
124
+ it("preserves precision for decimal numbers", () => {
125
+ expect(toPositiveNumber(0.1 + 0.2)).toBeCloseTo(0.3);
126
+ expect(toPositiveNumber("0.1")).toBe(0.1);
127
+ });
128
+
129
+ it("handles numeric strings with leading zeros", () => {
130
+ expect(toPositiveNumber("005")).toBe(5);
131
+ expect(toPositiveNumber("0.5")).toBe(0.5);
132
+ });
133
+
134
+ it("returns undefined for numeric strings with trailing non-numeric characters", () => {
135
+ expect(toPositiveNumber("5px")).toBeUndefined();
136
+ expect(toPositiveNumber("10%")).toBeUndefined();
137
+ });
138
+
139
+ it("handles scientific notation correctly", () => {
140
+ expect(toPositiveNumber("1.5e2")).toBe(150);
141
+ expect(toPositiveNumber("-2.5e3")).toBeUndefined();
142
+ });
143
+ });
144
+
145
+ describe("type conversion behavior", () => {
146
+ it("converts Date objects correctly", () => {
147
+ const date = new Date(2026, 1, 17);
148
+ expect(toPositiveNumber(date)).toBeUndefined();
149
+ });
150
+
151
+ it("converts functions to NaN (returns undefined)", () => {
152
+ expect(toPositiveNumber(() => {})).toBeUndefined();
153
+ expect(toPositiveNumber(Math.sqrt)).toBeUndefined();
154
+ });
155
+
156
+ it("handles Symbol values", () => {
157
+ expect(toPositiveNumber(Symbol("test"))).toBeUndefined();
158
+ });
159
+
160
+ it("converts BigInt values", () => {
161
+ expect(toPositiveNumber(5n)).toBe(5);
162
+ expect(toPositiveNumber(-5n)).toBeUndefined();
163
+ });
164
+ });
165
+ });
@@ -8,7 +8,7 @@ export const toNumber = (value: unknown): number | undefined => {
8
8
  return undefined;
9
9
  }
10
10
 
11
- if (R.is(Number, value) || R.is(String, value)) {
11
+ if (R.is(Number, value) || R.is(BigInt, value) || R.is(String, value)) {
12
12
  const numberOrNan = Number(value);
13
13
 
14
14
  return Number.isNaN(numberOrNan) ? undefined : numberOrNan;
@@ -69,6 +69,24 @@ export const isMinusZero = (value: number) => {
69
69
  return 1 / value === -Infinity;
70
70
  };
71
71
 
72
+ export const toPositiveNumber = (value: unknown): number | undefined => {
73
+ const possibleNumber = toNumber(value);
74
+
75
+ if (R.isNil(possibleNumber)) {
76
+ return undefined;
77
+ }
78
+
79
+ if (possibleNumber < 0) {
80
+ return undefined;
81
+ }
82
+
83
+ if (isZero(possibleNumber)) {
84
+ return undefined;
85
+ }
86
+
87
+ return possibleNumber;
88
+ };
89
+
72
90
  export const toPositiveNumberWithDefault = (
73
91
  defaultValue: number,
74
92
  value: unknown
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-utils",
3
- "version": "15.0.0-alpha.1966607451",
3
+ "version": "15.0.0-alpha.2060204268",
4
4
  "description": "Applicaster Zapp React Native utilities package",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -27,13 +27,13 @@
27
27
  },
28
28
  "homepage": "https://github.com/applicaster/quickbrick#readme",
29
29
  "dependencies": {
30
- "@applicaster/applicaster-types": "15.0.0-alpha.1966607451",
30
+ "@applicaster/applicaster-types": "15.0.0-alpha.2060204268",
31
31
  "buffer": "^5.2.1",
32
32
  "camelize": "^1.0.0",
33
33
  "dayjs": "^1.11.10",
34
+ "handlebars": "4.7.8",
34
35
  "memoizee": "0.4.15",
35
- "prop-types": "^15.0.0",
36
- "react-native-handlebars": "^5.0.0-alpha.1"
36
+ "prop-types": "^15.0.0"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@applicaster/zapp-pipes-v2-client": "*",