@applicaster/zapp-react-dom-app 14.0.0-alpha.3471443312 → 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 +66 -12
- package/App/Loader/loadSessionStorageData.js +22 -17
- package/App/Loader/utils/const.js +1 -0
- package/App/Loader/utils/platform.js +1 -21
- package/Polyfills/Storage/__tests__/storage.test.js +8 -17
- package/package.json +6 -8
|
@@ -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
|
+
}
|
|
@@ -8,12 +8,15 @@ import {
|
|
|
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: "",
|
|
@@ -149,6 +161,7 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
149
161
|
this.confirmDialog.setConfirmAction(this.performExit);
|
|
150
162
|
this.confirmDialog.setCancelAction(this.onConfirmDialogClose);
|
|
151
163
|
this.longPressDetector = new KeyboardLongPressManager();
|
|
164
|
+
this.accessibilityManager = AccessibilityManager.getInstance();
|
|
152
165
|
}
|
|
153
166
|
|
|
154
167
|
componentDidMount() {
|
|
@@ -313,13 +326,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
313
326
|
const { navigator } = this.props;
|
|
314
327
|
const { rivers } = this.props;
|
|
315
328
|
|
|
316
|
-
const
|
|
317
|
-
R.prop("id"),
|
|
318
|
-
R.find(R.prop("home")),
|
|
319
|
-
R.values
|
|
320
|
-
)(rivers);
|
|
329
|
+
const homeRiver = getHomeRiver(rivers);
|
|
321
330
|
|
|
322
|
-
const homePath = `/river/${
|
|
331
|
+
const homePath = `/river/${homeRiver?.id}`;
|
|
323
332
|
|
|
324
333
|
return homePath === navigator.currentRoute;
|
|
325
334
|
}
|
|
@@ -327,7 +336,7 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
327
336
|
goToHome() {
|
|
328
337
|
const { navigator } = this.props;
|
|
329
338
|
const { rivers } = this.props;
|
|
330
|
-
const homeRiver =
|
|
339
|
+
const homeRiver = getHomeRiver(rivers);
|
|
331
340
|
|
|
332
341
|
navigator.replace(homeRiver);
|
|
333
342
|
}
|
|
@@ -388,7 +397,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
388
397
|
note: backspace affects the keyboard input, so it behaves differently
|
|
389
398
|
*/
|
|
390
399
|
onBackPress(event) {
|
|
391
|
-
const { displayState, setDisplayState, navigator } =
|
|
400
|
+
const { displayState, setDisplayState, navigator, backToTopAction } =
|
|
401
|
+
this.props;
|
|
402
|
+
|
|
392
403
|
const { isDialogVisible } = confirmationDialogStore.getState();
|
|
393
404
|
const { isKeyboardVisible } = this.state;
|
|
394
405
|
|
|
@@ -407,8 +418,32 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
407
418
|
return;
|
|
408
419
|
}
|
|
409
420
|
|
|
421
|
+
const { action, payload } = backToTopAction();
|
|
422
|
+
|
|
410
423
|
switch (displayState) {
|
|
411
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;
|
|
412
447
|
case DISPLAY_STATES.PLAYER:
|
|
413
448
|
if (isDialogVisible) {
|
|
414
449
|
this.onConfirmDialogClose();
|
|
@@ -548,6 +583,13 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
548
583
|
) {
|
|
549
584
|
if (displayState === DISPLAY_STATES.PLAYER) {
|
|
550
585
|
setDisplayState(DISPLAY_STATES.HUD);
|
|
586
|
+
|
|
587
|
+
this.accessibilityManager.addHeading(
|
|
588
|
+
VIDEO_PLAYER_CONTROLS_NAVIGATION_MESSAGE
|
|
589
|
+
);
|
|
590
|
+
|
|
591
|
+
focusManager.recoverFocus();
|
|
592
|
+
this.resetHudTimeout();
|
|
551
593
|
} else {
|
|
552
594
|
focusManager.pressIn();
|
|
553
595
|
focusManager.press();
|
|
@@ -592,6 +634,12 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
592
634
|
this.resetHudTimeout();
|
|
593
635
|
}
|
|
594
636
|
|
|
637
|
+
if (displayState === DISPLAY_STATES.PLAYER) {
|
|
638
|
+
this.accessibilityManager.addHeading(
|
|
639
|
+
VIDEO_PLAYER_CONTROLS_NAVIGATION_MESSAGE
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
|
|
595
643
|
return true;
|
|
596
644
|
}
|
|
597
645
|
}
|
|
@@ -648,8 +696,13 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
648
696
|
onConfirmDialogClose() {
|
|
649
697
|
this.confirmDialog.hideDialog();
|
|
650
698
|
|
|
651
|
-
|
|
652
|
-
|
|
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);
|
|
653
706
|
}
|
|
654
707
|
|
|
655
708
|
handleInputFocus = (event: FocusEvent) => {
|
|
@@ -847,5 +900,6 @@ export const InteractionManager = R.compose(
|
|
|
847
900
|
withXray,
|
|
848
901
|
connectToStore(R.pick(["rivers"])),
|
|
849
902
|
PlayerContentContext.withConsumer,
|
|
850
|
-
DisplayStateContext.withConsumer
|
|
903
|
+
DisplayStateContext.withConsumer,
|
|
904
|
+
withBackToTopActionHOC
|
|
851
905
|
)(InteractionManagerClass);
|
|
@@ -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
|
};
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import * as R from "ramda";
|
|
2
|
-
import {
|
|
3
|
-
getStorageModule,
|
|
4
|
-
applyNamespaceToKeyName,
|
|
5
|
-
STORAGE_TYPES,
|
|
6
|
-
DEFAULT_NAMESPACE,
|
|
7
|
-
} from "../";
|
|
2
|
+
import { getStorageModule, STORAGE_TYPES } from "../";
|
|
8
3
|
|
|
9
4
|
import { StorageMock } from "./StorageMocks";
|
|
10
5
|
|
|
@@ -37,7 +32,6 @@ describe("storageObject", () => {
|
|
|
37
32
|
const value = "bar";
|
|
38
33
|
const namespaceValue = "baz";
|
|
39
34
|
const namespace = "baz";
|
|
40
|
-
const keyName = applyNamespaceToKeyName(key, namespace);
|
|
41
35
|
const failKey = "fail_key";
|
|
42
36
|
|
|
43
37
|
beforeEach(clearStorage);
|
|
@@ -54,16 +48,11 @@ describe("storageObject", () => {
|
|
|
54
48
|
it.each(storages)("sets a property in the storage", async (storage) => {
|
|
55
49
|
const result = await storage.setItem(key, value, null);
|
|
56
50
|
|
|
57
|
-
const keyWithDefaultNameSpace = applyNamespaceToKeyName(
|
|
58
|
-
key,
|
|
59
|
-
DEFAULT_NAMESPACE
|
|
60
|
-
);
|
|
61
|
-
|
|
62
51
|
expect(result).toBe(true);
|
|
63
52
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
);
|
|
53
|
+
const res = await storage.getItem(key, null);
|
|
54
|
+
|
|
55
|
+
expect(res).toEqual(value);
|
|
67
56
|
});
|
|
68
57
|
|
|
69
58
|
it.each(storages)(
|
|
@@ -73,7 +62,9 @@ describe("storageObject", () => {
|
|
|
73
62
|
|
|
74
63
|
expect(result).toBe(true);
|
|
75
64
|
|
|
76
|
-
|
|
65
|
+
const res = await storage.getItem(key, namespace);
|
|
66
|
+
|
|
67
|
+
expect(res).toEqual(namespaceValue);
|
|
77
68
|
}
|
|
78
69
|
);
|
|
79
70
|
|
|
@@ -108,7 +99,7 @@ describe("storageObject", () => {
|
|
|
108
99
|
"gets properties from the storage with a namespace",
|
|
109
100
|
(storage) => {
|
|
110
101
|
expect(storage.getItem(key, namespace)).resolves.toEqual(
|
|
111
|
-
|
|
102
|
+
namespaceValue
|
|
112
103
|
);
|
|
113
104
|
}
|
|
114
105
|
);
|
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,10 +37,8 @@
|
|
|
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
|
-
"react-native-safe-area-context": "*",
|
|
44
42
|
"react-native-svg": "*",
|
|
45
43
|
"uglify-js": "*",
|
|
46
44
|
"validate-color": "*",
|