@applicaster/zapp-react-native-utils 13.0.0-alpha.5855333506 → 13.0.0-alpha.5942605655

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 (126) hide show
  1. package/README.md +0 -10
  2. package/actionsExecutor/ActionExecutor.ts +5 -2
  3. package/actionsExecutor/ActionExecutorContext.tsx +163 -14
  4. package/actionsExecutor/consts.ts +4 -0
  5. package/analyticsUtils/currentScreenProperities.ts +6 -4
  6. package/appUtils/HooksManager/Hook.ts +6 -2
  7. package/appUtils/HooksManager/index.ts +3 -1
  8. package/appUtils/HooksManager/types.ts +2 -2
  9. package/appUtils/__tests__/__snapshots__/localizationsHelper.test.ts.snap +151 -0
  10. package/appUtils/__tests__/allZappLocales.ts +79 -0
  11. package/appUtils/__tests__/{localizationsHelper.test.js → localizationsHelper.test.ts} +11 -0
  12. package/appUtils/accessibilityManager/const.ts +18 -0
  13. package/appUtils/contextKeysManager/contextResolver.ts +7 -14
  14. package/appUtils/contextKeysManager/index.ts +2 -2
  15. package/appUtils/contextKeysManager/utils/index.ts +2 -1
  16. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +3 -0
  17. package/appUtils/focusManager/index.ios.ts +14 -4
  18. package/appUtils/focusManager/index.ts +24 -12
  19. package/appUtils/focusManager/utils/__tests__/findChild.test.ts +35 -0
  20. package/appUtils/focusManager/utils/index.ts +5 -0
  21. package/appUtils/keyCodes/index.ts +11 -7
  22. package/appUtils/localizationsHelper.ts +31 -0
  23. package/appUtils/orientationHelper.ts +11 -13
  24. package/appUtils/platform/platformUtils.ts +30 -3
  25. package/appUtils/playerManager/index.ts +1 -1
  26. package/appUtils/playerManager/player.ts +26 -14
  27. package/appUtils/playerManager/playerHooks/usePlayerCurrentTime.tsx +11 -7
  28. package/appUtils/playerManager/playerNative.ts +18 -3
  29. package/appUtils/playerManager/usePlayerTitleSummaryOverlay.tsx +7 -1
  30. package/cellUtils/index.ts +9 -5
  31. package/componentsUtils/__tests__/isFirstComponentGallery.test.ts +33 -0
  32. package/componentsUtils/__tests__/isFirstComponentScreenPicker.test.ts +33 -0
  33. package/componentsUtils/__tests__/isGallery.test.ts +33 -0
  34. package/componentsUtils/__tests__/isScreenPicker.test.ts +33 -0
  35. package/componentsUtils/index.ts +39 -0
  36. package/dateUtils/index.ts +19 -0
  37. package/equalUtils/__tests__/isEqual/combination.test.ts +263 -0
  38. package/equalUtils/index.ts +49 -30
  39. package/focusManager/FocusManager.ts +14 -2
  40. package/focusManager/index.ts +23 -4
  41. package/functionUtils/index.ts +46 -8
  42. package/idleUtils/__tests__/withTimeout$.test.ts +37 -0
  43. package/idleUtils/index.ts +1 -1
  44. package/idleUtils/withTimeout.ts +15 -2
  45. package/index.d.ts +0 -12
  46. package/localizationUtils/index.ts +8 -13
  47. package/manifestUtils/__tests__/createConfig.test.js +0 -2
  48. package/manifestUtils/defaultManifestConfigurations/generalContent.js +13 -0
  49. package/manifestUtils/defaultManifestConfigurations/player.js +9 -3
  50. package/manifestUtils/fonts/index.js +5 -6
  51. package/manifestUtils/index.js +2 -0
  52. package/manifestUtils/keys.js +27 -2
  53. package/manifestUtils/sharedConfiguration/screenPicker/__tests__/utils.test.js +304 -0
  54. package/manifestUtils/sharedConfiguration/screenPicker/stylesFields.js +875 -0
  55. package/manifestUtils/sharedConfiguration/screenPicker/utils.js +130 -0
  56. package/modalState/__tests__/index.test.ts +51 -0
  57. package/modalState/index.ts +32 -2
  58. package/navigationUtils/__tests__/__snapshots__/navigationUtils.test.js.snap +1 -0
  59. package/navigationUtils/index.ts +6 -4
  60. package/numberUtils/__tests__/toPositiveNumberWithDefault.test.ts +23 -3
  61. package/numberUtils/index.ts +11 -5
  62. package/package.json +4 -10
  63. package/playerUtils/configurationGenerator.ts +9 -11
  64. package/playerUtils/index.ts +23 -0
  65. package/reactHooks/advertising/index.ts +5 -5
  66. package/reactHooks/app/useAppState.ts +2 -2
  67. package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +5 -7
  68. package/reactHooks/autoscrolling/useTrackedView.ts +12 -1
  69. package/reactHooks/feed/useBatchLoading.ts +10 -12
  70. package/reactHooks/feed/useFeedLoader.tsx +17 -8
  71. package/reactHooks/hookModal/hooks/useHookModalScreenData.ts +39 -0
  72. package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.test.js +1 -1
  73. package/reactHooks/layout/useDimensions/useDimensions.ts +8 -0
  74. package/reactHooks/navigation/__mocks__/useNavigation.ts +3 -0
  75. package/reactHooks/navigation/__tests__/index.test.tsx +6 -17
  76. package/reactHooks/navigation/{useGetTabBarHeight.ts → getTabBarHeight.ts} +2 -4
  77. package/reactHooks/navigation/index.ts +13 -23
  78. package/reactHooks/navigation/useGetBottomTabBarHeight.ts +10 -3
  79. package/reactHooks/navigation/useNavigationPluginData.ts +8 -4
  80. package/reactHooks/navigation/useNavigationType.ts +4 -2
  81. package/reactHooks/navigation/useProfilerLogging.ts +15 -0
  82. package/reactHooks/navigation/useRoute.ts +4 -6
  83. package/reactHooks/screen/__tests__/useScreenBackgroundColor.test.tsx +69 -0
  84. package/reactHooks/screen/useScreenBackgroundColor.ts +3 -15
  85. package/reactHooks/state/README.md +79 -0
  86. package/reactHooks/state/ZStoreProvider.tsx +71 -0
  87. package/reactHooks/state/__tests__/ZStoreProvider.test.tsx +66 -0
  88. package/reactHooks/state/index.ts +2 -0
  89. package/reactHooks/state/useRefWithInitialValue.ts +14 -0
  90. package/reactHooks/state/useStateFromSubscribe.ts +23 -0
  91. package/reactHooks/useListenEventBusEvent.ts +1 -1
  92. package/reactHooks/usePluginConfiguration.ts +1 -1
  93. package/reactHooks/useSubscriberFor.ts +4 -3
  94. package/reactUtils/__tests__/__snapshots__/reactUtilsHelpers.test.js.snap +16 -4
  95. package/reactUtils/__tests__/reactUtils.test.js +1 -19
  96. package/reactUtils/__tests__/reactUtilsHelpers.test.js +72 -71
  97. package/reactUtils/createContext/__tests__/__snapshots__/helpers.test.js.snap +6 -72
  98. package/reactUtils/createContext/__tests__/__snapshots__/provider.test.js.snap +3 -28
  99. package/reactUtils/createContext/__tests__/__snapshots__/withConsumer.test.js.snap +3 -4
  100. package/reactUtils/createContext/__tests__/__snapshots__/withProvider.test.js.snap +7 -3
  101. package/reactUtils/createContext/__tests__/helpers.test.js +107 -121
  102. package/reactUtils/createContext/__tests__/{index.test.js → index.test.ts} +2 -2
  103. package/reactUtils/createContext/__tests__/provider.test.js +4 -6
  104. package/reactUtils/createContext/__tests__/withConsumer.test.js +12 -12
  105. package/reactUtils/createContext/__tests__/withProvider.test.js +4 -4
  106. package/reactUtils/createContext/helpers.ts +6 -1
  107. package/reactUtils/createContext/index.ts +11 -25
  108. package/reactUtils/index.ts +9 -11
  109. package/screenState/index.ts +24 -10
  110. package/services/js2native.ts +673 -0
  111. package/testUtils/index.tsx +0 -10
  112. package/theme/index.ts +1 -1
  113. package/time/BackgroundTimer.ts +55 -0
  114. package/time/Timer.ts +9 -6
  115. package/typeGuards/index.ts +3 -0
  116. package/types.ts +1 -0
  117. package/utils/README.md +30 -0
  118. package/utils/chunk.ts +5 -0
  119. package/utils/index.ts +5 -0
  120. package/utils/times.ts +5 -0
  121. package/zappFrameworkUtils/localStorageHelper.ts +38 -10
  122. package/zappFrameworkUtils/loginPluginUtils.ts +6 -2
  123. package/zappFrameworkUtils/presentPluginOneTime.ts +2 -3
  124. package/zappFrameworkUtils/types.ts +11 -0
  125. package/reactUtils/createContext/__tests__/index-no-react.test.js +0 -27
  126. /package/reactUtils/createContext/__tests__/__snapshots__/{index.test.js.snap → index.test.ts.snap} +0 -0
