@applicaster/zapp-react-dom-app 14.0.0-alpha.3259144304 → 14.0.0-alpha.3514550494
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/hooks/index.ts +34 -0
- package/App/InteractionManager/hoc/index.ts +4 -0
- package/App/InteractionManager/hoc/withBackToTopAction.tsx +48 -0
- package/App/InteractionManager/index.tsx +67 -18
- package/App/Loader/SplashLoader.js +1 -1
- package/App/Loader/loadSessionStorageData.js +22 -17
- package/App/Loader/utils/const.js +1 -0
- package/App/Loader/utils/platform.js +1 -21
- package/App/Splash/index.js +1 -1
- package/Polyfills/index.js +5 -6
- package/package.json +6 -9
|
@@ -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("../hooks", () => ({
|
|
14
|
+
useCurrentScreenIsHome: jest.fn(),
|
|
15
|
+
useCurrentScreenIsRoot: jest.fn(),
|
|
16
|
+
useCurrentScreenIsTabs: jest.fn(),
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils";
|
|
20
|
+
import {
|
|
21
|
+
useCurrentScreenIsHome,
|
|
22
|
+
useCurrentScreenIsRoot,
|
|
23
|
+
useCurrentScreenIsTabs,
|
|
24
|
+
} from "../hooks";
|
|
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
|
+
(useCurrentScreenIsRoot as jest.Mock).mockReturnValue(true);
|
|
51
|
+
(useCurrentScreenIsHome as jest.Mock).mockReturnValue(true);
|
|
52
|
+
(useCurrentScreenIsTabs 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
|
+
(useCurrentScreenIsRoot as jest.Mock).mockReturnValue(true);
|
|
72
|
+
(useCurrentScreenIsHome as jest.Mock).mockReturnValue(false);
|
|
73
|
+
(useCurrentScreenIsTabs 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
|
+
(useCurrentScreenIsRoot as jest.Mock).mockReturnValue(true);
|
|
88
|
+
(useCurrentScreenIsHome as jest.Mock).mockReturnValue(false);
|
|
89
|
+
(useCurrentScreenIsTabs 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
|
+
(useCurrentScreenIsRoot as jest.Mock).mockReturnValue(true);
|
|
111
|
+
(useCurrentScreenIsHome as jest.Mock).mockReturnValue(false);
|
|
112
|
+
(useCurrentScreenIsTabs 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
|
+
(useCurrentScreenIsRoot as jest.Mock).mockReturnValue(false);
|
|
136
|
+
(useCurrentScreenIsHome as jest.Mock).mockReturnValue(false);
|
|
137
|
+
(useCurrentScreenIsTabs 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,34 @@
|
|
|
1
|
+
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
2
|
+
import {
|
|
3
|
+
useHomeRiver,
|
|
4
|
+
useRivers,
|
|
5
|
+
} from "@applicaster/zapp-react-native-utils/reactHooks/state";
|
|
6
|
+
import { last } from "@applicaster/zapp-react-native-utils/utils";
|
|
7
|
+
|
|
8
|
+
export const useCurrentScreenIsHome = (): boolean => {
|
|
9
|
+
const navigator = useNavigation();
|
|
10
|
+
const homeRiver = useHomeRiver();
|
|
11
|
+
|
|
12
|
+
const homePath = `/river/${homeRiver.id}`;
|
|
13
|
+
|
|
14
|
+
return homePath === navigator.currentRoute;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const useCurrentScreenIsRoot = (): boolean => {
|
|
18
|
+
const { mainStack = [] } = useNavigation();
|
|
19
|
+
|
|
20
|
+
// root screen is the bottom(first pushed, deepest) element of the stack
|
|
21
|
+
return mainStack.length <= 1;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const useCurrentScreenIsTabs = (): boolean => {
|
|
25
|
+
const navigator = useNavigation();
|
|
26
|
+
|
|
27
|
+
const riverId = last(navigator.currentRoute.split("/"));
|
|
28
|
+
|
|
29
|
+
const rivers = useRivers();
|
|
30
|
+
|
|
31
|
+
const river = rivers[riverId];
|
|
32
|
+
|
|
33
|
+
return river?.type === "tabs_screen";
|
|
34
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils";
|
|
3
|
+
import {
|
|
4
|
+
useCurrentScreenIsHome,
|
|
5
|
+
useCurrentScreenIsRoot,
|
|
6
|
+
useCurrentScreenIsTabs,
|
|
7
|
+
} from "./hooks";
|
|
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 = useCurrentScreenIsHome();
|
|
20
|
+
const isRoot = useCurrentScreenIsRoot();
|
|
21
|
+
const isTabsScreen = useCurrentScreenIsTabs();
|
|
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,19 +1,22 @@
|
|
|
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,
|
|
8
8
|
sendQuickBrickEvent,
|
|
9
9
|
} from "@applicaster/zapp-react-native-bridge/QuickBrick";
|
|
10
10
|
|
|
11
|
+
import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
|
|
12
|
+
|
|
11
13
|
import {
|
|
12
14
|
debounce,
|
|
13
15
|
noop,
|
|
14
16
|
} from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
15
17
|
|
|
16
18
|
import {
|
|
19
|
+
AccessibilityManager,
|
|
17
20
|
ARROW_KEYS,
|
|
18
21
|
focusManager,
|
|
19
22
|
keyCode,
|
|
@@ -50,6 +53,8 @@ import {
|
|
|
50
53
|
import { OnScreenKeyboard } from "@applicaster/zapp-react-dom-ui-components/Components/OnScreenKeyboard";
|
|
51
54
|
import { KeyboardLongPressManager } from "@applicaster/zapp-react-dom-ui-components/Utils/KeyboardLongPressManager";
|
|
52
55
|
import { KeyInputHandler } from "@applicaster/zapp-react-native-utils/appUtils/keyInputHandler/KeyInputHandler";
|
|
56
|
+
import { getHomeRiver } from "@applicaster/zapp-react-native-utils/reactHooks/state";
|
|
57
|
+
import { withBackToTopActionHOC, BackToTopAction } from "./hoc";
|
|
53
58
|
|
|
54
59
|
const { withXray } = getXray();
|
|
55
60
|
const globalAny: any = global;
|
|
@@ -60,7 +65,8 @@ const { log_debug, log_warning } = createLogger({
|
|
|
60
65
|
});
|
|
61
66
|
|
|
62
67
|
const shouldUseOnScreenKeyboard = () =>
|
|
63
|
-
isVizioPlatform() ||
|
|
68
|
+
isVizioPlatform() ||
|
|
69
|
+
toBooleanWithDefaultFalse(window?.applicaster?.useOnScreenKeyboard);
|
|
64
70
|
|
|
65
71
|
type Props = {
|
|
66
72
|
displayState: string;
|
|
@@ -70,6 +76,7 @@ type Props = {
|
|
|
70
76
|
rivers: {};
|
|
71
77
|
xray: XRayContext;
|
|
72
78
|
confirmDialog: typeof confirmationDialogStore;
|
|
79
|
+
backToTopAction: BackToTopAction;
|
|
73
80
|
};
|
|
74
81
|
|
|
75
82
|
interface State {
|
|
@@ -83,6 +90,9 @@ type KeyCode = { code: string; keyCode: number | string };
|
|
|
83
90
|
export const alertConfirmationMesage =
|
|
84
91
|
"Are you sure you want to exit application?";
|
|
85
92
|
|
|
93
|
+
const VIDEO_PLAYER_CONTROLS_NAVIGATION_MESSAGE =
|
|
94
|
+
"Video player controls - use left/right to navigate";
|
|
95
|
+
|
|
86
96
|
class InteractionManagerClass extends React.Component<Props, State> {
|
|
87
97
|
onKeyDownListener: (keyCode: KeyCode) => void;
|
|
88
98
|
onMouseDownListener: (event: MouseEvent) => void;
|
|
@@ -98,6 +108,8 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
98
108
|
private confirmDialog: ConfirmationDialogState =
|
|
99
109
|
confirmationDialogStore.getState();
|
|
100
110
|
|
|
111
|
+
accessibilityManager: AccessibilityManager;
|
|
112
|
+
|
|
101
113
|
state: State = {
|
|
102
114
|
isKeyboardVisible: false,
|
|
103
115
|
keyboardInput: "",
|
|
@@ -139,14 +151,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
139
151
|
this.handleInputBlur = this.handleInputBlur.bind(this);
|
|
140
152
|
this.handleKeyboardInput = this.handleKeyboardInput.bind(this);
|
|
141
153
|
this.handleKeyboardDismiss = this.handleKeyboardDismiss.bind(this);
|
|
142
|
-
this.onKeyDownListener = this.onKeyDown.bind(this);
|
|
143
|
-
this.onKeyUp = this.onKeyUp.bind(this);
|
|
144
154
|
this.onMouseMoveListener = this.onMouseMove.bind(this);
|
|
145
155
|
this.onScrollListener = this.onScroll.bind(this);
|
|
146
156
|
this.onMouseDownListener = this.onMouseDown.bind(this);
|
|
147
|
-
this.onKeyboardStateChange = this.onKeyboardStateChange.bind(this);
|
|
148
|
-
this.onConfirmDialogOpen = this.onConfirmDialogOpen.bind(this);
|
|
149
|
-
this.onConfirmDialogClose = this.onConfirmDialogClose.bind(this);
|
|
150
157
|
|
|
151
158
|
this.handlePhysicalKeyboardDismiss =
|
|
152
159
|
this.handlePhysicalKeyboardDismiss.bind(this);
|
|
@@ -154,6 +161,7 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
154
161
|
this.confirmDialog.setConfirmAction(this.performExit);
|
|
155
162
|
this.confirmDialog.setCancelAction(this.onConfirmDialogClose);
|
|
156
163
|
this.longPressDetector = new KeyboardLongPressManager();
|
|
164
|
+
this.accessibilityManager = AccessibilityManager.getInstance();
|
|
157
165
|
}
|
|
158
166
|
|
|
159
167
|
componentDidMount() {
|
|
@@ -318,13 +326,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
318
326
|
const { navigator } = this.props;
|
|
319
327
|
const { rivers } = this.props;
|
|
320
328
|
|
|
321
|
-
const
|
|
322
|
-
R.prop("id"),
|
|
323
|
-
R.find(R.prop("home")),
|
|
324
|
-
R.values
|
|
325
|
-
)(rivers);
|
|
329
|
+
const homeRiver = getHomeRiver(rivers);
|
|
326
330
|
|
|
327
|
-
const homePath = `/river/${
|
|
331
|
+
const homePath = `/river/${homeRiver?.id}`;
|
|
328
332
|
|
|
329
333
|
return homePath === navigator.currentRoute;
|
|
330
334
|
}
|
|
@@ -332,7 +336,7 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
332
336
|
goToHome() {
|
|
333
337
|
const { navigator } = this.props;
|
|
334
338
|
const { rivers } = this.props;
|
|
335
|
-
const homeRiver =
|
|
339
|
+
const homeRiver = getHomeRiver(rivers);
|
|
336
340
|
|
|
337
341
|
navigator.replace(homeRiver);
|
|
338
342
|
}
|
|
@@ -393,7 +397,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
393
397
|
note: backspace affects the keyboard input, so it behaves differently
|
|
394
398
|
*/
|
|
395
399
|
onBackPress(event) {
|
|
396
|
-
const { displayState, setDisplayState, navigator } =
|
|
400
|
+
const { displayState, setDisplayState, navigator, backToTopAction } =
|
|
401
|
+
this.props;
|
|
402
|
+
|
|
397
403
|
const { isDialogVisible } = confirmationDialogStore.getState();
|
|
398
404
|
const { isKeyboardVisible } = this.state;
|
|
399
405
|
|
|
@@ -412,8 +418,32 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
412
418
|
return;
|
|
413
419
|
}
|
|
414
420
|
|
|
421
|
+
const { action, payload } = backToTopAction();
|
|
422
|
+
|
|
415
423
|
switch (displayState) {
|
|
416
424
|
case DISPLAY_STATES.DEFAULT:
|
|
425
|
+
if (action === "PLATFORM_BACK") {
|
|
426
|
+
this.platformBack();
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
if (action === "GO_HOME") {
|
|
430
|
+
this.goToHome();
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (action === "FOCUS_TOP_NAVIGATION") {
|
|
434
|
+
focusManager.focusTopNavigation(
|
|
435
|
+
payload.isTabsScreen,
|
|
436
|
+
payload.selectedEntry
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
if (action === "GO_BACK") {
|
|
441
|
+
if (navigator.canGoBack()) {
|
|
442
|
+
navigator.goBack();
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
break;
|
|
417
447
|
case DISPLAY_STATES.PLAYER:
|
|
418
448
|
if (isDialogVisible) {
|
|
419
449
|
this.onConfirmDialogClose();
|
|
@@ -553,6 +583,13 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
553
583
|
) {
|
|
554
584
|
if (displayState === DISPLAY_STATES.PLAYER) {
|
|
555
585
|
setDisplayState(DISPLAY_STATES.HUD);
|
|
586
|
+
|
|
587
|
+
this.accessibilityManager.addHeading(
|
|
588
|
+
VIDEO_PLAYER_CONTROLS_NAVIGATION_MESSAGE
|
|
589
|
+
);
|
|
590
|
+
|
|
591
|
+
focusManager.recoverFocus();
|
|
592
|
+
this.resetHudTimeout();
|
|
556
593
|
} else {
|
|
557
594
|
focusManager.pressIn();
|
|
558
595
|
focusManager.press();
|
|
@@ -597,6 +634,12 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
597
634
|
this.resetHudTimeout();
|
|
598
635
|
}
|
|
599
636
|
|
|
637
|
+
if (displayState === DISPLAY_STATES.PLAYER) {
|
|
638
|
+
this.accessibilityManager.addHeading(
|
|
639
|
+
VIDEO_PLAYER_CONTROLS_NAVIGATION_MESSAGE
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
|
|
600
643
|
return true;
|
|
601
644
|
}
|
|
602
645
|
}
|
|
@@ -653,8 +696,13 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
653
696
|
onConfirmDialogClose() {
|
|
654
697
|
this.confirmDialog.hideDialog();
|
|
655
698
|
|
|
656
|
-
|
|
657
|
-
|
|
699
|
+
const context: FocusManager.FocusContext = {
|
|
700
|
+
source: "cancel",
|
|
701
|
+
preserveScroll: true,
|
|
702
|
+
};
|
|
703
|
+
|
|
704
|
+
// restore initial focus after closing dialog(with preserve scrolling)
|
|
705
|
+
focusManager.setInitialFocus(undefined, context);
|
|
658
706
|
}
|
|
659
707
|
|
|
660
708
|
handleInputFocus = (event: FocusEvent) => {
|
|
@@ -852,5 +900,6 @@ export const InteractionManager = R.compose(
|
|
|
852
900
|
withXray,
|
|
853
901
|
connectToStore(R.pick(["rivers"])),
|
|
854
902
|
PlayerContentContext.withConsumer,
|
|
855
|
-
DisplayStateContext.withConsumer
|
|
903
|
+
DisplayStateContext.withConsumer,
|
|
904
|
+
withBackToTopActionHOC
|
|
856
905
|
)(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";
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import * as R from "ramda";
|
|
2
1
|
import { NativeModules } from "react-native";
|
|
3
2
|
import uuidv4 from "uuid/v4";
|
|
4
3
|
|
|
5
4
|
import { isEmptyOrNil } from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
6
|
-
import { mapKeys } from "@applicaster/zapp-react-native-utils/objectUtils";
|
|
7
5
|
import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
|
|
8
6
|
import { sessionStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage";
|
|
9
7
|
import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
|
|
10
8
|
|
|
11
|
-
import { renameKeys, getDeviceData } from "./utils/platform";
|
|
9
|
+
import { renameKeys, getDeviceData, getUserAgent } from "./utils/platform";
|
|
12
10
|
import { desiredKeysMap } from "./utils/const";
|
|
13
11
|
|
|
14
12
|
/**
|
|
@@ -55,6 +53,9 @@ export const loadPluginDataIntoSession = async (plugins = null) => {
|
|
|
55
53
|
async function gatherData(uuid) {
|
|
56
54
|
const deviceData = await getDeviceData();
|
|
57
55
|
|
|
56
|
+
// Prevent the device sdkVersion from overriding the build time value
|
|
57
|
+
delete deviceData.sdkVersion;
|
|
58
|
+
|
|
58
59
|
const { languageLocale, countryLocale } =
|
|
59
60
|
NativeModules?.QuickBrickCommunicationModule || {};
|
|
60
61
|
|
|
@@ -63,7 +64,9 @@ async function gatherData(uuid) {
|
|
|
63
64
|
...NativeModules?.QuickBrickCommunicationModule,
|
|
64
65
|
// Device data retrieved from native device apis
|
|
65
66
|
...deviceData,
|
|
66
|
-
|
|
67
|
+
userAgent: deviceData.userAgent || getUserAgent(),
|
|
68
|
+
uuid: uuid || uuidv4(), // Created on first session, persisted in local thereafter
|
|
69
|
+
sessionId: uuidv4(), // Created on every session
|
|
67
70
|
locale: `{language=${languageLocale}, country=${countryLocale}}`,
|
|
68
71
|
};
|
|
69
72
|
|
|
@@ -78,21 +81,23 @@ async function gatherData(uuid) {
|
|
|
78
81
|
* @param {Object} desiredKeys - The map of original key names to desired key names.
|
|
79
82
|
*/
|
|
80
83
|
function storeData(data, desiredKeys) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
const desiredKeysList = Object.keys(desiredKeys);
|
|
85
|
+
|
|
86
|
+
Object.entries(data).forEach(([key, value]) => {
|
|
87
|
+
if (!desiredKeysList.includes(key)) return;
|
|
88
|
+
|
|
89
|
+
if (isEmptyOrNil(value)) return;
|
|
90
|
+
|
|
91
|
+
if (typeof value === "object" || typeof value === "function") return;
|
|
92
|
+
|
|
93
|
+
const renamedKey = renameKeys(key);
|
|
94
|
+
|
|
95
|
+
if (renamedKey === "uuid") {
|
|
96
|
+
localStorage.setItem(renamedKey, value);
|
|
92
97
|
}
|
|
93
98
|
|
|
94
|
-
sessionStorage.setItem(
|
|
95
|
-
}
|
|
99
|
+
sessionStorage.setItem(renamedKey, value);
|
|
100
|
+
});
|
|
96
101
|
}
|
|
97
102
|
|
|
98
103
|
/**
|
|
@@ -257,26 +257,7 @@ export const getTizenInfo = () => {
|
|
|
257
257
|
*/
|
|
258
258
|
export const getDeviceData = async () => {
|
|
259
259
|
try {
|
|
260
|
-
let deviceData = {
|
|
261
|
-
modelName: null,
|
|
262
|
-
version: null,
|
|
263
|
-
versionMajor: null,
|
|
264
|
-
versionMinor: null,
|
|
265
|
-
versionDot: null,
|
|
266
|
-
sdkVersion: null,
|
|
267
|
-
screenWidth: null,
|
|
268
|
-
screenHeight: null,
|
|
269
|
-
uhd: null,
|
|
270
|
-
oled: null,
|
|
271
|
-
ddrSize: null,
|
|
272
|
-
uhd8K: null,
|
|
273
|
-
hdr10: null,
|
|
274
|
-
dolbyVision: null,
|
|
275
|
-
dolbyAtmos: null,
|
|
276
|
-
name: null,
|
|
277
|
-
osVersion: null,
|
|
278
|
-
networkType: null,
|
|
279
|
-
};
|
|
260
|
+
let deviceData = {};
|
|
280
261
|
|
|
281
262
|
if (isLgPlatform()) {
|
|
282
263
|
const [webOSInfo, webOSConnectionInfo] = await Promise.all([
|
|
@@ -308,7 +289,6 @@ export const getDeviceData = async () => {
|
|
|
308
289
|
platform: "vizio",
|
|
309
290
|
deviceMake: "Vizio",
|
|
310
291
|
deviceType: "tv",
|
|
311
|
-
userAgent: getUserAgent(),
|
|
312
292
|
deviceWidth: window.innerWidth,
|
|
313
293
|
deviceHeight: window.innerHeight,
|
|
314
294
|
};
|
package/App/Splash/index.js
CHANGED
package/Polyfills/index.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import { QuickBrickCommunicationModule } from "./QuickBrickCommunicationModule";
|
|
2
|
-
import { AnalyticsBridge } from "./AnalyticsBridge";
|
|
3
1
|
import { getStorageModule } from "./Storage";
|
|
4
2
|
import { DeviceEventEmitter } from "./DeviceEventEmitter";
|
|
5
|
-
import { AppLoaderBridge } from "./AppLoaderBridge";
|
|
6
3
|
import { isSamsungPlatform, isLgPlatform } from "../App/Loader/utils/platform";
|
|
7
4
|
|
|
8
5
|
// Polyfill for abort controller required by shaka-player 4.x.x
|
|
@@ -24,11 +21,13 @@ const PLATFORM_KEYS = {
|
|
|
24
21
|
// const DESKTOP_BROWSER = [PLATFORMS.linux, PLATFORMS.mac, PLATFORMS.win];
|
|
25
22
|
|
|
26
23
|
export function registerNativeModulesPolyfills(NativeModules) {
|
|
27
|
-
NativeModules.QuickBrickCommunicationModule = QuickBrickCommunicationModule;
|
|
28
24
|
NativeModules.LocalStorage = getStorageModule("localStorage");
|
|
29
25
|
NativeModules.SessionStorage = getStorageModule("sessionStorage");
|
|
30
|
-
NativeModules.AnalyticsBridge = AnalyticsBridge;
|
|
31
|
-
NativeModules.AppLoaderBridge = AppLoaderBridge;
|
|
26
|
+
NativeModules.AnalyticsBridge = require("./AnalyticsBridge").AnalyticsBridge;
|
|
27
|
+
NativeModules.AppLoaderBridge = require("./AppLoaderBridge").AppLoaderBridge;
|
|
28
|
+
|
|
29
|
+
NativeModules.QuickBrickCommunicationModule =
|
|
30
|
+
require("./QuickBrickCommunicationModule").QuickBrickCommunicationModule;
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
function getWebPlatform(fallbackPlatform) {
|
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.3514550494",
|
|
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.3514550494",
|
|
26
|
+
"@applicaster/zapp-react-native-bridge": "14.0.0-alpha.3514550494",
|
|
27
|
+
"@applicaster/zapp-react-native-redux": "14.0.0-alpha.3514550494",
|
|
28
|
+
"@applicaster/zapp-react-native-ui-components": "14.0.0-alpha.3514550494",
|
|
29
|
+
"@applicaster/zapp-react-native-utils": "14.0.0-alpha.3514550494",
|
|
30
30
|
"abortcontroller-polyfill": "^1.7.5",
|
|
31
31
|
"typeface-montserrat": "^0.0.54",
|
|
32
32
|
"video.js": "7.14.3",
|
|
@@ -37,12 +37,9 @@
|
|
|
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
|
-
"react-dom": "*",
|
|
43
41
|
"react-native": "*",
|
|
44
42
|
"react-native-svg": "*",
|
|
45
|
-
"react-native-web": "*",
|
|
46
43
|
"uglify-js": "*",
|
|
47
44
|
"validate-color": "*",
|
|
48
45
|
"zustand": "*"
|