@applicaster/zapp-react-native-utils 15.0.0-rc.14 → 15.0.0-rc.141

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 (178) hide show
  1. package/README.md +0 -6
  2. package/actionUtils/index.ts +7 -0
  3. package/actionsExecutor/ActionExecutorContext.tsx +86 -12
  4. package/actionsExecutor/feedDecorator.ts +6 -6
  5. package/adsUtils/__tests__/createVMAP.test.ts +419 -0
  6. package/adsUtils/index.ts +2 -2
  7. package/analyticsUtils/README.md +1 -1
  8. package/analyticsUtils/analyticsMapper.ts +10 -2
  9. package/appDataUtils/__tests__/urlScheme.test.ts +678 -0
  10. package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +0 -188
  11. package/appUtils/HooksManager/__tests__/hooksManager.test.js +16 -2
  12. package/appUtils/HooksManager/index.ts +45 -10
  13. package/appUtils/RiverFocusManager/{index.js → index.ts} +25 -18
  14. package/appUtils/accessibilityManager/__tests__/utils.test.ts +360 -0
  15. package/appUtils/accessibilityManager/const.ts +4 -0
  16. package/appUtils/accessibilityManager/hooks.ts +20 -13
  17. package/appUtils/accessibilityManager/index.ts +28 -1
  18. package/appUtils/accessibilityManager/utils.ts +59 -8
  19. package/appUtils/contextKeysManager/__tests__/getKeys/failure.test.ts +7 -2
  20. package/appUtils/contextKeysManager/__tests__/getKeys/success.test.ts +48 -0
  21. package/appUtils/contextKeysManager/contextResolver.ts +51 -22
  22. package/appUtils/contextKeysManager/index.ts +65 -10
  23. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +3 -0
  24. package/appUtils/focusManager/index.ios.ts +43 -4
  25. package/appUtils/focusManager/treeDataStructure/Tree/__tests__/Tree.test.js +46 -0
  26. package/appUtils/focusManager/treeDataStructure/Tree/index.js +18 -18
  27. package/appUtils/focusManagerAux/utils/index.ios.ts +122 -0
  28. package/appUtils/focusManagerAux/utils/index.ts +13 -7
  29. package/appUtils/focusManagerAux/utils/utils.ios.ts +202 -3
  30. package/appUtils/keyCodes/keys/keys.web.ts +1 -4
  31. package/appUtils/localizationsHelper.ts +4 -0
  32. package/appUtils/orientationHelper.ts +2 -4
  33. package/appUtils/platform/platformUtils.ts +117 -18
  34. package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +94 -4
  35. package/appUtils/playerManager/OverlayObserver/utils.ts +32 -20
  36. package/appUtils/playerManager/index.ts +9 -0
  37. package/appUtils/playerManager/player.ts +5 -1
  38. package/appUtils/playerManager/playerNative.ts +31 -17
  39. package/appUtils/playerManager/usePlayer.tsx +5 -3
  40. package/appUtils/playerManager/usePlayerState.tsx +14 -2
  41. package/arrayUtils/__tests__/allTruthy.test.ts +24 -0
  42. package/arrayUtils/__tests__/anyThruthy.test.ts +24 -0
  43. package/arrayUtils/index.ts +5 -0
  44. package/cellUtils/__tests__/cellUtils.test.ts +39 -0
  45. package/cellUtils/index.ts +43 -1
  46. package/cloudEventsUtils/__tests__/index.test.ts +529 -0
  47. package/cloudEventsUtils/index.ts +65 -1
  48. package/componentsUtils/index.ts +8 -0
  49. package/configurationUtils/__tests__/imageSrcFromMediaItem.test.ts +38 -0
  50. package/configurationUtils/__tests__/manifestKeyParser.test.ts +26 -26
  51. package/configurationUtils/index.ts +17 -11
  52. package/dateUtils/__tests__/dayjs.test.ts +327 -0
  53. package/dateUtils/index.ts +2 -0
  54. package/enumUtils/__tests__/getEnumKeyByEnumValue.test.ts +207 -0
  55. package/errorUtils/__tests__/GeneralError.test.ts +97 -0
  56. package/errorUtils/__tests__/HttpStatusCode.test.ts +344 -0
  57. package/errorUtils/__tests__/MissingPluginError.test.ts +113 -0
  58. package/errorUtils/__tests__/NetworkError.test.ts +202 -0
  59. package/errorUtils/__tests__/getParsedResponse.test.ts +188 -0
  60. package/errorUtils/__tests__/invariant.test.ts +112 -0
  61. package/focusManager/aux/index.ts +1 -1
  62. package/headersUtils/__tests__/headersUtils.test.js +11 -1
  63. package/headersUtils/index.ts +2 -1
  64. package/manifestUtils/_internals/__tests__/index.test.js +41 -0
  65. package/manifestUtils/_internals/index.js +33 -0
  66. package/manifestUtils/defaultManifestConfigurations/player.js +115 -11
  67. package/manifestUtils/fieldUtils/__tests__/fieldUtils.test.js +49 -0
  68. package/manifestUtils/fieldUtils/index.js +54 -0
  69. package/manifestUtils/index.js +2 -0
  70. package/manifestUtils/keys.js +249 -0
  71. package/manifestUtils/mobileAction/button/__tests__/mobileActionButton.test.js +168 -0
  72. package/manifestUtils/mobileAction/button/index.js +140 -0
  73. package/manifestUtils/mobileAction/container/__tests__/mobileActionButtonsContainer.test.js +102 -0
  74. package/manifestUtils/mobileAction/container/index.js +73 -0
  75. package/manifestUtils/mobileAction/groups/__tests__/buildMobileActionButtonGroups.test.js +127 -0
  76. package/manifestUtils/mobileAction/groups/defaults.js +76 -0
  77. package/manifestUtils/mobileAction/groups/index.js +80 -0
  78. package/manifestUtils/platformIsTV.js +13 -0
  79. package/manifestUtils/sharedConfiguration/screenPicker/utils.js +1 -0
  80. package/manifestUtils/tvAction/container/index.js +1 -1
  81. package/navigationUtils/index.ts +15 -5
  82. package/numberUtils/__tests__/toNumber.test.ts +27 -0
  83. package/numberUtils/__tests__/toPositiveNumber.test.ts +193 -0
  84. package/numberUtils/index.ts +23 -1
  85. package/package.json +4 -4
  86. package/playerUtils/usePlayerTTS.ts +8 -3
  87. package/pluginUtils/index.ts +4 -0
  88. package/reactHooks/advertising/index.ts +2 -2
  89. package/reactHooks/analytics/__tests__/useSendAnalyticsOnPress.test.ts +537 -0
  90. package/reactHooks/app/__tests__/useAppState.test.ts +1 -1
  91. package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
  92. package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +1 -2
  93. package/reactHooks/cell-click/__tests__/index.test.js +1 -3
  94. package/reactHooks/cell-click/index.ts +2 -1
  95. package/reactHooks/configuration/__tests__/index.test.tsx +1 -1
  96. package/reactHooks/connection/__tests__/index.test.js +1 -1
  97. package/reactHooks/debugging/__tests__/index.test.js +4 -4
  98. package/reactHooks/dev/__tests__/useReRenderLog.test.ts +188 -0
  99. package/reactHooks/device/useIsTablet.tsx +14 -19
  100. package/reactHooks/device/useMemoizedIsTablet.ts +3 -3
  101. package/reactHooks/events/index.ts +20 -0
  102. package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +32 -23
  103. package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +19 -19
  104. package/reactHooks/feed/__tests__/useEntryScreenId.test.tsx +4 -1
  105. package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +42 -30
  106. package/reactHooks/feed/__tests__/{useInflatedUrl.test.ts → useInflatedUrl.test.tsx} +62 -7
  107. package/reactHooks/feed/index.ts +0 -2
  108. package/reactHooks/feed/useBatchLoading.ts +7 -1
  109. package/reactHooks/feed/useEntryScreenId.ts +2 -2
  110. package/reactHooks/feed/useInflatedUrl.ts +44 -18
  111. package/reactHooks/feed/usePipesCacheReset.ts +3 -1
  112. package/reactHooks/flatList/useLoadNextPageIfNeeded.ts +13 -16
  113. package/reactHooks/hookModal/hooks/useHookModalScreenData.ts +12 -8
  114. package/reactHooks/index.ts +2 -0
  115. package/reactHooks/layout/__tests__/index.test.tsx +1 -1
  116. package/reactHooks/layout/__tests__/useLayoutVersion.test.tsx +1 -1
  117. package/reactHooks/layout/index.ts +1 -1
  118. package/reactHooks/layout/useDimensions/__tests__/{useDimensions.test.ts → useDimensions.test.tsx} +105 -25
  119. package/reactHooks/layout/useDimensions/useDimensions.ts +2 -2
  120. package/reactHooks/navigation/__tests__/index.test.tsx +40 -9
  121. package/reactHooks/navigation/index.ts +27 -11
  122. package/reactHooks/navigation/useRoute.ts +11 -7
  123. package/reactHooks/player/TVSeekControlller/TVSeekController.ts +27 -10
  124. package/reactHooks/player/__tests__/useAutoSeek._test.tsx +1 -1
  125. package/reactHooks/player/__tests__/useTapSeek._test.ts +1 -1
  126. package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +1 -1
  127. package/reactHooks/resolvers/__tests__/useComponentResolver.test.tsx +1 -1
  128. package/reactHooks/resolvers/useCellResolver.ts +6 -2
  129. package/reactHooks/resolvers/useComponentResolver.ts +19 -3
  130. package/reactHooks/screen/__tests__/useCurrentScreenData.test.tsx +2 -2
  131. package/reactHooks/screen/__tests__/useScreenBackgroundColor.test.tsx +1 -1
  132. package/reactHooks/screen/__tests__/useScreenData.test.tsx +1 -1
  133. package/reactHooks/screen/__tests__/useTargetScreenData.test.tsx +12 -4
  134. package/reactHooks/screen/useTargetScreenData.ts +4 -2
  135. package/reactHooks/state/__tests__/useComponentScreenState.test.ts +246 -0
  136. package/reactHooks/state/index.ts +2 -0
  137. package/reactHooks/state/useComponentScreenState.ts +45 -0
  138. package/reactHooks/state/useRefWithInitialValue.ts +10 -0
  139. package/reactHooks/state/useRivers.ts +1 -1
  140. package/reactHooks/ui/__tests__/useFadeOutWhenBlurred.test.ts +580 -0
  141. package/reactHooks/usePluginConfiguration.ts +2 -2
  142. package/reactHooks/utils/__tests__/index.test.js +1 -1
  143. package/rectUtils/__tests__/index.test.ts +549 -0
  144. package/rectUtils/index.ts +2 -2
  145. package/refreshUtils/RefreshCoordinator/__tests__/refreshCoordinator.test.ts +206 -0
  146. package/refreshUtils/RefreshCoordinator/index.ts +245 -0
  147. package/refreshUtils/RefreshCoordinator/utils/__tests__/getDataRefreshConfig.test.ts +104 -0
  148. package/refreshUtils/RefreshCoordinator/utils/index.ts +29 -0
  149. package/screenPickerUtils/__tests__/index.test.ts +333 -0
  150. package/screenPickerUtils/index.ts +5 -0
  151. package/screenState/__tests__/index.test.ts +1 -1
  152. package/screenUtils/index.ts +3 -0
  153. package/searchUtils/const.ts +7 -0
  154. package/searchUtils/index.ts +3 -0
  155. package/services/storageServiceSync.web.ts +1 -1
  156. package/stringUtils/index.ts +1 -1
  157. package/testUtils/index.tsx +30 -21
  158. package/time/__tests__/BackgroundTimer.test.ts +156 -0
  159. package/time/__tests__/Timer.test.ts +236 -0
  160. package/typeGuards/__tests__/isString.test.ts +21 -0
  161. package/typeGuards/index.ts +4 -0
  162. package/utils/__tests__/clone.test.ts +158 -0
  163. package/utils/__tests__/mapAccum.test.ts +73 -0
  164. package/utils/__tests__/mergeRight.test.ts +48 -0
  165. package/utils/__tests__/path.test.ts +7 -0
  166. package/utils/__tests__/selectors.test.ts +124 -0
  167. package/utils/clone.ts +7 -0
  168. package/utils/index.ts +21 -1
  169. package/utils/mapAccum.ts +23 -0
  170. package/utils/mergeRight.ts +5 -0
  171. package/utils/path.ts +6 -3
  172. package/utils/pathOr.ts +5 -1
  173. package/utils/selectors.ts +46 -0
  174. package/zappFrameworkUtils/HookCallback/callbackNavigationAction.ts +49 -12
  175. package/zappFrameworkUtils/HookCallback/hookCallbackManifestExtensions.config.js +1 -1
  176. package/reactHooks/componentsMap/index.ts +0 -55
  177. package/reactHooks/feed/__tests__/useFeedRefresh.test.tsx +0 -75
  178. package/reactHooks/feed/useFeedRefresh.tsx +0 -65
