@applicaster/zapp-react-native-utils 14.0.0-alpha.1054425138 → 14.0.0-alpha.1101330035
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 +11 -5
- package/actionsExecutor/ScreenActions.ts +82 -9
- package/actionsExecutor/StorageActions.ts +1 -1
- package/actionsExecutor/feedDecorator.ts +171 -0
- package/actionsExecutor/screenResolver.ts +11 -0
- package/analyticsUtils/AnalyticsEvents/helper.ts +81 -0
- package/analyticsUtils/AnalyticsEvents/sendOnClickEvent.ts +14 -4
- package/analyticsUtils/__tests__/analyticsUtils.test.js +14 -0
- package/analyticsUtils/events.ts +8 -0
- package/appUtils/accessibilityManager/index.ts +5 -2
- package/appUtils/contextKeysManager/contextResolver.ts +2 -3
- 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 +7 -2
- 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/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/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/package.json +2 -2
- 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/cell-click/index.ts +3 -0
- package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +20 -0
- package/reactHooks/feed/useBatchLoading.ts +3 -3
- package/reactHooks/feed/useFeedLoader.tsx +3 -3
- package/reactHooks/feed/usePipesCacheReset.ts +1 -1
- package/reactHooks/layout/isTablet/index.ts +12 -5
- package/reactHooks/navigation/index.ts +7 -3
- package/reactHooks/navigation/useIsScreenActive.ts +9 -5
- package/reactHooks/navigation/useRoute.ts +7 -2
- package/reactHooks/navigation/useScreenStateStore.ts +8 -0
- package/reactHooks/screen/useScreenContext.ts +1 -1
- package/reactHooks/state/__tests__/ZStoreProvider.test.tsx +2 -1
- package/riverComponetsMeasurementProvider/index.tsx +1 -1
- package/services/js2native.ts +1 -0
- package/storage/ScreenSingleValueProvider.ts +201 -0
- package/storage/ScreenStateMultiSelectProvider.ts +290 -0
- package/storage/StorageMultiSelectProvider.ts +192 -0
- package/storage/StorageSingleSelectProvider.ts +108 -0
- package/time/BackgroundTimer.ts +5 -3
- package/utils/index.ts +16 -1
- package/playerUtils/configurationGenerator.ts +0 -2572
|
@@ -36,7 +36,6 @@ import {
|
|
|
36
36
|
sessionStorageToggleFlag,
|
|
37
37
|
} from "./StorageActions";
|
|
38
38
|
|
|
39
|
-
import { ScreenSingleValueProvider } from "@applicaster/zapp-react-native-bridge/ZappStorage/ScreenSingleValueProvider";
|
|
40
39
|
import { screenSetVariable, screenToggleFlag } from "./ScreenActions";
|
|
41
40
|
|
|
42
41
|
export const { log_error, log_info, log_debug } = createLogger({
|
|
@@ -169,8 +168,7 @@ const prepareDefaultActions = (actionExecutor) => {
|
|
|
169
168
|
|
|
170
169
|
const entry = context?.entry || {};
|
|
171
170
|
const entryResolver = new EntryResolver(entry);
|
|
172
|
-
const
|
|
173
|
-
const screenData = ScreenSingleValueProvider.getState(route) as any;
|
|
171
|
+
const screenData = context?.screenStateStore.getState().data || {};
|
|
174
172
|
const screenResolver = new EntryResolver(screenData || {});
|
|
175
173
|
|
|
176
174
|
const data =
|
|
@@ -239,8 +237,14 @@ const prepareDefaultActions = (actionExecutor) => {
|
|
|
239
237
|
context?: Record<string, any>
|
|
240
238
|
): Promise<ActionResult> => {
|
|
241
239
|
const route = context?.screenRoute;
|
|
242
|
-
const
|
|
243
|
-
|
|
240
|
+
const screenStateStore = context?.screenStateStore;
|
|
241
|
+
|
|
242
|
+
await screenSetVariable(
|
|
243
|
+
route,
|
|
244
|
+
screenStateStore,
|
|
245
|
+
{ entry: context?.entry, options: action.options },
|
|
246
|
+
action
|
|
247
|
+
);
|
|
244
248
|
|
|
245
249
|
return Promise.resolve(ActionResult.Success);
|
|
246
250
|
}
|
|
@@ -253,9 +257,11 @@ const prepareDefaultActions = (actionExecutor) => {
|
|
|
253
257
|
context?: Record<string, any>
|
|
254
258
|
): Promise<ActionResult> => {
|
|
255
259
|
const screenRoute = context?.screenRoute;
|
|
260
|
+
const screenStateStore = context?.screenStateStore;
|
|
256
261
|
|
|
257
262
|
await screenToggleFlag(
|
|
258
263
|
screenRoute,
|
|
264
|
+
screenStateStore,
|
|
259
265
|
{ entry: context?.entry, options: action.options },
|
|
260
266
|
action
|
|
261
267
|
);
|
|
@@ -4,22 +4,94 @@ import { log_error, log_info } from "./ActionExecutorContext";
|
|
|
4
4
|
import { ActionResult } from "./ActionExecutor";
|
|
5
5
|
import { get } from "lodash";
|
|
6
6
|
|
|
7
|
-
import { ScreenMultiSelectProvider } from "@applicaster/zapp-react-native-bridge/ZappStorage/ScreenStateMultiSelectProvider";
|
|
8
7
|
import { onMaxTagsReached } from "./StorageActions";
|
|
8
|
+
import { ScreenMultiSelectProvider } from "../storage/ScreenStateMultiSelectProvider";
|
|
9
|
+
import { ScreenSingleValueProvider } from "../storage/ScreenSingleValueProvider";
|
|
9
10
|
|
|
10
|
-
export const screenSetVariable = (
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
export const screenSetVariable = async (
|
|
12
|
+
screenRoute: string,
|
|
13
|
+
screenStateStore: ScreenStateStore,
|
|
14
|
+
context: Record<string, any>,
|
|
15
|
+
action: ActionType
|
|
16
|
+
): Promise<ActionResult> => {
|
|
17
|
+
if (!context) {
|
|
18
|
+
log_error("handleAction: screenSetVariable action missing context");
|
|
19
|
+
|
|
20
|
+
return ActionResult.Error;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const entry = context?.entry as ZappEntry;
|
|
24
|
+
|
|
25
|
+
if (!entry) {
|
|
26
|
+
log_error(
|
|
27
|
+
"handleAction: screenSetVariable action missing entry. Entry is required to get the value."
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
return ActionResult.Error;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const tag = action.options?.selector
|
|
34
|
+
? get(entry, action.options.selector)
|
|
35
|
+
: (entry.extensions?.tag ?? entry.id);
|
|
36
|
+
|
|
37
|
+
const keyNamespace = action.options?.key;
|
|
38
|
+
|
|
39
|
+
if (!keyNamespace) {
|
|
40
|
+
log_error("handleAction: screenSetVariable action missing key namespace", {
|
|
41
|
+
keyNamespace,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return ActionResult.Error;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!tag) {
|
|
48
|
+
log_error(
|
|
49
|
+
"handleAction: screenSetVariable action could not determine tag",
|
|
50
|
+
{ selector: action.options?.selector, value: action.options?.value }
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
return ActionResult.Error;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
const singleValueProvider = ScreenSingleValueProvider.getProvider(
|
|
58
|
+
keyNamespace,
|
|
59
|
+
screenRoute,
|
|
60
|
+
screenStateStore
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const currentValue = await singleValueProvider.getValueAsync();
|
|
64
|
+
|
|
65
|
+
log_info(
|
|
66
|
+
`handleAction: screenSetVariable setting value: ${tag} for keyNamespace: ${keyNamespace}, previous value: ${currentValue}`
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
await singleValueProvider.setValue(String(tag));
|
|
70
|
+
|
|
71
|
+
log_info(
|
|
72
|
+
`handleAction: screenSetVariable successfully set value: ${tag} for keyNamespace: ${keyNamespace}`
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
return ActionResult.Success;
|
|
76
|
+
} catch (error) {
|
|
77
|
+
log_error("handleAction: screenSetVariable failed to set value", {
|
|
78
|
+
keyNamespace,
|
|
79
|
+
tag,
|
|
80
|
+
error,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
return ActionResult.Error;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
15
86
|
|
|
16
87
|
export const screenToggleFlag = async (
|
|
17
88
|
screenRoute: string,
|
|
89
|
+
screenStateStore: ScreenStateStore,
|
|
18
90
|
context: Record<string, any>,
|
|
19
91
|
action: ActionType
|
|
20
92
|
) => {
|
|
21
93
|
if (!context) {
|
|
22
|
-
log_error("handleAction:
|
|
94
|
+
log_error("handleAction: screenToggleFlag action missing context");
|
|
23
95
|
|
|
24
96
|
return ActionResult.Error;
|
|
25
97
|
}
|
|
@@ -28,7 +100,7 @@ export const screenToggleFlag = async (
|
|
|
28
100
|
|
|
29
101
|
if (!entry) {
|
|
30
102
|
log_error(
|
|
31
|
-
"handleAction:
|
|
103
|
+
"handleAction: screenToggleFlag action missing entry. Entry is required to get the tag."
|
|
32
104
|
);
|
|
33
105
|
|
|
34
106
|
return ActionResult.Error;
|
|
@@ -43,7 +115,8 @@ export const screenToggleFlag = async (
|
|
|
43
115
|
if (keyNamespace && tag) {
|
|
44
116
|
const multiSelectProvider = ScreenMultiSelectProvider.getProvider(
|
|
45
117
|
keyNamespace,
|
|
46
|
-
screenRoute
|
|
118
|
+
screenRoute,
|
|
119
|
+
screenStateStore
|
|
47
120
|
);
|
|
48
121
|
|
|
49
122
|
const selectedItems = await multiSelectProvider.getSelectedAsync();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ActionResult } from "./ActionExecutor";
|
|
2
2
|
import { get } from "lodash";
|
|
3
|
-
import { StorageMultiSelectProvider } from "@applicaster/zapp-react-native-
|
|
3
|
+
import { StorageMultiSelectProvider } from "@applicaster/zapp-react-native-utils/storage/StorageMultiSelectProvider";
|
|
4
4
|
import { log_error, log_info } from "./ActionExecutorContext";
|
|
5
5
|
import { postEvent } from "../reactHooks/useSubscriberFor";
|
|
6
6
|
import { TOGGLE_FLAG_MAX_ITEMS_REACHED_EVENT } from "./consts";
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import * as R from "ramda";
|
|
2
|
+
import { getNamespaceAndKey } from "../appUtils/contextKeysManager/utils";
|
|
3
|
+
import { createLogger } from "../logger";
|
|
4
|
+
|
|
5
|
+
const { log_error, log_verbose } = createLogger({
|
|
6
|
+
subsystem: "FeedDecorator",
|
|
7
|
+
category: "General",
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
function getScope(scope) {
|
|
11
|
+
if (scope === "screen") {
|
|
12
|
+
return scope;
|
|
13
|
+
} else if (!scope || scope === "ctx") {
|
|
14
|
+
return "ctx";
|
|
15
|
+
} else {
|
|
16
|
+
log_verbose(
|
|
17
|
+
`decorateFeed: Unsupported scope "${scope}" provided in preference_editor_options. Defaulting to "ctx".`
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
return "ctx";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function makeMultiSelect(feed: ZappFeed, key, decoratedFeed) {
|
|
25
|
+
const scope = getScope(
|
|
26
|
+
decoratedFeed.extensions?.preference_editor_options?.scope
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const behavior = {
|
|
30
|
+
...feed.extensions?.["behavior"],
|
|
31
|
+
select_mode: "multi",
|
|
32
|
+
current_selection: `@{${scope}/${key}}`,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
if (!feed.extensions) {
|
|
36
|
+
decoratedFeed.extensions = {
|
|
37
|
+
behavior,
|
|
38
|
+
};
|
|
39
|
+
} else {
|
|
40
|
+
decoratedFeed.extensions.behavior = behavior;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const actionType =
|
|
44
|
+
decoratedFeed.extensions?.preference_editor_options?.scope === "screen"
|
|
45
|
+
? "screenToggleFlag"
|
|
46
|
+
: decoratedFeed.extensions?.preference_editor_options?.scope === "session"
|
|
47
|
+
? "sessionStorageToggleFlag"
|
|
48
|
+
: "localStorageToggleFlag";
|
|
49
|
+
|
|
50
|
+
decoratedFeed.entry?.forEach((entry: ZappEntry) => {
|
|
51
|
+
entry.type.value = "action";
|
|
52
|
+
entry.id = entry.extensions?.tag || entry.id;
|
|
53
|
+
|
|
54
|
+
entry.extensions = {
|
|
55
|
+
...(entry.extensions || {}),
|
|
56
|
+
tap_actions: {
|
|
57
|
+
actions: [
|
|
58
|
+
{
|
|
59
|
+
type: actionType,
|
|
60
|
+
options: {
|
|
61
|
+
key,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return decoratedFeed;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function makeSingleSelect(feed: ZappFeed, key, decoratedFeed) {
|
|
73
|
+
const scope = getScope(
|
|
74
|
+
decoratedFeed.extensions?.preference_editor_options?.scope
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const behavior = {
|
|
78
|
+
...feed.extensions?.["behavior"],
|
|
79
|
+
select_mode: "single",
|
|
80
|
+
current_selection: `@{${scope}/${key}}`,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
if (!feed.extensions) {
|
|
84
|
+
decoratedFeed.extensions = {
|
|
85
|
+
behavior,
|
|
86
|
+
};
|
|
87
|
+
} else {
|
|
88
|
+
decoratedFeed.extensions.behavior = behavior;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const localStorageProducer = (entry: ZappFeed) => {
|
|
92
|
+
entry.id = entry.extensions?.tag || entry.id;
|
|
93
|
+
const { key: keyName, namespace } = getNamespaceAndKey(key);
|
|
94
|
+
|
|
95
|
+
const action =
|
|
96
|
+
decoratedFeed.extensions?.preference_editor_options?.scope === "session"
|
|
97
|
+
? "sessionStorageSet"
|
|
98
|
+
: "localStorageSet";
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
type: action,
|
|
102
|
+
options: {
|
|
103
|
+
content: {
|
|
104
|
+
[namespace]: {
|
|
105
|
+
[keyName]: entry.id,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const screenStateProducer = (entry: ZappFeed) => {
|
|
113
|
+
entry.id = entry.extensions?.tag || entry.id;
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
type: "screenSetVariable",
|
|
117
|
+
options: {
|
|
118
|
+
key,
|
|
119
|
+
value: entry.id,
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const producer =
|
|
125
|
+
decoratedFeed.extensions?.preference_editor_options?.scope === "screen"
|
|
126
|
+
? screenStateProducer
|
|
127
|
+
: localStorageProducer;
|
|
128
|
+
|
|
129
|
+
decoratedFeed.entry?.forEach((entry: ZappEntry) => {
|
|
130
|
+
entry.type.value = "action";
|
|
131
|
+
|
|
132
|
+
entry.extensions = {
|
|
133
|
+
...(entry.extensions || {}),
|
|
134
|
+
tap_actions: {
|
|
135
|
+
actions: [producer(entry)],
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
return decoratedFeed;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export const decorateFeed = (feed: ZappFeed) => {
|
|
144
|
+
if (!(feed.extensions?.["role"] === "preference_editor")) {
|
|
145
|
+
return feed;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const key = feed.extensions?.["preference_editor_options"]?.["key"];
|
|
149
|
+
|
|
150
|
+
if (!key) {
|
|
151
|
+
log_error(
|
|
152
|
+
`decorateFeed: No 'key' provided in feed titled "${feed.title}" with id "${feed.id}" in preference_editor_options. The preference_editor role requires a key for local storage.`
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
throw new Error(
|
|
156
|
+
"decorateFeed: No 'key' provided in feed preference_editor_options"
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const decoratedFeed = R.clone(feed);
|
|
161
|
+
|
|
162
|
+
const isSingleSelect =
|
|
163
|
+
(feed.extensions?.["preference_editor_options"]?.select_mode ||
|
|
164
|
+
feed.extensions?.["behavior"]?.select_mode) === "single";
|
|
165
|
+
|
|
166
|
+
if (isSingleSelect) {
|
|
167
|
+
return makeSingleSelect(feed, key, decoratedFeed);
|
|
168
|
+
} else {
|
|
169
|
+
return makeMultiSelect(feed, key, decoratedFeed);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { ScreenStateResolver } from "../appUtils/contextKeysManager/contextResolver";
|
|
3
|
+
import { useScreenStateStore } from "../reactHooks/navigation/useScreenStateStore";
|
|
4
|
+
|
|
5
|
+
export const useScreenResolvers = () => {
|
|
6
|
+
const screenStateStore = useScreenStateStore();
|
|
7
|
+
|
|
8
|
+
return useMemo(() => {
|
|
9
|
+
return { screen: new ScreenStateResolver(screenStateStore) };
|
|
10
|
+
}, [screenStateStore]);
|
|
11
|
+
};
|
|
@@ -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-utils/storage/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
|
-
|
|
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",
|
|
@@ -1,8 +1,9 @@
|
|
|
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
5
|
import { AccessibilityRole } from "react-native";
|
|
6
|
+
import { toString } from "../../utils";
|
|
6
7
|
|
|
7
8
|
export class AccessibilityManager {
|
|
8
9
|
private static _instance: AccessibilityManager | null = null;
|
|
@@ -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) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ContextKeysManager } from "./index";
|
|
2
2
|
import * as R from "ramda";
|
|
3
|
-
import { screenStates } from "@applicaster/zapp-react-native-bridge/ZappStorage/ScreenSingleValueProvider";
|
|
4
3
|
|
|
5
4
|
export interface IResolver {
|
|
6
5
|
resolve: (string) => Promise<string | number | object>;
|
|
@@ -26,10 +25,10 @@ export class EntryResolver implements IResolver {
|
|
|
26
25
|
// TODO: Move to proper place
|
|
27
26
|
|
|
28
27
|
export class ScreenStateResolver implements IResolver {
|
|
29
|
-
constructor(private
|
|
28
|
+
constructor(private screenStateStore: ScreenStateStore) {}
|
|
30
29
|
|
|
31
30
|
async resolve(key: string) {
|
|
32
|
-
const screenState =
|
|
31
|
+
const screenState = this.screenStateStore.getState().data;
|
|
33
32
|
|
|
34
33
|
return screenState?.[key];
|
|
35
34
|
}
|
|
@@ -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
|
};
|