@applicaster/zapp-react-native-utils 13.0.0-rc.13 → 13.0.0-rc.130

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/README.md +0 -10
  2. package/actionsExecutor/ActionExecutor.ts +16 -9
  3. package/actionsExecutor/ActionExecutorContext.tsx +229 -17
  4. package/actionsExecutor/consts.ts +4 -0
  5. package/alertUtils/alert.ts +148 -0
  6. package/alertUtils/index.ts +1 -148
  7. package/analyticsUtils/AnalyticPlayerListener.ts +18 -1
  8. package/analyticsUtils/__tests__/__snapshots__/analyticsManagerNoModule.test.js.snap +9 -9
  9. package/analyticsUtils/currentScreenProperities.ts +6 -4
  10. package/analyticsUtils/helpers/hooks.ts +1 -1
  11. package/appUtils/HooksManager/Hook.ts +6 -2
  12. package/appUtils/HooksManager/__tests__/__snapshots__/hook.test.js.snap +7 -7
  13. package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +186 -186
  14. package/appUtils/HooksManager/index.ts +3 -1
  15. package/appUtils/HooksManager/types.ts +5 -2
  16. package/appUtils/__tests__/__snapshots__/localizationsHelper.test.ts.snap +151 -0
  17. package/appUtils/__tests__/allZappLocales.ts +79 -0
  18. package/appUtils/__tests__/{localizationsHelper.test.js → localizationsHelper.test.ts} +11 -0
  19. package/appUtils/accessibilityManager/const.ts +18 -0
  20. package/appUtils/accessibilityManager/index.ts +42 -1
  21. package/appUtils/contextKeysManager/contextResolver.ts +66 -0
  22. package/appUtils/contextKeysManager/index.ts +2 -2
  23. package/appUtils/contextKeysManager/utils/index.ts +2 -1
  24. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +9 -6
  25. package/appUtils/focusManager/index.ios.ts +14 -4
  26. package/appUtils/focusManager/index.ts +108 -69
  27. package/appUtils/focusManager/treeDataStructure/Tree/index.js +23 -0
  28. package/appUtils/focusManager/utils/__tests__/findChild.test.ts +35 -0
  29. package/appUtils/focusManager/utils/enums.ts +4 -0
  30. package/appUtils/focusManager/utils/index.ts +5 -0
  31. package/appUtils/focusManagerAux/utils/index.ts +4 -3
  32. package/appUtils/keyCodes/__tests__/__snapshots__/keyCodes.test.js.snap +2 -2
  33. package/appUtils/keyCodes/__tests__/keyCodes.test.js +1 -1
  34. package/appUtils/keyCodes/index.ts +11 -7
  35. package/appUtils/keyCodes/keys/keysByPlatform.ts +4 -0
  36. package/appUtils/keyInputHandler/KeyInputHandler.ts +68 -0
  37. package/appUtils/localizationsHelper.ts +31 -0
  38. package/appUtils/orientationHelper.ts +11 -13
  39. package/appUtils/platform/const.ts +14 -0
  40. package/appUtils/platform/platformUtils.ts +47 -4
  41. package/appUtils/playerManager/index.ts +1 -1
  42. package/appUtils/playerManager/player.ts +42 -18
  43. package/appUtils/playerManager/playerHooks/usePlayerCurrentTime.tsx +11 -7
  44. package/appUtils/playerManager/playerNative.ts +18 -2
  45. package/appUtils/playerManager/usePlayerControllerSetup.tsx +3 -3
  46. package/appUtils/playerManager/usePlayerTitleSummaryOverlay.tsx +7 -1
  47. package/arrayUtils/__tests__/__snapshots__/arrayUtils.test.ts.snap +4 -4
  48. package/cellUtils/index.ts +9 -5
  49. package/componentsUtils/__tests__/isFirstComponentGallery.test.ts +33 -0
  50. package/componentsUtils/__tests__/isFirstComponentScreenPicker.test.ts +33 -0
  51. package/componentsUtils/__tests__/isGallery.test.ts +33 -0
  52. package/componentsUtils/__tests__/isScreenPicker.test.ts +33 -0
  53. package/componentsUtils/index.ts +39 -0
  54. package/dateUtils/index.ts +19 -0
  55. package/equalUtils/__tests__/isEqual/combination.test.ts +263 -0
  56. package/equalUtils/index.ts +49 -30
  57. package/focusManager/FocusManager.ts +14 -2
  58. package/focusManager/index.ts +23 -4
  59. package/functionUtils/__tests__/__snapshots__/functionUtils.test.js.snap +4 -4
  60. package/functionUtils/index.ts +46 -8
  61. package/idleUtils/__tests__/withTimeout$.test.ts +37 -0
  62. package/idleUtils/index.ts +1 -1
  63. package/idleUtils/withTimeout.ts +15 -2
  64. package/index.d.ts +0 -12
  65. package/localizationUtils/index.ts +8 -13
  66. package/logger/const.ts +9 -67
  67. package/manifestUtils/__tests__/createConfig.test.js +16 -16
  68. package/manifestUtils/defaultManifestConfigurations/generalContent.js +13 -0
  69. package/manifestUtils/defaultManifestConfigurations/player.js +9 -3
  70. package/manifestUtils/fonts/index.js +5 -6
  71. package/manifestUtils/index.js +2 -0
  72. package/manifestUtils/keys.js +27 -2
  73. package/manifestUtils/sharedConfiguration/screenPicker/__tests__/utils.test.js +304 -0
  74. package/manifestUtils/sharedConfiguration/screenPicker/stylesFields.js +875 -0
  75. package/manifestUtils/sharedConfiguration/screenPicker/utils.js +130 -0
  76. package/modalState/__tests__/index.test.ts +51 -0
  77. package/modalState/index.ts +32 -2
  78. package/navigationUtils/__tests__/__snapshots__/navigationUtils.test.js.snap +7 -6
  79. package/navigationUtils/__tests__/itemTypes.test.js +2 -2
  80. package/navigationUtils/__tests__/navigationUtils.test.js +2 -2
  81. package/navigationUtils/index.ts +6 -4
  82. package/numberUtils/__tests__/toPositiveNumberWithDefault.test.ts +23 -3
  83. package/numberUtils/index.ts +11 -5
  84. package/package.json +5 -10
  85. package/playerUtils/configurationGenerator.ts +9 -11
  86. package/playerUtils/index.ts +17 -0
  87. package/reactHooks/advertising/index.ts +5 -5
  88. package/reactHooks/app/useAppState.ts +2 -2
  89. package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
  90. package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +6 -8
  91. package/reactHooks/autoscrolling/useTrackedView.ts +12 -1
  92. package/reactHooks/cell-click/__tests__/index.test.js +10 -2
  93. package/reactHooks/cell-click/index.ts +7 -1
  94. package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +4 -4
  95. package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +10 -11
  96. package/reactHooks/feed/useBatchLoading.ts +10 -12
  97. package/reactHooks/feed/useFeedLoader.tsx +18 -9
  98. package/reactHooks/feed/usePipesCacheReset.ts +5 -5
  99. package/reactHooks/flatList/__tests__/index.test.tsx +30 -21
  100. package/reactHooks/hookModal/hooks/useHookModalScreenData.ts +39 -0
  101. package/reactHooks/layout/__tests__/index.test.tsx +10 -10
  102. package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.native.test.js +14 -28
  103. package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.test.js +1 -1
  104. package/reactHooks/layout/useDimensions/useDimensions.ts +8 -0
  105. package/reactHooks/navigation/__mocks__/useNavigation.ts +3 -0
  106. package/reactHooks/navigation/__tests__/index.test.tsx +6 -21
  107. package/reactHooks/navigation/getTabBarHeight.ts +10 -0
  108. package/reactHooks/navigation/index.ts +34 -236
  109. package/reactHooks/navigation/useGetBottomTabBarHeight.ts +19 -0
  110. package/reactHooks/navigation/useGetNavBarTopBorderWidth.ts +14 -0
  111. package/reactHooks/navigation/useIsScreenActive.ts +17 -0
  112. package/reactHooks/navigation/useNavigationPluginData.ts +19 -0
  113. package/reactHooks/navigation/useNavigationType.ts +17 -0
  114. package/reactHooks/navigation/usePathname.ts +4 -0
  115. package/reactHooks/navigation/useProfilerLogging.ts +15 -0
  116. package/reactHooks/navigation/useRoute.ts +98 -0
  117. package/reactHooks/navigation/useUniqueRouteSuffix.ts +41 -0
  118. package/reactHooks/player/TVSeekControlller/ISeekController.ts +32 -0
  119. package/reactHooks/player/TVSeekControlller/LongPressSeekController.ts +71 -0
  120. package/reactHooks/player/TVSeekControlller/TVSeekController.ts +258 -0
  121. package/reactHooks/player/TVSeekControlller/TapSeekController.ts +53 -0
  122. package/reactHooks/player/__tests__/{useAutoSeek.test.tsx → useAutoSeek._test.tsx} +2 -3
  123. package/reactHooks/player/const.ts +0 -4
  124. package/reactHooks/player/index.ts +0 -6
  125. package/reactHooks/screen/__tests__/useScreenBackgroundColor.test.tsx +69 -0
  126. package/reactHooks/screen/useScreenBackgroundColor.ts +3 -15
  127. package/reactHooks/state/README.md +79 -0
  128. package/reactHooks/state/ZStoreProvider.tsx +71 -0
  129. package/reactHooks/state/__tests__/ZStoreProvider.test.tsx +66 -0
  130. package/reactHooks/state/index.ts +2 -0
  131. package/reactHooks/state/useRefWithInitialValue.ts +14 -0
  132. package/reactHooks/state/useStateFromSubscribe.ts +23 -0
  133. package/reactHooks/useListenEventBusEvent.ts +1 -1
  134. package/reactHooks/usePluginConfiguration.ts +1 -1
  135. package/reactHooks/useSubscriberFor.ts +4 -3
  136. package/reactUtils/__tests__/__snapshots__/reactUtilsHelpers.test.js.snap +16 -4
  137. package/reactUtils/__tests__/reactUtils.test.js +1 -37
  138. package/reactUtils/__tests__/reactUtilsHelpers.test.js +72 -71
  139. package/reactUtils/createContext/__tests__/__snapshots__/helpers.test.js.snap +13 -79
  140. package/reactUtils/createContext/__tests__/__snapshots__/{index.test.js.snap → index.test.ts.snap} +2 -2
  141. package/reactUtils/createContext/__tests__/__snapshots__/provider.test.js.snap +3 -28
  142. package/reactUtils/createContext/__tests__/__snapshots__/withConsumer.test.js.snap +3 -4
  143. package/reactUtils/createContext/__tests__/__snapshots__/withProvider.test.js.snap +7 -3
  144. package/reactUtils/createContext/__tests__/helpers.test.js +107 -121
  145. package/reactUtils/createContext/__tests__/{index.test.js → index.test.ts} +2 -2
  146. package/reactUtils/createContext/__tests__/provider.test.js +4 -6
  147. package/reactUtils/createContext/__tests__/withConsumer.test.js +12 -12
  148. package/reactUtils/createContext/__tests__/withProvider.test.js +4 -4
  149. package/reactUtils/createContext/helpers.ts +6 -1
  150. package/reactUtils/createContext/index.ts +11 -25
  151. package/reactUtils/index.ts +9 -11
  152. package/screenState/index.ts +24 -10
  153. package/services/js2native.ts +673 -0
  154. package/testUtils/index.tsx +0 -10
  155. package/theme/__mocks__/index.ts +4 -0
  156. package/theme/index.ts +1 -1
  157. package/time/BackgroundTimer.ts +55 -0
  158. package/time/Timer.ts +9 -6
  159. package/typeGuards/index.ts +3 -0
  160. package/types.ts +1 -0
  161. package/utils/README.md +30 -0
  162. package/utils/chunk.ts +5 -0
  163. package/utils/index.ts +5 -0
  164. package/utils/times.ts +5 -0
  165. package/zappFrameworkUtils/localStorageHelper.ts +38 -10
  166. package/zappFrameworkUtils/loginPluginUtils.ts +6 -2
  167. package/zappFrameworkUtils/presentPluginOneTime.ts +2 -3
  168. package/zappFrameworkUtils/types.ts +11 -0
  169. package/reactHooks/player/useAutoSeek.tsx +0 -87
  170. package/reactHooks/player/useSeek.tsx +0 -66
  171. package/reactHooks/player/useTapSeek.tsx +0 -58
  172. package/reactUtils/createContext/__tests__/index-no-react.test.js +0 -27
  173. /package/reactHooks/player/__tests__/{useTapSeek.test.ts → useTapSeek._test.ts} +0 -0