@@ -0,0 +1,41 @@
1
+ const {
2
+ isKeyHasSuffix,
3
+ isKeyHasAnyOfSuffixes,
4
+ getKeyWithPrefixGenerator,
5
+ } = require("..");
6
+
7
+ describe("manifestUtils/_internals helpers", () => {
8
+ it("checks a key suffix", () => {
9
+ expect(
10
+ isKeyHasSuffix("button_enabled", "mobile_button_1_button_enabled")
11
+ ).toBe(true);
12
+
13
+ expect(
14
+ isKeyHasSuffix("button_enabled", "mobile_button_1_assign_action")
15
+ ).toBe(false);
16
+ });
17
+
18
+ it("checks key against multiple suffixes", () => {
19
+ const suffixes = ["font_color", "focused_font_color", "text_transform"];
20
+
21
+ expect(
22
+ isKeyHasAnyOfSuffixes(suffixes, "mobile_button_1_text_transform")
23
+ ).toBe(true);
24
+
25
+ expect(
26
+ isKeyHasAnyOfSuffixes(suffixes, "mobile_button_1_asset_alignment")
27
+ ).toBe(false);
28
+ });
29
+
30
+ it("generates stable key names using a prefix", () => {
31
+ const withMobileButtonPrefix = getKeyWithPrefixGenerator("mobile_button_2");
32
+
33
+ expect(withMobileButtonPrefix("display_mode")).toBe(
34
+ "mobile_button_2_display_mode"
35
+ );
36
+
37
+ expect(withMobileButtonPrefix("asset_enabled")).toBe(
38
+ "mobile_button_2_asset_enabled"
39
+ );
40
+ });
41
+ });
@@ -174,6 +174,36 @@ function generateFieldsFromDefaultsWithoutPrefixedLabel(
174
174
  )(fields);
