@applicaster/zapp-react-native-utils 13.0.0-rc.9 → 13.0.0-rc.91

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 (158) hide show
  1. package/README.md +0 -10
  2. package/actionsExecutor/ActionExecutor.ts +16 -9
  3. package/actionsExecutor/ActionExecutorContext.tsx +164 -11
  4. package/alertUtils/alert.ts +148 -0
  5. package/alertUtils/index.ts +1 -148
  6. package/analyticsUtils/AnalyticPlayerListener.ts +18 -1
  7. package/analyticsUtils/__tests__/__snapshots__/analyticsManagerNoModule.test.js.snap +9 -9
  8. package/analyticsUtils/currentScreenProperities.ts +6 -4
  9. package/analyticsUtils/helpers/hooks.ts +1 -1
  10. package/appUtils/HooksManager/{Hook.js → Hook.ts} +39 -23
  11. package/appUtils/HooksManager/__tests__/__snapshots__/hook.test.js.snap +10 -8
  12. package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +693 -0
  13. package/appUtils/HooksManager/__tests__/hook.test.js +196 -184
  14. package/appUtils/HooksManager/__tests__/hooksManager.test.js +96 -99
  15. package/appUtils/HooksManager/{constants.js → constants.ts} +1 -1
  16. package/appUtils/HooksManager/{index.js → index.ts} +124 -113
  17. package/appUtils/HooksManager/types.ts +119 -0
  18. package/appUtils/RiverFocusManager/index.js +17 -12
  19. package/appUtils/accessibilityManager/index.ts +42 -1
  20. package/appUtils/contextKeysManager/contextResolver.ts +66 -0
  21. package/appUtils/contextKeysManager/index.ts +2 -2
  22. package/appUtils/contextKeysManager/utils/index.ts +2 -1
  23. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +7 -6
  24. package/appUtils/focusManager/index.ts +100 -74
  25. package/appUtils/focusManager/treeDataStructure/Tree/index.js +25 -3
  26. package/appUtils/focusManager/treeDataStructure/Utils/index.js +1 -3
  27. package/appUtils/focusManager/utils/enums.ts +4 -0
  28. package/appUtils/focusManagerAux/utils/index.ts +4 -3
  29. package/appUtils/{index.js → index.ts} +1 -1
  30. package/appUtils/keyCodes/__tests__/__snapshots__/keyCodes.test.js.snap +2 -2
  31. package/appUtils/keyCodes/__tests__/keyCodes.test.js +4 -4
  32. package/appUtils/keyCodes/{index.js → index.ts} +13 -7
  33. package/appUtils/keyCodes/keys/index.ts +3 -0
  34. package/appUtils/keyCodes/{keys.android.js → keys/keyEventMapper.ts} +0 -19
  35. package/appUtils/keyCodes/keys/keys.android.ts +18 -0
  36. package/appUtils/keyCodes/keys/keys.ios.ts +25 -0
  37. package/appUtils/keyCodes/keys/keys.ts +15 -0
  38. package/appUtils/keyCodes/{keysByPlatform.js → keys/keysByPlatform.ts} +4 -0
  39. package/appUtils/keyCodes/keysByPlatform.ts +8 -0
  40. package/appUtils/keyInputHandler/KeyInputHandler.ts +68 -0
  41. package/appUtils/orientationHelper.ts +11 -13
  42. package/appUtils/platform/const.ts +14 -0
  43. package/appUtils/platform/platformUtils.ts +47 -18
  44. package/appUtils/playerManager/index.ts +1 -1
  45. package/appUtils/playerManager/player.ts +42 -18
  46. package/appUtils/playerManager/playerNative.ts +18 -2
  47. package/appUtils/playerManager/usePlayerControllerSetup.tsx +3 -3
  48. package/arrayUtils/__tests__/__snapshots__/arrayUtils.test.ts.snap +4 -4
  49. package/dateUtils/index.ts +2 -0
  50. package/domUtils/{cookieManager.js → cookieManager.ts} +1 -2
  51. package/equalUtils/__tests__/isEqual/combination.test.ts +263 -0
  52. package/equalUtils/index.ts +49 -30
  53. package/focusManager/FocusManager.ts +14 -2
  54. package/focusManager/index.ts +23 -4
  55. package/functionUtils/__tests__/__snapshots__/functionUtils.test.js.snap +4 -4
  56. package/functionUtils/index.ts +61 -19
  57. package/idleUtils/__tests__/withTimeout$.test.ts +37 -0
  58. package/idleUtils/index.ts +1 -1
  59. package/idleUtils/withTimeout.ts +15 -2
  60. package/index.d.ts +0 -12
  61. package/logger/const.ts +9 -67
  62. package/manifestUtils/__tests__/createConfig.test.js +16 -16
  63. package/manifestUtils/defaultManifestConfigurations/player.js +8 -0
  64. package/manifestUtils/fonts/index.js +5 -6
  65. package/manifestUtils/sharedConfiguration/screenPicker/__tests__/utils.test.js +304 -0
  66. package/manifestUtils/sharedConfiguration/screenPicker/stylesFields.js +875 -0
  67. package/manifestUtils/sharedConfiguration/screenPicker/utils.js +130 -0
  68. package/modalState/index.ts +1 -5
  69. package/navigationUtils/__tests__/__snapshots__/navigationUtils.test.js.snap +6 -6
  70. package/navigationUtils/__tests__/itemTypes.test.js +2 -2
  71. package/navigationUtils/__tests__/navigationUtils.test.js +2 -2
  72. package/navigationUtils/index.ts +17 -8
  73. package/numberUtils/index.ts +7 -5
  74. package/package.json +5 -10
  75. package/playerUtils/configurationGenerator.ts +8 -0
  76. package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
  77. package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +6 -8
  78. package/reactHooks/autoscrolling/useTrackedView.ts +12 -1
  79. package/reactHooks/cell-click/__tests__/index.test.js +10 -2
  80. package/reactHooks/cell-click/index.ts +7 -1
  81. package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +4 -4
  82. package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +10 -11
  83. package/reactHooks/feed/useFeedLoader.tsx +5 -3
  84. package/reactHooks/feed/usePipesCacheReset.ts +5 -5
  85. package/reactHooks/flatList/__tests__/index.test.tsx +30 -21
  86. package/reactHooks/hookModal/hooks/useHookModalScreenData.ts +39 -0
  87. package/reactHooks/layout/__tests__/index.test.tsx +10 -10
  88. package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.native.test.js +14 -28
  89. package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.test.js +1 -1
  90. package/reactHooks/layout/useDimensions/useDimensions.ts +8 -0
  91. package/reactHooks/navigation/__mocks__/useNavigation.ts +3 -0
  92. package/reactHooks/navigation/__tests__/index.test.tsx +6 -21
  93. package/reactHooks/navigation/index.ts +41 -240
  94. package/reactHooks/navigation/useGetBottomTabBarHeight.ts +12 -0
  95. package/reactHooks/navigation/useGetNavBarTopBorderWidth.ts +14 -0
  96. package/reactHooks/navigation/useGetTabBarHeight.ts +10 -0
  97. package/reactHooks/navigation/useIsScreenActive.ts +17 -0
  98. package/reactHooks/navigation/useNavigationPluginData.ts +15 -0
  99. package/reactHooks/navigation/useNavigationType.ts +15 -0
  100. package/reactHooks/navigation/usePathname.ts +4 -0
  101. package/reactHooks/navigation/useProfilerLogging.ts +15 -0
  102. package/reactHooks/navigation/useRoute.ts +98 -0
  103. package/reactHooks/navigation/useUniqueRouteSuffix.ts +41 -0
  104. package/reactHooks/player/TVSeekControlller/ISeekController.ts +32 -0
  105. package/reactHooks/player/TVSeekControlller/LongPressSeekController.ts +71 -0
  106. package/reactHooks/player/TVSeekControlller/TVSeekController.ts +258 -0
  107. package/reactHooks/player/TVSeekControlller/TapSeekController.ts +53 -0
  108. package/reactHooks/player/__tests__/{useAutoSeek.test.tsx → useAutoSeek._test.tsx} +2 -3
  109. package/reactHooks/player/const.ts +0 -4
  110. package/reactHooks/player/index.ts +0 -6
  111. package/reactHooks/state/useRefWithInitialValue.ts +14 -0
  112. package/reactHooks/state/useStateFromSubscribe.ts +23 -0
  113. package/reactHooks/usePluginConfiguration.ts +1 -1
  114. package/reactHooks/useSubscriberFor.ts +4 -3
  115. package/reactUtils/__tests__/__snapshots__/reactUtilsHelpers.test.js.snap +16 -4
  116. package/reactUtils/__tests__/reactUtils.test.js +1 -37
  117. package/reactUtils/__tests__/reactUtilsHelpers.test.js +72 -71
  118. package/reactUtils/createContext/__tests__/__snapshots__/helpers.test.js.snap +13 -79
  119. package/reactUtils/createContext/__tests__/__snapshots__/{index.test.js.snap → index.test.ts.snap} +2 -2
  120. package/reactUtils/createContext/__tests__/__snapshots__/provider.test.js.snap +3 -28
  121. package/reactUtils/createContext/__tests__/__snapshots__/withConsumer.test.js.snap +3 -4
  122. package/reactUtils/createContext/__tests__/__snapshots__/withProvider.test.js.snap +7 -3
  123. package/reactUtils/createContext/__tests__/helpers.test.js +107 -121
  124. package/reactUtils/createContext/__tests__/{index.test.js → index.test.ts} +2 -2
  125. package/reactUtils/createContext/__tests__/provider.test.js +4 -6
  126. package/reactUtils/createContext/__tests__/withConsumer.test.js +12 -12
  127. package/reactUtils/createContext/__tests__/withProvider.test.js +4 -4
  128. package/reactUtils/createContext/helpers.ts +6 -1
  129. package/reactUtils/createContext/index.ts +11 -25
  130. package/reactUtils/index.ts +0 -25
  131. package/screenState/index.ts +24 -10
  132. package/services/js2native.ts +673 -0
  133. package/testUtils/index.tsx +0 -10
  134. package/theme/__mocks__/index.ts +4 -0
  135. package/theme/index.ts +1 -1
  136. package/time/BackgroundTimer.ts +55 -0
  137. package/time/Timer.ts +9 -6
  138. package/types.ts +1 -0
  139. package/utils/README.md +30 -0
  140. package/utils/chunk.ts +5 -0
  141. package/utils/index.ts +5 -0
  142. package/utils/times.ts +5 -0
  143. package/zappFrameworkUtils/localStorageHelper.ts +6 -0
  144. package/zappFrameworkUtils/loginPluginUtils.ts +6 -2
  145. package/zappFrameworkUtils/presentPluginOneTime.ts +2 -3
  146. package/zappFrameworkUtils/types.ts +11 -0
  147. package/appUtils/keyCodes/keys.ios.js +0 -46
  148. package/reactHooks/player/useAutoSeek.tsx +0 -87
  149. package/reactHooks/player/useSeek.tsx +0 -66
  150. package/reactHooks/player/useTapSeek.tsx +0 -58
  151. package/reactUtils/createContext/__tests__/index-no-react.test.js +0 -27
  152. /package/appUtils/HooksManager/{logger.js → logger.ts} +0 -0
  153. /package/appUtils/{directionHelper.js → directionHelper.ts} +0 -0
  154. /package/appUtils/keyCodes/{androidTVKeys.js → androidTVKeys.ts} +0 -0
  155. /package/appUtils/keyCodes/{keys.web.js → keys/keys.web.ts} +0 -0
  156. /package/appUtils/{localizationsHelper.js → localizationsHelper.ts} +0 -0
  157. /package/domUtils/{logger.js → logger.ts} +0 -0
  158. /package/reactHooks/player/__tests__/{useTapSeek.test.ts → useTapSeek._test.ts} +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`
@@ -17,9 +17,10 @@ class ActionExecutor {
17
17
 
18
18
  handleAction = async (
19
19
  action: ActionType,
20
- entry: ZappEntry = null
20
+ context?: Record<string, any>
21
21
  ): Promise<ActionResult> => {
22
22
  const handler = this.registeredActions[action.type];
23
+ const entry = context?.entry as ZappEntry;
23
24
 
24
25
  if (!handler) {
25
26
  log_error(
@@ -38,11 +39,11 @@ class ActionExecutor {
38
39
  );
39
40
 
40
41
  try {
41
- return handler(action, entry);
42
+ return handler(action, context);
42
43
  } catch (error) {
43
44
  log_error(
44
45
  `handleAction: error handling action type: ${action.type}, message: ${error.message}`,
45
- { action, entry, error }
46
+ { action, context, error }
46
47
  );
47
48
 
48
49
  throw error;
@@ -51,11 +52,11 @@ class ActionExecutor {
51
52
 
52
53
  handleActions = async (
53
54
  actionTypes: ActionType[],
54
- entry: ZappEntry = null
55
+ context?: Record<string, any>
55
56
  ): Promise<ActionResult> => {
56
57
  for (const action of actionTypes) {
57
58
  // TODO: Handle action result error
58
- const result = await this.handleAction(action, entry);
59
+ const result = await this.handleAction(action, context);
59
60
 
60
61
  if (result === ActionResult.Cancel) {
61
62
  log_info(`handleActions: action: ${action.type} canceled`);
@@ -67,7 +68,10 @@ class ActionExecutor {
67
68
  return ActionResult.Success;
68
69
  };
69
70
 
70
- handleEntryActions = async (entry: ZappEntry): Promise<ActionResult> => {
71
+ handleEntryActions = async (
72
+ entry: ZappEntry,
73
+ context?: Record<string, any>
74
+ ): Promise<ActionResult> => {
71
75
  const tapActions = entry.extensions?.tap_actions?.actions;
72
76
 
73
77
  if (!tapActions) {
@@ -77,7 +81,7 @@ class ActionExecutor {
77
81
  if (!Array.isArray(tapActions)) {
78
82
  log_error(
79
83
  `handleEntryActions: tapActions is not an array for id: ${entry.id} title: ${entry.title}`,
80
- { entry }
84
+ { context, entry }
81
85
  );
82
86
 
83
87
  return;
@@ -87,7 +91,7 @@ class ActionExecutor {
87
91
  return;
88
92
  }
89
93
 
90
- await this.handleActions(tapActions, entry);
94
+ await this.handleActions(tapActions, { ...context, entry });
91
95
  };
92
96
 
93
97
  unregisterAction = (actionType: string) => {
@@ -96,7 +100,10 @@ class ActionExecutor {
96
100
 
97
101
  registerAction = (
98
102
  type: string,
99
- handler: (action: ActionType, entry?: ZappEntry) => Promise<ActionResult>
103
+ handler: (
104
+ action: ActionType,
105
+ context?: Record<string, any>
106
+ ) => Promise<ActionResult>
100
107
  ) => {
101
108
  if (this.registeredActions[type]) {
102
109
  log_error(`registerAction: action type: ${type} already registered`);
@@ -1,6 +1,6 @@
1
1
  /// <reference types="@applicaster/applicaster-types" />
2
-
3
- import React, { createContext, useMemo } from "react";
2
+ import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
3
+ import React, { createContext, useEffect, useMemo } from "react";
4
4
  import {
5
5
  actionExecutor as _actionExecutor,
6
6
  ActionResult,
@@ -12,8 +12,22 @@ import { showConfirmationDialog } from "../alertUtils";
12
12
  import { createCloudEvent, sendCloudEvent } from "../cloudEventsUtils";
13
13
  import { createLogger } from "../logger";
14
14
  import { StorageMultiSelectProvider } from "@applicaster/zapp-react-native-bridge/ZappStorage/StorageMultiSelectProvider";
15
+ import { ACTIVE_LAYOUT_ID_STORAGE_KEY } from "@applicaster/quick-brick-core/App/remoteContextReloader/consts";
16
+ import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
17
+ import { loadPipesData } from "@applicaster/zapp-react-native-redux/ZappPipes";
18
+ import {
19
+ EntryResolver,
20
+ resolveObjectValues,
21
+ } from "../appUtils/contextKeysManager/contextResolver";
22
+ import { useNavigation } from "../reactHooks";
23
+ import { get } from "lodash";
24
+
25
+ import {
26
+ useContentTypes,
27
+ usePickFromState,
28
+ } from "@applicaster/zapp-react-native-redux/hooks";
15
29
 
16
- const { log_error, log_info } = createLogger({
30
+ export const { log_error, log_info, log_debug } = createLogger({
17
31
  subsystem: "ActionExecutorContext",
18
32
  category: "General",
19
33
  });
@@ -21,20 +35,45 @@ const { log_error, log_info } = createLogger({
21
35
  type ActionExecutorContextType = {
22
36
  registerAction: (
23
37
  type: string,
24
- handler: (action: ActionType, entry: ZappEntry) => Promise<ActionResult>
38
+ handler: (
39
+ action: ActionType,
40
+ context?: Record<string, any>
41
+ ) => Promise<ActionResult>
25
42
  ) => void;
26
43
  unregisterAction: (type: string) => void;
27
- handleAction: (action: ActionType, entry: ZappEntry) => Promise<ActionResult>;
44
+ handleAction: (
45
+ action: ActionType,
46
+ context?: Record<string, any>
47
+ ) => Promise<ActionResult>;
28
48
  handleActions: (
29
49
  actions: ActionType[],
30
- entry: ZappEntry
50
+ context: Record<string, any>
51
+ ) => Promise<ActionResult>;
52
+ handleEntryActions: (
53
+ entry: ZappEntry,
54
+ context?: Record<string, any>
31
55
  ) => Promise<ActionResult>;
32
- handleEntryActions: (entry: ZappEntry) => Promise<ActionResult>;
33
56
  };
34
57
  type Props = {
35
58
  children: React.ReactNode;
36
59
  };
37
60
 
61
+ function findParentComponent(
62
+ childId: string,
63
+ parent: ZappRiver | ZappUIComponent
64
+ ): ZappRiver | ZappUIComponent | null {
65
+ for (const child of parent.ui_components) {
66
+ if (child.id === childId) return parent;
67
+
68
+ if (child.ui_components) {
69
+ const found = findParentComponent(childId, child);
70
+ if (found) return found;
71
+ }
72
+ }
73
+
74
+ return null;
75
+ }
76
+
38
77
  const prepareDefaultActions = (actionExecutor) => {
39
78
  actionExecutor.registerAction("localStorageSet", async (action) => {
40
79
  const namespaces = action.options.content;
@@ -44,6 +83,46 @@ const prepareDefaultActions = (actionExecutor) => {
44
83
  return ActionResult.Success;
45
84
  });
46
85
 
86
+ actionExecutor.registerAction(
87
+ "refreshComponent",
88
+ async (_action, context) => {
89
+ const dispatch = appStore.getDispatch();
90
+
91
+ const dataSource =
92
+ context?.component?.data?.source ||
93
+ findParentComponent(context?.component.id, context?.screenData)?.data
94
+ ?.source;
95
+
96
+ log_info(`handleAction: refreshComponent for dataSource:${dataSource}`);
97
+
98
+ // TODO: In theory we should wait callback to complete, before completing the action, but now it's not needed
99
+ // TODO: handle focused item removal
100
+ dispatch(
101
+ loadPipesData(dataSource, {
102
+ silentRefresh: false,
103
+ clearCache: true,
104
+ callback: (_data) => {},
105
+ riverId: context?.screenData?.id,
106
+ })
107
+ );
108
+
109
+ return ActionResult.Success;
110
+ }
111
+ );
112
+
113
+ actionExecutor.registerAction("switchLayout", async (action) => {
114
+ log_info("handleAction: switchLayout event");
115
+
116
+ await localStorage.setItem(
117
+ ACTIVE_LAYOUT_ID_STORAGE_KEY,
118
+ action.options.layoutId
119
+ );
120
+
121
+ QuickBrickManager.sendQuickBrickEvent(QUICK_BRICK_EVENTS.FORCE_APP_RELOAD);
122
+
123
+ return ActionResult.Success;
124
+ });
125
+
47
126
  actionExecutor.registerAction("appRestart", async () => {
48
127
  log_info(`handleAction: ${QUICK_BRICK_EVENTS.FORCE_APP_RELOAD} event`);
49
128
 
@@ -66,13 +145,21 @@ const prepareDefaultActions = (actionExecutor) => {
66
145
  return confirmationPromise;
67
146
  });
68
147
 
69
- actionExecutor.registerAction("sendCloudEvent", async (action, entry) => {
148
+ actionExecutor.registerAction("sendCloudEvent", async (action, context) => {
70
149
  try {
71
150
  const options = action.options;
72
151
 
152
+ const entry = context?.entry || {};
153
+ const entryResolver = new EntryResolver(entry);
154
+
155
+ const data =
156
+ options?.data && options.inflateData
157
+ ? await resolveObjectValues(options.data, { entry: entryResolver })
158
+ : options?.data || entry;
159
+
73
160
  const cloudEvent = await createCloudEvent({
74
161
  type: options.type || "com.applicaster.selector.action.v1",
75
- data: options.data || entry,
162
+ data,
76
163
  subject: options.subject || entry?.id,
77
164
  });
78
165
 
@@ -103,9 +190,33 @@ const prepareDefaultActions = (actionExecutor) => {
103
190
 
104
191
  actionExecutor.registerAction(
105
192
  "localStorageToggleFlag",
106
- async (action: ActionType, entry?: ZappEntry): Promise<ActionResult> => {
193
+ async (
194
+ action: ActionType,
195
+ context?: Record<string, any>
196
+ ): Promise<ActionResult> => {
197
+ if (!context) {
198
+ log_error(
199
+ "handleAction: localStorageToggleFlag action missing context"
200
+ );
201
+
202
+ return ActionResult.Error;
203
+ }
204
+
205
+ const entry = context?.entry as ZappEntry;
206
+
207
+ if (!entry) {
208
+ log_error(
209
+ "handleAction: localStorageToggleFlag action missing entry. Entry is required to get the tag."
210
+ );
211
+
212
+ return ActionResult.Error;
213
+ }
214
+
215
+ const tag = action.options?.selector
216
+ ? get(entry, action.options.selector)
217
+ : (entry.extensions?.tag ?? entry.id);
218
+
107
219
  const keyNamespace = action.options?.key;
108
- const tag = entry?.extensions?.tag;
109
220
 
110
221
  if (keyNamespace && tag) {
111
222
  const multiSelectProvider =
@@ -146,6 +257,10 @@ export function withActionExecutor(Component) {
146
257
  prepareDefaultActions(_actionExecutor);
147
258
 
148
259
  return function ActionExecutorComponent(props: Props) {
260
+ const navigator = useNavigation();
261
+ const { rivers } = usePickFromState(["rivers"]);
262
+ const contentTypes = useContentTypes();
263
+
149
264
  const handlers = useMemo(() => {
150
265
  return {
151
266
  unregisterAction: _actionExecutor.unregisterAction,
@@ -156,6 +271,44 @@ export function withActionExecutor(Component) {
156
271
  };
157
272
  }, []);
158
273
 
274
+ useEffect(() => {
275
+ return _actionExecutor.registerAction(
276
+ "navigateToScreen",
277
+ async (action: ActionType, context?: Record<string, any>) => {
278
+ const screenType = action.options?.typeMapping;
279
+
280
+ if (!screenType) {
281
+ log_error("navigateToScreen: typeMapping option is missing");
282
+
283
+ return ActionResult.Error;
284
+ }
285
+
286
+ const screenId = contentTypes?.[screenType]?.screen_id || null;
287
+
288
+ if (!screenId) {
289
+ log_error(
290
+ `navigateToScreen: can not resolve screen type mapping: ${screenType}`
291
+ );
292
+
293
+ return ActionResult.Error;
294
+ }
295
+
296
+ const river = rivers[screenId];
297
+
298
+ if (!river) {
299
+ log_error("navigateToScreen: can not resolve river");
300
+
301
+ return ActionResult.Error;
302
+ }
303
+
304
+ context?.callback?.({ success: false, error: null, abort: true });
305
+ navigator.replace(river);
306
+
307
+ return ActionResult.Success;
308
+ }
309
+ );
310
+ }, [navigator, rivers, contentTypes]);
311
+
159
312
  return (
160
313
  <ActionExecutorContext.Provider value={handlers}>
161
314
  <Component {...props} />
@@ -0,0 +1,148 @@
1
+ import { Alert } from "react-native";
2
+ import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
3
+ import { confirmationDialogStore } from "@applicaster/zapp-react-native-ui-components/Contexts/ConfirmDialogState";
4
+
5
+ // #region "Alert Dialog"
6
+
7
+ const globalAny: any = global;
8
+
9
+ const showWebAlertDialog = ({ message, completion }: AlertWebDialog) => {
10
+ globalAny?.alert?.(message);
11
+ completion?.();
12
+ };
13
+
14
+ const showNativeAlertDialog = ({
15
+ title,
16
+ message,
17
+ okButtonText,
18
+ completion,
19
+ }: AlertDialogType) => {
20
+ Alert.alert(title, message, [
21
+ {
22
+ text: okButtonText,
23
+ onPress: completion,
24
+ },
25
+ ]);
26
+ };
27
+
28
+ export const showAlertDialog = ({
29
+ title,
30
+ message,
31
+ okButtonText,
32
+ completion,
33
+ }: AlertDialogType) => {
34
+ if (isWeb()) {
35
+ showWebAlertDialog({ message, completion });
36
+ } else {
37
+ showNativeAlertDialog({
38
+ title,
39
+ message,
40
+ okButtonText,
41
+ completion,
42
+ });
43
+ }
44
+ };
45
+
46
+ // #endregion "Alert Dialog"
47
+
48
+ // #region "Confirmation Dialog"
49
+
50
+ const showWebDialog = ({
51
+ message,
52
+ confirmCompletion,
53
+ cancelCompletion,
54
+ }: WebConfirmationDialog) => {
55
+ const isConfirmed = globalAny?.confirm?.(message);
56
+
57
+ if (isConfirmed) {
58
+ confirmCompletion?.();
59
+ } else {
60
+ cancelCompletion?.();
61
+ }
62
+ };
63
+
64
+ const showNativeDialog = ({
65
+ title,
66
+ message,
67
+ okButtonText,
68
+ cancelButtonText,
69
+ confirmCompletion,
70
+ cancelCompletion,
71
+ }: ConfirmationDialog) => {
72
+ Alert.alert(title, message, [
73
+ {
74
+ text: cancelButtonText,
75
+ onPress: cancelCompletion,
76
+ },
77
+ {
78
+ text: okButtonText,
79
+ style: "destructive",
80
+ onPress: confirmCompletion,
81
+ },
82
+ ]);
83
+ };
84
+
85
+ const handleCustomDialog = (data) => {
86
+ const {
87
+ showDialog,
88
+ hideDialog,
89
+ setConfirmAction,
90
+ setCancelAction,
91
+ setMessages,
92
+ } = confirmationDialogStore.getState();
93
+
94
+ setMessages(data.messages);
95
+
96
+ if (data?.cancelCompletion) {
97
+ setCancelAction(() => {
98
+ data.cancelCompletion();
99
+ hideDialog();
100
+ });
101
+ }
102
+
103
+ if (data?.confirmCompletion) {
104
+ setConfirmAction(() => {
105
+ data.confirmCompletion();
106
+ hideDialog();
107
+ });
108
+ }
109
+
110
+ showDialog();
111
+ };
112
+
113
+ export const showConfirmationDialog = ({
114
+ title,
115
+ message,
116
+ okButtonText,
117
+ cancelButtonText,
118
+ confirmCompletion,
119
+ cancelCompletion,
120
+ }: CustomConfirmationDialog): void => {
121
+ if (isWeb()) {
122
+ if (cancelCompletion) {
123
+ handleCustomDialog({
124
+ messages: {
125
+ title,
126
+ message,
127
+ okButtonText,
128
+ cancelButtonText,
129
+ },
130
+ confirmCompletion,
131
+ cancelCompletion,
132
+ });
133
+ } else {
134
+ showWebDialog({ message, confirmCompletion, cancelCompletion });
135
+ }
136
+ } else {
137
+ showNativeDialog({
138
+ title,
139
+ message,
140
+ okButtonText,
141
+ cancelButtonText,
142
+ confirmCompletion,
143
+ cancelCompletion,
144
+ });
145
+ }
146
+ };
147
+
148
+ // #endregion "Confirmation Dialog"
@@ -1,148 +1 @@
1
- import { Alert } from "react-native";
2
- import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
3
- import { confirmationDialogStore } from "@applicaster/zapp-react-native-ui-components/Contexts/ConfirmDialogState";
4
-
5
- // #region "Alert Dialog"
6
-
7
- const globalAny: any = global;
8
-
9
- const showWebAlertDialog = ({ message, completion }: AlertWebDialog) => {
10
- globalAny?.alert?.(message);
11
- completion?.();
12
- };
13
-
14
- const showNativeAlertDialog = ({
15
- title,
16
- message,
17
- okButtonText,
18
- completion,
19
- }: AlertDialogType) => {
20
- Alert.alert(title, message, [
21
- {
22
- text: okButtonText,
23
- onPress: completion,
24
- },
25
- ]);
26
- };
27
-
28
- export const showAlertDialog = ({
29
- title,
30
- message,
31
- okButtonText,
32
- completion,
33
- }: AlertDialogType) => {
34
- if (isWeb()) {
35
- showWebAlertDialog({ message, completion });
36
- } else {
37
- showNativeAlertDialog({
38
- title,
39
- message,
40
- okButtonText,
41
- completion,
42
- });
43
- }
44
- };
45
-
46
- // #endregion "Alert Dialog"
47
-
48
- // #region "Confirmation Dialog"
49
-
50
- const showWebDialog = ({
51
- message,
52
- confirmCompletion,
53
- cancelCompletion,
54
- }: WebConfirmationDialog) => {
55
- const isConfirmed = globalAny?.confirm?.(message);
56
-
57
- if (isConfirmed) {
58
- confirmCompletion?.();
59
- } else {
60
- cancelCompletion?.();
61
- }
62
- };
63
-
64
- const showNativeDialog = ({
65
- title,
66
- message,
67
- okButtonText,
68
- cancelButtonText,
69
- confirmCompletion,
70
- cancelCompletion,
71
- }: ConfirmationDialog) => {
72
- Alert.alert(title, message, [
73
- {
74
- text: cancelButtonText,
75
- onPress: cancelCompletion,
76
- },
77
- {
78
- text: okButtonText,
79
- style: "destructive",
80
- onPress: confirmCompletion,
81
- },
82
- ]);
83
- };
84
-
85
- const handleCustomDialog = (data) => {
86
- const {
87
- showDialog,
88
- hideDialog,
89
- setConfirmAction,
90
- setCancelAction,
91
- setMessages,
92
- } = confirmationDialogStore.getState();
93
-
94
- setMessages(data.messages);
95
-
96
- if (data?.cancelCompletion) {
97
- setCancelAction(() => {
98
- data.cancelCompletion();
99
- hideDialog();
100
- });
101
- }
102
-
103
- if (data?.confirmCompletion) {
104
- setConfirmAction(() => {
105
- data.confirmCompletion();
106
- hideDialog();
107
- });
108
- }
109
-
110
- showDialog();
111
- };
112
-
113
- export const showConfirmationDialog = ({
114
- title,
115
- message,
116
- okButtonText,
117
- cancelButtonText,
118
- confirmCompletion,
119
- cancelCompletion,
120
- }: CustomConfirmationDialog): void => {
121
- if (isWeb()) {
122
- if (cancelCompletion) {
123
- handleCustomDialog({
124
- messages: {
125
- title,
126
- message,
127
- okButtonText,
128
- cancelButtonText,
129
- },
130
- confirmCompletion,
131
- cancelCompletion,
132
- });
133
- } else {
134
- showWebDialog({ message, confirmCompletion, cancelCompletion });
135
- }
136
- } else {
137
- showNativeDialog({
138
- title,
139
- message,
140
- okButtonText,
141
- cancelButtonText,
142
- confirmCompletion,
143
- cancelCompletion,
144
- });
145
- }
146
- };
147
-
148
- // #endregion "Confirmation Dialog"
1
+ export { showAlertDialog, showConfirmationDialog } from "./alert";
@@ -14,7 +14,7 @@ export class AnalyticPlayerListener
14
14
  static analyticsListenerID = "analytics-listener";
15
15
  private analyticsTracker: PlayerAnalyticsTracker;
16
16
  private player: Player;
17
-
17
+ private isSeeking: boolean = false;
18
18
  private onVideoLoadCalled; // android only
19
19
 
20
20
  constructor(props: Props) {
@@ -40,10 +40,27 @@ export class AnalyticPlayerListener
40
40
  };
41
41
 
42
42
  onPlayerPause = (event) => {
43
+ if (this.player?.seekController?.isSeeking()) {
44
+ this.isSeeking = true;
45
+
46
+ return;
47
+ }
48
+
43
49
  this.handleAnalyticEvent(PLAYBACK_EVENT.pause, event);
44
50
  };
45
51
 
46
52
  onPlayerResume = (event) => {
53
+ if (this.player?.seekController?.isSeeking()) {
54
+ return;
55
+ }
56
+
57
+ if (this.isSeeking) {
58
+ // Fallback due to player resume event been async and arriving with delays
59
+ this.isSeeking = false;
60
+
61
+ return;
62
+ }
63
+
47
64
  this.handleAnalyticEvent(PLAYBACK_EVENT.play, event);
48
65
  };
49
66
 
@@ -1,24 +1,24 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`AnalyticsManager - with undefined Native Module doesn't crash when calling the methods 1`] = `
4
- Array [
5
- Array [
6
- Object {
4
+ [
5
+ [
6
+ {
7
7
  "message": "Analytics Bridge is missing - no event will be sent",
8
8
  },
9
9
  ],
10
- Array [
11
- Object {
10
+ [
11
+ {
12
12
  "message": "Analytics Bridge is missing - no event will be sent",
13
13
  },
14
14
  ],
15
- Array [
16
- Object {
15
+ [
16
+ {
17
17
  "message": "Analytics Bridge is missing - no event will be sent",
18
18
  },
19
19
  ],
20
- Array [
21
- Object {
20
+ [
21
+ {
22
22
  "message": "Analytics Bridge is missing - no event will be sent",
23
23
  },
24
24
  ],