@applicaster/zapp-react-native-utils 16.0.0-alpha.4416921324 → 16.0.0-alpha.4548770949

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 (173) hide show
  1. package/actionUtils/index.ts +3 -1
  2. package/actionsExecutor/ActionExecutor.ts +50 -3
  3. package/actionsExecutor/ActionExecutorContext.tsx +99 -17
  4. package/actionsExecutor/__tests__/ActionExecutor.test.ts +71 -0
  5. package/actionsExecutor/__tests__/StorageActions.test.ts +98 -0
  6. package/actionsExecutor/__tests__/feedDecorator.test.ts +91 -0
  7. package/actionsExecutor/__tests__/screenToggleFlag.test.ts +90 -0
  8. package/actionsExecutor/actions/__tests__/dismissBottomSheet.test.ts +25 -0
  9. package/actionsExecutor/actions/__tests__/goBack.test.ts +62 -0
  10. package/actionsExecutor/actions/__tests__/goHome.test.ts +19 -0
  11. package/actionsExecutor/actions/__tests__/loadItemsFromSource.test.ts +88 -0
  12. package/actionsExecutor/actions/__tests__/navigateToScreen.test.ts +267 -0
  13. package/actionsExecutor/actions/__tests__/openBottomSheet.customContent.test.ts +100 -0
  14. package/actionsExecutor/actions/__tests__/openBottomSheet.inlineItems.test.ts +372 -0
  15. package/actionsExecutor/actions/__tests__/presentScreen.test.ts +127 -0
  16. package/actionsExecutor/actions/__tests__/showAlert.test.ts +49 -0
  17. package/actionsExecutor/actions/__tests__/showToast.test.ts +88 -0
  18. package/actionsExecutor/actions/dismissBottomSheet.ts +23 -0
  19. package/actionsExecutor/actions/goBack.ts +60 -0
  20. package/actionsExecutor/actions/goHome.ts +31 -0
  21. package/actionsExecutor/actions/index.ts +12 -0
  22. package/actionsExecutor/actions/navigateToScreen.ts +43 -45
  23. package/actionsExecutor/actions/openBottomSheet.ts +340 -0
  24. package/actionsExecutor/actions/presentScreen.ts +78 -0
  25. package/actionsExecutor/actions/refreshComponent.ts +6 -0
  26. package/actionsExecutor/actions/screenToggleFlag.ts +1 -3
  27. package/actionsExecutor/actions/sendCloudEvent.ts +6 -1
  28. package/actionsExecutor/actions/showAlert.ts +51 -0
  29. package/actionsExecutor/actions/showToast.ts +64 -8
  30. package/actionsExecutor/consts.ts +27 -0
  31. package/actionsExecutor/feedDecorator.ts +12 -6
  32. package/analyticsUtils/PlayerAnalyticsManager.ts +1 -1
  33. package/appUtils/HooksManager/index.ts +9 -0
  34. package/appUtils/contextKeysManager/__tests__/getKey/failure.test.ts +1 -22
  35. package/appUtils/contextKeysManager/__tests__/getKey/success/fullSearch.test.ts +1 -25
  36. package/appUtils/contextKeysManager/__tests__/getKey/success/searchInSecure.test.ts +1 -7
  37. package/appUtils/contextKeysManager/__tests__/removeKey/failure.test.ts +0 -25
  38. package/appUtils/contextKeysManager/__tests__/removeKey/success.test.ts +0 -6
  39. package/appUtils/contextKeysManager/__tests__/setKey/failure/failedToSaveInStorage.test.ts +0 -40
  40. package/appUtils/contextKeysManager/__tests__/setKey/{success/saveItemAndReference.test.ts → success.test.ts} +2 -42
  41. package/appUtils/contextKeysManager/index.ts +28 -129
  42. package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +142 -59
  43. package/appUtils/playerManager/OverlayObserver/__tests__/getUpcomingQueue.test.ts +67 -0
  44. package/appUtils/playerManager/OverlayObserver/__tests__/liveContent.test.ts +205 -0
  45. package/appUtils/playerManager/OverlayObserver/__tests__/utils.test.ts +56 -0
  46. package/appUtils/playerManager/OverlayObserver/getUpcomingQueue.android.tv.ts +4 -0
  47. package/appUtils/playerManager/OverlayObserver/getUpcomingQueue.ios.tv.ts +4 -0
  48. package/appUtils/playerManager/OverlayObserver/getUpcomingQueue.ts +24 -0
  49. package/appUtils/playerManager/OverlayObserver/getUpcomingQueue.web.ts +4 -0
  50. package/appUtils/playerManager/OverlayObserver/utils.ts +51 -20
  51. package/appUtils/playerManager/__tests__/playerContent.test.ts +403 -0
  52. package/appUtils/playerManager/__tests__/playerDiagnostics.test.ts +62 -0
  53. package/appUtils/playerManager/__tests__/playerFactory.test.ts +1 -1
  54. package/appUtils/playerManager/__tests__/playerNative.test.ts +114 -0
  55. package/appUtils/playerManager/__tests__/playerNativeCommand.test.ts +62 -0
  56. package/appUtils/playerManager/__tests__/playerToolbox.test.ts +281 -0
  57. package/appUtils/playerManager/__tests__/usePlayerContent.test.tsx +64 -0
  58. package/appUtils/playerManager/__tests__/usePlayerControllerSetup.test.tsx +62 -0
  59. package/appUtils/playerManager/{conts.ts → const.ts} +33 -0
  60. package/appUtils/playerManager/index.ts +8 -1
  61. package/appUtils/playerManager/player.ts +140 -3
  62. package/appUtils/playerManager/playerFactory.ts +1 -1
  63. package/appUtils/playerManager/playerNative.ts +28 -4
  64. package/appUtils/playerManager/playerNativeCommand.ts +3 -6
  65. package/appUtils/playerManager/playerToolbox.ts +196 -0
  66. package/appUtils/playerManager/usePlayerContent.tsx +43 -0
  67. package/appUtils/playerManager/usePlayerControllerSetup.tsx +7 -1
  68. package/appUtils/playerManager/userLanguagePreference.ts +1 -1
  69. package/arrayUtils/__tests__/reorderByIds.test.ts +63 -0
  70. package/arrayUtils/index.ts +62 -0
  71. package/cellUtils/__tests__/getButtonsEnabled.test.ts +28 -0
  72. package/cellUtils/__tests__/getCellNavigationEnabled.test.ts +36 -0
  73. package/cellUtils/__tests__/getIsCellNavigationEnabled.test.ts +35 -0
  74. package/cellUtils/__tests__/isCellNavigationEnabled.test.ts +21 -0
  75. package/cellUtils/index.ts +70 -3
  76. package/configurationUtils/__tests__/manifestKeyParser.test.ts +21 -0
  77. package/configurationUtils/__tests__/modalBlocksParser.test.ts +403 -0
  78. package/configurationUtils/manifestKeyParser.ts +50 -10
  79. package/configurationUtils/modalBlocksParser.ts +252 -0
  80. package/entryActions/__tests__/buildEntryActions.test.ts +235 -0
  81. package/entryActions/aliasPresentation.ts +108 -0
  82. package/entryActions/buildEntryActions.ts +167 -0
  83. package/entryActions/index.ts +15 -0
  84. package/entryActions/types.ts +39 -0
  85. package/focusManager/FocusManager.ts +26 -0
  86. package/focusManager/__tests__/FocusManager.test.ts +9 -0
  87. package/localizationUtils/index.ts +12 -6
  88. package/logger/__tests__/xrayToolbox.test.ts +69 -0
  89. package/logger/xrayToolbox.ts +67 -0
  90. package/manifestUtils/__tests__/player.audioControls.test.js +158 -0
  91. package/manifestUtils/_internals/index.js +8 -3
  92. package/manifestUtils/defaultManifestConfigurations/generalContent.js +6 -0
  93. package/manifestUtils/defaultManifestConfigurations/player.js +338 -1
  94. package/manifestUtils/index.js +3 -0
  95. package/manifestUtils/keys.js +7 -2
  96. package/manifestUtils/mobileAction/container/__tests__/mobileActionButtonsContainer.test.js +21 -0
  97. package/manifestUtils/mobileAction/groups/__tests__/buildMobileActionButtonGroups.test.js +1 -1
  98. package/manifestUtils/mobileAction/groups/defaults.js +2 -1
  99. package/manifestUtils/modalBlocks.js +304 -0
  100. package/modalState/ContentViewModel.ts +113 -0
  101. package/modalState/EditableCollection.ts +17 -0
  102. package/modalState/EditableCollectionRegistry.ts +51 -0
  103. package/modalState/ModalOrchestrator.ts +213 -0
  104. package/modalState/RemoteEditableCollection.ts +235 -0
  105. package/modalState/__tests__/ContentViewModel.editable.test.ts +69 -0
  106. package/modalState/__tests__/ContentViewModel.test.ts +165 -0
  107. package/modalState/__tests__/EditableCollectionRegistry.test.ts +112 -0
  108. package/modalState/__tests__/ModalOrchestrator.phase3.test.ts +86 -0
  109. package/modalState/__tests__/RemoteEditableCollection.test.ts +415 -0
  110. package/modalState/__tests__/index.test.ts +30 -1
  111. package/modalState/__tests__/useBottomSheetContent.test.ts +349 -0
  112. package/modalState/__tests__/useModalStoreState.test.ts +142 -0
  113. package/modalState/index.ts +37 -83
  114. package/modalState/store.ts +109 -0
  115. package/modalState/types.ts +173 -0
  116. package/modalState/useBottomSheetContent.ts +109 -0
  117. package/navigationUtils/xrayNavigator.ts +12 -0
  118. package/package.json +3 -2
  119. package/playerUtils/__tests__/contentDataKeys.test.ts +297 -0
  120. package/playerUtils/__tests__/resolvePlayerActions.test.ts +138 -0
  121. package/playerUtils/__tests__/resolvePlayerTitleSubtitle.test.ts +180 -0
  122. package/playerUtils/contentDataKeys.ts +134 -0
  123. package/playerUtils/index.ts +37 -16
  124. package/playerUtils/isAudioItem.ts +26 -0
  125. package/playerUtils/resolvePlayerActions.ts +71 -0
  126. package/playerUtils/resolvePlayerTitleSubtitle.ts +76 -0
  127. package/pluginUtils/__tests__/pluginUtils.test.js +32 -0
  128. package/pluginUtils/index.ts +29 -0
  129. package/quickBrickAssets/__tests__/index.test.ts +18 -0
  130. package/quickBrickAssets/index.ts +35 -0
  131. package/reactHooks/__tests__/getPluginConfiguration.test.ts +82 -0
  132. package/reactHooks/actions/index.ts +74 -3
  133. package/reactHooks/cell-click/__tests__/index.test.js +64 -0
  134. package/reactHooks/cell-click/index.ts +21 -14
  135. package/reactHooks/connection/index.tsx +8 -5
  136. package/reactHooks/feed/__tests__/feedInvalidation.test.tsx +338 -0
  137. package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +8 -2
  138. package/reactHooks/feed/__tests__/useMarkPipesDataStale.test.tsx +243 -0
  139. package/reactHooks/feed/useFeedLoader.tsx +28 -1
  140. package/reactHooks/feed/useLoadPipesDataDispatch.ts +12 -11
  141. package/reactHooks/feed/useMarkPipesDataStale.ts +68 -23
  142. package/reactHooks/index.ts +2 -0
  143. package/reactHooks/layout/index.ts +1 -1
  144. package/reactHooks/navigation/__tests__/index.test.tsx +176 -1
  145. package/reactHooks/navigation/__tests__/usePresentScreen.test.ts +154 -0
  146. package/reactHooks/navigation/index.ts +2 -0
  147. package/reactHooks/navigation/usePresentScreen.ts +157 -0
  148. package/reactHooks/navigation/useRoute.ts +22 -5
  149. package/reactHooks/usePluginConfiguration.ts +88 -47
  150. package/reactHooks/utils/__tests__/index.test.js +22 -2
  151. package/reactHooks/utils/index.ts +11 -1
  152. package/riverComponetsMeasurementProvider/index.tsx +3 -1
  153. package/uiActionsRegistrator/__tests__/resolveActionIdentifiers.test.ts +93 -0
  154. package/uiActionsRegistrator/__tests__/subscribe.test.ts +133 -0
  155. package/uiActionsRegistrator/__tests__/usableActionItems.test.ts +52 -0
  156. package/uiActionsRegistrator/index.ts +25 -203
  157. package/uiActionsRegistrator/registry.ts +351 -0
  158. package/uiActionsRegistrator/resolveActionIdentifiers.ts +100 -0
  159. package/uiActionsRegistrator/usableActionItems.ts +66 -0
  160. package/zappFrameworkUtils/__tests__/localStorageHelper.test.ts +146 -0
  161. package/zappFrameworkUtils/localStorageHelper.ts +19 -15
  162. package/appUtils/contextKeysManager/__tests__/getKey/success/byReference.test.ts +0 -56
  163. package/appUtils/contextKeysManager/__tests__/getKeyByReference/failure.test.ts +0 -265
  164. package/appUtils/contextKeysManager/__tests__/getKeyByReference/success.test.ts +0 -303
  165. package/appUtils/contextKeysManager/__tests__/removeReferenceForKey/failure.test.ts +0 -82
  166. package/appUtils/contextKeysManager/__tests__/removeReferenceForKey/success.test.ts +0 -41
  167. package/appUtils/contextKeysManager/__tests__/setKey/success/saveItemButNotReference.test.ts +0 -208
  168. package/appUtils/contextKeysManager/__tests__/setReferenceForKey/failure.test.ts +0 -93
  169. package/appUtils/contextKeysManager/__tests__/setReferenceForKey/success.test.ts +0 -45
  170. package/appUtils/playerManager/usePlayerTitleSummaryOverlay.tsx +0 -56
  171. package/playerUtils/__tests__/getPlayerActionButtons.test.ts +0 -54
  172. package/playerUtils/getPlayerActionButtons.ts +0 -17
  173. /package/reactHooks/actions/__tests__/{index.test.js → index.test.tsx} +0 -0