175
175
  }
176
176
 
177
+ /**
178
+ * Checks whether a generated manifest field key ends with the given suffix.
179
+ *
180
+ * @param {string} suffix
181
+ * @param {string} key
182
+ * @returns {boolean}
183
+ */
184
+ const isKeyHasSuffix = (suffix, key) => key.endsWith(`_${suffix}`);
185
+
186
+ /**
187
+ * Checks whether a generated manifest field key ends with any supported suffix.
188
+ *
189
+ * @param {string[]} suffixes
190
+ * @param {string} key
191
+ * @returns {boolean}
192
+ */
193
+ const isKeyHasAnyOfSuffixes = (suffixes, key) =>
194
+ suffixes.some((suffix) => key.endsWith(`_${suffix}`));
195
+
196
+ /**
197
+ * Creates a helper that prefixes a manifest field suffix with a shared key stem.
198
+ *
199
+ * @param {string} prefix
200
+ * @returns {(suffix: string) => string}
201
+ */
202
+ function getKeyWithPrefixGenerator(prefix) {
203
+ // expect prefix as lower snake case, e.g. "mobile_buttons_container"
204
+ return (suffix) => `${prefix}_${suffix}`;
205
+ }
206
+
177
207
  module.exports = {
178
208
  toSnakeCase,
179
209
  toCamelCase,
@@ -185,4 +215,7 @@ module.exports = {
185
215
  getDefaultConfiguration,
186
216
  compact,
187
217
  replaceUnderscoreToSpace,
218
+ isKeyHasSuffix,
219
+ isKeyHasAnyOfSuffixes,
220
+ getKeyWithPrefixGenerator,
188
221
  };
@@ -123,6 +123,12 @@ function getPlayerConfiguration({ platform, version }) {
123
123
  key: "skip_button_localization_text_skip_intro",
124
124
  initial_value: "Skip Intro",
125
125
  },
126
+ {
127
+ type: "text_input",
128
+ label: "Stream error message",
129
+ key: "stream_error_message",
130
+ initial_value: "Cannot play stream",
131
+ },
126
132
  {
127
133
  type: "text_input",
128
134
  label: "Locked message",
@@ -331,10 +337,53 @@ function getPlayerConfiguration({ platform, version }) {
331
337
  label_tooltip: "Hint for skip intro button accessibility",
332
338
  type: "text_input",
333
339
  },
340
+ {
341
+ type: "text_input",
342
+ label: "Text Tracks Label",
343
+ key: "text_tracks_label",
344
+ initial_value: "Subtitles",
345
+ label_tooltip: "Label for the text tracks list",
346
+ },
347
+ {
348
+ type: "text_input",
349
+ label: "Audio Tracks Label",
350
+ key: "audio_tracks_label",
351
+ initial_value: "Audio",
352
+ label_tooltip: "Label for the audio tracks list",
353
+ },
354
+ {
355
+ type: "text_input",
356
+ label: "Off Track Label",
357
+ key: "off_track_label",
358
+ initial_value: "Off",
359
+ label_tooltip: "Label for the 'Off' option in text tracks list",
360
+ },
361
+ {
362
+ type: "text_input",
363
+ label: "Default Track Label",
364
+ key: "default_track_label",
365
+ initial_value: "Default",
366
+ label_tooltip:
367
+ "Label for the 'Default' audio track in audio tracks list",
368
+ },
334
369
  ],
335
370
  };