@@ -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;
@@ -4,6 +4,8 @@ import { HOOKS_EVENTS } from "./constants";
4
4
  export interface HookConfiguration {}
5
5
 
6
6
  /* existing Hook Plugn props: sample */
7
+
8
+ /*
7
9
  interface _HookModulePlugin {
8
10
  Component:
9
11
  | React.FC<HookPluginProps>
@@ -23,6 +25,7 @@ interface _HookModulePlugin {
23
25
  presentUI: (payload?: HookPluginProps["payload"]) => void
24
26
  ) => any;
25
27
  }
28
+ */
26
29
 
27
30
  //* Derived from usage */
28
31
  export interface HookModule {
@@ -100,7 +103,7 @@ export interface Hook<T extends HookModule = HookModule> {
100
103
  identifier: string;
101
104
  configuration: T["configuration"];
102
105
  setStateAndNotify(
103
- event: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS],
106
+ event: (typeof HOOKS_EVENTS)[keyof typeof HOOKS_EVENTS],
104
107
  opts: {
105
108
  error?: typeof Error;
106
109
  route?: string;
@@ -109,7 +112,7 @@ export interface Hook<T extends HookModule = HookModule> {
109
112
  }
110
113
  );
111
114
  general?: {
112
- transition_type: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS];
115
+ transition_type: (typeof HOOKS_EVENTS)[keyof typeof HOOKS_EVENTS];
113
116
  allow_screen_plugin_presentation: boolean;
114
117
  is_flow_blocker: boolean;
115
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;
@@ -6,6 +6,9 @@ import { AccessibilityRole } from "react-native";
6
6
 
7
7
  export class AccessibilityManager {
8
8
  private static _instance: AccessibilityManager | null = null;
9
+ private headingTimeout: NodeJS.Timeout | null = null;
10
+ private WORDS_PER_MINUTE = 160;
11
+ private MINIMUM_PAUSE = 500;
9
12
  private state$ = new BehaviorSubject<AccessibilityState>({
10
13
  screenReaderEnabled: false,
11
14
  reduceMotionEnabled: false,
@@ -20,6 +23,7 @@ export class AccessibilityManager {
20
23
 
21
24
  private ttsManager = TTSManager.getInstance();
22
25
  private localizations: { [key: string]: string } = {};
26
+ private headingQueue: string[] = [];
23
27
 
24
28
  private constructor() {}
25
29
 
@@ -52,6 +56,28 @@ export class AccessibilityManager {
52
56
  return this.state$.asObservable();
53
57
  }
54
58
 
59
+ /** Calculates the reading time for a given text
60
+ * This method is a bit of a hack because we don't have a callback, or promise from VIZIO API
61
+ * @param text - The text to calculate the reading time for
62
+ * @returns The reading time in milliseconds
63
+ */
64
+ private calculateReadingTime(text: string): number {
65
+ const words = text.trim().split(/\s+/).length;
66
+
67
+ return Math.max(
68
+ this.MINIMUM_PAUSE,
69
+ (words / this.WORDS_PER_MINUTE) * 60 * 1000
70
+ );
71
+ }
72
+
73
+ /**
74
+ * Adds a heading to the queue, headings will be read before the next text
75
+ * Each heading will be read once and removed from the queue
76
+ */
77
+ public addHeading(heading: string) {
78
+ this.headingQueue.push(heading);
79
+ }
80
+
55
81
  /**
56
82
  * text you want to be read, if you want to use localized text pass keyOfLocalizedText instead
57
83
  * keyOfLocalizedText is the key to the localized text
@@ -85,7 +111,22 @@ export class AccessibilityManager {
85
111
  textToRead = localizedMessage;
86
112
  }
87
113
 
88
- this.ttsManager && this.ttsManager.readText(textToRead);
114
+ if (this.headingQueue.length > 0) {
115
+ const heading = this.headingQueue.shift()!;
116
+ this.ttsManager?.readText(heading);
117
+
118
+ if (this.headingTimeout) {
119
+ clearTimeout(this.headingTimeout);
120
+ }
121
+
122
+ const pauseTime = this.calculateReadingTime(heading);
123
+
124
+ this.headingTimeout = setTimeout(() => {
125
+ this.ttsManager?.readText(textToRead);
126
+ }, pauseTime);
127
+ } else {
128
+ this.ttsManager?.readText(textToRead);
129
+ }
89
130
 
90
131
  this.announcements$.next({
91
132
  message: textToRead,
@@ -0,0 +1,66 @@
1
+ import { ContextKeysManager } from "./index";
2
+ import * as R from "ramda";
3
+
4
+ interface IResolver {
5
+ resolve: (string) => Promise<string | number | object>;
6
+ }
7
+
8
+ export class EntryResolver implements IResolver {
9
+ entry: ZappEntry;
10
+
11
+ constructor(entry: ZappEntry) {
12
+ this.entry = entry;
13
+ }
14
+
15
+ async resolve(key: string) {
16
+ if (!key || key.length === 0) {
17
+ return this.entry;
18
+ }
19
+
20
+ return R.view(R.lensPath(key.split(".")), this.entry);
21
+ }
22
+ }
23
+
24
+ export class ContextResolver implements IResolver {
25
+ resolve = async (compositeKey: string) =>
26
+ ContextKeysManager.instance.getKey(compositeKey);
27
+ }
28
+
29
+ export const resolveObjectValues = async (
30
+ data: Record<string, any>,
31
+ resolvers: Record<string, IResolver> = null
32
+ ) => {
33
+ const entries = Object.entries(data);
34
+
35
+ const exResolvers = { ctx: new ContextResolver(), ...resolvers };
36
+
37
+ const resolvedEntries = await Promise.all(
38
+ entries.map(async ([key, value]) => {
39
+ if (typeof value !== "string") {
40
+ return [key, value];
41
+ }
42
+
43
+ if (!value.startsWith("@")) {
44
+ return [key, value];
45
+ }
46
+
47
+ const regex = /@{([^/]+)\/([^}]*)}/;
48
+
49
+ const match = (value as string).match(regex);
50
+
51
+ if (match) {
52
+ const contextResolverName = match[1];
53
+ const compositeKey = match[2];
54
+
55
+ const resolver = exResolvers[contextResolverName] || exResolvers.ctx;
56
+ const resolvedValue = await resolver.resolve(compositeKey);
57
+
58
+ return [key, resolvedValue];
59
+ }
60
+
61
+ return [key, value];
62
+ })
63
+ );
64
+
65
+ return Object.fromEntries(resolvedEntries);
66
+ };
@@ -16,12 +16,12 @@ import {
16
16
 
17
17
  export { StorageLevel };
18
18
 
19
- type KeyNameObj = {
19
+ export type KeyNameObj = {
20
20
  namespace: string;
21
21
  key: string;
22
22
  };
23
23
 
24
- type KeyName = string | KeyNameObj;
24
+ export type KeyName = string | KeyNameObj;
25
25
 
26
26
  type ParsedKeyAndNamespace = {
27
27
  namespace?: string;
@@ -1,10 +1,11 @@
1
1
  import * as R from "ramda";
2
2
  import { DEFAULT_NAMESPACE } from "../consts";
3
+ import { KeyName, KeyNameObj } from "../index";
3
4
 
4
5
  const lastDotRegex = /\.([^.]+)$/;
5
6
  const splitByLastDot = R.compose(R.init, R.split(lastDotRegex));
6
7
 
7
- export function getNamespaceAndKey(namespacedKey) {
8
+ export function getNamespaceAndKey(namespacedKey: KeyName): KeyNameObj {
8
9
  if (typeof namespacedKey !== "string") return namespacedKey;
9
10
 
10
11
  const namespacedKeyProps = namespacedKey.includes(".")
@@ -1,14 +1,15 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`focusManager should be defined 1`] = `
4
- Object {
4
+ {
5
5
  "blur": [Function],
6
6
  "disableFocus": [Function],
7
7
  "enableFocus": [Function],
8
+ "findPreferredFocusChild": [Function],
8
9
  "focusableTree": Tree {
9
10
  "loadingCounter": 0,
10
- "root": Object {
11
- "children": Array [],
11
+ "root": {
12
+ "children": [],
12
13
  "component": null,
13
14
  "id": "root",
14
15
  "lastFocusedItem": null,
@@ -28,6 +29,7 @@ Object {
28
29
  "moveFocus": [Function],
29
30
  "on": [Function],
30
31
  "press": [Function],
32
+ "pressIn": [Function],
31
33
  "pressOut": [Function],
32
34
  "recoverFocus": [Function],
33
35
  "register": [Function],
@@ -39,12 +41,12 @@ Object {
39
41
  `;
40
42
 
41
43
  exports[`focusManagerIOS should be defined 1`] = `
42
- Object {
44
+ {
43
45
  "focus": [Function],
44
46
  "focusableTree": Tree {
45
47
  "loadingCounter": 0,
46
- "root": Object {
47
- "children": Array [],
48
+ "root": {
49
+ "children": [],
48
50
  "component": null,
49
51
  "id": "root",
50
52
  "lastFocusedItem": null,
@@ -59,6 +61,7 @@ Object {
59
61
  "getCurrentGroup": [Function],
60
62
  "getGroupById": [Function],
61
63
  "getGroupRootById": [Function],
64
+ "getPreferredFocusChild": [Function],
62
65
  "invokeHandler": [Function],
63
66
  "isGroupItemFocused": [Function],
64
67
  "moveFocus": [Function],
@@ -1,8 +1,10 @@
1
1
  import { NativeModules } from "react-native";
2
2
  import * as R from "ramda";
3
+
3
4
  import { Tree } from "./treeDataStructure/Tree";
4
5
  import { findFocusableNode } from "./treeDataStructure/Utils";
5
6
  import { subscriber } from "../../functionUtils";
7
+ import { findChild } from "./utils";
6
8
 
7
9
  const { FocusableManagerModule } = NativeModules;
8
10
 
@@ -52,10 +54,7 @@ export const focusManager = (function () {
52
54
  const node = focusableTree.findInTree(groupId);
53
55
 
54
56
  if (node?.children?.length > 0) {
55
- const preferredFocus = R.compose(
56
- R.find(R.pathEq(["component", "props", "preferredFocus"], true)),
57
- R.prop("children")
58
- )(node);
57
+ const preferredFocus = findChild(true, node);
59
58
 
60
59
  if (preferredFocus?.component?.isGroup) {
61
60
  return getPreferredFocusInGroup({ groupId: preferredFocus?.id });
@@ -382,6 +381,16 @@ export const focusManager = (function () {
382
381
  forceFocusOnItem({ focusableItem, callback });
383
382
  }
384
383
 
384
+ function getPreferredFocusChild(id) {
385
+ const node = focusableTree.findInTree(id);
386
+
387
+ if (node?.children?.length > 0) {
388
+ return findChild(true, node) || findChild(false, node);
389
+ }
390
+
391
+ return node;
392
+ }
393
+
385
394
  return {
386
395
  on,
387
396
  invokeHandler,
@@ -402,5 +411,6 @@ export const focusManager = (function () {
402
411
  getCurrentGroup,
403
412
  getGroupRootById,
404
413
  isGroupItemFocused,
414
+ getPreferredFocusChild,
405
415
  };
406
416
  })();