@@ -204,6 +204,20 @@ function getPlayerConfiguration({ platform, version }) {
204
204
  label_tooltip: "Label for close button accessibility",
205
205
  type: "text_input",
206
206
  },
207
+ {
208
+ key: "accessibility_overflow_label",
209
+ label: "Accessibility overflow label",
210
+ initial_value: "More actions",
211
+ label_tooltip: "Label for the overflow (…) button accessibility",
212
+ type: "text_input",
213
+ },
214
+ {
215
+ key: "accessibility_overflow_hint",
216
+ label: "Accessibility overflow hint",
217
+ initial_value: "Opens the remaining player actions",
218
+ label_tooltip: "Hint for the overflow (…) button accessibility",
219
+ type: "text_input",
220
+ },
207
221
  {
208
222
  key: "accessibility_close_hint",
209
223
  label: "Accessibility close hint",
@@ -383,7 +397,45 @@ function getPlayerConfiguration({ platform, version }) {
383
397
  initial_value: "Start Over",
384
398
  type: "text_input",
385
399
  });
400
+ }
401
+
402
+ if (isMobile(platform)) {
403
+ // Screen reader strings for the audio player's playlist controls. Mobile
404
+ // only, because the audio player layout itself is mobile only.
405
+ localizations.fields.push({
406
+ key: "accessibility_previous_track_label",
407
+ label: "Accessibility previous track label",
408
+ initial_value: "Previous track button",
409
+ label_tooltip: "Label for previous track button accessibility",
410
+ type: "text_input",
411
+ });
412
+
413
+ localizations.fields.push({
414
+ key: "accessibility_previous_track_hint",
415
+ label: "Accessibility previous track hint",
416
+ initial_value: "Press to play the previous track",
417
+ label_tooltip: "Hint for previous track button accessibility",
418
+ type: "text_input",
419
+ });
420
+
421
+ localizations.fields.push({
422
+ key: "accessibility_next_track_label",
423
+ label: "Accessibility next track label",
424
+ initial_value: "Next track button",
425
+ label_tooltip: "Label for next track button accessibility",
426
+ type: "text_input",
427
+ });
386
428
 
429
+ localizations.fields.push({
430
+ key: "accessibility_next_track_hint",
431
+ label: "Accessibility next track hint",
432
+ initial_value: "Press to play the next track",
433
+ label_tooltip: "Hint for next track button accessibility",
434
+ type: "text_input",
435
+ });
436
+ }
437
+
438
+ if (isTV(platform)) {
387
439
  styles.fields.push(
388
440
  fieldsGroup("Always Show Scrub Bar & Timestamp", "", [
389
441
  {
@@ -753,7 +805,7 @@ function getPlayerConfiguration({ platform, version }) {
753
805
  label: "Player action buttons",
754
806
  initial_value: null,
755
807
  label_tooltip:
756
- "type here the identifiers of the action buttons you want to show on the player, separated by commas. Only 2 action buttons may be added at the same time",
808
+ "Comma-separated action identifiers. The entry_actions token expands from the playing entry's extensions.entry_action. When more than 2 actions resolve, the video and fullscreen audio players show Overflow (…) plus one companion - the first action that did not come from the entry, otherwise the first one - and the Overflow sheet lists every resolved action. A repeated identifier is counted once. No extra plugin is required.",
757
809
  type: "text_input",
758
810
  },
759
811
  {
@@ -778,6 +830,14 @@ function getPlayerConfiguration({ platform, version }) {
778
830
  type: "switch",
779
831
  label_tooltip:
780
832
  "Enable this option to have a floating video player when the app is in the background.",
833
+ },
834
+ {
835
+ key: "vertical_video_player",
836
+ label: "Vertical video mode",
837
+ initial_value: false,
838
+ type: "switch",
839
+ label_tooltip:
840
+ "Enable this option to use the vertical video player layout.",
781
841
  }
782
842
  );
783
843
 
@@ -1053,6 +1113,13 @@ function getPlayerConfiguration({ platform, version }) {
1053
1113
  type: "uploader",
1054
1114
  label_tooltip: "Override default close badge / icon",
1055
1115
  },
1116
+ {
1117
+ key: "overflow",
1118
+ label: "Overflow badge",
1119
+ type: "uploader",
1120
+ label_tooltip:
1121
+ "Override default overflow (…) badge / icon, shown when more action buttons resolve than fit on the player overlay",
1122
+ },
1056
1123
  {
1057
1124
  key: "lock",
1058
1125
  label: "Lock player badge",
@@ -1221,6 +1288,13 @@ function getPlayerConfiguration({ platform, version }) {
1221
1288
  type: "uploader",
1222
1289
  label_tooltip: "Playback Speed 0.8x",
1223
1290
  initial_value: null,
1291
+ rules: "conditional",
1292
+ conditional_fields: [
1293
+ {
1294
+ key: "styles/player_controls_layout",
1295
+ condition_value: "playback_speed_and_sleep_timer",
1296
+ },
1297
+ ],
1224
1298
  },
1225
1299
  {
1226
1300
  key: "speed_1",
@@ -1228,6 +1302,13 @@ function getPlayerConfiguration({ platform, version }) {
1228
1302
  type: "uploader",
1229
1303
  label_tooltip: "Playback Speed 1x",
1230
1304
  initial_value: null,
1305
+ rules: "conditional",
1306
+ conditional_fields: [
1307
+ {
1308
+ key: "styles/player_controls_layout",
1309
+ condition_value: "playback_speed_and_sleep_timer",
1310
+ },
1311
+ ],
1231
1312
  },
1232
1313
  {
1233
1314
  key: "speed_1_2",
@@ -1235,6 +1316,13 @@ function getPlayerConfiguration({ platform, version }) {
1235
1316
  type: "uploader",
1236
1317
  label_tooltip: "Playback Speed 1.2x",
1237
1318
  initial_value: null,
1319
+ rules: "conditional",
1320
+ conditional_fields: [
1321
+ {
1322
+ key: "styles/player_controls_layout",
1323
+ condition_value: "playback_speed_and_sleep_timer",
1324
+ },
1325
+ ],
1238
1326
  },
1239
1327
  {
1240
1328
  key: "speed_1_5",
@@ -1242,6 +1330,13 @@ function getPlayerConfiguration({ platform, version }) {
1242
1330
  type: "uploader",
1243
1331
  label_tooltip: "Playback Speed 1.5x",
1244
1332
  initial_value: null,
1333
+ rules: "conditional",
1334
+ conditional_fields: [
1335
+ {
1336
+ key: "styles/player_controls_layout",
1337
+ condition_value: "playback_speed_and_sleep_timer",
1338
+ },
1339
+ ],
1245
1340
  },
1246
1341
  {
1247
1342
  key: "speed_2",
@@ -1249,6 +1344,13 @@ function getPlayerConfiguration({ platform, version }) {
1249
1344
  type: "uploader",
1250
1345
  label_tooltip: "Playback Speed 2x",
1251
1346
  initial_value: null,
1347
+ rules: "conditional",
1348
+ conditional_fields: [
1349
+ {
1350
+ key: "styles/player_controls_layout",
1351
+ condition_value: "playback_speed_and_sleep_timer",
1352
+ },
1353
+ ],
1252
1354
  },
1253
1355
  {
1254
1356
  key: "sleep_timer",
@@ -1256,6 +1358,13 @@ function getPlayerConfiguration({ platform, version }) {
1256
1358
  type: "uploader",
1257
1359
  label_tooltip: "Sleep Timer Default",
1258
1360
  initial_value: null,
1361
+ rules: "conditional",
1362
+ conditional_fields: [
1363
+ {
1364
+ key: "styles/player_controls_layout",
1365
+ condition_value: "playback_speed_and_sleep_timer",
1366
+ },
1367
+ ],
1259
1368
  },
1260
1369
  {
1261
1370
  key: "sleep_timer_active",
@@ -1263,6 +1372,43 @@ function getPlayerConfiguration({ platform, version }) {
1263
1372
  type: "uploader",
1264
1373
  label_tooltip: "Sleep Timer Active",
1265
1374
  initial_value: null,
1375
+ rules: "conditional",
1376
+ conditional_fields: [
1377
+ {
1378
+ key: "styles/player_controls_layout",
1379
+ condition_value: "playback_speed_and_sleep_timer",
1380
+ },
1381
+ ],
1382
+ },
1383
+ {
1384
+ key: "previous_track",
1385
+ label: "Previous Track Control Icon",
1386
+ type: "uploader",
1387
+ label_tooltip:
1388
+ "Override the default Previous Track icon. Recommended size 120x120px (@3x).",
1389
+ initial_value: null,
1390
+ rules: "conditional",
1391
+ conditional_fields: [
1392
+ {
1393
+ key: "styles/player_controls_layout",
1394
+ condition_value: "playlist_controls",
1395
+ },
1396
+ ],
1397
+ },
1398
+ {
1399
+ key: "next_track",
1400
+ label: "Next Track Control Icon",
1401
+ type: "uploader",
1402
+ label_tooltip:
1403
+ "Override the default Next Track icon. Recommended size 120x120px (@3x).",
1404
+ initial_value: null,
1405
+ rules: "conditional",
1406
+ conditional_fields: [
1407
+ {
1408
+ key: "styles/player_controls_layout",
1409
+ condition_value: "playlist_controls",
1410
+ },
1411
+ ],
1266
1412
  },
1267
1413
  ]
1268
1414
  ),
@@ -1279,6 +1425,35 @@ function getPlayerConfiguration({ platform, version }) {
1279
1425
  type: "switch",
1280
1426
  label_tooltip: "Select whether you want to display title in player",
1281
1427
  },
1428
+ {
1429
+ section: "title",
1430
+ key: "title_data_key_source",
1431
+ label: "Title data key",
1432
+ initial_value: "title",
1433
+ type: "select",
1434
+ options: [
1435
+ { text: "Title", value: "title" },
1436
+ { text: "Other", value: "other" },
1437
+ ],
1438
+ label_tooltip:
1439
+ "Select which feed data key provides the player content title. Keep 'Title' to use the entry title",
1440
+ },
1441
+ {
1442
+ section: "title",
1443
+ key: "title_custom_data_key",
1444
+ label: "Custom title data key",
1445
+ initial_value: "",
1446
+ type: "text_input",
1447
+ rules: "conditional",
1448
+ conditional_fields: [
1449
+ {
1450
+ key: "styles/title_data_key_source",
1451
+ condition_value: "other",
1452
+ },
1453
+ ],
1454
+ label_tooltip:
1455
+ "Data key on the feed entry, dot notation supported, for example extensions.episode_name. Falls back to the entry title if the key is empty or missing",
1456
+ },
1282
1457
  {
1283
1458
  section: "title",
1284
1459
  key: "title_font_android",
@@ -1686,6 +1861,35 @@ function getPlayerConfiguration({ platform, version }) {
1686
1861
  label_tooltip:
1687
1862
  "Select whether you want to display subtitle in player",
1688
1863
  },
1864
+ {
1865
+ section: "subtitle",
1866
+ key: "subtitle_data_key_source",
1867
+ label: "Subtitle data key",
1868
+ initial_value: "summary",
1869
+ type: "select",
1870
+ options: [
1871
+ { text: "Subtitle", value: "summary" },
1872
+ { text: "Other", value: "other" },
1873
+ ],
1874
+ label_tooltip:
1875
+ "Select which feed data key provides the player content subtitle. Keep 'Subtitle' to use the entry summary",
1876
+ },
1877
+ {
1878
+ section: "subtitle",
1879
+ key: "subtitle_custom_data_key",
1880
+ label: "Custom subtitle data key",
1881
+ initial_value: "",
1882
+ type: "text_input",
1883
+ rules: "conditional",
1884
+ conditional_fields: [
1885
+ {
1886
+ key: "styles/subtitle_data_key_source",
1887
+ condition_value: "other",
1888
+ },
1889
+ ],
1890
+ label_tooltip:
1891
+ "Data key on the feed entry, dot notation supported, for example extensions.episode_subtitle. Falls back to the entry summary if the key is empty or missing",
1892
+ },
1689
1893
  {
1690
1894
  section: "subtitle",
1691
1895
  key: "subtitle_font_android",
@@ -2850,6 +3054,33 @@ function getPlayerConfiguration({ platform, version }) {
2850
3054
  "Video Player - Title Text",
2851
3055
  "Video Player Title Text Label Styles",
2852
3056
  [
3057
+ {
3058
+ key: "video_player_title_data_key_source",
3059
+ label: "Video title data key",
3060
+ initial_value: "title",
3061
+ type: "select",
3062
+ options: [
3063
+ { text: "Title", value: "title" },
3064
+ { text: "Other", value: "other" },
3065
+ ],
3066
+ label_tooltip:
3067
+ "Select which feed data key provides the video player title. Keep 'Title' to use the entry title",
3068
+ },
3069
+ {
3070
+ key: "video_player_title_custom_data_key",
3071
+ label: "Custom video title data key",
3072
+ initial_value: "",
3073
+ type: "text_input",
3074
+ rules: "conditional",
3075
+ conditional_fields: [
3076
+ {
3077
+ key: "styles/video_player_title_data_key_source",
3078
+ condition_value: "other",
3079
+ },
3080
+ ],
3081
+ label_tooltip:
3082
+ "Data key on the feed entry, dot notation supported, for example extensions.episode_name. Falls back to the entry title if the key is empty or missing",
3083
+ },
2853
3084
  {
2854
3085
  key: "player_title_color",
2855
3086
  label: "Font color",
@@ -2935,6 +3166,33 @@ function getPlayerConfiguration({ platform, version }) {
2935
3166
  "Video Player - Summary Text",
2936
3167
  "Video Player Summary Text Label Styles",
2937
3168
  [
3169
+ {
3170
+ key: "video_player_summary_data_key_source",
3171
+ label: "Video summary data key",
3172
+ initial_value: "summary",
3173
+ type: "select",
3174
+ options: [
3175
+ { text: "Summary", value: "summary" },
3176
+ { text: "Other", value: "other" },
3177
+ ],
3178
+ label_tooltip:
3179
+ "Select which feed data key provides the video player summary. Keep 'Summary' to use the entry summary",
3180
+ },
3181
+ {
3182
+ key: "video_player_summary_custom_data_key",
3183
+ label: "Custom video summary data key",
3184
+ initial_value: "",
3185
+ type: "text_input",
3186
+ rules: "conditional",
3187
+ conditional_fields: [
3188
+ {
3189
+ key: "styles/video_player_summary_data_key_source",
3190
+ condition_value: "other",
3191
+ },
3192
+ ],
3193
+ label_tooltip:
3194
+ "Data key on the feed entry, dot notation supported, for example extensions.episode_subtitle. Falls back to the entry summary if the key is empty or missing",
3195
+ },
2938
3196
  {
2939
3197
  key: "player_summary_color",
2940
3198
  label: "Font color",
@@ -3020,6 +3278,33 @@ function getPlayerConfiguration({ platform, version }) {
3020
3278
  "Audio Player - Title Text",
3021
3279
  "Audio Player Title Text Label Styles",
3022
3280
  [
3281
+ {
3282
+ key: "audio_player_title_data_key_source",
3283
+ label: "Audio title data key",
3284
+ initial_value: "title",
3285
+ type: "select",
3286
+ options: [
3287
+ { text: "Title", value: "title" },
3288
+ { text: "Other", value: "other" },
3289
+ ],
3290
+ label_tooltip:
3291
+ "Select which feed data key provides the audio player title. Keep 'Title' to use the entry title",
3292
+ },
3293
+ {
3294
+ key: "audio_player_title_custom_data_key",
3295
+ label: "Custom audio title data key",
3296
+ initial_value: "",
3297
+ type: "text_input",
3298
+ rules: "conditional",
3299
+ conditional_fields: [
3300
+ {
3301
+ key: "styles/audio_player_title_data_key_source",
3302
+ condition_value: "other",
3303
+ },
3304
+ ],
3305
+ label_tooltip:
3306
+ "Data key on the feed entry, dot notation supported, for example extensions.episode_name. Falls back to the entry title if the key is empty or missing",
3307
+ },
3023
3308
  {
3024
3309
  key: "audio_player_title_color",
3025
3310
  label: "Audio player title color",
@@ -3105,6 +3390,33 @@ function getPlayerConfiguration({ platform, version }) {
3105
3390
  "Audio Player - Summary Text",
3106
3391
  "Audio Player Summary Text Label Styles",
3107
3392
  [
3393
+ {
3394
+ key: "audio_player_summary_data_key_source",
3395
+ label: "Audio summary data key",
3396
+ initial_value: "summary",
3397
+ type: "select",
3398
+ options: [
3399
+ { text: "Summary", value: "summary" },
3400
+ { text: "Other", value: "other" },
3401
+ ],
3402
+ label_tooltip:
3403
+ "Select which feed data key provides the audio player summary. Keep 'Summary' to use the entry summary",
3404
+ },
3405
+ {
3406
+ key: "audio_player_summary_custom_data_key",
3407
+ label: "Custom audio summary data key",
3408
+ initial_value: "",
3409
+ type: "text_input",
3410
+ rules: "conditional",
3411
+ conditional_fields: [
3412
+ {
3413
+ key: "styles/audio_player_summary_data_key_source",
3414
+ condition_value: "other",
3415
+ },
3416
+ ],
3417
+ label_tooltip:
3418
+ "Data key on the feed entry, dot notation supported, for example extensions.episode_subtitle. Falls back to the entry summary if the key is empty or missing",
3419
+ },
3108
3420
  {
3109
3421
  key: "audio_player_summary_color",
3110
3422
  label: "Audio player summary color",
@@ -3451,6 +3763,31 @@ function getPlayerConfiguration({ platform, version }) {
3451
3763
  },
3452
3764
  ],
3453
3765
  },
3766
+ {
3767
+ key: "player_controls_layout",
3768
+ label: "Player Controls Layout",
3769
+ type: "select",
3770
+ initial_value: "playback_speed_and_sleep_timer",
3771
+ label_tooltip:
3772
+ "Choose which secondary controls appear in the audio player transport row.",
3773
+ rules: "conditional",
3774
+ conditional_fields: [
3775
+ {
3776
+ key: "styles/full_screen_audio_player",
3777
+ condition_value: true,
3778
+ },
3779
+ ],
3780
+ options: [
3781
+ {
3782
+ text: "Playback Speed & Sleep Timer (Default)",
3783
+ value: "playback_speed_and_sleep_timer",
3784
+ },
3785
+ {
3786
+ text: "Playlist Controls (Previous & Next)",
3787
+ value: "playlist_controls",
3788
+ },
3789
+ ],
3790
+ },
3454
3791
  {
3455
3792
  key: "audio_player_artwork_shadow_enabled",
3456
3793
  label: "Image Shadow Enabled",
@@ -24,6 +24,7 @@ const {
24
24
  const { buttonKey } = require("./buttons");
25
25
  const { tvBadges } = require("./tvBadges");
26
26
  const { mobileProgressBar, tvProgressBar } = require("./progressBar");
27
+ const { getModalBlockStyles, getModalLocalizations } = require("./modalBlocks");
27
28
 
28
29
  const {
29
30
  secondaryImage,
@@ -54,4 +55,6 @@ module.exports = {
54
55
  getUpdatedSecondaryImageKeys,
55
56
  DEFAULT_GRADIENT_IMAGE,
56
57
  compact,
58
+ getModalBlockStyles,
59
+ getModalLocalizations,
57
60
  };
@@ -412,6 +412,12 @@ const mobileActionButtonContainerFields = (positionOptions) => [
412
412
  type: ZAPPIFEST_FIELDS.switch,
413
413
  suffix: "buttons enabled",
414
414
  },
415
+ {
416
+ type: ZAPPIFEST_FIELDS.switch,
417
+ suffix: "cell navigation enabled",
418
+ label_tooltip:
419
+ "Controls whether tapping on the cell (outside the buttons) triggers its navigation behavior. When disabled, only the configured buttons are interactive. Useful for Home screens (tap anywhere to open) vs. Details screens (only buttons should work).",
420
+ },
415
421
  {
416
422
  type: ZAPPIFEST_FIELDS.select,
417
423
  suffix: "position",
@@ -472,14 +478,13 @@ const MOBILE_ACTION_BUTTON_FIELDS = [
472
478
  suffix: "assign action",
473
479
  options: [
474
480
  { text: "primary navigation", value: "navigation_action" },
475
- { text: "secondary navigation", value: "secondary_navigation" },
476
481
  { text: "favorite", value: "local_storage_favourites_action" },
477
482
  { text: "more", value: "open-modal-bottom-sheet-cell-action" },
478
483
  { text: "add to calendar", value: "add_to_calendar_action" },
479
484
  { text: "share", value: "native_share_action" },
480
485
  { text: "downloads", value: "offline-content-button" },
481
486
  { text: "trailer", value: "trailer_action" },
482
- { text: "mute/unmute", value: "mute_unmute" },
487
+ { text: "mute/unmute", value: "mute_unmute_action" },
483
488
  ],
484
489
  },
485
490
  {
@@ -7,6 +7,7 @@ describe("mobileActionButtonsContainer", () => {
7
7
  description: "container",
8
8
  defaults: {
9
9
  buttonsEnabled: false,
10
+ cellNavigationEnabled: false,
10
11
  position: ["over_image", "text_label_1", "text_label_2"],
11
12
  align: "left",
12
13
  overImagePosition: "bottom_left",
@@ -31,6 +32,26 @@ describe("mobileActionButtonsContainer", () => {
31
32
  expect(enabledField).toBeTruthy();
32
33
  expect(enabledField.type).toBe("switch");
33
34
 
35
+ const cellNavigationField = result.fields.find(
36
+ (field) =>
37
+ field.key === "mobile_buttons_container_cell_navigation_enabled"
38
+ );
39
+
40
+ expect(cellNavigationField).toMatchObject({
41
+ type: "switch",
42
+ label: "Cell navigation enabled",
43
+ initial_value: false,
44
+ label_tooltip: expect.stringContaining(
45
+ "Controls whether tapping on the cell"
46
+ ),
47
+ conditional_fields: [
48
+ {
49
+ key: "styles/mobile_buttons_container_buttons_enabled",
50
+ condition_value: true,
51
+ },
52
+ ],
53
+ });
54
+
34
55
  const positionField = result.fields.find(
35
56
  (field) => field.key === "mobile_buttons_container_position"
36
57
  );
@@ -67,7 +67,7 @@ describe("buildMobileActionButtonGroups", () => {
67
67
  );
68
68
 
69
69
  expect(button2EnabledField.initial_value).toBe(false);
70
- expect(button2AssignActionField.initial_value).toBe("secondary_navigation");
70
+ expect(button2AssignActionField.initial_value).toBe("trailer_action");
71
71
 
72
72
  const button3Fields = groups[3].fields;
73
73
 
@@ -1,5 +1,6 @@
1
1
  const DEFAULT_MOBILE_ACTION_BUTTONS_CONTAINER_DEFAULTS = {
2
2
  buttonsEnabled: false,
3
+ cellNavigationEnabled: false,
3
4
 
4
5
  align: "left",
5
6
  overImagePosition: "bottom_left",
@@ -63,7 +64,7 @@ const DEFAULT_MOBILE_ACTION_BUTTON_PRESETS = {
63
64
  },
64
65
  2: {
65
66
  buttonEnabled: false,
66
- assignAction: "secondary_navigation",
67
+ assignAction: "trailer_action",
67
68
  },
68
69
  3: {
69
70
  buttonEnabled: false,