@applicaster/zapp-react-native-utils 14.0.0-alpha.1661204539 → 14.0.0-alpha.1887720441
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.
- package/actionsExecutor/ActionExecutorContext.tsx +82 -53
- package/analyticsUtils/AnalyticsEvents/helper.ts +81 -0
- package/analyticsUtils/AnalyticsEvents/sendHeaderClickEvent.ts +1 -1
- package/analyticsUtils/AnalyticsEvents/sendMenuClickEvent.ts +2 -1
- package/analyticsUtils/AnalyticsEvents/sendOnClickEvent.ts +14 -4
- package/analyticsUtils/__tests__/analyticsUtils.test.js +14 -0
- package/analyticsUtils/events.ts +8 -0
- package/analyticsUtils/index.tsx +3 -4
- package/analyticsUtils/manager.ts +1 -1
- package/appUtils/HooksManager/Hook.ts +4 -4
- package/appUtils/HooksManager/index.ts +11 -1
- package/appUtils/accessibilityManager/index.ts +7 -4
- package/appUtils/contextKeysManager/contextResolver.ts +1 -15
- package/appUtils/focusManager/treeDataStructure/Tree/index.js +1 -1
- package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +0 -15
- package/appUtils/playerManager/useChapterMarker.tsx +0 -1
- package/appUtils/playerManager/usePlayerControllerSetup.tsx +16 -0
- package/arrayUtils/__tests__/isEmptyArray.test.ts +63 -0
- package/arrayUtils/__tests__/isFilledArray.test.ts +1 -1
- package/arrayUtils/index.ts +8 -3
- package/audioPlayerUtils/__tests__/getArtworkImage.test.ts +144 -0
- package/audioPlayerUtils/__tests__/getBackgroundImage.test.ts +72 -0
- package/audioPlayerUtils/__tests__/getImageFromEntry.test.ts +110 -0
- package/audioPlayerUtils/assets/index.ts +2 -0
- package/audioPlayerUtils/index.ts +242 -0
- package/componentsUtils/__tests__/isTabsScreen.test.ts +38 -0
- package/componentsUtils/index.ts +4 -1
- package/conf/player/__tests__/selectors.test.ts +34 -0
- package/conf/player/selectors.ts +10 -0
- package/configurationUtils/__tests__/configurationUtils.test.js +0 -31
- package/configurationUtils/__tests__/getMediaItems.test.ts +65 -0
- package/configurationUtils/__tests__/imageSrcFromMediaItem.test.ts +34 -0
- package/configurationUtils/__tests__/manifestKeyParser.test.ts +547 -0
- package/configurationUtils/index.ts +63 -34
- package/configurationUtils/manifestKeyParser.ts +57 -32
- package/focusManager/FocusManager.ts +26 -16
- package/focusManager/Tree.ts +25 -21
- package/focusManager/__tests__/FocusManager.test.ts +50 -8
- package/index.d.ts +0 -9
- package/manifestUtils/_internals/getDefaultConfiguration.js +28 -0
- package/manifestUtils/{_internals.js → _internals/index.js} +2 -25
- package/manifestUtils/createConfig.js +4 -1
- package/manifestUtils/defaultManifestConfigurations/player.js +1239 -200
- package/manifestUtils/progressBar/__tests__/mobileProgressBar.test.js +0 -30
- package/manifestUtils/sharedConfiguration/screenPicker/stylesFields.js +1 -2
- package/navigationUtils/__tests__/mapContentTypesToRivers.test.ts +130 -0
- package/navigationUtils/index.ts +6 -4
- package/package.json +2 -3
- package/playerUtils/__tests__/configurationUtils.test.ts +1 -65
- package/playerUtils/__tests__/getPlayerActionButtons.test.ts +54 -0
- package/playerUtils/_internals/__tests__/utils.test.ts +71 -0
- package/playerUtils/_internals/index.ts +1 -0
- package/playerUtils/_internals/utils.ts +31 -0
- package/playerUtils/configurationUtils.ts +0 -44
- package/playerUtils/getPlayerActionButtons.ts +17 -0
- package/playerUtils/index.ts +59 -0
- package/playerUtils/useValidatePlayerConfig.tsx +22 -19
- package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +15 -14
- package/reactHooks/cell-click/index.ts +1 -5
- package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +39 -88
- package/reactHooks/feed/useBatchLoading.ts +11 -9
- package/reactHooks/feed/useFeedLoader.tsx +15 -18
- package/reactHooks/feed/usePipesCacheReset.ts +3 -3
- package/reactHooks/flatList/useSequentialRenderItem.tsx +3 -3
- package/reactHooks/layout/__tests__/index.test.tsx +3 -1
- package/reactHooks/layout/isTablet/index.ts +12 -5
- package/reactHooks/layout/useDimensions/__tests__/useDimensions.test.ts +34 -36
- package/reactHooks/layout/useDimensions/useDimensions.ts +2 -3
- package/reactHooks/layout/useLayoutVersion.ts +5 -5
- package/reactHooks/navigation/index.ts +7 -5
- package/reactHooks/navigation/useIsScreenActive.ts +9 -5
- package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +4 -0
- package/reactHooks/screen/useScreenContext.ts +1 -1
- package/reactHooks/state/__tests__/ZStoreProvider.test.tsx +2 -1
- package/reactHooks/state/useRivers.ts +7 -8
- package/riverComponetsMeasurementProvider/index.tsx +1 -1
- package/services/js2native.ts +1 -0
- package/testUtils/index.tsx +7 -8
- package/time/BackgroundTimer.ts +6 -4
- package/utils/index.ts +17 -1
- package/actionsExecutor/ScreenActions.ts +0 -90
- package/actionsExecutor/StorageActions.ts +0 -110
- package/actionsExecutor/screenResolver.ts +0 -8
- package/playerUtils/configurationGenerator.ts +0 -2572
- package/storage/ScreenSingleValueProvider.ts +0 -92
- package/storage/ScreenStateMultiSelectProvider.ts +0 -119
- package/storage/StorageMultiSelectProvider.ts +0 -192
- package/storage/StorageSingleSelectProvider.ts +0 -108
|
@@ -16,6 +16,7 @@ import { QUICK_BRICK_EVENTS } from "@applicaster/zapp-react-native-bridge/QuickB
|
|
|
16
16
|
import { showConfirmationDialog } from "../alertUtils";
|
|
17
17
|
import { createCloudEvent, sendCloudEvent } from "../cloudEventsUtils";
|
|
18
18
|
import { createLogger } from "../logger";
|
|
19
|
+
import { StorageMultiSelectProvider } from "@applicaster/zapp-react-native-bridge/ZappStorage/StorageMultiSelectProvider";
|
|
19
20
|
import { ACTIVE_LAYOUT_ID_STORAGE_KEY } from "@applicaster/quick-brick-core/App/remoteContextReloader/consts";
|
|
20
21
|
import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
|
|
21
22
|
import { loadPipesData } from "@applicaster/zapp-react-native-redux/ZappPipes";
|
|
@@ -24,20 +25,15 @@ import {
|
|
|
24
25
|
resolveObjectValues,
|
|
25
26
|
} from "../appUtils/contextKeysManager/contextResolver";
|
|
26
27
|
import { useNavigation } from "../reactHooks";
|
|
28
|
+
import { get } from "../utils";
|
|
27
29
|
|
|
28
30
|
import {
|
|
29
31
|
useContentTypes,
|
|
30
32
|
usePickFromState,
|
|
31
33
|
} from "@applicaster/zapp-react-native-redux/hooks";
|
|
32
|
-
import {
|
|
34
|
+
import { TOGGLE_FLAG_MAX_ITEMS_REACHED_EVENT } from "./consts";
|
|
35
|
+
import { postEvent, useSubscriberFor } from "../reactHooks/useSubscriberFor";
|
|
33
36
|
import { APP_EVENTS } from "../appUtils/events";
|
|
34
|
-
import {
|
|
35
|
-
localStorageToggleFlag,
|
|
36
|
-
sessionStorageToggleFlag,
|
|
37
|
-
} from "./StorageActions";
|
|
38
|
-
|
|
39
|
-
import { ScreenSingleValueProvider } from "@applicaster/zapp-react-native-utils/storage/ScreenSingleValueProvider";
|
|
40
|
-
import { screenSetVariable, screenToggleFlag } from "./ScreenActions";
|
|
41
37
|
|
|
42
38
|
export const { log_error, log_info, log_debug } = createLogger({
|
|
43
39
|
subsystem: "ActionExecutorContext",
|
|
@@ -86,6 +82,19 @@ function findParentComponent(
|
|
|
86
82
|
return null;
|
|
87
83
|
}
|
|
88
84
|
|
|
85
|
+
// send all data just in case (like for message string formatting)
|
|
86
|
+
// Type is not exported for now
|
|
87
|
+
type MaxTagsReachedEvent = {
|
|
88
|
+
selectedItems: string[];
|
|
89
|
+
maxItems: number;
|
|
90
|
+
tag: string;
|
|
91
|
+
keyNamespace: string;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
async function onMaxTagsReached(data: MaxTagsReachedEvent) {
|
|
95
|
+
postEvent(TOGGLE_FLAG_MAX_ITEMS_REACHED_EVENT, [data]);
|
|
96
|
+
}
|
|
97
|
+
|
|
89
98
|
const prepareDefaultActions = (actionExecutor) => {
|
|
90
99
|
actionExecutor.registerAction("localStorageSet", async (action) => {
|
|
91
100
|
const namespaces = action.options.content;
|
|
@@ -169,16 +178,10 @@ const prepareDefaultActions = (actionExecutor) => {
|
|
|
169
178
|
|
|
170
179
|
const entry = context?.entry || {};
|
|
171
180
|
const entryResolver = new EntryResolver(entry);
|
|
172
|
-
const route = context.screenRoute;
|
|
173
|
-
const screenData = ScreenSingleValueProvider.getState(route) as any;
|
|
174
|
-
const screenResolver = new EntryResolver(screenData || {});
|
|
175
181
|
|
|
176
182
|
const data =
|
|
177
183
|
options?.data && options.inflateData
|
|
178
|
-
? await resolveObjectValues(options.data, {
|
|
179
|
-
entry: entryResolver,
|
|
180
|
-
screen: screenResolver,
|
|
181
|
-
})
|
|
184
|
+
? await resolveObjectValues(options.data, { entry: entryResolver })
|
|
182
185
|
: options?.data || entry;
|
|
183
186
|
|
|
184
187
|
const cloudEvent = await createCloudEvent({
|
|
@@ -212,55 +215,81 @@ const prepareDefaultActions = (actionExecutor) => {
|
|
|
212
215
|
return ActionResult.Error;
|
|
213
216
|
});
|
|
214
217
|
|
|
215
|
-
actionExecutor.registerAction(
|
|
216
|
-
"sessionStorageToggleFlag",
|
|
217
|
-
async (
|
|
218
|
-
action: ActionType,
|
|
219
|
-
context?: Record<string, any>
|
|
220
|
-
): Promise<ActionResult> => {
|
|
221
|
-
return await sessionStorageToggleFlag(context, action);
|
|
222
|
-
}
|
|
223
|
-
);
|
|
224
|
-
|
|
225
218
|
actionExecutor.registerAction(
|
|
226
219
|
"localStorageToggleFlag",
|
|
227
220
|
async (
|
|
228
221
|
action: ActionType,
|
|
229
222
|
context?: Record<string, any>
|
|
230
223
|
): Promise<ActionResult> => {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
224
|
+
if (!context) {
|
|
225
|
+
log_error(
|
|
226
|
+
"handleAction: localStorageToggleFlag action missing context"
|
|
227
|
+
);
|
|
234
228
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
async (
|
|
238
|
-
action: ActionType,
|
|
239
|
-
context?: Record<string, any>
|
|
240
|
-
): Promise<ActionResult> => {
|
|
241
|
-
const route = context?.screenRoute;
|
|
242
|
-
const { key, value } = action.options;
|
|
243
|
-
screenSetVariable(route, key, value);
|
|
229
|
+
return ActionResult.Error;
|
|
230
|
+
}
|
|
244
231
|
|
|
245
|
-
|
|
246
|
-
}
|
|
247
|
-
);
|
|
232
|
+
const entry = context?.entry as ZappEntry;
|
|
248
233
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
context?: Record<string, any>
|
|
254
|
-
): Promise<ActionResult> => {
|
|
255
|
-
const screenRoute = context?.screenRoute;
|
|
234
|
+
if (!entry) {
|
|
235
|
+
log_error(
|
|
236
|
+
"handleAction: localStorageToggleFlag action missing entry. Entry is required to get the tag."
|
|
237
|
+
);
|
|
256
238
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
239
|
+
return ActionResult.Error;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const tag = action.options?.selector
|
|
243
|
+
? get(entry, action.options.selector)
|
|
244
|
+
: (entry.extensions?.tag ?? entry.id);
|
|
245
|
+
|
|
246
|
+
const keyNamespace = action.options?.key;
|
|
247
|
+
|
|
248
|
+
if (keyNamespace && tag) {
|
|
249
|
+
const multiSelectProvider =
|
|
250
|
+
StorageMultiSelectProvider.getProvider(keyNamespace);
|
|
251
|
+
|
|
252
|
+
const selectedItems = await multiSelectProvider.getSelectedAsync();
|
|
253
|
+
const isTagInSelectedItems = selectedItems.includes(tag);
|
|
254
|
+
|
|
255
|
+
log_info(
|
|
256
|
+
`handleAction: localStorageToggleFlag event will ${
|
|
257
|
+
isTagInSelectedItems ? "remove" : "add"
|
|
258
|
+
} tag: ${tag} for keyNamespace: ${keyNamespace}, current selectedItems: ${selectedItems}`
|
|
259
|
+
);
|
|
262
260
|
|
|
263
|
-
|
|
261
|
+
if (selectedItems.includes(tag)) {
|
|
262
|
+
await multiSelectProvider.removeItem(tag);
|
|
263
|
+
} else {
|
|
264
|
+
const maxItems = action.options?.max_items;
|
|
265
|
+
|
|
266
|
+
if (maxItems && selectedItems.length >= maxItems) {
|
|
267
|
+
log_info(
|
|
268
|
+
`handleAction: localStorageToggleFlag event reached max items limit: ${maxItems}, cannot add tag: ${tag}`
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
await onMaxTagsReached({
|
|
272
|
+
selectedItems,
|
|
273
|
+
maxItems,
|
|
274
|
+
tag,
|
|
275
|
+
keyNamespace,
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
return ActionResult.Cancel;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
await multiSelectProvider.addItem(tag);
|
|
282
|
+
}
|
|
283
|
+
} else {
|
|
284
|
+
log_error(
|
|
285
|
+
"handleAction: localStorageToggleFlag event missing keyNamespace or tag",
|
|
286
|
+
{ keyNamespace, tag }
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
return ActionResult.Error;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return ActionResult.Success;
|
|
264
293
|
}
|
|
265
294
|
);
|
|
266
295
|
};
|
|
@@ -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
|
|
|
@@ -4,7 +4,7 @@ import { postAnalyticEvent } from "../manager";
|
|
|
4
4
|
import { ANALYTICS_CORE_EVENTS } from "../events";
|
|
5
5
|
|
|
6
6
|
type SendHeaderClickEventProps = {
|
|
7
|
-
extraProps:
|
|
7
|
+
extraProps: Record<string, any>;
|
|
8
8
|
component?: ZappUIComponent;
|
|
9
9
|
zappPipesData?: ZappPipesData;
|
|
10
10
|
item?: ZappEntry;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
/// <reference types="../../" />
|
|
1
2
|
import { log_error, log_debug } from "../logger";
|
|
2
3
|
import { replaceAnalyticsPropsNils } from "./helper";
|
|
3
4
|
import { postAnalyticEvent } from "../manager";
|
|
4
5
|
|
|
5
6
|
import { ANALYTICS_CORE_EVENTS } from "../events";
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
type AnalyticsDefaultHelperProperties = {
|
|
8
9
|
analyticsScreenData: AnalyticsScreenProperties;
|
|
9
10
|
extraProps: any;
|
|
10
11
|
props;
|
|
@@ -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
|
-
|
|
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();
|
package/analyticsUtils/events.ts
CHANGED
|
@@ -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",
|
package/analyticsUtils/index.tsx
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="@applicaster/zapp-react-native-utils" />
|
|
2
1
|
import * as R from "ramda";
|
|
3
2
|
import * as React from "react";
|
|
4
3
|
import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
@@ -31,7 +30,7 @@ import { ANALYTICS_CORE_EVENTS } from "./events";
|
|
|
31
30
|
import { noop } from "../functionUtils";
|
|
32
31
|
|
|
33
32
|
type ComponentWithChildrenProps = {
|
|
34
|
-
children: React.
|
|
33
|
+
children: React.ReactElement;
|
|
35
34
|
};
|
|
36
35
|
|
|
37
36
|
export function sendSelectCellEvent(item, component, headerTitle, itemIndex) {
|
|
@@ -120,11 +119,11 @@ export function getAnalyticsFunctions({
|
|
|
120
119
|
export const AnalyticsContext =
|
|
121
120
|
React.createContext<GetAnalyticsFunctions>(noop);
|
|
122
121
|
|
|
123
|
-
export function AnalyticsProvider(
|
|
122
|
+
export function AnalyticsProvider({ children }: ComponentWithChildrenProps) {
|
|
124
123
|
return (
|
|
125
124
|
// @ts-ignore - this is a valid context provider
|
|
126
125
|
<AnalyticsContext.Provider value={getAnalyticsFunctions}>
|
|
127
|
-
{
|
|
126
|
+
{children}
|
|
128
127
|
</AnalyticsContext.Provider>
|
|
129
128
|
);
|
|
130
129
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
2
2
|
import * as R from "ramda";
|
|
3
3
|
import { NativeModules } from "react-native";
|
|
4
|
-
import { ANALYTICS_CORE_EVENTS } from "
|
|
4
|
+
import { ANALYTICS_CORE_EVENTS } from "./events";
|
|
5
5
|
|
|
6
6
|
import { analyticsUtilsLogger } from "./logger";
|
|
7
7
|
|
|
@@ -65,10 +65,6 @@ export class Hook implements HookInterface {
|
|
|
65
65
|
event: (typeof HOOKS_EVENTS)[keyof typeof HOOKS_EVENTS],
|
|
66
66
|
...args
|
|
67
67
|
) {
|
|
68
|
-
if (this.state === hookState(HOOKS_EVENTS.CANCEL)) {
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
68
|
this.state = hookState(event);
|
|
73
69
|
this.manager.subscriber.invokeHandler(event, ...args);
|
|
74
70
|
}
|
|
@@ -198,4 +194,8 @@ export class Hook implements HookInterface {
|
|
|
198
194
|
R.eqProps("weight", nextHook, this)
|
|
199
195
|
);
|
|
200
196
|
}
|
|
197
|
+
|
|
198
|
+
isCancelled(): boolean {
|
|
199
|
+
return this.state === hookState(HOOKS_EVENTS.CANCEL);
|
|
200
|
+
}
|
|
201
201
|
}
|
|
@@ -255,7 +255,7 @@ export function HooksManager({
|
|
|
255
255
|
* @param {Array<Hook>} restOfHooks to run
|
|
256
256
|
* @returns {function} callback function
|
|
257
257
|
*/
|
|
258
|
-
function hookCallback(hookPlugin, restOfHooks, initialPayload) {
|
|
258
|
+
function hookCallback(hookPlugin: Hook, restOfHooks: Hook[], initialPayload) {
|
|
259
259
|
/**
|
|
260
260
|
* callback invoked after a hook is executed
|
|
261
261
|
* @param {object} options
|
|
@@ -273,6 +273,16 @@ export function HooksManager({
|
|
|
273
273
|
}) {
|
|
274
274
|
let callback = callbackArg;
|
|
275
275
|
|
|
276
|
+
if (hookPlugin.isCancelled()) {
|
|
277
|
+
logHookEvent(
|
|
278
|
+
hooksManagerLogger.info,
|
|
279
|
+
`hookCallback: hook was cancelled: ${hookPlugin["identifier"]}`,
|
|
280
|
+
{}
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
|
|
276
286
|
if (error) {
|
|
277
287
|
logHookEvent(
|
|
278
288
|
hooksManagerLogger.error,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BehaviorSubject } from "rxjs";
|
|
2
2
|
import { accessibilityManagerLogger as logger } from "./logger";
|
|
3
|
-
import { TTSManager } from "../platform
|
|
3
|
+
import { TTSManager } from "../platform";
|
|
4
4
|
import { BUTTON_ACCESSIBILITY_KEYS } from "./const";
|
|
5
|
+
import { toString } from "../../utils";
|
|
5
6
|
import { AccessibilityRole } from "react-native";
|
|
6
7
|
|
|
7
8
|
export class AccessibilityManager {
|
|
@@ -135,7 +136,9 @@ export class AccessibilityManager {
|
|
|
135
136
|
});
|
|
136
137
|
}
|
|
137
138
|
|
|
138
|
-
public getButtonAccessibilityProps(
|
|
139
|
+
public getButtonAccessibilityProps(name: string): AccessibilityProps {
|
|
140
|
+
const buttonName = toString(name);
|
|
141
|
+
|
|
139
142
|
const buttonConfig = BUTTON_ACCESSIBILITY_KEYS[buttonName];
|
|
140
143
|
|
|
141
144
|
if (!buttonConfig) {
|
|
@@ -144,7 +147,7 @@ export class AccessibilityManager {
|
|
|
144
147
|
accessibilityHint: `Press button to perform action on ${buttonName}`,
|
|
145
148
|
"aria-label": buttonName,
|
|
146
149
|
"aria-description": `Press button to perform action on ${buttonName}`,
|
|
147
|
-
accessibilityRole: "button"
|
|
150
|
+
accessibilityRole: "button",
|
|
148
151
|
"aria-role": "button",
|
|
149
152
|
};
|
|
150
153
|
}
|
|
@@ -163,7 +166,7 @@ export class AccessibilityManager {
|
|
|
163
166
|
accessibilityHint: hint,
|
|
164
167
|
"aria-label": label,
|
|
165
168
|
"aria-description": hint,
|
|
166
|
-
accessibilityRole: "button"
|
|
169
|
+
accessibilityRole: "button",
|
|
167
170
|
"aria-role": "button",
|
|
168
171
|
};
|
|
169
172
|
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { ContextKeysManager } from "./index";
|
|
2
2
|
import * as R from "ramda";
|
|
3
|
-
import { screenStates } from "@applicaster/zapp-react-native-utils/storage/ScreenSingleValueProvider";
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
interface IResolver {
|
|
6
5
|
resolve: (string) => Promise<string | number | object>;
|
|
7
6
|
}
|
|
8
7
|
|
|
9
|
-
// TODO: Rename to ObjectKeyResolver or similar
|
|
10
8
|
export class EntryResolver implements IResolver {
|
|
11
9
|
entry: ZappEntry;
|
|
12
10
|
|
|
@@ -23,18 +21,6 @@ export class EntryResolver implements IResolver {
|
|
|
23
21
|
}
|
|
24
22
|
}
|
|
25
23
|
|
|
26
|
-
// TODO: Move to proper place
|
|
27
|
-
|
|
28
|
-
export class ScreenStateResolver implements IResolver {
|
|
29
|
-
constructor(private route: string) {}
|
|
30
|
-
|
|
31
|
-
async resolve(key: string) {
|
|
32
|
-
const screenState = screenStates[this.route];
|
|
33
|
-
|
|
34
|
-
return screenState?.[key];
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
24
|
export class ContextResolver implements IResolver {
|
|
39
25
|
resolve = async (compositeKey: string) =>
|
|
40
26
|
ContextKeysManager.instance.getKey(compositeKey);
|
|
@@ -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;
|
|
@@ -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
|
};
|