@applicaster/zapp-react-native-utils 13.0.6-alpha.4390983410 → 14.0.0-alpha.1015356256

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 (38) hide show
  1. package/actionsExecutor/ActionExecutorContext.tsx +1 -1
  2. package/analyticsUtils/AnalyticsEvents/helper.ts +81 -0
  3. package/analyticsUtils/AnalyticsEvents/sendOnClickEvent.ts +14 -4
  4. package/analyticsUtils/__tests__/analyticsUtils.test.js +14 -0
  5. package/analyticsUtils/events.ts +8 -0
  6. package/appUtils/accessibilityManager/index.ts +37 -5
  7. package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +0 -15
  8. package/appUtils/playerManager/useChapterMarker.tsx +0 -1
  9. package/configurationUtils/__tests__/manifestKeyParser.test.ts +547 -0
  10. package/configurationUtils/manifestKeyParser.ts +57 -32
  11. package/focusManager/FocusManager.ts +22 -10
  12. package/focusManager/Tree.ts +25 -21
  13. package/focusManager/__tests__/FocusManager.test.ts +50 -8
  14. package/index.d.ts +3 -0
  15. package/manifestUtils/_internals/getDefaultConfiguration.js +28 -0
  16. package/manifestUtils/{_internals.js → _internals/index.js} +2 -25
  17. package/manifestUtils/createConfig.js +4 -1
  18. package/manifestUtils/defaultManifestConfigurations/player.js +1565 -572
  19. package/manifestUtils/progressBar/__tests__/mobileProgressBar.test.js +0 -30
  20. package/navigationUtils/__tests__/navigationUtils.test.js +0 -65
  21. package/navigationUtils/index.ts +0 -31
  22. package/package.json +2 -2
  23. package/playerUtils/__tests__/configurationUtils.test.ts +1 -65
  24. package/playerUtils/_internals/__tests__/utils.test.ts +71 -0
  25. package/playerUtils/_internals/index.ts +1 -0
  26. package/playerUtils/_internals/utils.ts +31 -0
  27. package/playerUtils/configurationUtils.ts +0 -44
  28. package/playerUtils/getPlayerActionButtons.ts +1 -1
  29. package/playerUtils/useValidatePlayerConfig.tsx +22 -19
  30. package/reactHooks/feed/useBatchLoading.ts +1 -1
  31. package/reactHooks/feed/usePipesCacheReset.ts +1 -1
  32. package/reactHooks/navigation/index.ts +7 -3
  33. package/reactHooks/screen/useScreenContext.ts +1 -1
  34. package/reactHooks/state/__tests__/ZStoreProvider.test.tsx +2 -1
  35. package/riverComponetsMeasurementProvider/index.tsx +1 -1
  36. package/services/js2native.ts +1 -0
  37. package/utils/index.ts +4 -0
  38. package/playerUtils/configurationGenerator.ts +0 -2572
@@ -25,7 +25,7 @@ import {
25
25
  resolveObjectValues,
26
26
  } from "../appUtils/contextKeysManager/contextResolver";
27
27
  import { useNavigation } from "../reactHooks";
28
- import { get } from "lodash";
28
+ import { get } from "../utils";
29
29
 