336
371
 
337
372
  if (isTV(platform)) {
373
+ localizations.fields.push({
374
+ key: "back_to_live_label",
375
+ label: "Back to live label",
376
+ initial_value: "Back To Live",
377
+ type: "text_input",
378
+ });
379
+
380
+ localizations.fields.push({
381
+ key: "start_over_label",
382
+ label: "Start over label",
383
+ initial_value: "Start Over",
384
+ type: "text_input",
385
+ });
386
+
338
387
  styles.fields.push(
339
388
  fieldsGroup("Always Show Scrub Bar & Timestamp", "", [
340
389
  {
@@ -447,7 +496,7 @@ function getPlayerConfiguration({ platform, version }) {
447
496
  ),
448
497
  fieldsGroup(
449
498
  "Skip Button",
450
- "This section allows you to configure the skip button styles for tv",
499
+ "This section allows you to configure the skip button behaviour",
451
500
  [
452
501
  {
453
502
  type: "switch",
@@ -464,6 +513,12 @@ function getPlayerConfiguration({ platform, version }) {
464
513
  label: "Persistent Button Toggle",
465
514
  initial_value: true,
466
515
  },
516
+ ]
517
+ ),
518
+ fieldsGroup(
519
+ "Labeled Button Style",
520
+ "This section allows you to configure the labeled button styles",
521
+ [
467
522
  {
468
523
  type: "color_picker_rgba",
469
524
  label_tooltip: "",
@@ -619,6 +674,44 @@ function getPlayerConfiguration({ platform, version }) {
619
674
  );
620
675
  }
621
676
 
677
+ if (isTV(platform)) {
678
+ general.fields.push(
679
+ {
680
+ key: "liveSeekingEnabled",
681
+ label: "Live Seeking Enabled",
682
+ initial_value: false,
683
+ type: "switch",
684
+ label_tooltip: "Enable Live Seek",
685
+ },
686
+ {
687
+ key: "minimumAllowedSeekableDurationInSeconds",
688
+ label: "Minimum allowed seekable duration in seconds",
689
+ initial_value: 300,
690
+ type: "number_input",
691
+ label_tooltip:
692
+ "If duration less than this value, player will disable 'liveSeekingEnabled' value",
693
+ },
694
+ {
695
+ key: "live_image",
696
+ label: "Live badge",
697
+ type: "uploader",
698
+ label_tooltip: "Override default live badge / icon",
699
+ },
700
+ {
701
+ key: "live_width",
702
+ label: "Live badge width",
703
+ type: "number_input",
704
+ initial_value: 85,
705
+ },
706
+ {
707
+ key: "live_height",
708
+ label: "Live badge height",
709
+ type: "number_input",
710
+ initial_value: 50,
711
+ }
712
+ );
713
+ }
714
+
622
715
  if (isMobile(platform)) {
623
716
  general.fields.push(
624
717
  {
@@ -1142,40 +1235,35 @@ function getPlayerConfiguration({ platform, version }) {
1142
1235
  label: "Playback Speed 0.8x",
1143
1236
  type: "uploader",
1144
1237
  label_tooltip: "Playback Speed 0.8x",
1145
- initial_value:
1146
- "data:image/png;base64,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",
1238
+ initial_value: null,
1147
1239
  },
1148
1240
  {
1149
1241
  key: "speed_1",
1150
1242
  label: "Playback Speed 1x",
1151
1243
  type: "uploader",
1152
1244
  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",
1245
+ initial_value: null,
1155
1246
  },
1156
1247
  {
1157
1248
  key: "speed_1_2",
1158
1249
  label: "Playback Speed 1.2x",
1159
1250
  type: "uploader",
1160
1251
  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",
1252
+ initial_value: null,
1163
1253
  },
1164
1254
  {
1165
1255
  key: "speed_1_5",
1166
1256
  label: "Playback Speed 1.5x",
1167
1257
  type: "uploader",
1168
1258
  label_tooltip: "Playback Speed 1.5x",
1169
- initial_value:
1170
- "data:image/png;base64,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",
1259
+ initial_value: null,
1171
1260
  },
1172
1261
  {
1173
1262
  key: "speed_2",
1174
1263
  label: "Playback Speed 2x",
1175
1264
  type: "uploader",
1176
1265
  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",
1266
+ initial_value: null,
1179
1267
  },
1180
1268
  {
1181
1269
  key: "sleep_timer",
@@ -3429,6 +3517,22 @@ function getPlayerConfiguration({ platform, version }) {
3429
3517
  label_tooltip:
3430
3518
  "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
3519
  },
3520
+ {
3521
+ key: "advanced_player_styles",
3522
+ label: "Advanced Player Styles",
3523
+ type: "text_input",
3524
+ multiline: true,
3525
+ initial_value: `.vjs-text-track-cue {
3526
+ inset: unset !important;
3527
+ top: 94% !important;
3528
+ bottom: 0 !important;
3529
+ left: 0 !important;
3530
+ right: 0 !important;
3531
+ width: 100% !important;
3532
+ }`,
3533
+ label_tooltip:
3534
+ "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.",
3535
+ },
3432
3536
  {
3433
3537
  key: "use_dashjs_player",
3434
3538
  label: "Use Enhanced Player for DASH streams",
@@ -0,0 +1,49 @@
1
+ const {
2
+ withConditional,
3
+ getConditionalKey,
4
+ createConditionalField,
5
+ } = require("..");
6
+
7
+ describe("manifestUtils/fieldUtils", () => {
8
+ it("appends conditions and adds all_conditions when there is more than one condition", () => {
9
+ const config = {
10
+ key: "mobile_button_1_width",
11
+ conditional_fields: [
12
+ { key: "styles/mobile_button_1_button_enabled", condition_value: true },
13
+ ],
14
+ };
15
+
16
+ const result = withConditional([
17
+ { key: "styles/mobile_button_1_display_mode", condition_value: "fixed" },
18
+ ])(config);
19
+
20
+ expect(result.conditional_fields).toEqual([
21
+ { key: "styles/mobile_button_1_button_enabled", condition_value: true },
22
+ { key: "styles/mobile_button_1_display_mode", condition_value: "fixed" },
23
+ ]);
24
+
25
+ expect(result.rules).toBe("all_conditions");
26
+ });
27
+
28
+ it("creates category-prefixed conditional key", () => {
29
+ expect(
30
+ getConditionalKey("mobile_buttons_container_position", "styles")
31
+ ).toBe("styles/mobile_buttons_container_position");
32
+ });
33
+
34
+ it("creates conditional fields with default category and with raw key", () => {
35
+ expect(
36
+ createConditionalField("mobile_button_1_asset_enabled", true)
37
+ ).toEqual({
38
+ key: "styles/mobile_button_1_asset_enabled",
39
+ condition_value: true,
40
+ });
41
+
42
+ expect(
43
+ createConditionalField("mobile_button_1_asset_enabled", true, null)
44
+ ).toEqual({
45
+ key: "mobile_button_1_asset_enabled",
46
+ condition_value: true,
47
+ });
48
+ });
49
+ });
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Appends new conditional_fields from conditions array
3
+ * to config.conditional_fields
4
+ * if there are more than 1 condition, sets rules to "all_conditions"
5
+ *
6
+ * @param {Array<{key: string, condition_value: unknown}>} conditions
7
+ * @returns {(config: object) => object}
8
+ */
9
+ const withConditional = (conditions) => (config) => {
10
+ const conditional_fields = [
11
+ ...(config.conditional_fields || []),
12
+ ...conditions,
13
+ ];
14
+
15
+ const next = { ...config, conditional_fields };
16
+
17
+ if (conditional_fields.length > 1) {
18
+ return { ...next, rules: "all_conditions" };
19
+ }
20
+
21
+ return next;
22
+ };
23
+
24
+ /**
25
+ * Builds key for conditional fields prepending category, e.g. "styles/mobile_buttons_container_position"
26
+ *
27
+ * @param {string} key
28
+ * @param {string} category
29
+ * @returns {string}
30
+ */
31
+ function getConditionalKey(key, category) {
32
+ return `${category}/${key}`;
33
+ }
34
+
35
+ /**
36
+ * Returns a conditional field object for manifest visibility rules.
37
+ *
38
+ * @param {string} key
39
+ * @param {unknown} condition_value
40
+ * @param {string|null} [category="styles"] Pass `null` to use the key as-is.
41
+ * @returns {{key: string, condition_value: unknown}}
42
+ */
43
+ function createConditionalField(key, condition_value, category = "styles") {
44
+ return {
45
+ key: category ? getConditionalKey(key, category) : key,
46
+ condition_value,
47
+ };
48
+ }
49
+
50
+ module.exports = {
51
+ withConditional,
52
+ getConditionalKey,
53
+ createConditionalField,
54
+ };
@@ -8,6 +8,7 @@ const {
8
8
 
9
9
  const { tvActionButtonsContainer } = require("./tvAction/container");
10
10
  const { tvActionButton } = require("./tvAction/button");
11
+ const { buildMobileActionButtonGroups } = require("./mobileAction/groups");
11
12
  const { compact } = require("./_internals");
12
13
 
13
14
  const { spacingKey, absolutePositionElement } = require("./containers");
@@ -43,6 +44,7 @@ module.exports = {
43
44
  tvMenuLabel,
44
45
  tvActionButtonsContainer,
45
46
  tvActionButton,
47
+ buildMobileActionButtonGroups,
46
48
  mobileCellLabel,
47
49
  tvCellLabel,
48
50
  tvBadges,
@@ -406,6 +406,232 @@ const TV_ACTION_BUTTON_FIELDS = [
406
406
  },
407
407
  ];
408
408
 
409
+ const mobileActionButtonContainerFields = (positionOptions) => [
410
+ {
411
+ type: ZAPPIFEST_FIELDS.switch,
412
+ suffix: "buttons enabled",
413
+ },
414
+ {
415
+ type: ZAPPIFEST_FIELDS.select,
416
+ suffix: "position",
417
+ options: positionOptions,
418
+ },
419
+ {
420
+ type: ZAPPIFEST_FIELDS.select,
421
+ suffix: "align",
422
+ options: ["left", "center", "right"],
423
+ },
424
+ {
425
+ type: ZAPPIFEST_FIELDS.select,
426
+ suffix: "over image position",
427
+ options: ["center", "top_left", "top_right", "bottom_left", "bottom_right"],
428
+ },
429
+ {
430
+ type: ZAPPIFEST_FIELDS.number_input,
431
+ suffix: "margin top",
432
+ },
433
+ {
434
+ type: ZAPPIFEST_FIELDS.number_input,
435
+ suffix: "margin right",
436
+ },
437
+ {
438
+ type: ZAPPIFEST_FIELDS.number_input,
439
+ suffix: "margin bottom",
440
+ },
441
+ {
442
+ type: ZAPPIFEST_FIELDS.number_input,
443
+ suffix: "margin left",
444
+ },
445
+ {
446
+ type: ZAPPIFEST_FIELDS.select,
447
+ suffix: "stacking",
448
+ options: ["horizontal", "vertical"],
449
+ },
450
+ {
451
+ type: ZAPPIFEST_FIELDS.number_input,
452
+ suffix: "horizontal gutter",
453
+ },
454
+ {
455
+ type: ZAPPIFEST_FIELDS.number_input,
456
+ suffix: "vertical gutter",
457
+ },
458
+ {
459
+ type: ZAPPIFEST_FIELDS.switch,
460
+ suffix: "independent styles",
461
+ },
462
+ ];
463
+
464
+ const MOBILE_ACTION_BUTTON_FIELDS = [
465
+ {
466
+ type: ZAPPIFEST_FIELDS.switch,
467
+ suffix: "button enabled",
468
+ },
469
+ {
470
+ type: ZAPPIFEST_FIELDS.select,
471
+ suffix: "assign action",
472
+ options: [
473
+ { text: "primary navigation", value: "navigation_action" },
474
+ { text: "secondary navigation", value: "secondary_navigation" },
475
+ { text: "favorite", value: "local_storage_favourites_action" },
476
+ { text: "more", value: "more" },
477
+ { text: "add to calendar", value: "add_to_calendar" },
478
+ { text: "share", value: "share" },
479
+ { text: "downloads", value: "downloads" },
480
+ { text: "trailer", value: "trailer_action" },
481
+ { text: "mute/unmute", value: "mute_unmute" },
482
+ ],
483
+ },
484
+ {
485
+ type: ZAPPIFEST_FIELDS.select,
486
+ suffix: "display mode",
487
+ options: ["dynamic", "fixed", "fill"],
488
+ },
489
+ {
490
+ type: ZAPPIFEST_FIELDS.number_input,
491
+ suffix: "width",
492
+ },
493
+ {
494
+ type: ZAPPIFEST_FIELDS.select,
495
+ suffix: "contents alignment",
496
+ options: ["left", "center", "right"],
497
+ },
498
+ {
499
+ type: ZAPPIFEST_FIELDS.color_picker,
500
+ suffix: "background color",
501
+ },
502
+ {
503
+ type: ZAPPIFEST_FIELDS.color_picker,
504
+ suffix: "focused background color",
505
+ },
506
+ {
507
+ type: ZAPPIFEST_FIELDS.color_picker,
508
+ suffix: "border color",
509
+ },
510
+ {
511
+ type: ZAPPIFEST_FIELDS.color_picker,
512
+ suffix: "focused border color",
513
+ },
514
+ {
515
+ type: ZAPPIFEST_FIELDS.number_input,
516
+ suffix: "border size",
517
+ },
518
+ {
519
+ type: ZAPPIFEST_FIELDS.number_input,
520
+ suffix: "corner radius",
521
+ },
522
+ {
523
+ type: ZAPPIFEST_FIELDS.number_input,
524
+ suffix: "padding top",
525
+ },
526
+ {
527
+ type: ZAPPIFEST_FIELDS.number_input,
528
+ suffix: "padding right",
529
+ },
530
+ {
531
+ type: ZAPPIFEST_FIELDS.number_input,
532
+ suffix: "padding bottom",
533
+ },
534
+ {
535
+ type: ZAPPIFEST_FIELDS.number_input,
536
+ suffix: "padding left",
537
+ },
538
+ {
539
+ type: ZAPPIFEST_FIELDS.switch,
540
+ suffix: "asset enabled",
541
+ },
542
+ {
543
+ type: ZAPPIFEST_FIELDS.select,
544
+ suffix: "action asset flavour",
545
+ options: ["flavour_1", "flavour_2"],
546
+ },
547
+ {
548
+ type: ZAPPIFEST_FIELDS.select,
549
+ suffix: "asset alignment",
550
+ options: ["left", "right", "above", "below"],
551
+ },
552
+ {
553
+ type: ZAPPIFEST_FIELDS.number_input,
554
+ suffix: "asset height",
555
+ },
556
+ {
557
+ type: ZAPPIFEST_FIELDS.number_input,
558
+ suffix: "asset width",
559
+ },
560
+ {
561
+ type: ZAPPIFEST_FIELDS.number_input,
562
+ suffix: "asset margin top",
563
+ },
564
+ {
565
+ type: ZAPPIFEST_FIELDS.number_input,
566
+ suffix: "asset margin right",
567
+ },
568
+ {
569
+ type: ZAPPIFEST_FIELDS.number_input,
570
+ suffix: "asset margin bottom",
571
+ },
572
+ {
573
+ type: ZAPPIFEST_FIELDS.number_input,
574
+ suffix: "asset margin left",
575
+ },
576
+ {
577
+ type: ZAPPIFEST_FIELDS.switch,
578
+ suffix: "label enabled",
579
+ },
580
+ {
581
+ type: ZAPPIFEST_FIELDS.color_picker,
582
+ suffix: "font color",
583
+ },
584
+ {
585
+ type: ZAPPIFEST_FIELDS.color_picker,
586
+ suffix: "focused font color",
587
+ },
588
+ {
589
+ type: ZAPPIFEST_FIELDS.font_selector.ios,
590
+ suffix: "iOS font family",
591
+ },
592
+ {
593
+ type: ZAPPIFEST_FIELDS.font_selector.android,
594
+ suffix: "android font family",
595
+ },
596
+ {
597
+ type: ZAPPIFEST_FIELDS.number_input,
598
+ suffix: "font size",
599
+ },
600
+ {
601
+ type: ZAPPIFEST_FIELDS.number_input,
602
+ suffix: "line height",
603
+ },
604
+ {
605
+ type: ZAPPIFEST_FIELDS.number_input,
606
+ suffix: "iOS letter spacing",
607
+ },
608
+ {
609
+ type: ZAPPIFEST_FIELDS.number_input,
610
+ suffix: "android letter spacing",
611
+ },
612
+ {
613
+ type: ZAPPIFEST_FIELDS.select,
614
+ suffix: "text transform",
615
+ options: ["default", "lowercase", "uppercase", "capitalize"],
616
+ },
617
+ {
618
+ type: ZAPPIFEST_FIELDS.number_input,
619
+ suffix: "margin top",
620
+ },
621
+ {
622
+ type: ZAPPIFEST_FIELDS.number_input,
623
+ suffix: "margin right",
624
+ },
625
+ {
626
+ type: ZAPPIFEST_FIELDS.number_input,
627
+ suffix: "margin bottom",
628
+ },
629
+ {
630
+ type: ZAPPIFEST_FIELDS.number_input,
631
+ suffix: "margin left",
632
+ },
633
+ ];
634
+
409
635
  const TV_MENU_LABEL_FIELDS = [
410
636
  {
411
637
  type: ZAPPIFEST_FIELDS.switch,
@@ -959,6 +1185,27 @@ const TV_CELL_LABEL_FIELDS = [
959
1185
  rules: "conditional",
960
1186
  conditions: [{ key: "switch", section: "styles", value: true }],
961
1187
  },
1188
+ {
1189
+ type: ZAPPIFEST_FIELDS.font_selector.roku,
1190
+ suffix: "roku font family",
1191
+ tooltip: "",
1192
+ rules: "conditional",
1193
+ conditions: [{ key: "switch", section: "styles", value: true }],
1194
+ },
1195
+ {
1196
+ type: ZAPPIFEST_FIELDS.number_input,
1197
+ suffix: "roku font size",
1198
+ tooltip: "",
1199
+ rules: "conditional",
1200
+ conditions: [{ key: "switch", section: "styles", value: true }],
1201
+ },
1202
+ {
1203
+ type: ZAPPIFEST_FIELDS.number_input,
1204
+ suffix: "roku line height",
1205
+ tooltip: "",
1206
+ rules: "conditional",
1207
+ conditions: [{ key: "switch", section: "styles", value: true }],
1208
+ },
962
1209
  {
963
1210
  type: ZAPPIFEST_FIELDS.select,
964
1211
  suffix: "text alignment",
@@ -2113,6 +2360,8 @@ module.exports = {
2113
2360
  TV_COLOR_STATES,
2114
2361
  TV_ACTION_BUTTON_FIELDS,
2115
2362
  tvActionButtonContainerFields,
2363
+ MOBILE_ACTION_BUTTON_FIELDS,
2364
+ mobileActionButtonContainerFields,
2116
2365
  MOBILE_CELL_LABEL_FIELDS,
2117
2366
  TV_CELL_LABEL_FIELDS,
2118
2367
  TV_CELL_BADGE_FIELDS,