package/README.md CHANGED
@@ -376,16 +376,6 @@ useEffect(() => {
376
376
  }, []);
377
377
  ```
378
378
 
379
- ### testUtils
380
-
381
- `@applicaster/zapp-react-native-utils/testUtils`
382
-
383
- - `testIDEquals: (testId: any) => boolean | { width: number, height: number }` - Function to be used in tandem with enzyme findWhere
384
-
385
- ```javascript
386
- wrapper.findWhere(testIDEquals("text"));
387
- ```
388
-
389
379
  ### appUtils - contextKeysManager
390
380
 
391
381
  `@applicaster/zapp-react-native-utils/appUtils/contextKeyManager`
@@ -33,7 +33,7 @@ class ActionExecutor {
33
33
 
34
34
  log_debug(
35
35
  `handleAction: ${action.type}${
36
- entry ? `, entry id ${entry?.id}, title: ${entry?.title}` : ""
36
+ entry ? `, entry id ${entry.id}, title: ${entry.title}` : ""
37
37
  }`,
38
38
  { action, entry }
39
39
  );
@@ -100,7 +100,10 @@ class ActionExecutor {
100
100
 
101
101
  registerAction = (
102
102
  type: string,
103
- handler: (action: ActionType, entry?: ZappEntry) => Promise<ActionResult>
103
+ handler: (
104
+ action: ActionType,
105
+ context?: Record<string, any>
106
+ ) => Promise<ActionResult>
104
107
  ) => {
105
108
  if (this.registeredActions[type]) {
106
109
  log_error(`registerAction: action type: ${type} already registered`);
@@ -1,13 +1,18 @@
1
1
  /// <reference types="@applicaster/applicaster-types" />
2
2
  import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
3
- import React, { createContext, useMemo } from "react";
3
+ import React, { createContext, useEffect, useMemo } from "react";
4
4
  import {
5
5
  actionExecutor as _actionExecutor,
6
6
  ActionResult,
7
7
  } from "./ActionExecutor";
8
- import { batchSaveToLocalStorage } from "../zappFrameworkUtils/localStorageHelper";
9
- import { QUICK_BRICK_EVENTS } from "@applicaster/zapp-react-native-bridge/QuickBrick";
8
+ import {
9
+ batchRemoveAllFromNamespaceForStorage,
10
+ batchSave,
11
+ } from "../zappFrameworkUtils/localStorageHelper";
12
+ import { sessionStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage";
13
+
10
14
  import * as QuickBrickManager from "@applicaster/zapp-react-native-bridge/QuickBrick";
15
+ import { QUICK_BRICK_EVENTS } from "@applicaster/zapp-react-native-bridge/QuickBrick";
11
16
  import { showConfirmationDialog } from "../alertUtils";
12
17
  import { createCloudEvent, sendCloudEvent } from "../cloudEventsUtils";
13
18
  import { createLogger } from "../logger";
@@ -19,13 +24,22 @@ import {
19
24
  EntryResolver,
20
25
  resolveObjectValues,
21
26
  } from "../appUtils/contextKeysManager/contextResolver";
27
+ import { useNavigation } from "../reactHooks";
28
+ import { get } from "lodash";
22
29
 
23
- const { log_error, log_info } = createLogger({
30
+ import {
31
+ useContentTypes,
32
+ usePickFromState,
33
+ } from "@applicaster/zapp-react-native-redux/hooks";
34
+ import { TOGGLE_FLAG_MAX_ITEMS_REACHED_EVENT } from "./consts";
35
+ import { postEvent, useSubscriberFor } from "../reactHooks/useSubscriberFor";
36
+ import { APP_EVENTS } from "../appUtils/events";
37
+
38
+ export const { log_error, log_info, log_debug } = createLogger({
24
39
  subsystem: "ActionExecutorContext",
25
40
  category: "General",
26
41
  });
27
42
 
28
- // TODO: move entry inside options and rename options to context
29
43
  type ActionExecutorContextType = {
30
44
  registerAction: (
31
45
  type: string,
@@ -52,10 +66,47 @@ type Props = {
52
66
  children: React.ReactNode;
53
67
  };
54
68
 
69
+ function findParentComponent(
70
+ childId: string,
71
+ parent: ZappRiver | ZappUIComponent
72
+ ): ZappRiver | ZappUIComponent | null {
73
+ for (const child of parent.ui_components) {
74
+ if (child.id === childId) return parent;
75
+
76
+ if (child.ui_components) {
77
+ const found = findParentComponent(childId, child);
78
+ if (found) return found;
79
+ }
80
+ }
81
+
82
+ return null;
83
+ }
84
+
85
+ // send all data just in case (like for message string formatting)
86
+ // Type is not exported for now
87
+ type MaxTagsReachedEvent = {
88
+ selectedItems: string[];
89
+ maxItems: number;
90
+ tag: string;
91
+ keyNamespace: string;
92
+ };
93
+
94
+ async function onMaxTagsReached(data: MaxTagsReachedEvent) {
95
+ postEvent(TOGGLE_FLAG_MAX_ITEMS_REACHED_EVENT, [data]);
96
+ }
97
+
55
98
  const prepareDefaultActions = (actionExecutor) => {
56
99
  actionExecutor.registerAction("localStorageSet", async (action) => {
57
100
  const namespaces = action.options.content;
58
- await batchSaveToLocalStorage(namespaces);
101
+ await batchSave(namespaces, localStorage);
102
+ // TODO: Add support for ownershipKey and ownershipNamespace
103
+
104
+ return ActionResult.Success;
105
+ });
106
+
107
+ actionExecutor.registerAction("sessionStorageSet", async (action) => {
108
+ const namespaces = action.options.content;
109
+ await batchSave(namespaces, sessionStorage);
59
110
  // TODO: Add support for ownershipKey and ownershipNamespace
60
111
 
61
112
  return ActionResult.Success;
@@ -66,11 +117,13 @@ const prepareDefaultActions = (actionExecutor) => {
66
117
  async (_action, context) => {
67
118
  const dispatch = appStore.getDispatch();
68
119
 
69
- log_info("handleAction: refreshComponent event");
120
+ const dataSource =
121
+ context?.component?.data?.source ||
122
+ findParentComponent(context?.component.id, context?.screenData)?.data
123
+ ?.source;
70
124
 
71
- const dataSource = context?.component?.data?.source;
125
+ log_info(`handleAction: refreshComponent for dataSource:${dataSource}`);
72
126
 
73
- // TODO: Later we can pass component ids to do refresh instead of current one
74
127
  // TODO: In theory we should wait callback to complete, before completing the action, but now it's not needed
75
128
  // TODO: handle focused item removal
76
129
  dispatch(
@@ -110,15 +163,13 @@ const prepareDefaultActions = (actionExecutor) => {
110
163
  actionExecutor.registerAction("confirmDialog", async (action) => {
111
164
  log_info("handleAction: confirmDialog event");
112
165
 
113
- const confirmationPromise = new Promise<ActionResult>((resolve) => {
166
+ return new Promise<ActionResult>((resolve) => {
114
167
  showConfirmationDialog({
115
168
  ...action.options,
116
169
  confirmCompletion: () => resolve(ActionResult.Success),
117
170
  cancelCompletion: () => resolve(ActionResult.Cancel),
118
171
  });
119
172
  });
120
-
121
- return confirmationPromise;
122
173
  });
123
174
 
124
175
  actionExecutor.registerAction("sendCloudEvent", async (action, context) => {
@@ -166,9 +217,33 @@ const prepareDefaultActions = (actionExecutor) => {
166
217
 
167
218
  actionExecutor.registerAction(
168
219
  "localStorageToggleFlag",
169
- async (action: ActionType, entry?: ZappEntry): Promise<ActionResult> => {
220
+ async (
221
+ action: ActionType,
222
+ context?: Record<string, any>
223
+ ): Promise<ActionResult> => {
224
+ if (!context) {
225
+ log_error(
226
+ "handleAction: localStorageToggleFlag action missing context"
227
+ );
228
+
229
+ return ActionResult.Error;
230
+ }
231
+
232
+ const entry = context?.entry as ZappEntry;
233
+
234
+ if (!entry) {
235
+ log_error(
236
+ "handleAction: localStorageToggleFlag action missing entry. Entry is required to get the tag."
237
+ );
238
+
239
+ return ActionResult.Error;
240
+ }
241
+
242
+ const tag = action.options?.selector
243
+ ? get(entry, action.options.selector)
244
+ : (entry.extensions?.tag ?? entry.id);
245
+
170
246
  const keyNamespace = action.options?.key;
171
- const tag = entry?.extensions?.tag;
172
247
 
173
248
  if (keyNamespace && tag) {
174
249
  const multiSelectProvider =
@@ -186,6 +261,23 @@ const prepareDefaultActions = (actionExecutor) => {
186
261
  if (selectedItems.includes(tag)) {
187
262
  await multiSelectProvider.removeItem(tag);
188
263
  } else {
264
+ const maxItems = action.options?.max_items;
265
+
266
+ if (maxItems && selectedItems.length >= maxItems) {
267
+ log_info(
268
+ `handleAction: localStorageToggleFlag event reached max items limit: ${maxItems}, cannot add tag: ${tag}`
269
+ );
270
+
271
+ await onMaxTagsReached({
272
+ selectedItems,
273
+ maxItems,
274
+ tag,
275
+ keyNamespace,
276
+ });
277
+
278
+ return ActionResult.Cancel;
279
+ }
280
+
189
281
  await multiSelectProvider.addItem(tag);
190
282
  }
191
283
  } else {
@@ -209,6 +301,10 @@ export function withActionExecutor(Component) {
209
301
  prepareDefaultActions(_actionExecutor);
210
302
 
211
303
  return function ActionExecutorComponent(props: Props) {
304
+ const navigator = useNavigation();
305
+ const { rivers } = usePickFromState(["rivers"]);
306
+ const contentTypes = useContentTypes();
307
+
212
308
  const handlers = useMemo(() => {
213
309
  return {
214
310
  unregisterAction: _actionExecutor.unregisterAction,
@@ -219,6 +315,59 @@ export function withActionExecutor(Component) {
219
315
  };
220
316
  }, []);
221
317
 
318
+ useSubscriberFor(APP_EVENTS.onLogout, () => {
319
+ log_debug(
320
+ "User profile: onLogout event received, clearing user profile data"
321
+ );
322
+
323
+ const userAccountKey = "user_account";
324
+ void batchRemoveAllFromNamespaceForStorage(userAccountKey, localStorage);
325
+
326
+ void batchRemoveAllFromNamespaceForStorage(
327
+ userAccountKey,
328
+ sessionStorage
329
+ );
330
+ });
331
+
332
+ useEffect(() => {
333
+ return _actionExecutor.registerAction(
334
+ "navigateToScreen",
335
+
336
+ async (action: ActionType, context?: Record<string, any>) => {
337
+ const screenType = action.options?.typeMapping;
338
+
339
+ if (!screenType) {
340
+ log_error("navigateToScreen: typeMapping option is missing");
341
+
342
+ return ActionResult.Error;
343
+ }
344
+
345
+ const screenId = contentTypes?.[screenType]?.screen_id || null;
346
+
347
+ if (!screenId) {
348
+ log_error(
349
+ `navigateToScreen: can not resolve screen type mapping: ${screenType}`
350
+ );
351
+
352
+ return ActionResult.Error;
353
+ }
354
+
355
+ const river = rivers[screenId];
356
+
357
+ if (!river) {
358
+ log_error("navigateToScreen: can not resolve river");
359
+
360
+ return ActionResult.Error;
361
+ }
362
+
363
+ context?.callback?.({ success: false, error: null, abort: true });
364
+ navigator.replace(river);
365
+
366
+ return ActionResult.Success;
367
+ }
368
+ );
369
+ }, [navigator, rivers, contentTypes]);
370
+
222
371
  return (
223
372
  <ActionExecutorContext.Provider value={handlers}>
224
373
  <Component {...props} />
@@ -0,0 +1,4 @@
1
+ export const TOGGLE_FLAG_MAX_ITEMS_REACHED_EVENT =
2
+ "action.localStorageToggleFlag.maxItemsReached";
3
+
4
+ export const ACTION_EXECUTOR_EVENT_SOURCE = "ActionExecutor";
@@ -72,12 +72,14 @@ const mappedScreenPropertiesScreen = (
72
72
  screenData
73
73
  ): AnalyticsScreenProperties => {
74
74
  return {
75
- screen_name: screenData?.targetScreen?.name,
75
+ screen_name: screenData?.targetScreen?.name || screenData?.name,
76
76
  screen_entry_title: screenData?.title,
77
77
  screen_entry_id: R.isNil(screenData?.type) ? null : screenData?.id,
78
- screen_layout_id: screenData?.targetScreen?.id,
79
- screen_type: screenData?.targetScreen?.type,
80
- home_screen: screenData?.targetScreen?.home,
78
+ screen_layout_id: screenData?.targetScreen?.id || screenData?.id,
79
+ screen_type: screenData?.targetScreen?.type || screenData?.type,
80
+ home_screen: !R.isNil(screenData?.targetScreen?.home)
81
+ ? screenData?.targetScreen?.home
82
+ : screenData?.home,
81
83
  };
82
84
  };
83
85
 
@@ -16,7 +16,7 @@ const BASE_HOOK_PROPERTIES = ["screen_id", "identifier", "weight"];
16
16
  * @returns {number} index
17
17
  */
18
18
  const hookState: (
19
- arg0: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS]
19
+ arg0: (typeof HOOKS_EVENTS)[keyof typeof HOOKS_EVENTS]
20
20
  ) => number = R.indexOf(R.__, R.values(HOOKS_EVENTS));
21
21
 
22
22
  /**
@@ -62,9 +62,13 @@ export class Hook implements HookInterface {
62
62
  * @param {Array<Any>} args variadic arguments to invoke the handler with
63
63
  */
64
64
  setStateAndNotify(
65
- event: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS],
65
+ event: (typeof HOOKS_EVENTS)[keyof typeof HOOKS_EVENTS],
66
66
  ...args
67
67
  ) {
68
+ if (this.state === hookState(HOOKS_EVENTS.CANCEL)) {
69
+ return;
70
+ }
71
+
68
72
  this.state = hookState(event);
69
73
  this.manager.subscriber.invokeHandler(event, ...args);
70
74
  }
@@ -84,7 +84,7 @@ export function HooksManager({
84
84
  plugins,
85
85
  startUpHooksData = {},
86
86
  }: HookManagerArgs): HookManager {
87
- hooksManagerLogger.addContext({ targetScreen });
87
+ hooksManagerLogger.addContext({ targetScreenId: targetScreen.id });
88
88
 
89
89
  function logHookEvent(func, message, data) {
90
90
  func({
@@ -269,6 +269,7 @@ export function HooksManager({
269
269
  payload = initialPayload,
270
270
  callback: callbackArg,
271
271
  cancelled,
272
+ abort,
272
273
  }) {
273
274
  let callback = callbackArg;
274
275
 
@@ -308,6 +309,7 @@ export function HooksManager({
308
309
  hookPlugin.setStateAndNotify(HOOKS_EVENTS.CANCEL, {
309
310
  hookPlugin,
310
311
  payload,
312
+ abort,
311
313
  });
312
314
 
313
315
  const isHookInHomescreen = payload?.home;
@@ -103,7 +103,7 @@ export interface Hook<T extends HookModule = HookModule> {
103
103
  identifier: string;
104
104
  configuration: T["configuration"];
105
105
  setStateAndNotify(
106
- event: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS],
106
+ event: (typeof HOOKS_EVENTS)[keyof typeof HOOKS_EVENTS],
107
107
  opts: {
108
108
  error?: typeof Error;
109
109
  route?: string;
@@ -112,7 +112,7 @@ export interface Hook<T extends HookModule = HookModule> {
112
112
  }
113
113
  );
114
114
  general?: {
115
- transition_type: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS];
115
+ transition_type: (typeof HOOKS_EVENTS)[keyof typeof HOOKS_EVENTS];
116
116
  allow_screen_plugin_presentation: boolean;
117
117
  is_flow_blocker: boolean;
118
118
  };
@@ -0,0 +1,151 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`toDayJSLocaleMap [af] returns a valid dayjs locale 1`] = `"af"`;
4
+
5
+ exports[`toDayJSLocaleMap [ar] returns a valid dayjs locale 1`] = `"ar"`;
6
+
7
+ exports[`toDayJSLocaleMap [bg] returns a valid dayjs locale 1`] = `"bg"`;
8
+
9
+ exports[`toDayJSLocaleMap [bn] returns a valid dayjs locale 1`] = `"bn"`;
10
+
11
+ exports[`toDayJSLocaleMap [bo] returns a valid dayjs locale 1`] = `"bo"`;
12
+
13
+ exports[`toDayJSLocaleMap [ca] returns a valid dayjs locale 1`] = `"ca"`;
14
+
15
+ exports[`toDayJSLocaleMap [cs] returns a valid dayjs locale 1`] = `"cs"`;
16
+
17
+ exports[`toDayJSLocaleMap [da] returns a valid dayjs locale 1`] = `"da"`;
18
+
19
+ exports[`toDayJSLocaleMap [de] returns a valid dayjs locale 1`] = `"de"`;
20
+
21
+ exports[`toDayJSLocaleMap [el] returns a valid dayjs locale 1`] = `"el"`;
22
+
23
+ exports[`toDayJSLocaleMap [en] returns a valid dayjs locale 1`] = `"en"`;
24
+
25
+ exports[`toDayJSLocaleMap [en-GB] returns a valid dayjs locale 1`] = `"en-gb"`;
26
+
27
+ exports[`toDayJSLocaleMap [en-UK] returns a valid dayjs locale 1`] = `"en-gb"`;
28
+
29
+ exports[`toDayJSLocaleMap [es] returns a valid dayjs locale 1`] = `"es"`;
30
+
31
+ exports[`toDayJSLocaleMap [es-LA] returns a valid dayjs locale 1`] = `"es"`;
32
+
33
+ exports[`toDayJSLocaleMap [es-MX] returns a valid dayjs locale 1`] = `"es-mx"`;
34
+
35
+ exports[`toDayJSLocaleMap [es-US] returns a valid dayjs locale 1`] = `"es-us"`;
36
+
37
+ exports[`toDayJSLocaleMap [et] returns a valid dayjs locale 1`] = `"et"`;
38
+
39
+ exports[`toDayJSLocaleMap [eu] returns a valid dayjs locale 1`] = `"eu"`;
40
+
41
+ exports[`toDayJSLocaleMap [fa] returns a valid dayjs locale 1`] = `"fa"`;
42
+
43
+ exports[`toDayJSLocaleMap [fi] returns a valid dayjs locale 1`] = `"fi"`;
44
+
45
+ exports[`toDayJSLocaleMap [fj] returns a valid dayjs locale 1`] = `"en"`;
46
+
47
+ exports[`toDayJSLocaleMap [fr] returns a valid dayjs locale 1`] = `"fr"`;
48
+
49
+ exports[`toDayJSLocaleMap [ga] returns a valid dayjs locale 1`] = `"ga"`;
50
+
51
+ exports[`toDayJSLocaleMap [gu] returns a valid dayjs locale 1`] = `"gu"`;
52
+
53
+ exports[`toDayJSLocaleMap [he] returns a valid dayjs locale 1`] = `"he"`;
54
+
55
+ exports[`toDayJSLocaleMap [hi] returns a valid dayjs locale 1`] = `"hi"`;
56
+
57
+ exports[`toDayJSLocaleMap [hr] returns a valid dayjs locale 1`] = `"hr"`;
58
+
59
+ exports[`toDayJSLocaleMap [hu] returns a valid dayjs locale 1`] = `"hu"`;
60
+
61
+ exports[`toDayJSLocaleMap [hy] returns a valid dayjs locale 1`] = `"hy-am"`;
62
+
63
+ exports[`toDayJSLocaleMap [id] returns a valid dayjs locale 1`] = `"id"`;
64
+
65
+ exports[`toDayJSLocaleMap [is] returns a valid dayjs locale 1`] = `"is"`;
66
+
67
+ exports[`toDayJSLocaleMap [it] returns a valid dayjs locale 1`] = `"it"`;
68
+
69
+ exports[`toDayJSLocaleMap [ja] returns a valid dayjs locale 1`] = `"ja"`;
70
+
71
+ exports[`toDayJSLocaleMap [ka] returns a valid dayjs locale 1`] = `"ka"`;
72
+
73
+ exports[`toDayJSLocaleMap [km] returns a valid dayjs locale 1`] = `"km"`;
74
+
75
+ exports[`toDayJSLocaleMap [ko] returns a valid dayjs locale 1`] = `"ko"`;
76
+
77
+ exports[`toDayJSLocaleMap [la] returns a valid dayjs locale 1`] = `"en"`;
78
+
79
+ exports[`toDayJSLocaleMap [lt] returns a valid dayjs locale 1`] = `"lt"`;
80
+
81
+ exports[`toDayJSLocaleMap [lv] returns a valid dayjs locale 1`] = `"lv"`;
82
+
83
+ exports[`toDayJSLocaleMap [mi] returns a valid dayjs locale 1`] = `"mi"`;
84
+
85
+ exports[`toDayJSLocaleMap [mk] returns a valid dayjs locale 1`] = `"mk"`;
86
+
87
+ exports[`toDayJSLocaleMap [ml] returns a valid dayjs locale 1`] = `"ml"`;
88
+
89
+ exports[`toDayJSLocaleMap [mn] returns a valid dayjs locale 1`] = `"mn"`;
90
+
91
+ exports[`toDayJSLocaleMap [mr] returns a valid dayjs locale 1`] = `"mr"`;
92
+
93
+ exports[`toDayJSLocaleMap [ms] returns a valid dayjs locale 1`] = `"ms"`;
94
+
95
+ exports[`toDayJSLocaleMap [mt] returns a valid dayjs locale 1`] = `"mt"`;
96
+
97
+ exports[`toDayJSLocaleMap [ne] returns a valid dayjs locale 1`] = `"ne"`;
98
+
99
+ exports[`toDayJSLocaleMap [nl] returns a valid dayjs locale 1`] = `"nl"`;
100
+
101
+ exports[`toDayJSLocaleMap [no] returns a valid dayjs locale 1`] = `"en"`;
102
+
103
+ exports[`toDayJSLocaleMap [pa] returns a valid dayjs locale 1`] = `"pa-in"`;
104
+
105
+ exports[`toDayJSLocaleMap [pl] returns a valid dayjs locale 1`] = `"pl"`;
106
+
107
+ exports[`toDayJSLocaleMap [pt] returns a valid dayjs locale 1`] = `"pt"`;
108
+
109
+ exports[`toDayJSLocaleMap [pt-BR] returns a valid dayjs locale 1`] = `"pt-br"`;
110
+
111
+ exports[`toDayJSLocaleMap [qu] returns a valid dayjs locale 1`] = `"en"`;
112
+
113
+ exports[`toDayJSLocaleMap [ro] returns a valid dayjs locale 1`] = `"ro"`;
114
+
115
+ exports[`toDayJSLocaleMap [ru] returns a valid dayjs locale 1`] = `"ru"`;
116
+
117
+ exports[`toDayJSLocaleMap [sk] returns a valid dayjs locale 1`] = `"sk"`;
118
+
119
+ exports[`toDayJSLocaleMap [sl] returns a valid dayjs locale 1`] = `"sl"`;
120
+
121
+ exports[`toDayJSLocaleMap [sm] returns a valid dayjs locale 1`] = `"en"`;
122
+
123
+ exports[`toDayJSLocaleMap [sq] returns a valid dayjs locale 1`] = `"sq"`;
124
+
125
+ exports[`toDayJSLocaleMap [sr] returns a valid dayjs locale 1`] = `"sr"`;
126
+
127
+ exports[`toDayJSLocaleMap [sv] returns a valid dayjs locale 1`] = `"sv"`;
128
+
129
+ exports[`toDayJSLocaleMap [sw] returns a valid dayjs locale 1`] = `"sw"`;
130
+
131
+ exports[`toDayJSLocaleMap [ta] returns a valid dayjs locale 1`] = `"ta"`;
132
+
133
+ exports[`toDayJSLocaleMap [te] returns a valid dayjs locale 1`] = `"te"`;
134
+
135
+ exports[`toDayJSLocaleMap [th] returns a valid dayjs locale 1`] = `"th"`;
136
+
137
+ exports[`toDayJSLocaleMap [to] returns a valid dayjs locale 1`] = `"en"`;
138
+
139
+ exports[`toDayJSLocaleMap [tr] returns a valid dayjs locale 1`] = `"tr"`;
140
+
141
+ exports[`toDayJSLocaleMap [tt] returns a valid dayjs locale 1`] = `"en"`;
142
+
143
+ exports[`toDayJSLocaleMap [uk] returns a valid dayjs locale 1`] = `"uk"`;
144
+
145
+ exports[`toDayJSLocaleMap [ur] returns a valid dayjs locale 1`] = `"ur"`;
146
+
147
+ exports[`toDayJSLocaleMap [uz] returns a valid dayjs locale 1`] = `"uz"`;
148
+
149
+ exports[`toDayJSLocaleMap [vi] returns a valid dayjs locale 1`] = `"vi"`;
150
+
151
+ exports[`toDayJSLocaleMap [zh] returns a valid dayjs locale 1`] = `"zh"`;
@@ -0,0 +1,79 @@
1
+ export default [
2
+ // common locales from https://rubygems.org/gems/language_list
3
+ "en",
4
+ "fr",
5
+ "de",
6
+ "nl",
7
+ "ru",
8
+ "es",
9
+ "he",
10
+ "hy",
11
+ "sq",
12
+ "af",
13
+ "ar",
14
+ "eu",
15
+ "bn",
16
+ "bg",
17
+ "zh",
18
+ "cs",
19
+ "km",
20
+ "ca",
21
+ "hr",
22
+ "da",
23
+ "et",
24
+ "fj",
25
+ "fi",
26
+ "gu",
27
+ "ka",
28
+ "hu",
29
+ "hi",
30
+ "it",
31
+ "is",
32
+ "id",
33
+ "ga",
34
+ "ja",
35
+ "ko",
36
+ "la",
37
+ "lv",
38
+ "lt",
39
+ "ms",
40
+ "mi",
41
+ "mn",
42
+ "mt",
43
+ "mk",
44
+ "el",
45
+ "mr",
46
+ "ml",
47
+ "ne",
48
+ "no",
49
+ "pa",
50
+ "pl",
51
+ "pt",
52
+ "fa",
53
+ "qu",
54
+ "ro",
55
+ "sk",
56
+ "sm",
57
+ "sr",
58
+ "sw",
59
+ "sv",
60
+ "sl",
61
+ "to",
62
+ "tr",
63
+ "th",
64
+ "te",
65
+ "bo",
66
+ "tt",
67
+ "ta",
68
+ "uk",
69
+ "ur",
70
+ "uz",
71
+ "vi",
72
+ // Extra locales https://github.com/applicaster/zapp/blob/5604794f15cfd270ae494b0db85e542de4cebfaa/config/additional_languages.yml
73
+ "en-UK",
74
+ "en-GB",
75
+ "es-LA",
76
+ "pt-BR",
77
+ "es-MX",
78
+ "es-US",
79
+ ];
@@ -8,6 +8,7 @@ const {
8
8
  getLocale,
9
9
  getLanguageCode,
10
10
  getCountryCode,
11
+ toDayJSLocaleMap,
11
12
  } = require("../localizationsHelper");
12
13
 
13
14
  describe("getLocale", () => {
@@ -69,3 +70,13 @@ describe("getCountryCode", () => {
69
70
  expect(currentValue).toEqual(expectedValue);
70
71
  });
71
72
  });
73
+
74
+ describe("toDayJSLocaleMap", () => {
75
+ const allZappLocales: string[] = require("./allZappLocales").default;
76
+
77
+ it.each(allZappLocales)("[%s] returns a valid dayjs locale", (locale) => {
78
+ const dayJSLocale = toDayJSLocaleMap(locale);
79
+ expect(dayJSLocale).toBeDefined();
80
+ expect(dayJSLocale).toMatchSnapshot();
81
+ });
82
+ });
@@ -47,4 +47,22 @@ export const BUTTON_ACCESSIBILITY_KEYS = {
47
47
  label: "accessibility_fullscreen_label",
48
48
  hint: "accessibility_fullscreen_hint",
49
49
  },
50
+ // EPG-specific buttons
51
+ now: {
52
+ label: "accessibility_now_label",
53
+ hint: "accessibility_now_hint",
54
+ },
55
+ day: {
56
+ label: "accessibility_day_label",
57
+ hint: "accessibility_day_hint",
58
+ },
59
+ program: {
60
+ label: "accessibility_program_label",
61
+ hint: "accessibility_program_hint",
62
+ },
63
+ // Menu-specific buttons
64
+ menu_item: {
65
+ label: "accessibility_menu_item_label",
66
+ hint: "accessibility_menu_item_hint",
67
+ },
50
68
  } as const;