@applicaster/zapp-react-native-utils 15.0.0-alpha.1456157166 → 15.0.0-alpha.1615225514

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 (101) hide show
  1. package/actionsExecutor/ActionExecutorContext.tsx +3 -6
  2. package/actionsExecutor/feedDecorator.ts +6 -6
  3. package/adsUtils/index.ts +2 -2
  4. package/analyticsUtils/AnalyticPlayerListener.ts +5 -2
  5. package/analyticsUtils/README.md +1 -1
  6. package/analyticsUtils/analyticsMapper.ts +10 -2
  7. package/appUtils/HooksManager/index.ts +10 -10
  8. package/appUtils/RiverFocusManager/{index.js → index.ts} +25 -18
  9. package/appUtils/accessibilityManager/__tests__/utils.test.ts +360 -0
  10. package/appUtils/accessibilityManager/const.ts +4 -0
  11. package/appUtils/accessibilityManager/hooks.ts +20 -13
  12. package/appUtils/accessibilityManager/index.ts +28 -1
  13. package/appUtils/accessibilityManager/utils.ts +59 -8
  14. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +4 -0
  15. package/appUtils/focusManager/index.ios.ts +59 -3
  16. package/appUtils/focusManagerAux/utils/index.ios.ts +122 -0
  17. package/appUtils/focusManagerAux/utils/index.ts +19 -1
  18. package/appUtils/focusManagerAux/utils/utils.ios.ts +231 -0
  19. package/appUtils/keyCodes/keys/keys.web.ts +1 -4
  20. package/appUtils/orientationHelper.ts +2 -4
  21. package/appUtils/platform/platformUtils.ts +117 -18
  22. package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +94 -4
  23. package/appUtils/playerManager/OverlayObserver/utils.ts +32 -20
  24. package/appUtils/playerManager/conts.ts +21 -0
  25. package/appUtils/playerManager/player.ts +4 -0
  26. package/appUtils/playerManager/playerNative.ts +29 -16
  27. package/appUtils/playerManager/usePlayerState.tsx +14 -2
  28. package/arrayUtils/__tests__/allTruthy.test.ts +24 -0
  29. package/arrayUtils/__tests__/anyThruthy.test.ts +24 -0
  30. package/arrayUtils/index.ts +5 -0
  31. package/cellUtils/index.ts +32 -0
  32. package/configurationUtils/__tests__/manifestKeyParser.test.ts +26 -26
  33. package/focusManager/aux/index.ts +1 -1
  34. package/manifestUtils/defaultManifestConfigurations/player.js +96 -11
  35. package/manifestUtils/keys.js +21 -0
  36. package/manifestUtils/sharedConfiguration/screenPicker/utils.js +1 -0
  37. package/manifestUtils/tvAction/container/index.js +1 -1
  38. package/navigationUtils/index.ts +19 -16
  39. package/package.json +4 -4
  40. package/playerUtils/usePlayerTTS.ts +8 -3
  41. package/pluginUtils/index.ts +4 -0
  42. package/reactHooks/advertising/index.ts +2 -2
  43. package/reactHooks/app/__tests__/useAppState.test.ts +1 -1
  44. package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
  45. package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +1 -2
  46. package/reactHooks/cell-click/__tests__/index.test.js +1 -3
  47. package/reactHooks/configuration/__tests__/index.test.tsx +1 -1
  48. package/reactHooks/connection/__tests__/index.test.js +1 -1
  49. package/reactHooks/debugging/__tests__/index.test.js +4 -4
  50. package/reactHooks/device/useMemoizedIsTablet.ts +3 -3
  51. package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +32 -23
  52. package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +19 -19
  53. package/reactHooks/feed/__tests__/useEntryScreenId.test.tsx +4 -1
  54. package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +42 -30
  55. package/reactHooks/feed/__tests__/useFeedRefresh.test.tsx +1 -1
  56. package/reactHooks/feed/__tests__/{useInflatedUrl.test.ts → useInflatedUrl.test.tsx} +62 -7
  57. package/reactHooks/feed/useBatchLoading.ts +7 -1
  58. package/reactHooks/feed/useEntryScreenId.ts +2 -2
  59. package/reactHooks/feed/useInflatedUrl.ts +43 -17
  60. package/reactHooks/feed/usePipesCacheReset.ts +3 -1
  61. package/reactHooks/flatList/useLoadNextPageIfNeeded.ts +13 -16
  62. package/reactHooks/layout/__tests__/index.test.tsx +1 -1
  63. package/reactHooks/layout/__tests__/useLayoutVersion.test.tsx +1 -1
  64. package/reactHooks/layout/index.ts +1 -1
  65. package/reactHooks/layout/useDimensions/__tests__/{useDimensions.test.ts → useDimensions.test.tsx} +105 -25
  66. package/reactHooks/layout/useDimensions/useDimensions.ts +2 -2
  67. package/reactHooks/navigation/__tests__/index.test.tsx +1 -1
  68. package/reactHooks/navigation/index.ts +11 -6
  69. package/reactHooks/navigation/useRoute.ts +8 -6
  70. package/reactHooks/player/TVSeekControlller/TVSeekController.ts +27 -10
  71. package/reactHooks/player/__tests__/useAutoSeek._test.tsx +1 -1
  72. package/reactHooks/player/__tests__/useTapSeek._test.ts +1 -1
  73. package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +1 -1
  74. package/reactHooks/resolvers/__tests__/useComponentResolver.test.tsx +1 -1
  75. package/reactHooks/resolvers/useCellResolver.ts +6 -2
  76. package/reactHooks/resolvers/useComponentResolver.ts +8 -2
  77. package/reactHooks/screen/__tests__/useCurrentScreenData.test.tsx +2 -2
  78. package/reactHooks/screen/__tests__/useScreenBackgroundColor.test.tsx +1 -1
  79. package/reactHooks/screen/__tests__/useScreenData.test.tsx +1 -1
  80. package/reactHooks/screen/__tests__/useTargetScreenData.test.tsx +12 -4
  81. package/reactHooks/screen/useTargetScreenData.ts +4 -2
  82. package/reactHooks/state/useRivers.ts +1 -1
  83. package/reactHooks/usePluginConfiguration.ts +2 -2
  84. package/reactHooks/utils/__tests__/index.test.js +1 -1
  85. package/screenState/__tests__/index.test.ts +1 -1
  86. package/searchUtils/const.ts +7 -0
  87. package/searchUtils/index.ts +3 -0
  88. package/stringUtils/index.ts +1 -1
  89. package/testUtils/index.tsx +30 -21
  90. package/utils/__tests__/mapAccum.test.ts +73 -0
  91. package/utils/__tests__/mergeRight.test.ts +48 -0
  92. package/utils/__tests__/selectors.test.ts +124 -0
  93. package/utils/index.ts +20 -0
  94. package/utils/mapAccum.ts +23 -0
  95. package/utils/mergeRight.ts +5 -0
  96. package/utils/path.ts +6 -3
  97. package/utils/pathOr.ts +5 -1
  98. package/utils/selectors.ts +46 -0
  99. package/zappFrameworkUtils/HookCallback/callbackNavigationAction.ts +128 -38
  100. package/zappFrameworkUtils/HookCallback/hookCallbackManifestExtensions.config.js +26 -10
  101. package/zappFrameworkUtils/HookCallback/useCallbackActions.ts +6 -9
