@applicaster/zapp-react-native-utils 15.1.0-rc.1 → 16.0.0-rc.1
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/README.md +0 -6
- package/actionUtils/index.ts +7 -0
- package/actionsExecutor/ActionExecutorContext.tsx +43 -12
- package/actionsExecutor/feedDecorator.ts +6 -6
- package/adsUtils/__tests__/createVMAP.test.ts +419 -0
- package/adsUtils/index.ts +2 -2
- package/analyticsUtils/README.md +1 -1
- package/appDataUtils/__tests__/urlScheme.test.ts +678 -0
- package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +0 -188
- package/appUtils/HooksManager/__tests__/hooksManager.test.js +16 -2
- package/appUtils/HooksManager/index.ts +10 -10
- package/appUtils/RiverFocusManager/{index.js → index.ts} +25 -18
- package/appUtils/accessibilityManager/const.ts +4 -0
- package/appUtils/accessibilityManager/utils.ts +0 -1
- package/appUtils/contextKeysManager/__tests__/getKeys/failure.test.ts +7 -2
- package/appUtils/contextKeysManager/__tests__/getKeys/success.test.ts +48 -0
- package/appUtils/contextKeysManager/contextResolver.ts +51 -22
- package/appUtils/contextKeysManager/index.ts +65 -10
- package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +3 -0
- package/appUtils/focusManager/index.ios.ts +43 -4
- package/appUtils/focusManager/treeDataStructure/Tree/__tests__/Tree.test.js +46 -0
- package/appUtils/focusManager/treeDataStructure/Tree/index.js +18 -18
- package/appUtils/focusManagerAux/utils/index.ios.ts +122 -0
- package/appUtils/focusManagerAux/utils/index.ts +11 -3
- package/appUtils/focusManagerAux/utils/utils.ios.ts +202 -3
- package/appUtils/keyCodes/keys/keys.web.ts +1 -4
- package/appUtils/orientationHelper.ts +2 -4
- package/appUtils/platform/platformUtils.ts +1 -1
- package/appUtils/playerManager/player.ts +4 -0
- package/appUtils/playerManager/playerNative.ts +30 -21
- package/appUtils/playerManager/usePlayerState.tsx +14 -2
- package/cloudEventsUtils/__tests__/index.test.ts +529 -0
- package/cloudEventsUtils/index.ts +65 -1
- package/componentsUtils/index.ts +8 -0
- package/configurationUtils/__tests__/manifestKeyParser.test.ts +26 -26
- package/enumUtils/__tests__/getEnumKeyByEnumValue.test.ts +207 -0
- package/errorUtils/__tests__/GeneralError.test.ts +97 -0
- package/errorUtils/__tests__/HttpStatusCode.test.ts +344 -0
- package/errorUtils/__tests__/MissingPluginError.test.ts +113 -0
- package/errorUtils/__tests__/NetworkError.test.ts +202 -0
- package/errorUtils/__tests__/getParsedResponse.test.ts +188 -0
- package/errorUtils/__tests__/invariant.test.ts +112 -0
- package/focusManager/aux/index.ts +1 -1
- package/headersUtils/__tests__/headersUtils.test.js +11 -1
- package/headersUtils/index.ts +2 -1
- package/manifestUtils/_internals/__tests__/index.test.js +41 -0
- package/manifestUtils/_internals/index.js +33 -0
- package/manifestUtils/defaultManifestConfigurations/player.js +59 -1
- package/manifestUtils/fieldUtils/__tests__/fieldUtils.test.js +49 -0
- package/manifestUtils/fieldUtils/index.js +54 -0
- package/manifestUtils/index.js +2 -0
- package/manifestUtils/keys.js +228 -0
- package/manifestUtils/mobileAction/button/__tests__/mobileActionButton.test.js +168 -0
- package/manifestUtils/mobileAction/button/index.js +140 -0
- package/manifestUtils/mobileAction/container/__tests__/mobileActionButtonsContainer.test.js +102 -0
- package/manifestUtils/mobileAction/container/index.js +73 -0
- package/manifestUtils/mobileAction/groups/__tests__/buildMobileActionButtonGroups.test.js +127 -0
- package/manifestUtils/mobileAction/groups/defaults.js +76 -0
- package/manifestUtils/mobileAction/groups/index.js +80 -0
- package/manifestUtils/tvAction/container/index.js +1 -1
- package/numberUtils/__tests__/toNumber.test.ts +27 -0
- package/numberUtils/__tests__/toPositiveNumber.test.ts +193 -0
- package/numberUtils/index.ts +23 -1
- package/package.json +4 -4
- package/pluginUtils/index.ts +4 -0
- package/reactHooks/advertising/index.ts +2 -2
- package/reactHooks/analytics/__tests__/useSendAnalyticsOnPress.test.ts +537 -0
- package/reactHooks/app/__tests__/useAppState.test.ts +1 -1
- package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
- package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +1 -2
- package/reactHooks/cell-click/__tests__/index.test.js +1 -3
- package/reactHooks/cell-click/index.ts +2 -1
- package/reactHooks/configuration/__tests__/index.test.tsx +1 -1
- package/reactHooks/connection/__tests__/index.test.js +1 -1
- package/reactHooks/debugging/__tests__/index.test.js +4 -4
- package/reactHooks/dev/__tests__/useReRenderLog.test.ts +188 -0
- package/reactHooks/device/useIsTablet.tsx +14 -19
- package/reactHooks/device/useMemoizedIsTablet.ts +3 -3
- package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +32 -23
- package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +19 -19
- package/reactHooks/feed/__tests__/useEntryScreenId.test.tsx +4 -1
- package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +42 -30
- package/reactHooks/feed/__tests__/useInflatedUrl.test.tsx +1 -1
- package/reactHooks/feed/index.ts +0 -2
- package/reactHooks/feed/useBatchLoading.ts +7 -1
- package/reactHooks/feed/useEntryScreenId.ts +2 -2
- package/reactHooks/feed/usePipesCacheReset.ts +3 -1
- package/reactHooks/flatList/useLoadNextPageIfNeeded.ts +13 -16
- package/reactHooks/layout/__tests__/index.test.tsx +1 -1
- package/reactHooks/layout/__tests__/useLayoutVersion.test.tsx +1 -1
- package/reactHooks/layout/useDimensions/__tests__/{useDimensions.test.ts → useDimensions.test.tsx} +105 -25
- package/reactHooks/layout/useDimensions/useDimensions.ts +2 -2
- package/reactHooks/navigation/__tests__/index.test.tsx +2 -4
- package/reactHooks/navigation/index.ts +7 -6
- package/reactHooks/navigation/useRoute.ts +8 -6
- package/reactHooks/player/TVSeekControlller/TVSeekController.ts +27 -10
- package/reactHooks/player/__tests__/useAutoSeek._test.tsx +1 -1
- package/reactHooks/player/__tests__/useTapSeek._test.ts +1 -1
- package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +1 -1
- package/reactHooks/resolvers/__tests__/useComponentResolver.test.tsx +1 -1
- package/reactHooks/resolvers/useCellResolver.ts +6 -2
- package/reactHooks/resolvers/useComponentResolver.ts +8 -2
- package/reactHooks/screen/__tests__/useCurrentScreenData.test.tsx +2 -2
- package/reactHooks/screen/__tests__/useScreenBackgroundColor.test.tsx +1 -1
- package/reactHooks/screen/__tests__/useScreenData.test.tsx +1 -1
- package/reactHooks/screen/__tests__/useTargetScreenData.test.tsx +12 -4
- package/reactHooks/screen/index.ts +0 -2
- package/reactHooks/screen/useTargetScreenData.ts +4 -2
- package/reactHooks/state/useRivers.ts +1 -1
- package/reactHooks/ui/__tests__/useFadeOutWhenBlurred.test.ts +580 -0
- package/reactHooks/usePluginConfiguration.ts +2 -2
- package/reactHooks/utils/__tests__/index.test.js +1 -1
- package/rectUtils/__tests__/index.test.ts +549 -0
- package/rectUtils/index.ts +2 -2
- package/refreshUtils/RefreshCoordinator/__tests__/refreshCoordinator.test.ts +206 -0
- package/refreshUtils/RefreshCoordinator/index.ts +245 -0
- package/refreshUtils/RefreshCoordinator/utils/__tests__/getDataRefreshConfig.test.ts +104 -0
- package/refreshUtils/RefreshCoordinator/utils/index.ts +29 -0
- package/screenPickerUtils/__tests__/index.test.ts +333 -0
- package/screenState/__tests__/index.test.ts +1 -1
- package/screenUtils/index.ts +3 -0
- package/searchUtils/const.ts +7 -0
- package/searchUtils/index.ts +3 -0
- package/stringUtils/index.ts +1 -1
- package/testUtils/index.tsx +30 -21
- package/time/__tests__/BackgroundTimer.test.ts +156 -0
- package/time/__tests__/Timer.test.ts +236 -0
- package/typeGuards/__tests__/isString.test.ts +21 -0
- package/typeGuards/index.ts +4 -0
- package/utils/__tests__/mergeRight.test.ts +48 -0
- package/utils/__tests__/path.test.ts +7 -0
- package/utils/__tests__/selectors.test.ts +124 -0
- package/utils/index.ts +13 -0
- package/utils/mergeRight.ts +5 -0
- package/utils/path.ts +6 -3
- package/utils/pathOr.ts +5 -1
- package/utils/selectors.ts +46 -0
- package/zappFrameworkUtils/HookCallback/callbackNavigationAction.ts +1 -1
- package/zappFrameworkUtils/HookCallback/hookCallbackManifestExtensions.config.js +1 -1
- package/zappFrameworkUtils/loginPluginUtils.ts +1 -1
- package/reactHooks/componentsMap/index.ts +0 -55
- package/reactHooks/feed/__tests__/useFeedRefresh.test.tsx +0 -75
- package/reactHooks/feed/useFeedRefresh.tsx +0 -65
- package/reactHooks/screen/useIsStandaloneFullscreen.ts +0 -12
|
@@ -1,193 +1,5 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
-
exports[`HooksManager when target route is playable executes the player hook 1`] = `
|
|
4
|
-
[
|
|
5
|
-
{
|
|
6
|
-
"callback": [Function],
|
|
7
|
-
"hookPlugin": Hook {
|
|
8
|
-
"configuration": {
|
|
9
|
-
"config_field": "bar",
|
|
10
|
-
},
|
|
11
|
-
"identifier": "headless_player_hook",
|
|
12
|
-
"lastHook": true,
|
|
13
|
-
"manager": {
|
|
14
|
-
"executeHook": [Function],
|
|
15
|
-
"handleHooks": [Function],
|
|
16
|
-
"presentScreenHook": [Function],
|
|
17
|
-
"runInBackground": [Function],
|
|
18
|
-
"subscriber": {
|
|
19
|
-
"handlers": {
|
|
20
|
-
"complete": [
|
|
21
|
-
[MockFunction] {
|
|
22
|
-
"calls": [
|
|
23
|
-
[
|
|
24
|
-
{
|
|
25
|
-
"callback": [Function],
|
|
26
|
-
"hookPlugin": [Circular],
|
|
27
|
-
"payload": {
|
|
28
|
-
"foo": "bar",
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
[Function],
|
|
32
|
-
],
|
|
33
|
-
],
|
|
34
|
-
"results": [
|
|
35
|
-
{
|
|
36
|
-
"type": "return",
|
|
37
|
-
"value": undefined,
|
|
38
|
-
},
|
|
39
|
-
],
|
|
40
|
-
},
|
|
41
|
-
],
|
|
42
|
-
"presentScreenHook": [
|
|
43
|
-
[MockFunction],
|
|
44
|
-
],
|
|
45
|
-
"success": [
|
|
46
|
-
[MockFunction] {
|
|
47
|
-
"calls": [
|
|
48
|
-
[Circular],
|
|
49
|
-
],
|
|
50
|
-
"results": [
|
|
51
|
-
{
|
|
52
|
-
"type": "return",
|
|
53
|
-
"value": undefined,
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
},
|
|
57
|
-
],
|
|
58
|
-
},
|
|
59
|
-
"invokeHandler": [Function],
|
|
60
|
-
"on": [Function],
|
|
61
|
-
"removeHandler": [Function],
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
"module": {
|
|
65
|
-
"hasPlayerHook": true,
|
|
66
|
-
"run": [MockFunction] {
|
|
67
|
-
"calls": [
|
|
68
|
-
[
|
|
69
|
-
{
|
|
70
|
-
"foo": "bar",
|
|
71
|
-
},
|
|
72
|
-
[Function],
|
|
73
|
-
{
|
|
74
|
-
"config_field": "bar",
|
|
75
|
-
},
|
|
76
|
-
],
|
|
77
|
-
],
|
|
78
|
-
"results": [
|
|
79
|
-
{
|
|
80
|
-
"type": "return",
|
|
81
|
-
"value": undefined,
|
|
82
|
-
},
|
|
83
|
-
],
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
"state": 7,
|
|
87
|
-
"weight": 1,
|
|
88
|
-
},
|
|
89
|
-
"payload": {
|
|
90
|
-
"foo": "bar",
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
[Function],
|
|
94
|
-
]
|
|
95
|
-
`;
|
|
96
|
-
|
|
97
|
-
exports[`HooksManager when target route is playable executes the player hook 2`] = `
|
|
98
|
-
[
|
|
99
|
-
{
|
|
100
|
-
"callback": [Function],
|
|
101
|
-
"hookPlugin": Hook {
|
|
102
|
-
"configuration": {
|
|
103
|
-
"config_field": "bar",
|
|
104
|
-
},
|
|
105
|
-
"identifier": "headless_player_hook",
|
|
106
|
-
"lastHook": true,
|
|
107
|
-
"manager": {
|
|
108
|
-
"executeHook": [Function],
|
|
109
|
-
"handleHooks": [Function],
|
|
110
|
-
"presentScreenHook": [Function],
|
|
111
|
-
"runInBackground": [Function],
|
|
112
|
-
"subscriber": {
|
|
113
|
-
"handlers": {
|
|
114
|
-
"complete": [
|
|
115
|
-
[MockFunction] {
|
|
116
|
-
"calls": [
|
|
117
|
-
[Circular],
|
|
118
|
-
],
|
|
119
|
-
"results": [
|
|
120
|
-
{
|
|
121
|
-
"type": "return",
|
|
122
|
-
"value": undefined,
|
|
123
|
-
},
|
|
124
|
-
],
|
|
125
|
-
},
|
|
126
|
-
],
|
|
127
|
-
"presentScreenHook": [
|
|
128
|
-
[MockFunction],
|
|
129
|
-
],
|
|
130
|
-
"success": [
|
|
131
|
-
[MockFunction] {
|
|
132
|
-
"calls": [
|
|
133
|
-
[
|
|
134
|
-
{
|
|
135
|
-
"callback": [Function],
|
|
136
|
-
"hookPlugin": [Circular],
|
|
137
|
-
"payload": {
|
|
138
|
-
"foo": "bar",
|
|
139
|
-
},
|
|
140
|
-
},
|
|
141
|
-
[Function],
|
|
142
|
-
],
|
|
143
|
-
],
|
|
144
|
-
"results": [
|
|
145
|
-
{
|
|
146
|
-
"type": "return",
|
|
147
|
-
"value": undefined,
|
|
148
|
-
},
|
|
149
|
-
],
|
|
150
|
-
},
|
|
151
|
-
],
|
|
152
|
-
},
|
|
153
|
-
"invokeHandler": [Function],
|
|
154
|
-
"on": [Function],
|
|
155
|
-
"removeHandler": [Function],
|
|
156
|
-
},
|
|
157
|
-
},
|
|
158
|
-
"module": {
|
|
159
|
-
"hasPlayerHook": true,
|
|
160
|
-
"run": [MockFunction] {
|
|
161
|
-
"calls": [
|
|
162
|
-
[
|
|
163
|
-
{
|
|
164
|
-
"foo": "bar",
|
|
165
|
-
},
|
|
166
|
-
[Function],
|
|
167
|
-
{
|
|
168
|
-
"config_field": "bar",
|
|
169
|
-
},
|
|
170
|
-
],
|
|
171
|
-
],
|
|
172
|
-
"results": [
|
|
173
|
-
{
|
|
174
|
-
"type": "return",
|
|
175
|
-
"value": undefined,
|
|
176
|
-
},
|
|
177
|
-
],
|
|
178
|
-
},
|
|
179
|
-
},
|
|
180
|
-
"state": 7,
|
|
181
|
-
"weight": 1,
|
|
182
|
-
},
|
|
183
|
-
"payload": {
|
|
184
|
-
"foo": "bar",
|
|
185
|
-
},
|
|
186
|
-
},
|
|
187
|
-
[Function],
|
|
188
|
-
]
|
|
189
|
-
`;
|
|
190
|
-
|
|
191
3
|
exports[`HooksManager when there are preload hooks hook with screen: executes 1`] = `
|
|
192
4
|
[
|
|
193
5
|
{
|
|
@@ -116,9 +116,23 @@ describe("HooksManager", () => {
|
|
|
116
116
|
headlessPlayerHook.configuration
|
|
117
117
|
);
|
|
118
118
|
|
|
119
|
-
expect(successHandler
|
|
119
|
+
expect(successHandler).toHaveBeenCalledTimes(1);
|
|
120
|
+
expect(successHandler.mock.calls[0][0].payload).toEqual(payload);
|
|
120
121
|
|
|
121
|
-
expect(
|
|
122
|
+
expect(successHandler.mock.calls[0][0].hookPlugin.identifier).toBe(
|
|
123
|
+
"headless_player_hook"
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
expect(typeof successHandler.mock.calls[0][1]).toBe("function");
|
|
127
|
+
|
|
128
|
+
expect(completeHandler).toHaveBeenCalledTimes(1);
|
|
129
|
+
expect(completeHandler.mock.calls[0][0].payload).toEqual(payload);
|
|
130
|
+
|
|
131
|
+
expect(completeHandler.mock.calls[0][0].hookPlugin.identifier).toBe(
|
|
132
|
+
"headless_player_hook"
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
expect(typeof completeHandler.mock.calls[0][1]).toBe("function");
|
|
122
136
|
});
|
|
123
137
|
});
|
|
124
138
|
|
|
@@ -234,7 +234,7 @@ export function HooksManager({
|
|
|
234
234
|
function completeHook(hookPlugin, payload, callback) {
|
|
235
235
|
logHookEvent(
|
|
236
236
|
hooksManagerLogger.info,
|
|
237
|
-
`completeHook: hook sequence completed successfully: ${hookPlugin
|
|
237
|
+
`completeHook: hook sequence completed successfully: ${hookPlugin.identifier}`,
|
|
238
238
|
{
|
|
239
239
|
payload,
|
|
240
240
|
hook: hookPlugin,
|
|
@@ -280,7 +280,7 @@ export function HooksManager({
|
|
|
280
280
|
if (hookPlugin.isCancelled()) {
|
|
281
281
|
logHookEvent(
|
|
282
282
|
hooksManagerLogger.info,
|
|
283
|
-
`hookCallback: hook was cancelled: ${hookPlugin
|
|
283
|
+
`hookCallback: hook was cancelled: ${hookPlugin.identifier}`,
|
|
284
284
|
{}
|
|
285
285
|
);
|
|
286
286
|
|
|
@@ -313,7 +313,7 @@ export function HooksManager({
|
|
|
313
313
|
if (!success) {
|
|
314
314
|
logHookEvent(
|
|
315
315
|
hooksManagerLogger.info,
|
|
316
|
-
`hookCallback: hook was cancelled: ${hookPlugin
|
|
316
|
+
`hookCallback: hook was cancelled: ${hookPlugin.identifier}`,
|
|
317
317
|
{
|
|
318
318
|
payload,
|
|
319
319
|
hook: hookPlugin,
|
|
@@ -344,7 +344,7 @@ export function HooksManager({
|
|
|
344
344
|
if (isHookInHomescreen && isHookFlowBlocker && cancelled) {
|
|
345
345
|
logHookEvent(
|
|
346
346
|
hooksManagerLogger.info,
|
|
347
|
-
`hookCallback: send app to background, cancelled flow blocker hook ${hookPlugin
|
|
347
|
+
`hookCallback: send app to background, cancelled flow blocker hook ${hookPlugin.identifier} on home screen`,
|
|
348
348
|
{
|
|
349
349
|
payload,
|
|
350
350
|
hook: hookPlugin,
|
|
@@ -359,7 +359,7 @@ export function HooksManager({
|
|
|
359
359
|
} else {
|
|
360
360
|
logHookEvent(
|
|
361
361
|
hooksManagerLogger.info,
|
|
362
|
-
`hookCallback: hook successfully finished: ${hookPlugin
|
|
362
|
+
`hookCallback: hook successfully finished: ${hookPlugin.identifier}`,
|
|
363
363
|
{
|
|
364
364
|
payload,
|
|
365
365
|
hook: hookPlugin,
|
|
@@ -369,7 +369,7 @@ export function HooksManager({
|
|
|
369
369
|
if (!callback) {
|
|
370
370
|
logHookEvent(
|
|
371
371
|
hooksManagerLogger.warn,
|
|
372
|
-
`hookCallback: ${hookPlugin
|
|
372
|
+
`hookCallback: ${hookPlugin.identifier} is missing \`callback\`, using hookCallback(default one)`,
|
|
373
373
|
{
|
|
374
374
|
hookPlugin,
|
|
375
375
|
}
|
|
@@ -432,7 +432,7 @@ export function HooksManager({
|
|
|
432
432
|
|
|
433
433
|
logHookEvent(
|
|
434
434
|
hooksManagerLogger.info,
|
|
435
|
-
`presentScreenHook: Presenting screen hook: ${hookPlugin
|
|
435
|
+
`presentScreenHook: Presenting screen hook: ${hookPlugin.identifier}`,
|
|
436
436
|
{
|
|
437
437
|
hook: hookPlugin,
|
|
438
438
|
payload,
|
|
@@ -454,7 +454,7 @@ export function HooksManager({
|
|
|
454
454
|
hooksManager.executeHook = function (hookPlugin, payload, callback) {
|
|
455
455
|
logHookEvent(
|
|
456
456
|
hooksManagerLogger.info,
|
|
457
|
-
`executeHook: ${hookPlugin
|
|
457
|
+
`executeHook: ${hookPlugin.identifier}`,
|
|
458
458
|
{
|
|
459
459
|
hook: hookPlugin,
|
|
460
460
|
payload,
|
|
@@ -466,7 +466,7 @@ export function HooksManager({
|
|
|
466
466
|
} catch (error) {
|
|
467
467
|
logHookEvent(
|
|
468
468
|
hooksManagerLogger.error,
|
|
469
|
-
`executeHook: error executing hook: ${hookPlugin
|
|
469
|
+
`executeHook: error executing hook: ${hookPlugin.identifier} error: ${error.message}`,
|
|
470
470
|
{
|
|
471
471
|
hook: hookPlugin,
|
|
472
472
|
payload,
|
|
@@ -493,7 +493,7 @@ export function HooksManager({
|
|
|
493
493
|
try {
|
|
494
494
|
logHookEvent(
|
|
495
495
|
hooksManagerLogger.info,
|
|
496
|
-
`runInBackground: Executing hook: ${hookPlugin
|
|
496
|
+
`runInBackground: Executing hook: ${hookPlugin.identifier}`,
|
|
497
497
|
{
|
|
498
498
|
hook: hookPlugin,
|
|
499
499
|
payload,
|
|
@@ -1,11 +1,31 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import {
|
|
1
|
+
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager/index.ios";
|
|
2
|
+
import { QUICK_BRICK_CONTENT } from "@applicaster/quick-brick-core/const";
|
|
3
|
+
import { isNil, isEmpty } from "@applicaster/zapp-react-native-utils/utils";
|
|
4
|
+
import { isNotNil } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
|
|
4
5
|
|
|
5
6
|
let riverFocusData = {};
|
|
6
7
|
let initialyPresentedScreenFocused = false;
|
|
7
8
|
|
|
8
9
|
export const riverFocusManager = (function () {
|
|
10
|
+
/**
|
|
11
|
+
* Create unique key that will be used for save focused group data inside specific screen
|
|
12
|
+
* @param {{ screenId: string, isInsideContainer: boolean }}
|
|
13
|
+
* screenId Unique Id of the screen from layout.json
|
|
14
|
+
* isInsideContainer If this screen a screen picker child
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
function screenFocusableGroupId({
|
|
18
|
+
screenId,
|
|
19
|
+
isInsideContainer,
|
|
20
|
+
}: {
|
|
21
|
+
screenId: string;
|
|
22
|
+
isInsideContainer: Option<boolean>;
|
|
23
|
+
}) {
|
|
24
|
+
return `${QUICK_BRICK_CONTENT}-${screenId}${
|
|
25
|
+
isNil(isInsideContainer) ? "" : "-isInsideContainer"
|
|
26
|
+
}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
9
29
|
function setScreenFocusableData({
|
|
10
30
|
screenFocusableGroupId,
|
|
11
31
|
groupId,
|
|
@@ -78,8 +98,8 @@ export const riverFocusManager = (function () {
|
|
|
78
98
|
}) {
|
|
79
99
|
// Check if screen should be focused
|
|
80
100
|
const shouldFocus =
|
|
81
|
-
(initialyPresentedScreenFocused === false &&
|
|
82
|
-
|
|
101
|
+
(initialyPresentedScreenFocused === false && isEmpty(riverFocusData)) ||
|
|
102
|
+
isNotNil(riverFocusData[screenFocusableGroupId]) ||
|
|
83
103
|
isDeepLink;
|
|
84
104
|
|
|
85
105
|
// TODO: Uncommit it to start fixing bug where selection wrong item
|
|
@@ -118,19 +138,6 @@ export const riverFocusManager = (function () {
|
|
|
118
138
|
}
|
|
119
139
|
}
|
|
120
140
|
|
|
121
|
-
/**
|
|
122
|
-
* Create unique key that will be used for save focused group data inside specific screen
|
|
123
|
-
* @param {{ screenId: string, isInsideContainer: boolean }}
|
|
124
|
-
* screenId Unique Id of the screen from layout.json
|
|
125
|
-
* isInsideContainer If this screen a screen picker child
|
|
126
|
-
*
|
|
127
|
-
*/
|
|
128
|
-
function screenFocusableGroupId({ screenId, isInsideContainer }) {
|
|
129
|
-
return `RiverFocusableGroup-${screenId}${
|
|
130
|
-
R.isNil(isInsideContainer) ? "" : "-isInsideContainer"
|
|
131
|
-
}`;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
141
|
return {
|
|
135
142
|
setScreenFocusableData,
|
|
136
143
|
clearAllScreensData,
|
|
@@ -31,6 +31,10 @@ export const BUTTON_ACCESSIBILITY_KEYS = {
|
|
|
31
31
|
hint: "accessibility_close_mini_hint",
|
|
32
32
|
},
|
|
33
33
|
},
|
|
34
|
+
back_to_live: {
|
|
35
|
+
label: "back_to_live_label",
|
|
36
|
+
hint: "",
|
|
37
|
+
},
|
|
34
38
|
maximize: {
|
|
35
39
|
label: "accessibility_maximize_label",
|
|
36
40
|
hint: "accessibility_maximize_hint",
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
import { NativeModules } from "react-native";
|
|
1
2
|
import { ContextKeysManager } from "../..";
|
|
2
3
|
|
|
3
4
|
describe("Context Keys Manager - getKeys", () => {
|
|
4
|
-
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
delete NativeModules.ContextResolverBridge;
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it("returns null if all keys are invalid 1", async () => {
|
|
5
10
|
// setup
|
|
6
11
|
const keys = [null];
|
|
7
12
|
|
|
@@ -24,7 +29,7 @@ describe("Context Keys Manager - getKeys", () => {
|
|
|
24
29
|
expect(getKey.mock.calls).toEqual([[null]]);
|
|
25
30
|
});
|
|
26
31
|
|
|
27
|
-
it("returns null if all keys are invalid", async () => {
|
|
32
|
+
it("returns null if all keys are invalid 2", async () => {
|
|
28
33
|
// setup
|
|
29
34
|
const keys = [null, undefined];
|
|
30
35
|
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import { NativeModules } from "react-native";
|
|
1
2
|
import { ContextKeysManager } from "../..";
|
|
2
3
|
|
|
3
4
|
describe("Context Keys Manager - getKeys", () => {
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
delete NativeModules.ContextResolverBridge;
|
|
7
|
+
});
|
|
8
|
+
|
|
4
9
|
it("returns value if found by getKey", async () => {
|
|
5
10
|
// setup
|
|
6
11
|
const keys = ["namespace.key"];
|
|
@@ -165,4 +170,47 @@ describe("Context Keys Manager - getKeys", () => {
|
|
|
165
170
|
expect(getKey).toHaveBeenCalledTimes(2);
|
|
166
171
|
expect(getKey.mock.calls).toEqual([[keys[0]], [keys[1]]]);
|
|
167
172
|
});
|
|
173
|
+
|
|
174
|
+
it("returns values from native bridge when available", async () => {
|
|
175
|
+
// setup
|
|
176
|
+
const keys = ["namespace.key1", "namespace.key2"];
|
|
177
|
+
|
|
178
|
+
const contextObj = [
|
|
179
|
+
{ key: keys[0], required: true },
|
|
180
|
+
{ key: keys[1], required: false },
|
|
181
|
+
];
|
|
182
|
+
|
|
183
|
+
const resolved = {
|
|
184
|
+
[keys[0]]: "value1",
|
|
185
|
+
[keys[1]]: "value2",
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const reactNative = require("react-native");
|
|
189
|
+
|
|
190
|
+
const bridgeMock = {
|
|
191
|
+
resolveContextKeys: jest.fn().mockResolvedValue(resolved),
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
reactNative.__setContextResolverBridgeMock(bridgeMock);
|
|
195
|
+
|
|
196
|
+
const contextManager = new ContextKeysManager({});
|
|
197
|
+
const getKey = jest.spyOn(contextManager, "getKey");
|
|
198
|
+
|
|
199
|
+
// run
|
|
200
|
+
const result = await contextManager.getKeys(keys, contextObj);
|
|
201
|
+
|
|
202
|
+
// verify
|
|
203
|
+
const map = new Map();
|
|
204
|
+
map.set(keys[0], "value1");
|
|
205
|
+
map.set(keys[1], "value2");
|
|
206
|
+
|
|
207
|
+
expect(result).toEqual(map);
|
|
208
|
+
|
|
209
|
+
expect(bridgeMock.resolveContextKeys).toHaveBeenCalledWith({
|
|
210
|
+
[keys[0]]: true,
|
|
211
|
+
[keys[1]]: false,
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
expect(getKey).not.toHaveBeenCalled();
|
|
215
|
+
});
|
|
168
216
|
});
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { ContextKeysManager } from "./index";
|
|
2
|
-
import
|
|
3
|
-
import * as _ from "lodash";
|
|
2
|
+
import { get, values } from "@applicaster/zapp-react-native-utils/utils";
|
|
4
3
|
import { useScreenStateStore } from "../../reactHooks/navigation/useScreenStateStore";
|
|
5
4
|
|
|
5
|
+
const contextKeyPattern = /@{([^/]+)\/([^}]*)}/;
|
|
6
|
+
const contextVariablePattern = /@\{([^}]*)\}/g;
|
|
7
|
+
|
|
6
8
|
export interface IResolver {
|
|
7
9
|
resolve: (string) => Promise<string | number | object>;
|
|
8
10
|
}
|
|
@@ -20,7 +22,7 @@ export class EntryResolver implements IResolver {
|
|
|
20
22
|
return this.entry;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
return
|
|
25
|
+
return get(this.entry, key.split("."));
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
28
|
|
|
@@ -39,7 +41,7 @@ export class ScreenStateResolver implements IResolver {
|
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
if (key.includes(".")) {
|
|
42
|
-
return
|
|
44
|
+
return get(screenState, key.split("."));
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
return screenState?.[key];
|
|
@@ -61,21 +63,16 @@ export const resolveObjectValues = async (
|
|
|
61
63
|
|
|
62
64
|
const resolvedEntries = await Promise.all(
|
|
63
65
|
entries.map(async ([key, value]) => {
|
|
64
|
-
if (typeof value !== "string") {
|
|
66
|
+
if (typeof value !== "string" || !value.startsWith("@")) {
|
|
65
67
|
return [key, value];
|
|
66
68
|
}
|
|
67
69
|
|
|
68
|
-
|
|
69
|
-
return [key, value];
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const regex = /@{([^/]+)\/([^}]*)}/;
|
|
70
|
+
const regex = contextKeyPattern;
|
|
73
71
|
|
|
74
72
|
const match = (value as string).match(regex);
|
|
75
73
|
|
|
76
74
|
if (match) {
|
|
77
|
-
const contextResolverName = match
|
|
78
|
-
const compositeKey = match[2];
|
|
75
|
+
const [_, contextResolverName, compositeKey] = match;
|
|
79
76
|
|
|
80
77
|
const resolver = exResolvers[contextResolverName] || exResolvers.ctx;
|
|
81
78
|
const resolvedValue = await resolver.resolve(compositeKey);
|
|
@@ -90,18 +87,50 @@ export const resolveObjectValues = async (
|
|
|
90
87
|
return Object.fromEntries(resolvedEntries);
|
|
91
88
|
};
|
|
92
89
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
90
|
+
// Simple memoization cache
|
|
91
|
+
const extractAtValuesCache = new Map<any, string[]>();
|
|
92
|
+
|
|
93
|
+
const flatMapDeep = <T, U>(arr: T[], fn: (value: T) => U | U[]): U[] => {
|
|
94
|
+
const result: U[] = [];
|
|
97
95
|
|
|
98
|
-
|
|
96
|
+
const flatten = (items: any) => {
|
|
97
|
+
for (const item of items) {
|
|
98
|
+
if (Array.isArray(item)) {
|
|
99
|
+
flatten(item);
|
|
100
|
+
} else {
|
|
101
|
+
result.push(item);
|
|
102
|
+
}
|
|
99
103
|
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
flatten(arr.map(fn));
|
|
100
107
|
|
|
101
|
-
|
|
102
|
-
|
|
108
|
+
return result;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const extractAtValues = (input: any): string[] => {
|
|
112
|
+
if (extractAtValuesCache.has(input)) {
|
|
113
|
+
return extractAtValuesCache.get(input)!;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const result = flatMapDeep(
|
|
117
|
+
Array.isArray(input) ? input : [input],
|
|
118
|
+
(value: any) => {
|
|
119
|
+
if (typeof value === "string") {
|
|
120
|
+
const matches = value.match(contextVariablePattern);
|
|
121
|
+
|
|
122
|
+
return matches ? matches.map((match) => match.slice(2, -1)) : [];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (typeof value === "object" && value !== null) {
|
|
126
|
+
return extractAtValues(values(value));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return [];
|
|
103
130
|
}
|
|
131
|
+
);
|
|
104
132
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
133
|
+
extractAtValuesCache.set(input, result);
|
|
134
|
+
|
|
135
|
+
return result;
|
|
136
|
+
};
|