@applicaster/zapp-react-native-utils 16.0.0-rc.9 → 16.0.0-rc.91
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/ActionExecutor.ts +57 -12
- package/actionsExecutor/ActionExecutorContext.tsx +113 -314
- package/actionsExecutor/__tests__/ActionExecutor.test.ts +71 -0
- package/actionsExecutor/__tests__/feedDecorator.test.ts +61 -0
- package/actionsExecutor/actions/__tests__/dismissBottomSheet.test.ts +25 -0
- package/actionsExecutor/actions/__tests__/goBack.test.ts +62 -0
- package/actionsExecutor/actions/__tests__/goHome.test.ts +19 -0
- package/actionsExecutor/actions/__tests__/loadItemsFromSource.test.ts +88 -0
- package/actionsExecutor/actions/__tests__/navigateToScreen.test.ts +133 -0
- package/actionsExecutor/actions/__tests__/openBottomSheet.customContent.test.ts +76 -0
- package/actionsExecutor/actions/__tests__/openBottomSheet.inlineItems.test.ts +212 -0
- package/actionsExecutor/actions/__tests__/presentScreen.test.ts +127 -0
- package/actionsExecutor/actions/__tests__/showAlert.test.ts +49 -0
- package/actionsExecutor/actions/__tests__/showToast.test.ts +88 -0
- package/actionsExecutor/actions/appRestart.ts +24 -0
- package/actionsExecutor/actions/confirmDialog.ts +53 -0
- package/actionsExecutor/actions/dismissBottomSheet.ts +23 -0
- package/actionsExecutor/actions/goBack.ts +60 -0
- package/actionsExecutor/actions/goHome.ts +31 -0
- package/actionsExecutor/actions/index.ts +42 -0
- package/actionsExecutor/actions/localStorageRemove.ts +27 -0
- package/actionsExecutor/actions/localStorageSet.ts +28 -0
- package/actionsExecutor/actions/localStorageToggleFlag.ts +28 -0
- package/actionsExecutor/actions/navigateToScreen.ts +137 -0
- package/actionsExecutor/actions/openBottomSheet.ts +329 -0
- package/actionsExecutor/actions/presentScreen.ts +78 -0
- package/actionsExecutor/actions/refreshComponent.ts +85 -0
- package/actionsExecutor/actions/screenSetVariable.ts +35 -0
- package/actionsExecutor/actions/screenToggleFlag.ts +38 -0
- package/actionsExecutor/actions/sendCloudEvent.ts +93 -0
- package/actionsExecutor/actions/sessionStorageRemove.ts +19 -0
- package/actionsExecutor/actions/sessionStorageSet.ts +20 -0
- package/actionsExecutor/actions/sessionStorageToggleFlag.ts +15 -0
- package/actionsExecutor/actions/showAlert.ts +51 -0
- package/actionsExecutor/actions/showToast.ts +87 -0
- package/actionsExecutor/actions/switchLayout.ts +40 -0
- package/actionsExecutor/consts.ts +27 -0
- package/actionsExecutor/feedDecorator.ts +6 -6
- package/actionsExecutor/types.ts +59 -0
- package/analyticsUtils/AnalyticsEvents/sendMenuClickEvent.ts +2 -2
- package/analyticsUtils/PlayerAnalyticsManager.ts +12 -2
- package/analyticsUtils/__tests__/analyticsMapper.test.ts +35 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testACP_events.json +1 -1
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testBlockUnlistedParams_rules.json +1 -1
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testEmptyRenameKeepsName_events.json +4 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testEmptyRenameKeepsName_rules.json +6 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testEventRegex_events.json +3 -9
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testIgnoreOrdering_events.json +18 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testIgnoreOrdering_rules.json +16 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexEventNoFallback_events.json +4 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexEventNoFallback_rules.json +6 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexMultiGroupRename_events.json +4 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexMultiGroupRename_rules.json +6 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexNonNamedFullMatch_events.json +4 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexNonNamedFullMatch_rules.json +6 -0
- package/analyticsUtils/__tests__/fixtures/index.js +20 -0
- package/analyticsUtils/analyticsMapper.ts +4 -1
- package/analyticsUtils/playerAnalyticsTracker.ts +26 -3
- package/appUtils/HooksManager/index.ts +12 -8
- package/appUtils/contextKeysManager/__tests__/getKey/failure.test.ts +1 -1
- package/appUtils/contextKeysManager/__tests__/removeKey/failure.test.ts +1 -1
- package/appUtils/contextKeysManager/__tests__/setKey/failure/invalidKey.test.ts +4 -4
- package/appUtils/contextKeysManager/index.ts +1 -1
- package/appUtils/contextKeysManager/utils/index.ts +38 -25
- package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +143 -53
- package/appUtils/playerManager/OverlayObserver/__tests__/liveContent.test.ts +205 -0
- package/appUtils/playerManager/OverlayObserver/__tests__/utils.test.ts +49 -0
- package/appUtils/playerManager/OverlayObserver/getUpcomingQueue.android.tv.ts +4 -0
- package/appUtils/playerManager/OverlayObserver/getUpcomingQueue.ios.tv.ts +4 -0
- package/appUtils/playerManager/OverlayObserver/getUpcomingQueue.ts +11 -0
- package/appUtils/playerManager/OverlayObserver/getUpcomingQueue.web.ts +4 -0
- package/appUtils/playerManager/OverlayObserver/utils.ts +54 -20
- package/appUtils/playerManager/__tests__/playerContent.test.ts +403 -0
- package/appUtils/playerManager/__tests__/playerFactory.test.ts +1 -1
- package/appUtils/playerManager/__tests__/playerNative.test.ts +38 -0
- package/appUtils/playerManager/__tests__/usePlayerContent.test.tsx +64 -0
- package/appUtils/playerManager/{conts.ts → const.ts} +20 -0
- package/appUtils/playerManager/index.ts +1 -1
- package/appUtils/playerManager/player.ts +115 -3
- package/appUtils/playerManager/playerFactory.ts +1 -1
- package/appUtils/playerManager/playerNative.ts +6 -4
- package/appUtils/playerManager/usePlayerContent.tsx +43 -0
- package/appUtils/playerManager/usePlayerControllerSetup.tsx +1 -1
- package/appUtils/playerManager/userLanguagePreference.ts +1 -1
- package/arrayUtils/__tests__/{anyThruthy.test.ts → anyTruthy.test.ts} +8 -0
- package/arrayUtils/__tests__/arrayUtils.test.ts +165 -108
- package/arrayUtils/__tests__/isEmptyArray.test.ts +11 -0
- package/arrayUtils/__tests__/isFilledArray.test.ts +12 -0
- package/arrayUtils/__tests__/isFirst.test.ts +17 -0
- package/arrayUtils/__tests__/isIndexInRange.test.ts +14 -0
- package/arrayUtils/__tests__/isLast.test.ts +31 -0
- package/arrayUtils/__tests__/makeListOf.test.ts +31 -0
- package/arrayUtils/__tests__/makeListOfIndexes.test.ts +20 -0
- package/arrayUtils/__tests__/reorderByIds.test.ts +50 -0
- package/arrayUtils/__tests__/sample.test.ts +61 -0
- package/arrayUtils/index.ts +136 -20
- package/bottomSheet/__tests__/scrollContext.test.tsx +35 -0
- package/bottomSheet/index.ts +17 -0
- package/cellUtils/index.ts +33 -8
- package/colorUtils/__tests__/isTransparentColor.test.ts +76 -0
- package/colorUtils/__tests__/isValidColor.test.ts +70 -0
- package/colorUtils/index.ts +50 -0
- package/configurationUtils/__tests__/manifestKeyParser.test.ts +21 -0
- package/configurationUtils/__tests__/modalBlocksParser.test.ts +208 -0
- package/configurationUtils/manifestKeyParser.ts +50 -10
- package/configurationUtils/modalBlocksParser.ts +200 -0
- package/entryActions/__tests__/buildEntryActions.test.ts +235 -0
- package/entryActions/aliasPresentation.ts +108 -0
- package/entryActions/buildEntryActions.ts +167 -0
- package/entryActions/index.ts +15 -0
- package/entryActions/types.ts +39 -0
- package/manifestUtils/__tests__/player.audioControls.test.js +158 -0
- package/manifestUtils/_internals/index.js +14 -3
- package/manifestUtils/defaultManifestConfigurations/generalContent.js +41 -0
- package/manifestUtils/defaultManifestConfigurations/player.js +349 -20
- package/manifestUtils/fieldUtils/__tests__/fieldUtils.test.js +84 -0
- package/manifestUtils/fieldUtils/index.js +125 -0
- package/manifestUtils/index.js +3 -0
- package/manifestUtils/keys.js +9 -0
- package/manifestUtils/mobileAction/button/index.js +16 -0
- package/manifestUtils/mobileAction/container/index.js +3 -1
- package/manifestUtils/mobileAction/groups/defaults.js +3 -1
- package/manifestUtils/modalBlocks.js +304 -0
- package/manifestUtils/platformIsTV.js +1 -0
- package/modalState/ContentViewModel.ts +113 -0
- package/modalState/EditableCollection.ts +17 -0
- package/modalState/EditableCollectionRegistry.ts +51 -0
- package/modalState/ModalOrchestrator.ts +211 -0
- package/modalState/RemoteEditableCollection.ts +235 -0
- package/modalState/__tests__/ContentViewModel.editable.test.ts +69 -0
- package/modalState/__tests__/ContentViewModel.test.ts +165 -0
- package/modalState/__tests__/EditableCollectionRegistry.test.ts +112 -0
- package/modalState/__tests__/ModalOrchestrator.phase3.test.ts +47 -0
- package/modalState/__tests__/RemoteEditableCollection.test.ts +415 -0
- package/modalState/__tests__/index.test.ts +30 -1
- package/modalState/__tests__/useBottomSheetContent.test.ts +349 -0
- package/modalState/__tests__/useModalStoreState.test.ts +142 -0
- package/modalState/index.ts +35 -83
- package/modalState/store.ts +109 -0
- package/modalState/types.ts +160 -0
- package/modalState/useBottomSheetContent.ts +109 -0
- package/numberUtils/__tests__/isMinusZero.test.ts +20 -0
- package/numberUtils/__tests__/isZero.test.ts +27 -0
- package/numberUtils/__tests__/requireNumber.test.ts +50 -0
- package/numberUtils/__tests__/toNumber.test.ts +27 -0
- package/numberUtils/__tests__/toNumberWithDefault.test.ts +64 -0
- package/numberUtils/__tests__/toNumberWithDefaultZero.test.ts +48 -0
- package/numberUtils/index.ts +27 -8
- package/package.json +2 -2
- package/pipesUtils/__tests__/buildUrlWithQuery.test.ts +33 -0
- package/pipesUtils/__tests__/withPipesEndpoint.test.tsx +56 -0
- package/pipesUtils/index.ts +1 -0
- package/pipesUtils/withPipesEndpoint.tsx +54 -0
- package/playerUtils/__tests__/contentDataKeys.test.ts +297 -0
- package/playerUtils/__tests__/resolvePlayerActions.test.ts +138 -0
- package/playerUtils/__tests__/resolvePlayerTitleSubtitle.test.ts +180 -0
- package/playerUtils/contentDataKeys.ts +134 -0
- package/playerUtils/index.ts +41 -18
- package/playerUtils/isAudioItem.ts +26 -0
- package/playerUtils/resolvePlayerActions.ts +71 -0
- package/playerUtils/resolvePlayerTitleSubtitle.ts +76 -0
- package/reactHooks/actions/index.ts +117 -2
- package/reactHooks/cell-click/__tests__/index.test.js +64 -0
- package/reactHooks/cell-click/index.ts +39 -24
- package/reactHooks/feed/__mocks__/useMarkPipesDataStale.ts +4 -0
- package/reactHooks/feed/__tests__/useInflatedUrl.test.tsx +25 -0
- package/reactHooks/feed/index.ts +5 -1
- package/reactHooks/feed/useBatchLoading.ts +9 -1
- package/reactHooks/feed/{usePipesCacheReset.ts → useMarkPipesDataStale.ts} +12 -4
- package/reactHooks/index.ts +2 -0
- package/reactHooks/layout/index.ts +1 -1
- package/reactHooks/navigation/__mocks__/index.ts +4 -0
- package/reactHooks/navigation/__tests__/index.test.tsx +176 -1
- package/reactHooks/navigation/__tests__/useIsScreenActive.test.ts +42 -0
- package/reactHooks/navigation/__tests__/usePresentScreen.test.ts +154 -0
- package/reactHooks/navigation/index.ts +3 -1
- package/reactHooks/navigation/useIsScreenActive.ts +29 -8
- package/reactHooks/navigation/usePresentScreen.ts +157 -0
- package/reactHooks/navigation/useRoute.ts +22 -5
- package/reactHooks/state/useComponentScreenState.ts +1 -1
- package/reactHooks/usePluginConfiguration.ts +4 -1
- package/reactHooks/utils/__tests__/index.test.js +22 -2
- package/reactHooks/utils/index.ts +13 -2
- package/reactHooks/videoModal/hooks/useVideoModalScreenData.tsx +22 -4
- package/riverComponetsMeasurementProvider/index.tsx +12 -8
- package/stringUtils/__tests__/stringUtils.test.js +42 -0
- package/stringUtils/index.ts +2 -2
- package/uiActionsRegistrator/__tests__/resolveActionIdentifiers.test.ts +93 -0
- package/uiActionsRegistrator/__tests__/subscribe.test.ts +107 -0
- package/uiActionsRegistrator/__tests__/usableActionItems.test.ts +52 -0
- package/uiActionsRegistrator/index.ts +25 -0
- package/uiActionsRegistrator/registry.ts +335 -0
- package/uiActionsRegistrator/resolveActionIdentifiers.ts +100 -0
- package/uiActionsRegistrator/usableActionItems.ts +66 -0
- package/zappFrameworkUtils/__tests__/localStorageHelper.test.ts +146 -0
- package/zappFrameworkUtils/localStorageHelper.ts +19 -15
- package/appUtils/playerManager/usePlayerTitleSummaryOverlay.tsx +0 -56
- package/playerUtils/__tests__/getPlayerActionButtons.test.ts +0 -54
- package/playerUtils/getPlayerActionButtons.ts +0 -17
- package/reactHooks/feed/__mocks__/usePipesCacheReset.ts +0 -1
- /package/reactHooks/actions/__tests__/{index.test.js → index.test.tsx} +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createLogger } from "../logger";
|
|
2
|
+
import type { ActionExecutionContext, ActionHandler } from "./types";
|
|
2
3
|
|
|
3
4
|
export enum ActionResult {
|
|
4
5
|
Success = "success",
|
|
@@ -11,13 +12,13 @@ const { log_error, log_debug, log_info } = createLogger({
|
|
|
11
12
|
category: "General",
|
|
12
13
|
});
|
|
13
14
|
|
|
14
|
-
class ActionExecutor {
|
|
15
|
-
private registeredActions: Record<string,
|
|
16
|
-
// TODO: Remove context
|
|
15
|
+
export class ActionExecutor {
|
|
16
|
+
private registeredActions: Record<string, ActionHandler> = {};
|
|
17
17
|
|
|
18
|
+
// TODO: Remove context
|
|
18
19
|
handleAction = async (
|
|
19
20
|
action: ActionType,
|
|
20
|
-
context?:
|
|
21
|
+
context?: ActionExecutionContext
|
|
21
22
|
): Promise<ActionResult> => {
|
|
22
23
|
const handler = this.registeredActions[action.type];
|
|
23
24
|
const entry = context?.entry as ZappEntry;
|
|
@@ -52,10 +53,9 @@ class ActionExecutor {
|
|
|
52
53
|
|
|
53
54
|
handleActions = async (
|
|
54
55
|
actionTypes: ActionType[],
|
|
55
|
-
context?:
|
|
56
|
+
context?: ActionExecutionContext
|
|
56
57
|
): Promise<ActionResult> => {
|
|
57
58
|
for (const action of actionTypes) {
|
|
58
|
-
// TODO: Handle action result error
|
|
59
59
|
const result = await this.handleAction(action, context);
|
|
60
60
|
|
|
61
61
|
if (result === ActionResult.Cancel) {
|
|
@@ -63,6 +63,16 @@ class ActionExecutor {
|
|
|
63
63
|
|
|
64
64
|
return result;
|
|
65
65
|
}
|
|
66
|
+
|
|
67
|
+
if (result === ActionResult.Error) {
|
|
68
|
+
// Everything after a failed step was written for a state that never
|
|
69
|
+
// happened — the event was refused, the screen never opened — so
|
|
70
|
+
// running it is how a chain ends up telling the user their mail was
|
|
71
|
+
// sent when it was not.
|
|
72
|
+
log_error(`handleActions: action: ${action.type} failed`, { action });
|
|
73
|
+
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
66
76
|
}
|
|
67
77
|
|
|
68
78
|
return ActionResult.Success;
|
|
@@ -70,7 +80,7 @@ class ActionExecutor {
|
|
|
70
80
|
|
|
71
81
|
handleEntryActions = async (
|
|
72
82
|
entry: ZappEntry,
|
|
73
|
-
context?:
|
|
83
|
+
context?: ActionExecutionContext
|
|
74
84
|
): Promise<ActionResult> => {
|
|
75
85
|
const tapActions = entry.extensions?.tap_actions?.actions;
|
|
76
86
|
|
|
@@ -98,12 +108,10 @@ class ActionExecutor {
|
|
|
98
108
|
delete this.registeredActions[actionType];
|
|
99
109
|
};
|
|
100
110
|
|
|
101
|
-
registerAction = (
|
|
111
|
+
registerAction = <TOptions = Record<string, any>>(
|
|
102
112
|
type: string,
|
|
103
|
-
handler:
|
|
104
|
-
|
|
105
|
-
context?: Record<string, any>
|
|
106
|
-
) => Promise<ActionResult>
|
|
113
|
+
handler: ActionHandler<TOptions>,
|
|
114
|
+
stateResolver?: (entry?: ZappEntry) => any
|
|
107
115
|
) => {
|
|
108
116
|
if (this.registeredActions[type]) {
|
|
109
117
|
log_error(`registerAction: action type: ${type} already registered`);
|
|
@@ -114,11 +122,48 @@ class ActionExecutor {
|
|
|
114
122
|
this.registeredActions[type] = handler;
|
|
115
123
|
log_debug(`registerAction: action type: ${type} registered`);
|
|
116
124
|
|
|
125
|
+
let unregisterState = () => {};
|
|
126
|
+
|
|
127
|
+
if (stateResolver) {
|
|
128
|
+
unregisterState = this.registerActionState(type, stateResolver);
|
|
129
|
+
}
|
|
130
|
+
|
|
117
131
|
return () => {
|
|
118
132
|
this.unregisterAction(type);
|
|
133
|
+
unregisterState();
|
|
119
134
|
log_debug(`registerAction: action type: ${type} un-registered`);
|
|
120
135
|
};
|
|
121
136
|
};
|
|
137
|
+
|
|
138
|
+
private actionStates: Record<string, (entry?: ZappEntry) => any> = {};
|
|
139
|
+
|
|
140
|
+
registerActionState = (
|
|
141
|
+
type: string,
|
|
142
|
+
stateResolver: (entry?: ZappEntry) => any
|
|
143
|
+
) => {
|
|
144
|
+
if (this.actionStates[type]) {
|
|
145
|
+
log_error(
|
|
146
|
+
`registerActionState: action type state: ${type} already registered`
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
return () => {};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
this.actionStates[type] = stateResolver;
|
|
153
|
+
log_debug(`registerActionState: action type state: ${type} registered`);
|
|
154
|
+
|
|
155
|
+
return () => {
|
|
156
|
+
delete this.actionStates[type];
|
|
157
|
+
|
|
158
|
+
log_debug(
|
|
159
|
+
`registerActionState: action type state: ${type} un-registered`
|
|
160
|
+
);
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
getActionState = (type: string, entry?: ZappEntry) => {
|
|
165
|
+
return this.actionStates[type]?.(entry);
|
|
166
|
+
};
|
|
122
167
|
}
|
|
123
168
|
|
|
124
169
|
export const actionExecutor = new ActionExecutor();
|
|
@@ -5,300 +5,150 @@ import {
|
|
|
5
5
|
actionExecutor as _actionExecutor,
|
|
6
6
|
ActionResult,
|
|
7
7
|
} from "./ActionExecutor";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
batchSave,
|
|
11
|
-
} from "../zappFrameworkUtils/localStorageHelper";
|
|
8
|
+
import { ActionExecutionContext, ActionHandler } from "./types";
|
|
9
|
+
import { batchRemoveAllFromNamespaceForStorage } from "../zappFrameworkUtils/localStorageHelper";
|
|
12
10
|
import { sessionStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage";
|
|
13
11
|
|
|
14
|
-
import
|
|
15
|
-
import { QUICK_BRICK_EVENTS } from "@applicaster/zapp-react-native-bridge/QuickBrick";
|
|
16
|
-
import { showConfirmationDialog } from "../alertUtils";
|
|
17
|
-
import { createCloudEvent, sendCloudEvent } from "../cloudEventsUtils";
|
|
18
|
-
import { createLogger } from "../logger";
|
|
19
|
-
import { ACTIVE_LAYOUT_ID_STORAGE_KEY } from "@applicaster/quick-brick-core/App/remoteContextReloader/consts";
|
|
20
|
-
import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
|
|
21
|
-
import { loadPipesData } from "@applicaster/zapp-react-native-redux/ZappPipes";
|
|
22
|
-
import {
|
|
23
|
-
EntryResolver,
|
|
24
|
-
resolveObjectValues,
|
|
25
|
-
} from "../appUtils/contextKeysManager/contextResolver";
|
|
26
|
-
import { useNavigation, useRivers } from "../reactHooks";
|
|
27
|
-
import {
|
|
28
|
-
getInflatedDataSourceUrl,
|
|
29
|
-
getSearchContext,
|
|
30
|
-
} from "../reactHooks/feed/useInflatedUrl";
|
|
31
|
-
|
|
12
|
+
import { useNavigation, usePresentScreen, useRivers } from "../reactHooks";
|
|
32
13
|
import { useContentTypes } from "@applicaster/zapp-react-native-redux/hooks";
|
|
33
14
|
import { useSubscriberFor } from "../reactHooks/useSubscriberFor";
|
|
34
15
|
import { APP_EVENTS } from "../appUtils/events";
|
|
35
|
-
import {
|
|
36
|
-
localStorageToggleFlag,
|
|
37
|
-
sessionStorageToggleFlag,
|
|
38
|
-
} from "./StorageActions";
|
|
16
|
+
import { createLogger } from "../logger";
|
|
39
17
|
|
|
40
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
appRestartAction,
|
|
20
|
+
confirmDialogAction,
|
|
21
|
+
showAlertAction,
|
|
22
|
+
createGoBackAction,
|
|
23
|
+
createGoHomeAction,
|
|
24
|
+
createNavigateToScreenAction,
|
|
25
|
+
dismissBottomSheetAction,
|
|
26
|
+
localStorageRemoveAction,
|
|
27
|
+
localStorageSetAction,
|
|
28
|
+
localStorageToggleFlagAction,
|
|
29
|
+
createPresentScreenAction,
|
|
30
|
+
openBottomSheetAction,
|
|
31
|
+
refreshComponentAction,
|
|
32
|
+
screenSetVariableAction,
|
|
33
|
+
screenToggleFlagAction,
|
|
34
|
+
sendCloudEventAction,
|
|
35
|
+
sessionStorageRemoveAction,
|
|
36
|
+
sessionStorageSetAction,
|
|
37
|
+
sessionStorageToggleFlagAction,
|
|
38
|
+
switchLayoutAction,
|
|
39
|
+
showToastAction,
|
|
40
|
+
} from "./actions";
|
|
41
|
+
|
|
42
|
+
import { ACTION_TYPES } from "./consts";
|
|
41
43
|
|
|
42
44
|
export const { log_error, log_info, log_debug } = createLogger({
|
|
43
45
|
subsystem: "ActionExecutorContext",
|
|
44
46
|
category: "General",
|
|
45
47
|
});
|
|
46
48
|
|
|
47
|
-
type ActionExecutorContextType = {
|
|
48
|
-
registerAction: (
|
|
49
|
+
export type ActionExecutorContextType = {
|
|
50
|
+
registerAction: <TOptions = Record<string, any>>(
|
|
49
51
|
type: string,
|
|
50
|
-
handler:
|
|
51
|
-
|
|
52
|
-
context?: Record<string, any>
|
|
53
|
-
) => Promise<ActionResult>
|
|
52
|
+
handler: ActionHandler<TOptions>,
|
|
53
|
+
stateResolver?: (entry?: ZappEntry) => any
|
|
54
54
|
) => void;
|
|
55
55
|
unregisterAction: (type: string) => void;
|
|
56
|
+
registerActionState: (
|
|
57
|
+
type: string,
|
|
58
|
+
stateResolver: (entry?: ZappEntry) => any
|
|
59
|
+
) => () => void;
|
|
60
|
+
getActionState: (type: string, entry?: ZappEntry) => any;
|
|
56
61
|
handleAction: (
|
|
57
62
|
action: ActionType,
|
|
58
|
-
context?:
|
|
63
|
+
context?: ActionExecutionContext
|
|
59
64
|
) => Promise<ActionResult>;
|
|
60
65
|
handleActions: (
|
|
61
66
|
actions: ActionType[],
|
|
62
|
-
context
|
|
67
|
+
context?: ActionExecutionContext
|
|
63
68
|
) => Promise<ActionResult>;
|
|
64
69
|
handleEntryActions: (
|
|
65
70
|
entry: ZappEntry,
|
|
66
|
-
context?:
|
|
71
|
+
context?: ActionExecutionContext
|
|
67
72
|
) => Promise<ActionResult>;
|
|
68
73
|
};
|
|
74
|
+
|
|
69
75
|
type Props = {
|
|
70
76
|
children: React.ReactNode;
|
|
71
77
|
};
|
|
72
78
|
|
|
73
|
-
function findParentComponent(
|
|
74
|
-
childId: string,
|
|
75
|
-
parent: ZappRiver | ZappUIComponent
|
|
76
|
-
): ZappRiver | ZappUIComponent | null {
|
|
77
|
-
for (const child of parent.ui_components) {
|
|
78
|
-
if (child.id === childId) return parent;
|
|
79
|
-
|
|
80
|
-
if (child.ui_components) {
|
|
81
|
-
const found = findParentComponent(childId, child);
|
|
82
|
-
if (found) return found;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
79
|
const prepareDefaultActions = (actionExecutor) => {
|
|
90
|
-
actionExecutor.registerAction("localStorageSet", async (action) => {
|
|
91
|
-
const namespaces = action.options.content;
|
|
92
|
-
await batchSave(namespaces, localStorage);
|
|
93
|
-
// TODO: Add support for ownershipKey and ownershipNamespace
|
|
94
|
-
|
|
95
|
-
return ActionResult.Success;
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
actionExecutor.registerAction("sessionStorageSet", async (action) => {
|
|
99
|
-
const namespaces = action.options.content;
|
|
100
|
-
await batchSave(namespaces, sessionStorage);
|
|
101
|
-
// TODO: Add support for ownershipKey and ownershipNamespace
|
|
102
|
-
|
|
103
|
-
return ActionResult.Success;
|
|
104
|
-
});
|
|
105
|
-
|
|
106
80
|
actionExecutor.registerAction(
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const dispatch = appStore.getDispatch();
|
|
110
|
-
|
|
111
|
-
const parentComponent = findParentComponent(
|
|
112
|
-
context?.component?.id,
|
|
113
|
-
context?.screenData
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
const componentSource = context?.component?.data?.source;
|
|
117
|
-
|
|
118
|
-
const componentData = componentSource
|
|
119
|
-
? context.component.data
|
|
120
|
-
: parentComponent?.data;
|
|
121
|
-
|
|
122
|
-
const source = componentData?.source;
|
|
123
|
-
const mapping = componentData?.mapping;
|
|
124
|
-
|
|
125
|
-
let dataSource = source;
|
|
126
|
-
|
|
127
|
-
if (source && mapping) {
|
|
128
|
-
dataSource =
|
|
129
|
-
getInflatedDataSourceUrl({
|
|
130
|
-
source,
|
|
131
|
-
contexts: {
|
|
132
|
-
entry: context?.entryContext,
|
|
133
|
-
screen: context?.screenData,
|
|
134
|
-
search: getSearchContext(null, mapping),
|
|
135
|
-
},
|
|
136
|
-
mapping,
|
|
137
|
-
}) || source;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
log_info(`handleAction: refreshComponent for dataSource:${dataSource}`, {
|
|
141
|
-
source,
|
|
142
|
-
inflatedUrl: dataSource,
|
|
143
|
-
mapping,
|
|
144
|
-
entryContextId: context?.entryContext?.id,
|
|
145
|
-
entryId: context?.entry?.id,
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
// TODO: In theory we should wait callback to complete, before completing the action, but now it's not needed
|
|
149
|
-
// TODO: handle focused item removal
|
|
150
|
-
dispatch(
|
|
151
|
-
loadPipesData(dataSource, {
|
|
152
|
-
silentRefresh: false,
|
|
153
|
-
clearCache: true,
|
|
154
|
-
riverId: context?.screenData?.id,
|
|
155
|
-
})
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
return ActionResult.Success;
|
|
159
|
-
}
|
|
81
|
+
ACTION_TYPES.LOCAL_STORAGE_SET,
|
|
82
|
+
localStorageSetAction
|
|
160
83
|
);
|
|
161
84
|
|
|
162
|
-
actionExecutor.registerAction(
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
ACTIVE_LAYOUT_ID_STORAGE_KEY,
|
|
167
|
-
action.options.layoutId
|
|
168
|
-
);
|
|
169
|
-
|
|
170
|
-
QuickBrickManager.sendQuickBrickEvent(QUICK_BRICK_EVENTS.FORCE_APP_RELOAD);
|
|
171
|
-
|
|
172
|
-
return ActionResult.Success;
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
actionExecutor.registerAction("appRestart", async () => {
|
|
176
|
-
log_info(`handleAction: ${QUICK_BRICK_EVENTS.FORCE_APP_RELOAD} event`);
|
|
177
|
-
|
|
178
|
-
QuickBrickManager.sendQuickBrickEvent(QUICK_BRICK_EVENTS.FORCE_APP_RELOAD);
|
|
179
|
-
|
|
180
|
-
return ActionResult.Success;
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
actionExecutor.registerAction("confirmDialog", async (action) => {
|
|
184
|
-
log_info("handleAction: confirmDialog event");
|
|
185
|
-
|
|
186
|
-
return new Promise<ActionResult>((resolve) => {
|
|
187
|
-
showConfirmationDialog({
|
|
188
|
-
...action.options,
|
|
189
|
-
confirmCompletion: () => resolve(ActionResult.Success),
|
|
190
|
-
cancelCompletion: () => resolve(ActionResult.Cancel),
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
actionExecutor.registerAction("sendCloudEvent", async (action, context) => {
|
|
196
|
-
try {
|
|
197
|
-
const options = action.options;
|
|
198
|
-
|
|
199
|
-
const entry = context?.entry || {};
|
|
200
|
-
const entryResolver = new EntryResolver(entry);
|
|
201
|
-
const screenData = context?.screenStateStore.getState().data || {};
|
|
202
|
-
const screenResolver = new EntryResolver(screenData || {});
|
|
203
|
-
|
|
204
|
-
const data =
|
|
205
|
-
options?.data && options.inflateData
|
|
206
|
-
? await resolveObjectValues(options.data, {
|
|
207
|
-
entry: entryResolver,
|
|
208
|
-
screen: screenResolver,
|
|
209
|
-
})
|
|
210
|
-
: options?.data || entry;
|
|
85
|
+
actionExecutor.registerAction(
|
|
86
|
+
ACTION_TYPES.SESSION_STORAGE_SET,
|
|
87
|
+
sessionStorageSetAction
|
|
88
|
+
);
|
|
211
89
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
});
|
|
90
|
+
actionExecutor.registerAction(
|
|
91
|
+
ACTION_TYPES.LOCAL_STORAGE_REMOVE,
|
|
92
|
+
localStorageRemoveAction
|
|
93
|
+
);
|
|
217
94
|
|
|
218
|
-
|
|
95
|
+
actionExecutor.registerAction(
|
|
96
|
+
ACTION_TYPES.SESSION_STORAGE_REMOVE,
|
|
97
|
+
sessionStorageRemoveAction
|
|
98
|
+
);
|
|
219
99
|
|
|
220
|
-
|
|
100
|
+
actionExecutor.registerAction(
|
|
101
|
+
ACTION_TYPES.REFRESH_COMPONENT,
|
|
102
|
+
refreshComponentAction
|
|
103
|
+
);
|
|
221
104
|
|
|
222
|
-
|
|
223
|
-
log_error("sendCloudEvent: error sending cloud event", { error });
|
|
105
|
+
actionExecutor.registerAction(ACTION_TYPES.SWITCH_LAYOUT, switchLayoutAction);
|
|
224
106
|
|
|
225
|
-
|
|
226
|
-
}
|
|
107
|
+
actionExecutor.registerAction(ACTION_TYPES.APP_RESTART, appRestartAction);
|
|
227
108
|
|
|
228
|
-
|
|
229
|
-
|
|
109
|
+
actionExecutor.registerAction(
|
|
110
|
+
ACTION_TYPES.CONFIRM_DIALOG,
|
|
111
|
+
confirmDialogAction
|
|
112
|
+
);
|
|
230
113
|
|
|
231
|
-
|
|
232
|
-
}
|
|
233
|
-
} catch (error) {
|
|
234
|
-
log_error("sendCloudEvent: error sending cloud event", {
|
|
235
|
-
action,
|
|
236
|
-
error,
|
|
237
|
-
});
|
|
238
|
-
}
|
|
114
|
+
actionExecutor.registerAction(ACTION_TYPES.SHOW_ALERT, showAlertAction);
|
|
239
115
|
|
|
240
|
-
|
|
241
|
-
|
|
116
|
+
actionExecutor.registerAction(
|
|
117
|
+
ACTION_TYPES.SEND_CLOUD_EVENT,
|
|
118
|
+
sendCloudEventAction
|
|
119
|
+
);
|
|
242
120
|
|
|
243
121
|
actionExecutor.registerAction(
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
action: ActionType,
|
|
247
|
-
context?: Record<string, any>
|
|
248
|
-
): Promise<ActionResult> => {
|
|
249
|
-
return await sessionStorageToggleFlag(context, action);
|
|
250
|
-
}
|
|
122
|
+
ACTION_TYPES.SESSION_STORAGE_TOGGLE_FLAG,
|
|
123
|
+
sessionStorageToggleFlagAction
|
|
251
124
|
);
|
|
252
125
|
|
|
253
126
|
actionExecutor.registerAction(
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
action: ActionType,
|
|
257
|
-
context?: Record<string, any>
|
|
258
|
-
): Promise<ActionResult> => {
|
|
259
|
-
return await localStorageToggleFlag(context, action);
|
|
260
|
-
}
|
|
127
|
+
ACTION_TYPES.LOCAL_STORAGE_TOGGLE_FLAG,
|
|
128
|
+
localStorageToggleFlagAction
|
|
261
129
|
);
|
|
262
130
|
|
|
263
131
|
actionExecutor.registerAction(
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
context?: Record<string, any>
|
|
268
|
-
): Promise<ActionResult> => {
|
|
269
|
-
const route = context?.screenRoute;
|
|
270
|
-
const screenStateStore = context?.screenStateStore;
|
|
271
|
-
|
|
272
|
-
await screenSetVariable(
|
|
273
|
-
route,
|
|
274
|
-
screenStateStore,
|
|
275
|
-
{ entry: context?.entry, options: action.options },
|
|
276
|
-
action
|
|
277
|
-
);
|
|
132
|
+
ACTION_TYPES.SCREEN_SET_VARIABLE,
|
|
133
|
+
screenSetVariableAction
|
|
134
|
+
);
|
|
278
135
|
|
|
279
|
-
|
|
280
|
-
|
|
136
|
+
actionExecutor.registerAction(
|
|
137
|
+
ACTION_TYPES.SCREEN_TOGGLE_FLAG,
|
|
138
|
+
screenToggleFlagAction
|
|
281
139
|
);
|
|
282
140
|
|
|
283
141
|
actionExecutor.registerAction(
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
context?: Record<string, any>
|
|
288
|
-
): Promise<ActionResult> => {
|
|
289
|
-
const screenRoute = context?.screenRoute;
|
|
290
|
-
const screenStateStore = context?.screenStateStore;
|
|
291
|
-
|
|
292
|
-
await screenToggleFlag(
|
|
293
|
-
screenRoute,
|
|
294
|
-
screenStateStore,
|
|
295
|
-
{ entry: context?.entry, options: action.options },
|
|
296
|
-
action
|
|
297
|
-
);
|
|
142
|
+
ACTION_TYPES.OPEN_BOTTOM_SHEET,
|
|
143
|
+
openBottomSheetAction
|
|
144
|
+
);
|
|
298
145
|
|
|
299
|
-
|
|
300
|
-
|
|
146
|
+
actionExecutor.registerAction(
|
|
147
|
+
ACTION_TYPES.DISMISS_BOTTOM_SHEET,
|
|
148
|
+
dismissBottomSheetAction
|
|
301
149
|
);
|
|
150
|
+
|
|
151
|
+
actionExecutor.registerAction(ACTION_TYPES.SHOW_TOAST, showToastAction);
|
|
302
152
|
};
|
|
303
153
|
|
|
304
154
|
export const ActionExecutorContext =
|
|
@@ -311,11 +161,14 @@ export function withActionExecutor(Component) {
|
|
|
311
161
|
const navigator = useNavigation();
|
|
312
162
|
const rivers = useRivers();
|
|
313
163
|
const contentTypes = useContentTypes();
|
|
164
|
+
const presentScreen = usePresentScreen();
|
|
314
165
|
|
|
315
166
|
const handlers = useMemo(() => {
|
|
316
167
|
return {
|
|
317
168
|
unregisterAction: _actionExecutor.unregisterAction,
|
|
318
169
|
registerAction: _actionExecutor.registerAction,
|
|
170
|
+
registerActionState: _actionExecutor.registerActionState,
|
|
171
|
+
getActionState: _actionExecutor.getActionState,
|
|
319
172
|
handleAction: _actionExecutor.handleAction,
|
|
320
173
|
handleActions: _actionExecutor.handleActions,
|
|
321
174
|
handleEntryActions: _actionExecutor.handleEntryActions,
|
|
@@ -338,85 +191,31 @@ export function withActionExecutor(Component) {
|
|
|
338
191
|
|
|
339
192
|
useEffect(() => {
|
|
340
193
|
return _actionExecutor.registerAction(
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
if (!screenType) {
|
|
347
|
-
log_error("navigateToScreen: typeMapping option is missing");
|
|
348
|
-
|
|
349
|
-
return ActionResult.Error;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
const navigationAction = action.options?.navigationAction;
|
|
353
|
-
const entrySource = action.options?.entry;
|
|
354
|
-
|
|
355
|
-
const entry = entrySource
|
|
356
|
-
? entrySource === "@{entry/}"
|
|
357
|
-
? context?.entry
|
|
358
|
-
: entrySource
|
|
359
|
-
: null;
|
|
360
|
-
|
|
361
|
-
if (entry) {
|
|
362
|
-
if (typeof entry !== "object") {
|
|
363
|
-
log_error(
|
|
364
|
-
`navigateToScreen: entry option is not an object, entry: ${entry}`
|
|
365
|
-
);
|
|
366
|
-
|
|
367
|
-
return ActionResult.Error;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
log_info(
|
|
371
|
-
`navigateToScreen: navigating to screen type: ${screenType} with entry id: ${entry.id}`
|
|
372
|
-
);
|
|
373
|
-
|
|
374
|
-
const overriddenEntry = {
|
|
375
|
-
...entry,
|
|
376
|
-
type: {
|
|
377
|
-
value: screenType,
|
|
378
|
-
},
|
|
379
|
-
};
|
|
380
|
-
|
|
381
|
-
if (navigationAction === "push") {
|
|
382
|
-
navigator.push(overriddenEntry);
|
|
383
|
-
} else {
|
|
384
|
-
navigator.replace(overriddenEntry);
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
return ActionResult.Success;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
const screenId = contentTypes?.[screenType]?.screen_id || null;
|
|
391
|
-
|
|
392
|
-
if (!screenId) {
|
|
393
|
-
log_error(
|
|
394
|
-
`navigateToScreen: can not resolve screen type mapping: ${screenType}`
|
|
395
|
-
);
|
|
396
|
-
|
|
397
|
-
return ActionResult.Error;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
const river = rivers[screenId];
|
|
401
|
-
|
|
402
|
-
if (!river) {
|
|
403
|
-
log_error("navigateToScreen: can not resolve river");
|
|
404
|
-
|
|
405
|
-
return ActionResult.Error;
|
|
406
|
-
}
|
|
194
|
+
ACTION_TYPES.NAVIGATE_TO_SCREEN,
|
|
195
|
+
createNavigateToScreenAction(navigator, rivers, contentTypes)
|
|
196
|
+
);
|
|
197
|
+
}, [navigator, rivers, contentTypes]);
|
|
407
198
|
|
|
408
|
-
|
|
199
|
+
useEffect(() => {
|
|
200
|
+
return _actionExecutor.registerAction(
|
|
201
|
+
ACTION_TYPES.PRESENT_SCREEN,
|
|
202
|
+
createPresentScreenAction(presentScreen)
|
|
203
|
+
);
|
|
204
|
+
}, [presentScreen]);
|
|
409
205
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
206
|
+
useEffect(() => {
|
|
207
|
+
return _actionExecutor.registerAction(
|
|
208
|
+
ACTION_TYPES.GO_BACK,
|
|
209
|
+
createGoBackAction(navigator)
|
|
210
|
+
);
|
|
211
|
+
}, [navigator]);
|
|
415
212
|
|
|
416
|
-
|
|
417
|
-
|
|
213
|
+
useEffect(() => {
|
|
214
|
+
return _actionExecutor.registerAction(
|
|
215
|
+
ACTION_TYPES.GO_HOME,
|
|
216
|
+
createGoHomeAction(navigator)
|
|
418
217
|
);
|
|
419
|
-
}, [navigator
|
|
218
|
+
}, [navigator]);
|
|
420
219
|
|
|
421
220
|
return (
|
|
422
221
|
<ActionExecutorContext.Provider value={handlers}>
|