@applicaster/zapp-react-dom-app 14.0.0-alpha.5114565431 → 14.0.0-alpha.5219335081
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/App/InteractionManager/hoc/__tests__/withBacktoTopActionHOC.test.tsx +149 -0
- package/App/InteractionManager/hoc/index.ts +4 -0
- package/App/InteractionManager/hoc/withBackToTopAction.tsx +48 -0
- package/App/InteractionManager/index.tsx +43 -12
- package/App/Loader/SplashLoader.js +1 -1
- package/App/Splash/index.js +1 -1
- package/package.json +6 -7
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@testing-library/react-native";
|
|
3
|
+
import { withBackToTopActionHOC } from "../withBackToTopAction";
|
|
4
|
+
|
|
5
|
+
// Mock focusManager and hook
|
|
6
|
+
jest.mock("@applicaster/zapp-react-native-utils/appUtils", () => ({
|
|
7
|
+
focusManager: {
|
|
8
|
+
isFocusOnMenu: jest.fn(),
|
|
9
|
+
isFocusOnContent: jest.fn(),
|
|
10
|
+
},
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/state", () => ({
|
|
14
|
+
useIsHomeScreen: jest.fn(),
|
|
15
|
+
useIsRootScreen: jest.fn(),
|
|
16
|
+
useIsTabsScreen: jest.fn(),
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils";
|
|
20
|
+
import {
|
|
21
|
+
useIsHomeScreen,
|
|
22
|
+
useIsRootScreen,
|
|
23
|
+
useIsTabsScreen,
|
|
24
|
+
} from "@applicaster/zapp-react-native-utils/reactHooks/state";
|
|
25
|
+
|
|
26
|
+
jest.mock("@applicaster/zapp-react-native-utils/reactHooks", () => ({
|
|
27
|
+
useNavigation: jest.fn(),
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
31
|
+
|
|
32
|
+
describe("withBackToTopActionHOC", () => {
|
|
33
|
+
let receivedProps: any;
|
|
34
|
+
|
|
35
|
+
const BaseComponent = (props) => {
|
|
36
|
+
receivedProps = props; // capture injected props
|
|
37
|
+
|
|
38
|
+
return <></>;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const Wrapped = withBackToTopActionHOC(BaseComponent);
|
|
42
|
+
|
|
43
|
+
beforeEach(() => {
|
|
44
|
+
jest.clearAllMocks();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("returns PLATFORM_BACK when on root screen, focus on menu, and is home", () => {
|
|
48
|
+
expect.assertions(1);
|
|
49
|
+
|
|
50
|
+
(useIsRootScreen as jest.Mock).mockReturnValue(true);
|
|
51
|
+
(useIsHomeScreen as jest.Mock).mockReturnValue(true);
|
|
52
|
+
(useIsTabsScreen as jest.Mock).mockReturnValue(false);
|
|
53
|
+
|
|
54
|
+
(useNavigation as jest.Mock).mockReturnValue({
|
|
55
|
+
getNestedEntry: () => undefined,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
(focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(true);
|
|
59
|
+
(focusManager.isFocusOnContent as jest.Mock).mockReturnValue(false);
|
|
60
|
+
|
|
61
|
+
render(<Wrapped />);
|
|
62
|
+
|
|
63
|
+
expect(receivedProps.backToTopAction()).toEqual({
|
|
64
|
+
action: "PLATFORM_BACK",
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("returns GO_HOME when on root screen, focus on menu, and not home", () => {
|
|
69
|
+
expect.assertions(1);
|
|
70
|
+
|
|
71
|
+
(useIsRootScreen as jest.Mock).mockReturnValue(true);
|
|
72
|
+
(useIsHomeScreen as jest.Mock).mockReturnValue(false);
|
|
73
|
+
(useIsTabsScreen as jest.Mock).mockReturnValue(false);
|
|
74
|
+
|
|
75
|
+
(useNavigation as jest.Mock).mockReturnValue({
|
|
76
|
+
getNestedEntry: () => undefined,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
(focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(true);
|
|
80
|
+
(focusManager.isFocusOnContent as jest.Mock).mockReturnValue(false);
|
|
81
|
+
|
|
82
|
+
render(<Wrapped />);
|
|
83
|
+
expect(receivedProps.backToTopAction()).toEqual({ action: "GO_HOME" });
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("returns FOCUS_TOP_NAVIGATION when on root screen and focus on content without tabs_screen", () => {
|
|
87
|
+
(useIsRootScreen as jest.Mock).mockReturnValue(true);
|
|
88
|
+
(useIsHomeScreen as jest.Mock).mockReturnValue(false);
|
|
89
|
+
(useIsTabsScreen as jest.Mock).mockReturnValue(false);
|
|
90
|
+
|
|
91
|
+
(useNavigation as jest.Mock).mockReturnValue({
|
|
92
|
+
getNestedEntry: () => "selectedEntry",
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
(focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(false);
|
|
96
|
+
(focusManager.isFocusOnContent as jest.Mock).mockReturnValue(true);
|
|
97
|
+
|
|
98
|
+
render(<Wrapped />);
|
|
99
|
+
|
|
100
|
+
expect(receivedProps.backToTopAction()).toEqual({
|
|
101
|
+
action: "FOCUS_TOP_NAVIGATION",
|
|
102
|
+
payload: {
|
|
103
|
+
isTabsScreen: false,
|
|
104
|
+
selectedEntry: "selectedEntry",
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("returns FOCUS_TOP_NAVIGATION when on root screen and focus on content with tabs_screen", () => {
|
|
110
|
+
(useIsRootScreen as jest.Mock).mockReturnValue(true);
|
|
111
|
+
(useIsHomeScreen as jest.Mock).mockReturnValue(false);
|
|
112
|
+
(useIsTabsScreen as jest.Mock).mockReturnValue(true);
|
|
113
|
+
|
|
114
|
+
(useNavigation as jest.Mock).mockReturnValue({
|
|
115
|
+
getNestedEntry: () => "selectedEntry",
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
(focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(false);
|
|
119
|
+
(focusManager.isFocusOnContent as jest.Mock).mockReturnValue(true);
|
|
120
|
+
|
|
121
|
+
render(<Wrapped />);
|
|
122
|
+
|
|
123
|
+
expect(receivedProps.backToTopAction()).toEqual({
|
|
124
|
+
action: "FOCUS_TOP_NAVIGATION",
|
|
125
|
+
payload: {
|
|
126
|
+
isTabsScreen: true,
|
|
127
|
+
selectedEntry: "selectedEntry",
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("returns GO_BACK in default case", () => {
|
|
133
|
+
expect.assertions(1);
|
|
134
|
+
|
|
135
|
+
(useIsRootScreen as jest.Mock).mockReturnValue(false);
|
|
136
|
+
(useIsHomeScreen as jest.Mock).mockReturnValue(false);
|
|
137
|
+
(useIsTabsScreen as jest.Mock).mockReturnValue(false);
|
|
138
|
+
|
|
139
|
+
(useNavigation as jest.Mock).mockReturnValue({
|
|
140
|
+
getNestedEntry: () => undefined,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
(focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(false);
|
|
144
|
+
(focusManager.isFocusOnContent as jest.Mock).mockReturnValue(false);
|
|
145
|
+
|
|
146
|
+
render(<Wrapped />);
|
|
147
|
+
expect(receivedProps.backToTopAction()).toEqual({ action: "GO_BACK" });
|
|
148
|
+
});
|
|
149
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils";
|
|
3
|
+
import {
|
|
4
|
+
useIsHomeScreen,
|
|
5
|
+
useIsRootScreen,
|
|
6
|
+
useIsTabsScreen,
|
|
7
|
+
} from "@applicaster/zapp-react-native-utils/reactHooks/state";
|
|
8
|
+
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
9
|
+
|
|
10
|
+
export type BACK_TO_TOP_ACTION = {
|
|
11
|
+
action: "PLATFORM_BACK" | "GO_HOME" | "FOCUS_TOP_NAVIGATION" | "GO_BACK";
|
|
12
|
+
payload?: { isTabsScreen: boolean; selectedEntry: ZappEntry };
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type BackToTopAction = () => BACK_TO_TOP_ACTION;
|
|
16
|
+
|
|
17
|
+
export function withBackToTopActionHOC(Component) {
|
|
18
|
+
return function WrappedComponent(props) {
|
|
19
|
+
const isHome = useIsHomeScreen();
|
|
20
|
+
const isRoot = useIsRootScreen();
|
|
21
|
+
const isTabsScreen = useIsTabsScreen();
|
|
22
|
+
|
|
23
|
+
const navigator = useNavigation();
|
|
24
|
+
const selectedEntry = navigator.getNestedEntry();
|
|
25
|
+
|
|
26
|
+
const backToTopAction = React.useCallback((): BACK_TO_TOP_ACTION => {
|
|
27
|
+
if (isRoot && focusManager.isFocusOnMenu() && isHome) {
|
|
28
|
+
return { action: "PLATFORM_BACK" };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (isRoot && focusManager.isFocusOnMenu() && !isHome) {
|
|
32
|
+
return { action: "GO_HOME" };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (isRoot && focusManager.isFocusOnContent()) {
|
|
36
|
+
return {
|
|
37
|
+
action: "FOCUS_TOP_NAVIGATION",
|
|
38
|
+
payload: { isTabsScreen, selectedEntry },
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// default
|
|
43
|
+
return { action: "GO_BACK" };
|
|
44
|
+
}, [isHome, isRoot, isTabsScreen, selectedEntry]);
|
|
45
|
+
|
|
46
|
+
return <Component {...props} backToTopAction={backToTopAction} />;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
3
|
|
|
4
|
-
import { connectToStore } from "@applicaster/zapp-react-native-redux";
|
|
4
|
+
import { connectToStore } from "@applicaster/zapp-react-native-redux/utils/connectToStore";
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
QUICK_BRICK_EVENTS,
|
|
@@ -50,6 +50,8 @@ import {
|
|
|
50
50
|
import { OnScreenKeyboard } from "@applicaster/zapp-react-dom-ui-components/Components/OnScreenKeyboard";
|
|
51
51
|
import { KeyboardLongPressManager } from "@applicaster/zapp-react-dom-ui-components/Utils/KeyboardLongPressManager";
|
|
52
52
|
import { KeyInputHandler } from "@applicaster/zapp-react-native-utils/appUtils/keyInputHandler/KeyInputHandler";
|
|
53
|
+
import { getHomeRiver } from "@applicaster/zapp-react-native-utils/reactHooks/state";
|
|
54
|
+
import { withBackToTopActionHOC, BackToTopAction } from "./hoc";
|
|
53
55
|
|
|
54
56
|
const { withXray } = getXray();
|
|
55
57
|
const globalAny: any = global;
|
|
@@ -70,6 +72,7 @@ type Props = {
|
|
|
70
72
|
rivers: {};
|
|
71
73
|
xray: XRayContext;
|
|
72
74
|
confirmDialog: typeof confirmationDialogStore;
|
|
75
|
+
backToTopAction: BackToTopAction;
|
|
73
76
|
};
|
|
74
77
|
|
|
75
78
|
interface State {
|
|
@@ -313,13 +316,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
313
316
|
const { navigator } = this.props;
|
|
314
317
|
const { rivers } = this.props;
|
|
315
318
|
|
|
316
|
-
const
|
|
317
|
-
R.prop("id"),
|
|
318
|
-
R.find(R.prop("home")),
|
|
319
|
-
R.values
|
|
320
|
-
)(rivers);
|
|
319
|
+
const homeRiver = getHomeRiver(rivers);
|
|
321
320
|
|
|
322
|
-
const homePath = `/river/${
|
|
321
|
+
const homePath = `/river/${homeRiver?.id}`;
|
|
323
322
|
|
|
324
323
|
return homePath === navigator.currentRoute;
|
|
325
324
|
}
|
|
@@ -327,7 +326,7 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
327
326
|
goToHome() {
|
|
328
327
|
const { navigator } = this.props;
|
|
329
328
|
const { rivers } = this.props;
|
|
330
|
-
const homeRiver =
|
|
329
|
+
const homeRiver = getHomeRiver(rivers);
|
|
331
330
|
|
|
332
331
|
navigator.replace(homeRiver);
|
|
333
332
|
}
|
|
@@ -388,7 +387,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
388
387
|
note: backspace affects the keyboard input, so it behaves differently
|
|
389
388
|
*/
|
|
390
389
|
onBackPress(event) {
|
|
391
|
-
const { displayState, setDisplayState, navigator } =
|
|
390
|
+
const { displayState, setDisplayState, navigator, backToTopAction } =
|
|
391
|
+
this.props;
|
|
392
|
+
|
|
392
393
|
const { isDialogVisible } = confirmationDialogStore.getState();
|
|
393
394
|
const { isKeyboardVisible } = this.state;
|
|
394
395
|
|
|
@@ -407,8 +408,32 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
407
408
|
return;
|
|
408
409
|
}
|
|
409
410
|
|
|
411
|
+
const { action, payload } = backToTopAction();
|
|
412
|
+
|
|
410
413
|
switch (displayState) {
|
|
411
414
|
case DISPLAY_STATES.DEFAULT:
|
|
415
|
+
if (action === "PLATFORM_BACK") {
|
|
416
|
+
this.platformBack();
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (action === "GO_HOME") {
|
|
420
|
+
this.goToHome();
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (action === "FOCUS_TOP_NAVIGATION") {
|
|
424
|
+
focusManager.focusTopNavigation(
|
|
425
|
+
payload.isTabsScreen,
|
|
426
|
+
payload.selectedEntry
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if (action === "GO_BACK") {
|
|
431
|
+
if (navigator.canGoBack()) {
|
|
432
|
+
navigator.goBack();
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
break;
|
|
412
437
|
case DISPLAY_STATES.PLAYER:
|
|
413
438
|
if (isDialogVisible) {
|
|
414
439
|
this.onConfirmDialogClose();
|
|
@@ -648,8 +673,13 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
648
673
|
onConfirmDialogClose() {
|
|
649
674
|
this.confirmDialog.hideDialog();
|
|
650
675
|
|
|
651
|
-
|
|
652
|
-
|
|
676
|
+
const context: FocusManager.FocusContext = {
|
|
677
|
+
source: "cancel",
|
|
678
|
+
preserveScroll: true,
|
|
679
|
+
};
|
|
680
|
+
|
|
681
|
+
// restore initial focus after closing dialog(with preserve scrolling)
|
|
682
|
+
focusManager.setInitialFocus(undefined, context);
|
|
653
683
|
}
|
|
654
684
|
|
|
655
685
|
handleInputFocus = (event: FocusEvent) => {
|
|
@@ -847,5 +877,6 @@ export const InteractionManager = R.compose(
|
|
|
847
877
|
withXray,
|
|
848
878
|
connectToStore(R.pick(["rivers"])),
|
|
849
879
|
PlayerContentContext.withConsumer,
|
|
850
|
-
DisplayStateContext.withConsumer
|
|
880
|
+
DisplayStateContext.withConsumer,
|
|
881
|
+
withBackToTopActionHOC
|
|
851
882
|
)(InteractionManagerClass);
|
|
@@ -3,7 +3,7 @@ import * as React from "react";
|
|
|
3
3
|
import * as R from "ramda";
|
|
4
4
|
import PropTypes from "prop-types";
|
|
5
5
|
|
|
6
|
-
import { connectToStore } from "@applicaster/zapp-react-native-redux";
|
|
6
|
+
import { connectToStore } from "@applicaster/zapp-react-native-redux/utils/connectToStore";
|
|
7
7
|
import { QUICK_BRICK_EVENTS } from "@applicaster/zapp-react-native-bridge/QuickBrick";
|
|
8
8
|
|
|
9
9
|
import { QuickBrickEvents } from "../../Polyfills/QuickBrickCommunicationModule";
|
package/App/Splash/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-dom-app",
|
|
3
|
-
"version": "14.0.0-alpha.
|
|
3
|
+
"version": "14.0.0-alpha.5219335081",
|
|
4
4
|
"description": "Zapp App Component for Applicaster's Quick Brick React Native App",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
},
|
|
23
23
|
"homepage": "https://github.com/applicaster/zapp-react-dom-app#readme",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@applicaster/zapp-react-dom-ui-components": "14.0.0-alpha.
|
|
26
|
-
"@applicaster/zapp-react-native-bridge": "14.0.0-alpha.
|
|
27
|
-
"@applicaster/zapp-react-native-redux": "14.0.0-alpha.
|
|
28
|
-
"@applicaster/zapp-react-native-ui-components": "14.0.0-alpha.
|
|
29
|
-
"@applicaster/zapp-react-native-utils": "14.0.0-alpha.
|
|
25
|
+
"@applicaster/zapp-react-dom-ui-components": "14.0.0-alpha.5219335081",
|
|
26
|
+
"@applicaster/zapp-react-native-bridge": "14.0.0-alpha.5219335081",
|
|
27
|
+
"@applicaster/zapp-react-native-redux": "14.0.0-alpha.5219335081",
|
|
28
|
+
"@applicaster/zapp-react-native-ui-components": "14.0.0-alpha.5219335081",
|
|
29
|
+
"@applicaster/zapp-react-native-utils": "14.0.0-alpha.5219335081",
|
|
30
30
|
"abortcontroller-polyfill": "^1.7.5",
|
|
31
31
|
"typeface-montserrat": "^0.0.54",
|
|
32
32
|
"video.js": "7.14.3",
|
|
@@ -37,7 +37,6 @@
|
|
|
37
37
|
"@applicaster/zapp-pipes-v2-client": "*",
|
|
38
38
|
"@react-native-community/netinfo": "*",
|
|
39
39
|
"core-js": "3.29.1",
|
|
40
|
-
"immer": "*",
|
|
41
40
|
"react": "*",
|
|
42
41
|
"react-native": "*",
|
|
43
42
|
"react-native-svg": "*",
|