30
30
  import {
31
31
  useContentTypes,
@@ -4,9 +4,12 @@ import {
4
4
  ANALYTICS_COMPONENT_EVENTS,
5
5
  ANALYTICS_CORE_EVENTS,
6
6
  ANALYTICS_ENTRY_EVENTS,
7
+ ANALYTICS_PREFERENCES_EVENTS,
7
8
  DOWNLOADS_EVENTS,
8
9
  } from "../events";
9
10
  import { isEmptyOrNil } from "../../cellUtils";
11
+ import { get } from "lodash";
12
+ import { StorageMultiSelectProvider } from "@applicaster/zapp-react-native-bridge/ZappStorage/StorageMultiSelectProvider";
10
13
 
11
14
  export enum OfflineItemState {
12
15
  notExist = "NOT_EXISTS",
@@ -102,6 +105,84 @@ export function eventForComponent(
102
105
  return analyticsProps;
103
106
  }
104
107
 
108
+ /**
109
+ * Checks if an item is currently selected in localStorage based on its actions
110
+ * @param item - The item to check
111
+ * @returns boolean indicating if the item is currently selected
112
+ */
113
+ function isItemPreviouslySelected(item: any): boolean {
114
+ const actions = item?.extensions?.tap_actions?.actions;
115
+
116
+ if (!actions) {
117
+ return false;
118
+ }
119
+
120
+ const localStorageAction = actions.find(
121
+ (action) => action?.type === "localStorageToggleFlag"
122
+ );
123
+
124
+ if (!localStorageAction?.options?.key) {
125
+ return false;
126
+ }
127
+
128
+ const keyNamespace = localStorageAction.options.key;
129
+
130
+ const tag = localStorageAction.options?.selector
131
+ ? get(item, localStorageAction.options.selector)
132
+ : (item.extensions?.tag ?? item.id);
133
+
134
+ if (!tag) {
135
+ return false;
136
+ }
137
+
138
+ try {
139
+ const multiSelectProvider =
140
+ StorageMultiSelectProvider.getProvider(keyNamespace);
141
+
142
+ const selectedItems = multiSelectProvider.getSelectedItems();
143
+
144
+ return selectedItems.includes(tag);
145
+ } catch (error) {
146
+ return false;
147
+ }
148
+ }
149
+
150
+ export function getLocalStorageSetPayload(extraProps) {
151
+ const { item } = extraProps;
152
+
153
+ const hasLocalStorageSetAction = item?.extensions?.tap_actions?.actions?.some(
154
+ (action) => action?.type === "localStorageSet"
155
+ );
156
+
157
+ if (!hasLocalStorageSetAction) {
158
+ return null;
159
+ }
160
+
161
+ return {
162
+ [ANALYTICS_PREFERENCES_EVENTS.ITEM_SELECTED_STATUS]: true,
163
+ };
164
+ }
165
+
166
+ export function getLocalStorageToggleFlagPayload(extraProps) {
167
+ const { item } = extraProps;
168
+
169
+ const hasLocalStorageToggleAction =
170
+ item?.extensions?.tap_actions?.actions?.some(
171
+ (action) => action?.type === "localStorageToggleFlag"
172
+ );
173
+
174
+ if (!hasLocalStorageToggleAction) {
175
+ return null;
176
+ }
177
+
178
+ const previouslySelected = isItemPreviouslySelected(item);
179
+
180
+ return {
181
+ [ANALYTICS_PREFERENCES_EVENTS.ITEM_SELECTED_STATUS]: !previouslySelected,
182
+ [ANALYTICS_PREFERENCES_EVENTS.PREVIOUS_SELECTED_STATE]: previouslySelected,
183
+ };
184
+ }
185
+
105
186
  export function playEventForType(item) {
106
187
  const itemType = item?.type && item.type?.value;
107
188
 
@@ -1,13 +1,13 @@
1
1
  import { log_error, log_debug } from "../logger";
2
-
3
- import { ANALYTICS_CORE_EVENTS } from "../events";
4
-
2
+ import { ANALYTICS_CORE_EVENTS, ACTION_TYPE } from "../events";
5
3
  import { postAnalyticEvent } from "../manager";
6
4
  import {
7
5
  replaceAnalyticsPropsNils,
8
6
  eventForEntry,
9
7
  eventForComponent,
10
8
  extensionsEvents,
9
+ getLocalStorageSetPayload,
10
+ getLocalStorageToggleFlagPayload,
11
11
  } from "./helper";
12
12
 
13
13
  declare type AnalyticsDefaultHelperProperties = {
@@ -26,7 +26,16 @@ export const sendOnClickEvent = ({
26
26
  const castedExtraProps: ExtraProps = extraProps;
27
27
  const componentData = component || extraProps.component;
28
28
  const data = zappPipesData || extraProps.zappPipesData;
29
- const eventName = ANALYTICS_CORE_EVENTS.TAP_CELL;
29
+
30
+ const actionCellPayload =
31
+ extraProps?.item?.type?.value === ACTION_TYPE
32
+ ? getLocalStorageSetPayload(extraProps) ||
33
+ getLocalStorageToggleFlagPayload(extraProps)
34
+ : null;
35
+
36
+ const eventName = actionCellPayload
37
+ ? ANALYTICS_CORE_EVENTS.TAP_SELECTABLE_CELL
38
+ : ANALYTICS_CORE_EVENTS.TAP_CELL;
30
39
 
31
40
  if (!analyticsScreenData) {
32
41
  log_error(
@@ -44,6 +53,7 @@ export const sendOnClickEvent = ({
44
53
  ...replaceAnalyticsPropsNils({
45
54
  ...analyticsScreenData,
46
55
  }),
56
+ ...actionCellPayload,
47
57
  };
48
58
 
49
59
  if (analyticsCustomProperties) {
@@ -3,8 +3,22 @@ import { ANALYTICS_CORE_EVENTS } from "../events";
3
3
 
4
4
  jest.mock("@applicaster/zapp-react-native-utils/reactUtils", () => ({
5
5
  isWeb: jest.fn(),
6
+ platformSelect: jest.fn(
7
+ (options) => options.android || options.ios || options.web
8
+ ),
6
9
  }));
7
10
 
11
+ jest.mock(
12
+ "@applicaster/zapp-react-native-bridge/ZappStorage/StorageMultiSelectProvider",
13
+ () => ({
14
+ StorageMultiSelectProvider: {
15
+ getProvider: jest.fn(() => ({
16
+ getSelectedItems: jest.fn(() => []),
17
+ })),
18
+ },
19
+ })
20
+ );
21
+
8
22
  const mock_postAnalyticEvent = jest.fn();
9
23
  const mock_startAnalyticsTimedEvent = jest.fn();
10
24
  const mock_endAnalyticsTimedEvent = jest.fn();
@@ -17,8 +17,11 @@ export const SCREEN_VIEW_EVENTS = {
17
17
  TIME_ON_SCREEN: "time_on_screen",
18
18
  };
19
19
 
20
+ export const ACTION_TYPE = "action";
21
+
20
22
  export const TAPPING_EVENTS = {
21
23
  TAP_CELL: "tap_cell",
24
+ TAP_SELECTABLE_CELL: "tap_selectable_cell",
22
25
  TAP_MENU: "tap_menu",
23
26
  TAP_NAVBAR_BACK_BUTTON: "tap_navbar_back_button",
24
27
  };
@@ -99,6 +102,11 @@ export const ANALYTICS_COMPONENT_EVENTS = {
99
102
  COMPONENT_SOURCE: "component_source",
100
103
  };
101
104
 
105
+ export const ANALYTICS_PREFERENCES_EVENTS = {
106
+ ITEM_SELECTED_STATUS: "item_selected_status",
107
+ PREVIOUS_SELECTED_STATE: "previous_selected_state",
108
+ };
109
+
102
110
  // ---------------- EVENTS ---------------------
103
111
  export const AD_EVENT = {
104
112
  ad_break_start: "player_ad_break_start",
@@ -1,9 +1,9 @@
1
1
  import { BehaviorSubject } from "rxjs";
2
2
  import { accessibilityManagerLogger as logger } from "./logger";
3
- import { TTSManager } from "../platform/platformUtils";
3
+ import { TTSManager } from "../platform";
4
4
  import { BUTTON_ACCESSIBILITY_KEYS } from "./const";
5
5
  import { AccessibilityRole } from "react-native";
6
- import _ from "lodash";
6
+ import { toString } from "../../utils";
7
7
 
8
8
  export class AccessibilityManager {
9
9
  private static _instance: AccessibilityManager | null = null;
@@ -137,18 +137,21 @@ export class AccessibilityManager {
137
137
  }
138
138
 
139
139
  public getButtonAccessibilityProps(name: string): AccessibilityProps {
140
- const buttonName = _.toString(name);
140
+ const buttonName = toString(name);
141
141
 
142
142
  const buttonConfig = BUTTON_ACCESSIBILITY_KEYS[buttonName];
143
143
 
144
144
  if (!buttonConfig) {
145
145
  return {
146
+ accessible: true,
146
147
  accessibilityLabel: buttonName,
147
148
  accessibilityHint: `Press button to perform action on ${buttonName}`,
148
149
  "aria-label": buttonName,
149
150
  "aria-description": `Press button to perform action on ${buttonName}`,
150
151
  accessibilityRole: "button" as AccessibilityRole,
151
152
  "aria-role": "button",
153
+ role: "button",
154
+ tabindex: 0,
152
155
  };
153
156
  }
154
157
 
@@ -162,23 +165,52 @@ export class AccessibilityManager {
162
165
  `Press button to perform action on ${buttonName}`;
163
166
 
164
167
  return {
168
+ accessible: true,
165
169
  accessibilityLabel: label,
166
170
  accessibilityHint: hint,
167
171
  "aria-label": label,
168
172
  "aria-description": hint,
169
173
  accessibilityRole: "button" as AccessibilityRole,
170
174
  "aria-role": "button",
175
+ role: "button",
176
+ tabindex: 0,
171
177
  };
172
178
  }
173
179
 
174
180
  public getInputAccessibilityProps(inputName: string): AccessibilityProps {
175
181
  return {
182
+ accessible: true,
176
183
  accessibilityLabel: inputName,
177
184
  accessibilityHint: `Enter text into ${inputName}`,
178
185
  "aria-label": inputName,
179
186
  "aria-description": `Enter text into ${inputName}`,
180
- accessibilityRole: "textbox" as AccessibilityRole,
181
- "aria-role": "textbox",
187
+ accessibilityRole: "text" as AccessibilityRole,
188
+ "aria-role": "text",
189
+ role: "text",
190
+ tabindex: 0,
191
+ };
192
+ }
193
+
194
+ /**
195
+ * Extracts accessibility props from component props and returns them as HTML attributes
196
+ * @param props - Component props containing accessibility properties
197
+ * @returns Object with accessibility HTML attributes
198
+ */
199
+ public getWebAccessibilityProps(props: any): AccessibilityProps {
200
+ const {
201
+ "aria-label": ariaLabel,
202
+ "aria-description": ariaDescription,
203
+ "aria-role": ariaRole,
204
+ role,
205
+ tabindex,
206
+ } = props;
207
+
208
+ return {
209
+ "aria-label": ariaLabel,
210
+ "aria-description": ariaDescription,
211
+ "aria-role": ariaRole,
212
+ role: role || ariaRole,
213
+ tabindex,
182
214
  };
183
215
  }
184
216
 
@@ -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