@@ -1,6 +1,6 @@
1
1
  import { useNavigation, useRivers, useScreenContext } from "../../reactHooks";
2
2
  import { createLogger } from "../../logger";
3
- import { useCallback, useMemo } from "react";
3
+ import { useCallback, useMemo, useRef, useEffect } from "react";
4
4
 
5
5
  export enum NavigationCallbackOptions {
6
6
  DEFAULT = "default",
@@ -9,10 +9,24 @@ export enum NavigationCallbackOptions {
9
9
  GO_TO_SCREEN = "go_to_screen",
10
10
  }
11
11
 
12
- export const CALLBACK_NAVIGATION_KEY = "hook_callback_navigation";
12
+ export enum ResultType {
13
+ login = "login",
14
+ logout = "logout",
15
+ }
16
+
17
+ export type CallbackResult = hookCallbackArgs & {
18
+ options?: {
19
+ resultType?: ResultType;
20
+ navigator?: QuickBrickAppNavigator;
21
+ };
22
+ };
23
+
24
+ export type ScreenResultCallback = (args: CallbackResult) => void | undefined;
25
+
26
+ export const CALLBACK_NAVIGATION_KEY = "completion_action";
13
27
 
14
28
  export const CALLBACK_NAVIGATION_GO_TO_SCREEN_KEY =
15
- "hook_callback_navigation_go_to_screen";
29
+ "completion_action_navigation_go_to_screen";
16
30
 
17
31
  type NavKeys = {
18
32
  action: NavigationCallbackOptions;
@@ -23,7 +37,7 @@ type General = Record<string, unknown>;
23
37
 
24
38
  const LogPrefix = "useCallbackNavigationAction:";
25
39
 
26
- const { log_info, log_verbose } = createLogger({
40
+ const { log_info, log_verbose, log_debug } = createLogger({
27
41
  subsystem: "hook-navigation-callback",
28
42
  });
29
43
 
@@ -32,53 +46,81 @@ const legacyMappingKeys = {
32
46
  actionType: "login_completion_action",
33
47
  targetScreen: "navigate_to_login_screen",
34
48
  },
35
- "quick-brick-user-account-ui-component": {
49
+ "quick-brick-user-account-ui-component.login": {
36
50
  actionType: "callbackAction",
37
51
  },
52
+ "quick-brick-login-multi-login-providers.login": {
53
+ actionType: "login_completion_action",
54
+ targetScreen: "navigate_to_login_screen",
55
+ },
56
+ "quick-brick-login-multi-login-providers.logout": {
57
+ actionType: "logout_completion_action",
58
+ targetScreen: "navigate_to_logout_screen",
59
+ },
60
+ "quick-brick-storefront": {
61
+ actionType: "purchase_completion_action",
62
+ targetScreen: "navigate_to_screen_after_purchase",
63
+ },
64
+ "zapp_login_plugin_oauth_tv_2_0.login": {
65
+ actionType: "login_completion_action",
66
+ targetScreen: "navigate_to_login_screen",
67
+ },
68
+ "zapp_login_plugin_oauth_tv_2_0.logout": {
69
+ actionType: "logout_completion_action",
70
+ targetScreen: "navigate_to_logout_screen",
71
+ },
38
72
  };
39
73
 
40
- const isNonEmptyString = (v: unknown): v is string =>
41
- typeof v === "string" && v.trim().length > 0;
42
-
43
- const NAV_ACTIONS = Object.values(NavigationCallbackOptions) as string[];
74
+ const NAV_ACTIONS = (
75
+ Object.values(NavigationCallbackOptions) as string[]
76
+ ).filter((value) => value !== NavigationCallbackOptions.DEFAULT);
44
77
 
45
78
  const isNavAction = (v: unknown): v is NavigationCallbackOptions =>
46
- typeof v === "string" && NAV_ACTIONS.includes(v.trim());
79
+ typeof v === "string" && NAV_ACTIONS.includes(v);
47
80
 
48
81
  export const getNavigationKeys = (
49
- item?: ZappUIComponent | ZappRiver
82
+ item?: ZappUIComponent | ZappRiver,
83
+ resultType: ResultType | null = null
50
84
  ): NavKeys => {
51
85
  const general = (item?.general ?? {}) as General;
52
- const pluginIdentifier = item?.type ?? "";
53
- const legacy = legacyMappingKeys[pluginIdentifier] ?? {};
86
+
87
+ const pluginIdentifier =
88
+ (item as any).identifier ?? item?.type ?? item?.component_type ?? "";
89
+
90
+ const legacy =
91
+ legacyMappingKeys[`${pluginIdentifier}.${resultType}`] ??
92
+ legacyMappingKeys[pluginIdentifier] ??
93
+ {};
94
+
95
+ const actionKey = resultType
96
+ ? `${resultType}_${CALLBACK_NAVIGATION_KEY}`
97
+ : CALLBACK_NAVIGATION_KEY;
54
98
 
55
99
  const rawAction =
56
- (general as General).hook_callback_navigation ??
100
+ (general as General)[actionKey] ??
57
101
  (legacy.actionType ? (general as General)[legacy.actionType] : undefined);
58
102
 
59
- let action: NavigationCallbackOptions | null = null;
60
-
61
- if (isNonEmptyString(rawAction)) {
62
- const trimmed = rawAction.trim();
63
- action = isNavAction(trimmed) ? trimmed : null;
64
- }
103
+ const action: NavigationCallbackOptions | null = isNavAction(rawAction)
104
+ ? rawAction
105
+ : null;
65
106
 
66
107
  if (!action) return null;
67
108
 
68
109
  let targetScreenId: string | null = null;
69
110
 
70
111
  if (action === NavigationCallbackOptions.GO_TO_SCREEN) {
112
+ const screenKey = resultType
113
+ ? `${resultType}_${CALLBACK_NAVIGATION_GO_TO_SCREEN_KEY}`
114
+ : CALLBACK_NAVIGATION_GO_TO_SCREEN_KEY;
115
+
71
116
  const screenId: string | null =
72
- ((general as General)[CALLBACK_NAVIGATION_GO_TO_SCREEN_KEY] as string) ??
117
+ ((general as General)[screenKey] as string) ??
73
118
  (legacy.targetScreen
74
119
  ? ((general as General)[legacy.targetScreen] as string)
75
120
  : undefined);
76
121
 
77
122
  if (screenId) {
78
- const trimmedTargetScreenId = screenId.trim();
79
-
80
- targetScreenId =
81
- trimmedTargetScreenId.length > 0 ? trimmedTargetScreenId : null;
123
+ targetScreenId = screenId.length > 0 ? screenId : null;
82
124
  }
83
125
  }
84
126
 
@@ -87,12 +129,20 @@ export const getNavigationKeys = (
87
129
 
88
130
  export const useCallbackNavigationAction = (
89
131
  item?: ZappUIComponent | ZappRiver
90
- ): hookCallback | undefined => {
132
+ ): ((
133
+ args: CallbackResult,
134
+ hookCallback?: hookCallback
135
+ ) => void | undefined) => {
91
136
  const navigation = useNavigation();
92
137
  const rivers = useRivers();
93
- const enabled = Boolean(item?.general?.[CALLBACK_NAVIGATION_KEY]);
94
138
  const screenContext = useScreenContext();
95
139
 
140
+ const navigationRef = useRef(navigation);
141
+
142
+ useEffect(() => {
143
+ navigationRef.current = navigation;
144
+ }, [navigation]);
145
+
96
146
  const overrideCallbackFromComponent = useMemo(() => {
97
147
  log_verbose(`${LogPrefix}: overridden callbackAction by component`);
98
148
 
@@ -105,16 +155,56 @@ export const useCallbackNavigationAction = (
105
155
  }
106
156
 
107
157
  const callbackAction = useCallback<hookCallback>(
108
- (_args: hookCallbackArgs) => {
109
- const data = getNavigationKeys(item) ?? {
110
- action: NavigationCallbackOptions.DEFAULT,
111
- targetScreenId: null,
112
- };
158
+ (args: CallbackResult, hookCallback: hookCallback = null) => {
159
+ if (!args.success) {
160
+ log_debug(
161
+ `${LogPrefix} callback called with no success, use original callback`
162
+ );
163
+
164
+ hookCallback?.(args);
165
+
166
+ return;
167
+ }
168
+
169
+ if (args.cancelled) {
170
+ log_debug(
171
+ `${LogPrefix} callback called but cancelled, use original callback`
172
+ );
173
+
174
+ hookCallback?.(args);
175
+
176
+ return;
177
+ }
178
+
179
+ let data = getNavigationKeys(item, args.options?.resultType ?? null);
180
+
181
+ if (!data) {
182
+ const isScreen = !hookCallback;
183
+
184
+ if (isScreen && args.options?.resultType === ResultType.login) {
185
+ log_debug(
186
+ `${LogPrefix} no navigation data found, applying GO BACK for login screen`
187
+ );
188
+
189
+ data = {
190
+ action: NavigationCallbackOptions.GO_BACK,
191
+ targetScreenId: null,
192
+ };
193
+ } else {
194
+ hookCallback?.(args);
195
+
196
+ return;
197
+ }
198
+ }
199
+
200
+ hookCallback?.({ ...args, success: false, cancelled: true });
201
+ const currentNavigation = navigationRef.current;
113
202
 
114
203
  switch (data.action) {
115
204
  case NavigationCallbackOptions.GO_BACK: {
116
- if (navigation.canGoBack()) {
117
- navigation.goBack();
205
+ if (currentNavigation.canGoBack()) {
206
+ currentNavigation.goBack();
207
+
118
208
  log_info(`${LogPrefix} performing 'GO BACK' action`);
119
209
  } else {
120
210
  log_info(`${LogPrefix} cannot perform 'GO BACK' action — ignoring`);
@@ -124,7 +214,7 @@ export const useCallbackNavigationAction = (
124
214
  }
125
215
 
126
216
  case NavigationCallbackOptions.GO_HOME: {
127
- navigation.goHome();
217
+ currentNavigation.goHome();
128
218
  log_info(`${LogPrefix} performing 'GO HOME' action`);
129
219
  break;
130
220
  }
@@ -140,7 +230,7 @@ export const useCallbackNavigationAction = (
140
230
  const screen = rivers[screenId];
141
231
 
142
232
  if (screen) {
143
- navigation.replace(screen);
233
+ currentNavigation.replace(screen);
144
234
 
145
235
  log_info(
146
236
  `${LogPrefix} performing 'GO TO SCREEN' action to screen: ${screenId}`
@@ -157,8 +247,8 @@ export const useCallbackNavigationAction = (
157
247
  }
158
248
  }
159
249
  },
160
- [item, navigation, rivers]
250
+ [item, rivers]
161
251
  );
162
252
 
163
- return enabled ? overrideCallbackFromComponent || callbackAction : undefined;
253
+ return overrideCallbackFromComponent || callbackAction;
164
254
  };
@@ -5,20 +5,32 @@ const NavigationCallbackOptions = {
5
5
  GO_TO_SCREEN: "go_to_screen",
6
6
  };
7
7
 
8
- const CALLBACK_NAVIGATION_KEY = "hook_callback_navigation";
8
+ const ResultType = {
9
+ login: "login",
10
+ logout: "logout",
11
+ };
12
+
13
+ const CALLBACK_NAVIGATION_KEY = "completion_action";
9
14
 
10
15
  const CALLBACK_NAVIGATION_GO_TO_SCREEN_KEY =
11
- "hook_callback_navigation_go_to_screen";
16
+ "completion_action_navigation_go_to_screen";
17
+
18
+ const callbackKeyPrefix = (key, prefix, keySeparator = "_") =>
19
+ prefix ? `${prefix}${keySeparator}${key}` : key;
12
20
 
13
- const extendManifestWithHookCallback = () => ({
21
+ const extendManifestWithHookCallback = (prefix = null) => ({
14
22
  group: true,
15
- label: "CallBack Navigation",
23
+ label: `CallBack Navigation: ${prefix}`,
16
24
  folded: true,
17
25
  fields: [
18
26
  {
19
27
  type: "select",
20
- key: CALLBACK_NAVIGATION_KEY,
21
- label: "Callback Navigation",
28
+ key: callbackKeyPrefix(CALLBACK_NAVIGATION_KEY, prefix),
29
+ label: callbackKeyPrefix(
30
+ "Callback Navigation",
31
+ prefix?.toUpperCase(),
32
+ " "
33
+ ),
22
34
  label_tooltip:
23
35
  "Defines what navigation action should be performed after the callback is called.",
24
36
  options: [
@@ -43,13 +55,17 @@ const extendManifestWithHookCallback = () => ({
43
55
  },
44
56
  {
45
57
  type: "screen_selector",
46
- key: CALLBACK_NAVIGATION_GO_TO_SCREEN_KEY,
47
- label: "Navigate to screen",
58
+ key: callbackKeyPrefix(CALLBACK_NAVIGATION_GO_TO_SCREEN_KEY, prefix),
59
+ label: callbackKeyPrefix(
60
+ "Navigate to screen",
61
+ prefix?.toUpperCase(),
62
+ " "
63
+ ),
48
64
  label_tooltip: "Screen you wish to navigate to after success purchase",
49
65
  rules: "conditional",
50
66
  conditional_fields: [
51
67
  {
52
- key: `general/${CALLBACK_NAVIGATION_KEY}`,
68
+ key: `general/${callbackKeyPrefix(CALLBACK_NAVIGATION_KEY, prefix)}`,
53
69
  condition_value: NavigationCallbackOptions.GO_TO_SCREEN,
54
70
  },
55
71
  ],
@@ -57,4 +73,4 @@ const extendManifestWithHookCallback = () => ({
57
73
  ],
58
74
  });
59
75
 
60
- module.exports = { extendManifestWithHookCallback };
76
+ module.exports = { extendManifestWithHookCallback, ResultType };
@@ -1,5 +1,8 @@
1
1
  import { useCallback } from "react";
2
- import { useCallbackNavigationAction } from "./callbackNavigationAction";
2
+ import {
3
+ CallbackResult,
4
+ useCallbackNavigationAction,
5
+ } from "./callbackNavigationAction";
3
6
 
4
7
  export const useCallbackActions = (
5
8
  item?: ZappUIComponent | ZappRiver,
@@ -8,14 +11,8 @@ export const useCallbackActions = (
8
11
  const navigationAction = useCallbackNavigationAction(item);
9
12
 
10
13
  return useCallback(
11
- async (data: hookCallbackArgs) => {
12
- if (navigationAction && data.success) {
13
- hookCallback?.({ ...data, success: false, cancelled: true });
14
-
15
- navigationAction(data);
16
- } else {
17
- hookCallback?.(data);
18
- }
14
+ async (data: CallbackResult) => {
15
+ navigationAction(data, hookCallback);
19
16
  },
20
17
  [navigationAction, hookCallback]
21
18
  );