@applicaster/zapp-react-dom-app 14.0.0-rc.5 → 14.0.0-rc.51
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 +47 -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/Storage/__tests__/storage.test.js +8 -17
- package/Polyfills/index.js +5 -6
- package/package.json +6 -10
|
@@ -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,13 +1,15 @@
|
|
|
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,
|
|
@@ -50,6 +52,8 @@ import {
|
|
|
50
52
|
import { OnScreenKeyboard } from "@applicaster/zapp-react-dom-ui-components/Components/OnScreenKeyboard";
|
|
51
53
|
import { KeyboardLongPressManager } from "@applicaster/zapp-react-dom-ui-components/Utils/KeyboardLongPressManager";
|
|
52
54
|
import { KeyInputHandler } from "@applicaster/zapp-react-native-utils/appUtils/keyInputHandler/KeyInputHandler";
|
|
55
|
+
import { getHomeRiver } from "@applicaster/zapp-react-native-utils/reactHooks/state";
|
|
56
|
+
import { withBackToTopActionHOC, BackToTopAction } from "./hoc";
|
|
53
57
|
|
|
54
58
|
const { withXray } = getXray();
|
|
55
59
|
const globalAny: any = global;
|
|
@@ -60,7 +64,8 @@ const { log_debug, log_warning } = createLogger({
|
|
|
60
64
|
});
|
|
61
65
|
|
|
62
66
|
const shouldUseOnScreenKeyboard = () =>
|
|
63
|
-
isVizioPlatform() ||
|
|
67
|
+
isVizioPlatform() ||
|
|
68
|
+
toBooleanWithDefaultFalse(window?.applicaster?.useOnScreenKeyboard);
|
|
64
69
|
|
|
65
70
|
type Props = {
|
|
66
71
|
displayState: string;
|
|
@@ -70,6 +75,7 @@ type Props = {
|
|
|
70
75
|
rivers: {};
|
|
71
76
|
xray: XRayContext;
|
|
72
77
|
confirmDialog: typeof confirmationDialogStore;
|
|
78
|
+
backToTopAction: BackToTopAction;
|
|
73
79
|
};
|
|
74
80
|
|
|
75
81
|
interface State {
|
|
@@ -139,14 +145,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
139
145
|
this.handleInputBlur = this.handleInputBlur.bind(this);
|
|
140
146
|
this.handleKeyboardInput = this.handleKeyboardInput.bind(this);
|
|
141
147
|
this.handleKeyboardDismiss = this.handleKeyboardDismiss.bind(this);
|
|
142
|
-
this.onKeyDownListener = this.onKeyDown.bind(this);
|
|
143
|
-
this.onKeyUp = this.onKeyUp.bind(this);
|
|
144
148
|
this.onMouseMoveListener = this.onMouseMove.bind(this);
|
|
145
149
|
this.onScrollListener = this.onScroll.bind(this);
|
|
146
150
|
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
151
|
|
|
151
152
|
this.handlePhysicalKeyboardDismiss =
|
|
152
153
|
this.handlePhysicalKeyboardDismiss.bind(this);
|
|
@@ -318,13 +319,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
318
319
|
const { navigator } = this.props;
|
|
319
320
|
const { rivers } = this.props;
|
|
320
321
|
|
|
321
|
-
const
|
|
322
|
-
R.prop("id"),
|
|
323
|
-
R.find(R.prop("home")),
|
|
324
|
-
R.values
|
|
325
|
-
)(rivers);
|
|
322
|
+
const homeRiver = getHomeRiver(rivers);
|
|
326
323
|
|
|
327
|
-
const homePath = `/river/${
|
|
324
|
+
const homePath = `/river/${homeRiver?.id}`;
|
|
328
325
|
|
|
329
326
|
return homePath === navigator.currentRoute;
|
|
330
327
|
}
|
|
@@ -332,7 +329,7 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
332
329
|
goToHome() {
|
|
333
330
|
const { navigator } = this.props;
|
|
334
331
|
const { rivers } = this.props;
|
|
335
|
-
const homeRiver =
|
|
332
|
+
const homeRiver = getHomeRiver(rivers);
|
|
336
333
|
|
|
337
334
|
navigator.replace(homeRiver);
|
|
338
335
|
}
|
|
@@ -393,7 +390,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
393
390
|
note: backspace affects the keyboard input, so it behaves differently
|
|
394
391
|
*/
|
|
395
392
|
onBackPress(event) {
|
|
396
|
-
const { displayState, setDisplayState, navigator } =
|
|
393
|
+
const { displayState, setDisplayState, navigator, backToTopAction } =
|
|
394
|
+
this.props;
|
|
395
|
+
|
|
397
396
|
const { isDialogVisible } = confirmationDialogStore.getState();
|
|
398
397
|
const { isKeyboardVisible } = this.state;
|
|
399
398
|
|
|
@@ -412,8 +411,32 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
412
411
|
return;
|
|
413
412
|
}
|
|
414
413
|
|
|
414
|
+
const { action, payload } = backToTopAction();
|
|
415
|
+
|
|
415
416
|
switch (displayState) {
|
|
416
417
|
case DISPLAY_STATES.DEFAULT:
|
|
418
|
+
if (action === "PLATFORM_BACK") {
|
|
419
|
+
this.platformBack();
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
if (action === "GO_HOME") {
|
|
423
|
+
this.goToHome();
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (action === "FOCUS_TOP_NAVIGATION") {
|
|
427
|
+
focusManager.focusTopNavigation(
|
|
428
|
+
payload.isTabsScreen,
|
|
429
|
+
payload.selectedEntry
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (action === "GO_BACK") {
|
|
434
|
+
if (navigator.canGoBack()) {
|
|
435
|
+
navigator.goBack();
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
break;
|
|
417
440
|
case DISPLAY_STATES.PLAYER:
|
|
418
441
|
if (isDialogVisible) {
|
|
419
442
|
this.onConfirmDialogClose();
|
|
@@ -653,8 +676,13 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
653
676
|
onConfirmDialogClose() {
|
|
654
677
|
this.confirmDialog.hideDialog();
|
|
655
678
|
|
|
656
|
-
|
|
657
|
-
|
|
679
|
+
const context: FocusManager.FocusContext = {
|
|
680
|
+
source: "cancel",
|
|
681
|
+
preserveScroll: true,
|
|
682
|
+
};
|
|
683
|
+
|
|
684
|
+
// restore initial focus after closing dialog(with preserve scrolling)
|
|
685
|
+
focusManager.setInitialFocus(undefined, context);
|
|
658
686
|
}
|
|
659
687
|
|
|
660
688
|
handleInputFocus = (event: FocusEvent) => {
|
|
@@ -852,5 +880,6 @@ export const InteractionManager = R.compose(
|
|
|
852
880
|
withXray,
|
|
853
881
|
connectToStore(R.pick(["rivers"])),
|
|
854
882
|
PlayerContentContext.withConsumer,
|
|
855
|
-
DisplayStateContext.withConsumer
|
|
883
|
+
DisplayStateContext.withConsumer,
|
|
884
|
+
withBackToTopActionHOC
|
|
856
885
|
)(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
|
@@ -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/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-rc.
|
|
3
|
+
"version": "14.0.0-rc.51",
|
|
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-rc.
|
|
26
|
-
"@applicaster/zapp-react-native-bridge": "14.0.0-rc.
|
|
27
|
-
"@applicaster/zapp-react-native-redux": "14.0.0-rc.
|
|
28
|
-
"@applicaster/zapp-react-native-ui-components": "14.0.0-rc.
|
|
29
|
-
"@applicaster/zapp-react-native-utils": "14.0.0-rc.
|
|
25
|
+
"@applicaster/zapp-react-dom-ui-components": "14.0.0-rc.51",
|
|
26
|
+
"@applicaster/zapp-react-native-bridge": "14.0.0-rc.51",
|
|
27
|
+
"@applicaster/zapp-react-native-redux": "14.0.0-rc.51",
|
|
28
|
+
"@applicaster/zapp-react-native-ui-components": "14.0.0-rc.51",
|
|
29
|
+
"@applicaster/zapp-react-native-utils": "14.0.0-rc.51",
|
|
30
30
|
"abortcontroller-polyfill": "^1.7.5",
|
|
31
31
|
"typeface-montserrat": "^0.0.54",
|
|
32
32
|
"video.js": "7.14.3",
|
|
@@ -37,13 +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
|
-
"react-native-safe-area-context": "*",
|
|
45
42
|
"react-native-svg": "*",
|
|
46
|
-
"react-native-web": "*",
|
|
47
43
|
"uglify-js": "*",
|
|
48
44
|
"validate-color": "*",
|
|
49
45
|
"zustand": "*"
|