@applicaster/zapp-react-native-utils 14.0.0-alpha.2247415563 → 14.0.0-alpha.2292190333

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 (83) hide show
  1. package/actionsExecutor/ActionExecutorContext.tsx +60 -84
  2. package/actionsExecutor/ScreenActions.ts +164 -0
  3. package/actionsExecutor/StorageActions.ts +110 -0
  4. package/actionsExecutor/feedDecorator.ts +171 -0
  5. package/actionsExecutor/screenResolver.ts +11 -0
  6. package/analyticsUtils/AnalyticsEvents/helper.ts +81 -0
  7. package/analyticsUtils/AnalyticsEvents/sendOnClickEvent.ts +14 -4
  8. package/analyticsUtils/__tests__/analyticsUtils.test.js +3 -0
  9. package/analyticsUtils/events.ts +8 -0
  10. package/appUtils/HooksManager/Hook.ts +4 -4
  11. package/appUtils/HooksManager/index.ts +11 -1
  12. package/appUtils/accessibilityManager/index.ts +5 -5
  13. package/appUtils/contextKeysManager/contextResolver.ts +42 -1
  14. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +5 -0
  15. package/appUtils/focusManager/__tests__/focusManager.test.js +1 -1
  16. package/appUtils/focusManager/index.ios.ts +10 -0
  17. package/appUtils/focusManager/index.ts +82 -11
  18. package/appUtils/focusManager/treeDataStructure/Tree/index.js +1 -1
  19. package/appUtils/focusManagerAux/utils/index.ts +106 -3
  20. package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +0 -15
  21. package/appUtils/playerManager/useChapterMarker.tsx +0 -1
  22. package/appUtils/playerManager/usePlayerControllerSetup.tsx +16 -0
  23. package/arrayUtils/index.ts +1 -1
  24. package/componentsUtils/__tests__/isTabsScreen.test.ts +38 -0
  25. package/componentsUtils/index.ts +4 -1
  26. package/configurationUtils/__tests__/manifestKeyParser.test.ts +546 -0
  27. package/configurationUtils/manifestKeyParser.ts +57 -32
  28. package/focusManager/FocusManager.ts +95 -20
  29. package/focusManager/Tree.ts +25 -21
  30. package/focusManager/__tests__/FocusManager.test.ts +50 -8
  31. package/focusManager/aux/index.ts +170 -0
  32. package/index.d.ts +0 -9
  33. package/manifestUtils/defaultManifestConfigurations/player.js +8 -0
  34. package/navigationUtils/__tests__/mapContentTypesToRivers.test.ts +130 -0
  35. package/navigationUtils/index.ts +6 -4
  36. package/package.json +2 -3
  37. package/playerUtils/getPlayerActionButtons.ts +1 -1
  38. package/playerUtils/index.ts +51 -0
  39. package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +3 -1
  40. package/reactHooks/cell-click/__tests__/index.test.js +3 -0
  41. package/reactHooks/cell-click/index.ts +8 -1
  42. package/reactHooks/debugging/__tests__/index.test.js +0 -1
  43. package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +8 -2
  44. package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +71 -31
  45. package/reactHooks/feed/index.ts +2 -0
  46. package/reactHooks/feed/useBatchLoading.ts +16 -9
  47. package/reactHooks/feed/useFeedLoader.tsx +36 -34
  48. package/reactHooks/feed/useLoadPipesDataDispatch.ts +57 -0
  49. package/reactHooks/feed/usePipesCacheReset.ts +3 -3
  50. package/reactHooks/flatList/useSequentialRenderItem.tsx +3 -3
  51. package/reactHooks/layout/__tests__/index.test.tsx +3 -1
  52. package/reactHooks/layout/isTablet/index.ts +12 -5
  53. package/reactHooks/layout/useDimensions/__tests__/useDimensions.test.ts +34 -36
  54. package/reactHooks/layout/useDimensions/useDimensions.ts +2 -3
  55. package/reactHooks/layout/useLayoutVersion.ts +5 -5
  56. package/reactHooks/navigation/index.ts +7 -5
  57. package/reactHooks/navigation/useIsScreenActive.ts +9 -5
  58. package/reactHooks/navigation/useRoute.ts +7 -2
  59. package/reactHooks/navigation/useScreenStateStore.ts +8 -0
  60. package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +4 -0
  61. package/reactHooks/screen/useScreenContext.ts +1 -1
  62. package/reactHooks/state/__tests__/ZStoreProvider.test.tsx +2 -1
  63. package/reactHooks/state/index.ts +1 -1
  64. package/reactHooks/state/useHomeRiver.ts +4 -2
  65. package/reactHooks/state/useRivers.ts +7 -8
  66. package/riverComponetsMeasurementProvider/index.tsx +1 -1
  67. package/screenPickerUtils/index.ts +13 -0
  68. package/services/js2native.ts +1 -0
  69. package/storage/ScreenSingleValueProvider.ts +204 -0
  70. package/storage/ScreenStateMultiSelectProvider.ts +293 -0
  71. package/storage/StorageMultiSelectProvider.ts +192 -0
  72. package/storage/StorageSingleSelectProvider.ts +108 -0
  73. package/time/BackgroundTimer.ts +6 -4
  74. package/utils/__tests__/find.test.ts +36 -0
  75. package/utils/__tests__/omit.test.ts +19 -0
  76. package/utils/__tests__/pathOr.test.ts +37 -0
  77. package/utils/__tests__/startsWith.test.ts +30 -0
  78. package/utils/endsWith.ts +9 -0
  79. package/utils/find.ts +3 -0
  80. package/utils/index.ts +16 -0
  81. package/utils/omit.ts +5 -0
  82. package/utils/pathOr.ts +5 -0
  83. package/utils/startsWith.ts +9 -0
@@ -1,14 +1,31 @@
1
- import { isNotNil } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
2
- import { find, last, pathOr, startsWith } from "ramda";
1
+ import {
2
+ isNil,
3
+ last,
4
+ startsWith,
5
+ find,
6
+ pathOr,
7
+ } from "@applicaster/zapp-react-native-utils/utils";
8
+
3
9
  import {
4
10
  QUICK_BRICK_CONTENT,
5
11
  QUICK_BRICK_NAVBAR,
6
12
  } from "@applicaster/quick-brick-core/const";
7
13
 
14
+ import {
15
+ getFocusableId,
16
+ SCREEN_PICKER_CONTAINER,
17
+ } from "@applicaster/zapp-react-native-utils/screenPickerUtils";
18
+
8
19
  // run check each 300 ms
9
20
  // run this check too often could lead to performance penalty on low-end devices
10
21
  const HOW_OFTEN_TO_CHECK_CONDITION = 300; // ms
11
22
 
23
+ const isTopMenu = (node) => startsWith(QUICK_BRICK_NAVBAR, node?.id);
24
+ const isContent = (node) => startsWith(QUICK_BRICK_CONTENT, node?.id);
25
+ const isRoot = (node) => node?.id === "root";
26
+
27
+ const isScrenPicker = (node) => startsWith(SCREEN_PICKER_CONTAINER, node?.id);
28
+
12
29
  type Props = {
13
30
  maxTimeout: number;
14
31
  conditionFn: () => boolean;
@@ -49,7 +66,7 @@ export const waitForActiveScreen = (currentRoute: string, focusableTree) => {
49
66
 
50
67
  const route = find((route) => route.id === currentRoute, routes);
51
68
 
52
- return isNotNil(route);
69
+ return !isNil(route);
53
70
  };
54
71
 
55
72
  return waitUntil({
@@ -99,3 +116,89 @@ export const waitForContent = (focusableTree) => {
99
116
  conditionFn: contentHasAnyChildren,
100
117
  });
101
118
  };
119
+
120
+ export const findSelectedTabId = (item: ZappEntry): string => {
121
+ const selectedTabId = getFocusableId(item.id);
122
+
123
+ return selectedTabId;
124
+ };
125
+
126
+ export const findSelectedMenuId = (focusableTree) => {
127
+ // Set focus with back button context
128
+ const navbar = getNavbarNode(focusableTree);
129
+
130
+ const selectedMenuItemId = find(
131
+ (child) => child.component.props.selected,
132
+ navbar.children
133
+ )?.id;
134
+
135
+ return selectedMenuItemId;
136
+ };
137
+
138
+ export const isTabsScreenContentFocused = (node) => {
139
+ if (isRoot(node)) {
140
+ return false;
141
+ }
142
+
143
+ if (isTopMenu(node)) {
144
+ return false;
145
+ }
146
+
147
+ if (isContent(node)) {
148
+ return false;
149
+ }
150
+
151
+ if (isScrenPicker(node)) {
152
+ return true;
153
+ }
154
+
155
+ return isTabsScreenContentFocused(node.parent);
156
+ };
157
+
158
+ export const isCurrentFocusOnMenu = (node) => {
159
+ if (isRoot(node)) {
160
+ return false;
161
+ }
162
+
163
+ if (isTopMenu(node)) {
164
+ return true;
165
+ }
166
+
167
+ if (isContent(node)) {
168
+ return false;
169
+ }
170
+
171
+ return isCurrentFocusOnMenu(node.parent);
172
+ };
173
+
174
+ export const isCurrentFocusOnContent = (node) => {
175
+ if (isRoot(node)) {
176
+ return false;
177
+ }
178
+
179
+ if (isTopMenu(node)) {
180
+ return false;
181
+ }
182
+
183
+ if (isContent(node)) {
184
+ return true;
185
+ }
186
+
187
+ return isCurrentFocusOnContent(node.parent);
188
+ };
189
+
190
+ export const isCurrentFocusOn = (id, node) => {
191
+ if (!node) {
192
+ return false;
193
+ }
194
+
195
+ if (isRoot(node)) {
196
+ return false;
197
+ }
198
+
199
+ if (node?.id === id) {
200
+ return true;
201
+ }
202
+
203
+ return isCurrentFocusOn(id, node.parent);
204
+ };
@@ -18,13 +18,6 @@ export const { log_verbose, log_debug, log_info, log_error } = createLogger({
18
18
  parent: utilsLogger,
19
19
  });
20
20
 
21
- type ActionChapter = {
22
- type: string;
23
- options?: {
24
- title: string;
25
- };
26
- };
27
-
28
21
  type ChapterMarkerOriginal = {
29
22
  id: string;
30
23
  title: string;
@@ -33,14 +26,6 @@ type ChapterMarkerOriginal = {
33
26
  actions: ActionChapter[];
34
27
  };
35
28
 
36
- export type ChapterMarkerEvent = {
37
- id: string;
38
- title: string;
39
- start_time: number;
40
- end_time: number;
41
- actions: ActionChapter[];
42
- };
43
-
44
29
  export type TitleSummaryEvent = {
45
30
  title: string | number;
46
31
  summary: string | number;
@@ -1,4 +1,3 @@
1
- import { ChapterMarkerEvent } from "./OverlayObserver/OverlaysObserver";
2
1
  import { usePlayer } from "./usePlayer";
3
2
  import * as React from "react";
4
3
 
@@ -5,6 +5,9 @@ import { playerManager } from "./index";
5
5
  import { useValidatePlayerConfig } from "../../playerUtils/useValidatePlayerConfig";
6
6
  import { PlayerRole } from "./conts";
7
7
  import { isAppleTV } from "@applicaster/zapp-react-native-ui-components/Helpers/Platform";
8
+ import { TVSeekController } from "../../reactHooks/player/TVSeekControlller/TVSeekController";
9
+ import { KeyInputHandler } from "../keyInputHandler/KeyInputHandler";
10
+ import { isTV } from "../../reactUtils";
8
11
 
9
12
  // TODO: Rename to ControllerType
10
13
  export const usePlayerControllerSetup = ({
@@ -76,5 +79,18 @@ export const usePlayerControllerSetup = ({
76
79
  };
77
80
  }, [playerId, playerController]);
78
81
 
82
+ useEffect(() => {
83
+ if (!isTV()) {
84
+ return;
85
+ }
86
+
87
+ if (playerController) {
88
+ const seekController = new TVSeekController(playerController);
89
+ playerController.seekController = seekController;
90
+
91
+ return KeyInputHandler.getInstance().addListener(seekController);
92
+ }
93
+ }, [playerController]);
94
+
79
95
  return playerController;
80
96
  };
@@ -93,7 +93,7 @@ export const isIndexInRange = (index: number, length: number): boolean => {
93
93
  export const makeListOfIndexes = (size: number): number[] =>
94
94
  Array.from({ length: size }, (_, index) => index);
95
95
 
96
- export const makeListOf = (value: unknown, size: number): number[] => {
96
+ export const makeListOf = <T>(value: T, size: number): T[] => {
97
97
  return Array(size).fill(value);
98
98
  };
99
99
 
@@ -0,0 +1,38 @@
1
+ import { isTabsScreen } from "..";
2
+
3
+ describe("isTabsScreen", () => {
4
+ it("should return true if the component type is 'screen-picker-qb-tv' and tabs_screen=true", () => {
5
+ const item = { component_type: "screen-picker-qb-tv", tabs_screen: true };
6
+ expect(isTabsScreen(item)).toBe(true);
7
+ });
8
+
9
+ it("should return true if the component type is 'screen-picker-qb-tv' and tabs_screen=false", () => {
10
+ const item = { component_type: "screen-picker-qb-tv", tabs_screen: false };
11
+ expect(isTabsScreen(item)).toBe(false);
12
+ });
13
+
14
+ it("should return false if the component type is not 'screen-picker-qb-tv'", () => {
15
+ const item = { component_type: "other-component" };
16
+ expect(isTabsScreen(item)).toBe(false);
17
+ });
18
+
19
+ it("should return false if the component type is undefined", () => {
20
+ const item = { component_type: undefined };
21
+ expect(isTabsScreen(item)).toBe(false);
22
+ });
23
+
24
+ it("should return false if the item is null", () => {
25
+ const item = null;
26
+ expect(isTabsScreen(item)).toBe(false);
27
+ });
28
+
29
+ it("should return false if the item is undefined", () => {
30
+ const item = undefined;
31
+ expect(isTabsScreen(item)).toBe(false);
32
+ });
33
+
34
+ it("should return false if the item is an empty object", () => {
35
+ const item = {};
36
+ expect(isTabsScreen(item)).toBe(false);
37
+ });
38
+ });
@@ -5,7 +5,7 @@ const EMPTY_GROUP_COMPONENT = "empty_group_component";
5
5
 
6
6
  const GALLERY = "gallery-qb";
7
7
 
8
- const SCREEN_PICKER = "screen-picker-qb-tv";
8
+ export const SCREEN_PICKER = "screen-picker-qb-tv";
9
9
 
10
10
  const HORIZONTAL_LIST = "horizontal_list_qb";
11
11
 
@@ -37,3 +37,6 @@ export const isEmptyGroup = (item): boolean =>
37
37
  export const isGroupInfo = (item): boolean =>
38
38
  item?.component_type === GROUP_INFO ||
39
39
  item?.component_type === GROUP_INFO_OLD;
40
+
41
+ export const isTabsScreen = (item): boolean =>
42
+ isScreenPicker(item) && item?.tabs_screen;