@applicaster/zapp-react-dom-app 12.0.0-alpha.4337072244 → 12.0.0-alpha.4354608902
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/index.tsx +115 -17
- package/App/Loader/SplashLoader.js +8 -7
- package/App/Loader/loadSessionStorageData.js +0 -1
- package/App/Loader/utils/const.js +3 -0
- package/App/Loader/utils/platform.js +79 -12
- package/App/Router/index.js +6 -7
- package/App/Splash/Spinner.js +0 -1
- package/App/Splash/Splash.js +9 -6
- package/Polyfills/AnalyticsBridge/index.ts +5 -1
- package/Polyfills/Storage/index.js +15 -26
- package/main.css +2 -2
- package/package.json +6 -6
|
@@ -31,14 +31,23 @@ import {
|
|
|
31
31
|
import { PlayerContentContext } from "@applicaster/zapp-react-dom-ui-components/Contexts";
|
|
32
32
|
|
|
33
33
|
import { withNavigator } from "@applicaster/zapp-react-native-ui-components/Decorators/Navigator";
|
|
34
|
-
import { Platform } from "react-native";
|
|
35
34
|
import { LONG_KEY_PRESS_TIMEOUT } from "@applicaster/quick-brick-core/const";
|
|
36
35
|
import { getXray } from "@applicaster/zapp-react-native-utils/logger";
|
|
37
36
|
import { confirmationDialogStore } from "@applicaster/zapp-react-native-ui-components/Contexts/ConfirmDialogState";
|
|
37
|
+
import {
|
|
38
|
+
isVizioPlatform,
|
|
39
|
+
isSamsungPlatform,
|
|
40
|
+
isLgPlatform,
|
|
41
|
+
} from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
42
|
+
|
|
43
|
+
import { OnScreenKeyboard } from "@applicaster/zapp-react-dom-ui-components/Components/OnScreenKeyboard";
|
|
38
44
|
|
|
39
45
|
const { withXray } = getXray();
|
|
40
46
|
const globalAny: any = global;
|
|
41
47
|
|
|
48
|
+
const shouldUseOnScreenKeyboard = () =>
|
|
49
|
+
isVizioPlatform() || window.applicaster.useOnScreenKeyboard;
|
|
50
|
+
|
|
42
51
|
type Props = {
|
|
43
52
|
displayState: string;
|
|
44
53
|
setDisplayState: (state: string) => void;
|
|
@@ -56,7 +65,7 @@ type Props = {
|
|
|
56
65
|
};
|
|
57
66
|
};
|
|
58
67
|
|
|
59
|
-
type State = { isKeyboardVisible: boolean };
|
|
68
|
+
type State = { isKeyboardVisible: boolean; keyboardInput: string };
|
|
60
69
|
|
|
61
70
|
type KeyCode = { code: string; keyCode: number | string };
|
|
62
71
|
|
|
@@ -76,6 +85,7 @@ export function withInteractionManager(Component: React.FC) {
|
|
|
76
85
|
sequenceTimeout: NodeJS.Timeout | null; // timeoutID
|
|
77
86
|
userSequence: number[] = [];
|
|
78
87
|
confirmDialog: any;
|
|
88
|
+
isDismissing = false;
|
|
79
89
|
|
|
80
90
|
constructor(props) {
|
|
81
91
|
super(props);
|
|
@@ -84,6 +94,7 @@ export function withInteractionManager(Component: React.FC) {
|
|
|
84
94
|
|
|
85
95
|
this.state = {
|
|
86
96
|
isKeyboardVisible: false,
|
|
97
|
+
keyboardInput: "",
|
|
87
98
|
};
|
|
88
99
|
|
|
89
100
|
this.onMouseMoveListener = debounce({
|
|
@@ -116,6 +127,10 @@ export function withInteractionManager(Component: React.FC) {
|
|
|
116
127
|
this.onConfirmDialogOpen = this.onConfirmDialogOpen.bind(this);
|
|
117
128
|
this.onConfirmDialogClose = this.onConfirmDialogClose.bind(this);
|
|
118
129
|
this.performExit = this.performExit.bind(this);
|
|
130
|
+
this.handleInputFocus = this.handleInputFocus.bind(this);
|
|
131
|
+
this.handleInputBlur = this.handleInputBlur.bind(this);
|
|
132
|
+
this.handleKeyboardInput = this.handleKeyboardInput.bind(this);
|
|
133
|
+
this.handleKeyboardDismiss = this.handleKeyboardDismiss.bind(this);
|
|
119
134
|
|
|
120
135
|
this.confirmDialog.setConfirmAction(this.performExit);
|
|
121
136
|
this.confirmDialog.setCancelAction(this.onConfirmDialogClose);
|
|
@@ -138,6 +153,8 @@ export function withInteractionManager(Component: React.FC) {
|
|
|
138
153
|
false
|
|
139
154
|
);
|
|
140
155
|
|
|
156
|
+
document.addEventListener("focusin", this.handleInputFocus);
|
|
157
|
+
|
|
141
158
|
document.addEventListener(
|
|
142
159
|
"cursorStateChange",
|
|
143
160
|
this.cursorVisibilityChange,
|
|
@@ -155,28 +172,31 @@ export function withInteractionManager(Component: React.FC) {
|
|
|
155
172
|
this.cursorVisibilityChange
|
|
156
173
|
);
|
|
157
174
|
|
|
158
|
-
document.removeEventListener(
|
|
159
|
-
"keyboardStateChange",
|
|
160
|
-
this.onKeyboardStateChange
|
|
161
|
-
);
|
|
175
|
+
document.removeEventListener("focusin", this.handleInputFocus);
|
|
162
176
|
|
|
163
177
|
document.removeEventListener("mousedown", this.onMouseDownListener);
|
|
164
178
|
|
|
165
179
|
if (this.timeout) {
|
|
166
180
|
this.clearTimeout();
|
|
167
181
|
}
|
|
182
|
+
|
|
183
|
+
this.isDismissing = false;
|
|
168
184
|
}
|
|
169
185
|
|
|
170
186
|
performExit() {
|
|
171
|
-
if (
|
|
187
|
+
if (isSamsungPlatform()) {
|
|
172
188
|
this.onConfirmDialogClose();
|
|
173
189
|
sendQuickBrickEvent(QUICK_BRICK_EVENTS.MOVE_APP_TO_BACKGROUND);
|
|
174
190
|
}
|
|
175
191
|
|
|
176
|
-
if (
|
|
192
|
+
if (isLgPlatform()) {
|
|
177
193
|
// webOS recommend to use this method when implemention a custom exit
|
|
178
194
|
globalAny.close();
|
|
179
195
|
}
|
|
196
|
+
|
|
197
|
+
if (isVizioPlatform()) {
|
|
198
|
+
window?.VIZIO?.exitApplication();
|
|
199
|
+
}
|
|
180
200
|
}
|
|
181
201
|
|
|
182
202
|
handleWebOsBack() {
|
|
@@ -205,7 +225,7 @@ export function withInteractionManager(Component: React.FC) {
|
|
|
205
225
|
platformBack() {
|
|
206
226
|
try {
|
|
207
227
|
// TODO: temporary hack until this code is refactored
|
|
208
|
-
if (
|
|
228
|
+
if (isSamsungPlatform() || isVizioPlatform()) {
|
|
209
229
|
const { isDialogVisible } = confirmationDialogStore.getState();
|
|
210
230
|
|
|
211
231
|
if (isDialogVisible) {
|
|
@@ -218,7 +238,7 @@ export function withInteractionManager(Component: React.FC) {
|
|
|
218
238
|
cancelCompletion: this.onConfirmDialogClose,
|
|
219
239
|
});
|
|
220
240
|
}
|
|
221
|
-
} else if (
|
|
241
|
+
} else if (isLgPlatform()) {
|
|
222
242
|
this.handleWebOsBack();
|
|
223
243
|
}
|
|
224
244
|
} catch (e) {
|
|
@@ -441,6 +461,7 @@ export function withInteractionManager(Component: React.FC) {
|
|
|
441
461
|
|
|
442
462
|
onKeyDown(event) {
|
|
443
463
|
const { displayState, setDisplayState, navigator } = this.props;
|
|
464
|
+
const { isKeyboardVisible } = this.state;
|
|
444
465
|
|
|
445
466
|
const { isDialogVisible } = confirmationDialogStore.getState();
|
|
446
467
|
|
|
@@ -451,6 +472,16 @@ export function withInteractionManager(Component: React.FC) {
|
|
|
451
472
|
}, LONG_KEY_PRESS_TIMEOUT);
|
|
452
473
|
}
|
|
453
474
|
|
|
475
|
+
if (isKeyboardVisible && shouldUseOnScreenKeyboard()) {
|
|
476
|
+
if (keyCode(event).matchesAny("Escape", "Back")) {
|
|
477
|
+
event.preventDefault();
|
|
478
|
+
event.stopPropagation();
|
|
479
|
+
this.handleKeyboardDismiss();
|
|
480
|
+
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
454
485
|
/**
|
|
455
486
|
When the player is displayed, we listen to Native Play / Pause / Stop
|
|
456
487
|
buttons. Any other key press will display the transport controls
|
|
@@ -534,7 +565,10 @@ export function withInteractionManager(Component: React.FC) {
|
|
|
534
565
|
const isHookInHomescreen = entryData?.payload?.home;
|
|
535
566
|
|
|
536
567
|
const isHookFlowBlocker =
|
|
537
|
-
entryData?.hookPlugin?.module?.isFlowBlocker
|
|
568
|
+
typeof entryData?.hookPlugin?.module?.isFlowBlocker ===
|
|
569
|
+
"function"
|
|
570
|
+
? entryData?.hookPlugin?.module?.isFlowBlocker()
|
|
571
|
+
: entryData?.hookPlugin?.module?.isFlowBlocker;
|
|
538
572
|
|
|
539
573
|
if (isHookInHomescreen && isHookFlowBlocker) {
|
|
540
574
|
this.platformBack();
|
|
@@ -567,7 +601,7 @@ export function withInteractionManager(Component: React.FC) {
|
|
|
567
601
|
}
|
|
568
602
|
|
|
569
603
|
if (keyCode(event).matches(KEYS.Exit)) {
|
|
570
|
-
if (
|
|
604
|
+
if (isSamsungPlatform() || shouldUseOnScreenKeyboard()) {
|
|
571
605
|
this.performExit();
|
|
572
606
|
|
|
573
607
|
return;
|
|
@@ -622,11 +656,9 @@ export function withInteractionManager(Component: React.FC) {
|
|
|
622
656
|
};
|
|
623
657
|
|
|
624
658
|
if (deltaY > 0) {
|
|
625
|
-
DIRECTION.value =
|
|
626
|
-
Platform.OS === ("lg_tv" as QuickBrickPlatforms) ? "down" : "up";
|
|
659
|
+
DIRECTION.value = isLgPlatform() ? "down" : "up";
|
|
627
660
|
} else if (deltaY < 0) {
|
|
628
|
-
DIRECTION.value =
|
|
629
|
-
Platform.OS === ("lg_tv" as QuickBrickPlatforms) ? "up" : "down";
|
|
661
|
+
DIRECTION.value = isLgPlatform() ? "up" : "down";
|
|
630
662
|
}
|
|
631
663
|
|
|
632
664
|
if (
|
|
@@ -662,10 +694,76 @@ export function withInteractionManager(Component: React.FC) {
|
|
|
662
694
|
|
|
663
695
|
onConfirmDialogClose() {
|
|
664
696
|
this.confirmDialog.hideDialog();
|
|
697
|
+
|
|
698
|
+
// restore initial focus after closing dialog
|
|
699
|
+
focusManager.setInitialFocus();
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
handleInputFocus = (event: FocusEvent) => {
|
|
703
|
+
if (!shouldUseOnScreenKeyboard()) return;
|
|
704
|
+
const target = event.target as HTMLElement;
|
|
705
|
+
|
|
706
|
+
if (this.isDismissing) {
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") {
|
|
711
|
+
this.setState({
|
|
712
|
+
isKeyboardVisible: true,
|
|
713
|
+
keyboardInput: (target as HTMLInputElement).value || "",
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
};
|
|
717
|
+
|
|
718
|
+
handleInputBlur(event: FocusEvent) {
|
|
719
|
+
if (!shouldUseOnScreenKeyboard()) return;
|
|
720
|
+
|
|
721
|
+
const target = event.target as HTMLElement;
|
|
722
|
+
|
|
723
|
+
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") {
|
|
724
|
+
const relatedTarget = event.relatedTarget as HTMLElement;
|
|
725
|
+
|
|
726
|
+
if (
|
|
727
|
+
!relatedTarget ||
|
|
728
|
+
(relatedTarget.tagName !== "INPUT" &&
|
|
729
|
+
relatedTarget.tagName !== "TEXTAREA")
|
|
730
|
+
) {
|
|
731
|
+
this.setState({ isKeyboardVisible: false });
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
handleKeyboardDismiss = () => {
|
|
737
|
+
this.isDismissing = true;
|
|
738
|
+
|
|
739
|
+
this.setState(
|
|
740
|
+
{
|
|
741
|
+
isKeyboardVisible: false,
|
|
742
|
+
keyboardInput: "",
|
|
743
|
+
},
|
|
744
|
+
() => {
|
|
745
|
+
this.isDismissing = false;
|
|
746
|
+
}
|
|
747
|
+
);
|
|
748
|
+
};
|
|
749
|
+
|
|
750
|
+
handleKeyboardInput(value: string) {
|
|
751
|
+
this.setState({ keyboardInput: value });
|
|
665
752
|
}
|
|
666
753
|
|
|
667
754
|
render() {
|
|
668
|
-
return
|
|
755
|
+
return (
|
|
756
|
+
<>
|
|
757
|
+
<Component {...this.props} />
|
|
758
|
+
{shouldUseOnScreenKeyboard() && this.state.isKeyboardVisible && (
|
|
759
|
+
<OnScreenKeyboard
|
|
760
|
+
initialValue={this.state.keyboardInput}
|
|
761
|
+
onInput={this.handleKeyboardInput}
|
|
762
|
+
onDismiss={this.handleKeyboardDismiss}
|
|
763
|
+
/>
|
|
764
|
+
)}
|
|
765
|
+
</>
|
|
766
|
+
);
|
|
669
767
|
}
|
|
670
768
|
}
|
|
671
769
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
/* global tizen */
|
|
3
2
|
import * as React from "react";
|
|
4
3
|
import * as R from "ramda";
|
|
4
|
+
import PropTypes from "prop-types";
|
|
5
5
|
|
|
6
6
|
import { connectToStore } from "@applicaster/zapp-react-native-redux";
|
|
7
7
|
import { QUICK_BRICK_EVENTS } from "@applicaster/zapp-react-native-bridge/QuickBrick";
|
|
@@ -9,17 +9,12 @@ import { QUICK_BRICK_EVENTS } from "@applicaster/zapp-react-native-bridge/QuickB
|
|
|
9
9
|
import { QuickBrickEvents } from "../../Polyfills/QuickBrickCommunicationModule";
|
|
10
10
|
import { Splash } from "../Splash";
|
|
11
11
|
|
|
12
|
-
type Props = {
|
|
13
|
-
appLaunched: boolean,
|
|
14
|
-
children: any,
|
|
15
|
-
};
|
|
16
|
-
|
|
17
12
|
const getAppLaunched = R.compose(
|
|
18
13
|
R.assoc("appLaunched", R.__, {}),
|
|
19
14
|
R.path(["appState", "appLaunched"])
|
|
20
15
|
);
|
|
21
16
|
|
|
22
|
-
class SplashHandler extends React.Component
|
|
17
|
+
class SplashHandler extends React.Component {
|
|
23
18
|
constructor(props) {
|
|
24
19
|
super(props);
|
|
25
20
|
|
|
@@ -76,6 +71,12 @@ class SplashHandler extends React.Component<Props> {
|
|
|
76
71
|
}
|
|
77
72
|
}
|
|
78
73
|
|
|
74
|
+
SplashHandler.propTypes = {
|
|
75
|
+
appLaunched: PropTypes.bool.isRequired,
|
|
76
|
+
children: PropTypes.node.isRequired,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
SplashHandler.shouldShowSplash = true;
|
|
79
80
|
SplashHandler.shouldShowSplash = true;
|
|
80
81
|
|
|
81
82
|
export const SplashLoader = connectToStore(getAppLaunched)(SplashHandler);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
/* global webOS */
|
|
3
2
|
/* global tizen */
|
|
4
3
|
/* eslint-disable no-console */
|
|
@@ -12,11 +11,28 @@ import {
|
|
|
12
11
|
PLATFORMS,
|
|
13
12
|
} from "./const";
|
|
14
13
|
|
|
14
|
+
/**
|
|
15
|
+
* @typedef {"tv" | "web" | "other"} DeviceType
|
|
16
|
+
* @typedef {"samsung_tv" | "lg_tv" | unknown} CustomPlatformTypes
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Retrieves the user agent string from the browser or global navigator.
|
|
21
|
+
* @returns {string} The user agent string.
|
|
22
|
+
*/
|
|
15
23
|
export const getUserAgent = () =>
|
|
16
24
|
window?.navigator?.userAgent || global?.navigator?.userAgent;
|
|
17
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Checks if the device is HD (1280 width).
|
|
28
|
+
* @returns {boolean} True if the device is HD, false otherwise.
|
|
29
|
+
*/
|
|
18
30
|
export const isHD = () => window.innerWidth === 1280;
|
|
19
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Checks if the platform is LG.
|
|
34
|
+
* @returns {boolean} True if the platform is LG, false otherwise.
|
|
35
|
+
*/
|
|
20
36
|
export const isLgPlatform = () => {
|
|
21
37
|
const userAgent = getUserAgent();
|
|
22
38
|
|
|
@@ -24,10 +40,13 @@ export const isLgPlatform = () => {
|
|
|
24
40
|
return false;
|
|
25
41
|
}
|
|
26
42
|
|
|
27
|
-
// Note: LG uses the number 0 in their userAgent, possibly because of Palm WebOS
|
|
28
43
|
return hasWebOS || userAgent.includes(PLATFORMS.webos);
|
|
29
44
|
};
|
|
30
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Checks if the platform is Samsung.
|
|
48
|
+
* @returns {boolean} True if the platform is Samsung, false otherwise.
|
|
49
|
+
*/
|
|
31
50
|
export const isSamsungPlatform = () => {
|
|
32
51
|
const userAgent = getUserAgent();
|
|
33
52
|
|
|
@@ -43,12 +62,39 @@ export const isSamsungPlatform = () => {
|
|
|
43
62
|
};
|
|
44
63
|
|
|
45
64
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
|
|
65
|
+
* Checks if the platform is Vizio by using the user agent string.
|
|
66
|
+
* @returns {boolean} True if the platform is Vizio, false otherwise.
|
|
67
|
+
*/
|
|
68
|
+
export const isVizioPlatform = () => {
|
|
69
|
+
const userAgent = getUserAgent();
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
userAgent.includes(PLATFORMS.vizio) ||
|
|
73
|
+
userAgent.includes(PLATFORMS.smartcast) ||
|
|
74
|
+
userAgent.includes(PLATFORMS.conjure)
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Checks if the Vizio APIs are available.
|
|
80
|
+
* @returns {boolean} True if the Vizio APIs are available, false otherwise.
|
|
81
|
+
*/
|
|
82
|
+
export const hasVizioAPIs = () => {
|
|
83
|
+
return (
|
|
84
|
+
typeof window.VIZIO !== "undefined" &&
|
|
85
|
+
window?.applicaster?.vizioLibraryDidLoad
|
|
86
|
+
);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Determines the device type based on the platform.
|
|
91
|
+
* @returns {DeviceType} The device type ("tv", "web", or "other").
|
|
49
92
|
*/
|
|
50
93
|
export const getDeviceType = () => {
|
|
51
|
-
|
|
94
|
+
/** @type {CustomPlatformTypes} */
|
|
95
|
+
const platformOS = Platform.OS;
|
|
96
|
+
|
|
97
|
+
switch (platformOS) {
|
|
52
98
|
case "samsung_tv":
|
|
53
99
|
return isSamsungPlatform() ? "tv" : "web";
|
|
54
100
|
case "lg_tv":
|
|
@@ -59,14 +105,15 @@ export const getDeviceType = () => {
|
|
|
59
105
|
};
|
|
60
106
|
|
|
61
107
|
/**
|
|
62
|
-
*
|
|
63
|
-
* @param {string} key - key
|
|
108
|
+
* Renames keys based on a predefined map.
|
|
109
|
+
* @param {string} key - The key to rename.
|
|
110
|
+
* @returns {string} The renamed key.
|
|
64
111
|
*/
|
|
65
112
|
export const renameKeys = (key) => desiredKeysMap?.[key] || key;
|
|
66
113
|
|
|
67
114
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
115
|
+
* Retrieves the connection info from WebOS.
|
|
116
|
+
* @returns {Promise<{networkType: string} | null>} A promise that resolves with the connection info or null.
|
|
70
117
|
*/
|
|
71
118
|
export const getWebOSConnectionInfo = () => {
|
|
72
119
|
return new Promise((resolve, reject) => {
|
|
@@ -79,7 +126,6 @@ export const getWebOSConnectionInfo = () => {
|
|
|
79
126
|
webOS.service.request("luna://com.palm.connectionmanager", {
|
|
80
127
|
method: "getStatus",
|
|
81
128
|
parameters: { subscribe: false },
|
|
82
|
-
|
|
83
129
|
onSuccess: (args) => {
|
|
84
130
|
const types = Object.keys(args)
|
|
85
131
|
.filter((key) => args[key].state === "connected")
|
|
@@ -87,7 +133,6 @@ export const getWebOSConnectionInfo = () => {
|
|
|
87
133
|
|
|
88
134
|
resolve({ networkType: types });
|
|
89
135
|
},
|
|
90
|
-
|
|
91
136
|
onFailure: (error) => {
|
|
92
137
|
console.error(
|
|
93
138
|
"getWebOSConnectionInfo: There was an error getting connection info",
|
|
@@ -100,6 +145,10 @@ export const getWebOSConnectionInfo = () => {
|
|
|
100
145
|
});
|
|
101
146
|
};
|
|
102
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Retrieves the connection info from Tizen.
|
|
150
|
+
* @returns {Promise<{networkType: string} | null>} A promise that resolves with the connection info or null.
|
|
151
|
+
*/
|
|
103
152
|
export const getTizenConnectionInfo = () => {
|
|
104
153
|
return new Promise((resolve, reject) => {
|
|
105
154
|
if (!isSamsungPlatform) {
|
|
@@ -253,6 +302,24 @@ export const getDeviceData = async () => {
|
|
|
253
302
|
...tizenConnectionInfo,
|
|
254
303
|
device_type: getDeviceType(),
|
|
255
304
|
};
|
|
305
|
+
} else if (isVizioPlatform()) {
|
|
306
|
+
deviceData = {
|
|
307
|
+
...deviceData,
|
|
308
|
+
platform: "vizio",
|
|
309
|
+
deviceMake: "Vizio",
|
|
310
|
+
deviceType: "tv",
|
|
311
|
+
userAgent: getUserAgent(),
|
|
312
|
+
deviceWidth: window.innerWidth,
|
|
313
|
+
deviceHeight: window.innerHeight,
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
if (hasVizioAPIs()) {
|
|
317
|
+
window.VIZIO.getFirmwareVersion(function (firmwareVersion) {
|
|
318
|
+
deviceData.osVersion = firmwareVersion;
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
deviceData.deviceModel = window.VIZIO.deviceModel;
|
|
322
|
+
}
|
|
256
323
|
}
|
|
257
324
|
|
|
258
325
|
return deviceData;
|
package/App/Router/index.js
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
1
|
import React from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
4
3
|
|
|
5
4
|
import { Router } from "react-router";
|
|
6
5
|
import { createMemoryHistory } from "history";
|
|
7
6
|
|
|
8
|
-
type Props = {
|
|
9
|
-
children: any,
|
|
10
|
-
};
|
|
11
|
-
|
|
12
7
|
const history = createMemoryHistory();
|
|
13
8
|
|
|
14
|
-
export const ZappDomRouter = ({ children, ...otherProps }
|
|
9
|
+
export const ZappDomRouter = ({ children, ...otherProps }) => (
|
|
15
10
|
<Router history={history} {...otherProps}>
|
|
16
11
|
{children}
|
|
17
12
|
</Router>
|
|
18
13
|
);
|
|
14
|
+
|
|
15
|
+
ZappDomRouter.propTypes = {
|
|
16
|
+
children: PropTypes.node.isRequired,
|
|
17
|
+
};
|
package/App/Splash/Spinner.js
CHANGED
package/App/Splash/Splash.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import React from "react";
|
|
3
2
|
|
|
4
|
-
import
|
|
3
|
+
import PropTypes from "prop-types";
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
remoteConfigurations: any,
|
|
8
|
-
};
|
|
5
|
+
import { verifyAssets } from "@applicaster/zapp-react-dom-ui-components/Helpers/protectHelper";
|
|
9
6
|
|
|
10
|
-
export const SplashComponent = ({ remoteConfigurations }
|
|
7
|
+
export const SplashComponent = ({ remoteConfigurations }) => {
|
|
11
8
|
const image = verifyAssets(remoteConfigurations.assets, [
|
|
12
9
|
"universal",
|
|
13
10
|
"splash",
|
|
@@ -19,3 +16,9 @@ export const SplashComponent = ({ remoteConfigurations }: Props) => {
|
|
|
19
16
|
</div>
|
|
20
17
|
);
|
|
21
18
|
};
|
|
19
|
+
|
|
20
|
+
SplashComponent.propTypes = {
|
|
21
|
+
remoteConfigurations: PropTypes.shape({
|
|
22
|
+
assets: PropTypes.object.isRequired,
|
|
23
|
+
}).isRequired,
|
|
24
|
+
};
|
|
@@ -105,7 +105,11 @@ function isInvalidAnalyticsData(eventName, payload = null) {
|
|
|
105
105
|
|
|
106
106
|
export const AnalyticsBridge = (function () {
|
|
107
107
|
let registeredAnalyticPlugins: {
|
|
108
|
-
module: {
|
|
108
|
+
module: {
|
|
109
|
+
sendEvent: Function;
|
|
110
|
+
initialize?: Function;
|
|
111
|
+
getPlayerConfiguration?: Function;
|
|
112
|
+
};
|
|
109
113
|
configuration?: any;
|
|
110
114
|
}[] = [];
|
|
111
115
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import * as R from "ramda";
|
|
3
2
|
|
|
4
3
|
import {
|
|
@@ -7,11 +6,11 @@ import {
|
|
|
7
6
|
} from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
8
7
|
import { mapKeys } from "@applicaster/zapp-react-native-utils/objectUtils";
|
|
9
8
|
|
|
10
|
-
export type StorageI = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
};
|
|
9
|
+
// export type StorageI = {
|
|
10
|
+
// setItem: (string, string, ?string) => Promise<any>,
|
|
11
|
+
// getItem: (string, ?string) => Promise<any>,
|
|
12
|
+
// getAllItems: () => Promise<any>,
|
|
13
|
+
// };
|
|
15
14
|
|
|
16
15
|
export const STORAGE_TYPES = ["localStorage", "sessionStorage"];
|
|
17
16
|
|
|
@@ -25,10 +24,7 @@ const NAMESPACE_SEPARATOR = "_::_";
|
|
|
25
24
|
* @param {?String} namespace
|
|
26
25
|
* @returns {String}
|
|
27
26
|
*/
|
|
28
|
-
export function applyNamespaceToKeyName(
|
|
29
|
-
key: string,
|
|
30
|
-
namespace: ?string
|
|
31
|
-
): string {
|
|
27
|
+
export function applyNamespaceToKeyName(key, namespace) {
|
|
32
28
|
return namespace ? `${namespace}${NAMESPACE_SEPARATOR}${key}` : key;
|
|
33
29
|
}
|
|
34
30
|
|
|
@@ -40,7 +36,7 @@ export function applyNamespaceToKeyName(
|
|
|
40
36
|
* @param {Function} fn function to run
|
|
41
37
|
* @returns {Promise}
|
|
42
38
|
*/
|
|
43
|
-
function tryAndResolve(fn
|
|
39
|
+
function tryAndResolve(fn) {
|
|
44
40
|
try {
|
|
45
41
|
return R.compose(
|
|
46
42
|
(value) => Promise.resolve(value),
|
|
@@ -62,7 +58,7 @@ function tryAndResolve(fn: (any) => any): Promise<any> {
|
|
|
62
58
|
* @returns {Function} storageObject.callMethod: invokes methods on the storage object
|
|
63
59
|
* @returns {Function} storageObject.getKeys: returns all existing keys in the storage object
|
|
64
60
|
*/
|
|
65
|
-
function getStorageObject(type
|
|
61
|
+
function getStorageObject(type) {
|
|
66
62
|
const storage = R.prop(type, window);
|
|
67
63
|
|
|
68
64
|
if (!R.includes(type, STORAGE_TYPES) || !storage) {
|
|
@@ -80,7 +76,7 @@ function getStorageObject(type: string): (any) => void | Promise<any> {
|
|
|
80
76
|
* @param {Array} args array of arguments to use when invoking the method
|
|
81
77
|
* @returns response of the method call
|
|
82
78
|
*/
|
|
83
|
-
function callMethod(method
|
|
79
|
+
function callMethod(method, ...args) {
|
|
84
80
|
return storage[method](...args);
|
|
85
81
|
}
|
|
86
82
|
|
|
@@ -107,9 +103,9 @@ function getStorageObject(type: string): (any) => void | Promise<any> {
|
|
|
107
103
|
/**
|
|
108
104
|
* returns an object to interact with a storage module (localStorage or sessionStorage)
|
|
109
105
|
* @param {String} type of storage
|
|
110
|
-
* @returns {
|
|
106
|
+
* @returns {StorageI}
|
|
111
107
|
*/
|
|
112
|
-
export function getStorageModule(type
|
|
108
|
+
export function getStorageModule(type) {
|
|
113
109
|
const Storage = getStorageObject(type);
|
|
114
110
|
|
|
115
111
|
/**
|
|
@@ -120,11 +116,7 @@ export function getStorageModule(type: string): StorageI {
|
|
|
120
116
|
* @param {?String} namespace
|
|
121
117
|
* @returns {Promise<Boolean|Error>}
|
|
122
118
|
*/
|
|
123
|
-
function setItem(
|
|
124
|
-
key: string,
|
|
125
|
-
value: string,
|
|
126
|
-
namespace: ?string = DEFAULT_NAMESPACE
|
|
127
|
-
): Promise<boolean | Error> {
|
|
119
|
+
function setItem(key, value, namespace = DEFAULT_NAMESPACE) {
|
|
128
120
|
const keyName = applyNamespaceToKeyName(
|
|
129
121
|
key,
|
|
130
122
|
namespace || DEFAULT_NAMESPACE
|
|
@@ -144,10 +136,7 @@ export function getStorageModule(type: string): StorageI {
|
|
|
144
136
|
* @param {?String} namespace
|
|
145
137
|
* @returns {Promise<Any|Error>}
|
|
146
138
|
*/
|
|
147
|
-
function getItem(
|
|
148
|
-
key: string,
|
|
149
|
-
namespace: ?string = DEFAULT_NAMESPACE
|
|
150
|
-
): Promise<any> {
|
|
139
|
+
function getItem(key, namespace = DEFAULT_NAMESPACE) {
|
|
151
140
|
const keyName = applyNamespaceToKeyName(
|
|
152
141
|
key,
|
|
153
142
|
namespace || DEFAULT_NAMESPACE
|
|
@@ -163,7 +152,7 @@ export function getStorageModule(type: string): StorageI {
|
|
|
163
152
|
* @param {?String} namespace
|
|
164
153
|
* @returns {Promise<Boolean|Error>}
|
|
165
154
|
*/
|
|
166
|
-
function removeItem(key
|
|
155
|
+
function removeItem(key, namespace = DEFAULT_NAMESPACE) {
|
|
167
156
|
const keyName = applyNamespaceToKeyName(key, namespace);
|
|
168
157
|
|
|
169
158
|
return tryAndResolve(() => Storage.callMethod("removeItem", keyName));
|
|
@@ -174,7 +163,7 @@ export function getStorageModule(type: string): StorageI {
|
|
|
174
163
|
* @param {?String} namespace
|
|
175
164
|
* @returns {Promise<Object|Error>}
|
|
176
165
|
*/
|
|
177
|
-
function getAllItems(namespace
|
|
166
|
+
function getAllItems(namespace = null) {
|
|
178
167
|
return tryAndResolve(() => {
|
|
179
168
|
const keys = Storage.getKeys();
|
|
180
169
|
|
package/main.css
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-dom-app",
|
|
3
|
-
"version": "12.0.0-alpha.
|
|
3
|
+
"version": "12.0.0-alpha.4354608902",
|
|
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": "12.0.0-alpha.
|
|
26
|
-
"@applicaster/zapp-react-native-bridge": "12.0.0-alpha.
|
|
27
|
-
"@applicaster/zapp-react-native-redux": "12.0.0-alpha.
|
|
28
|
-
"@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.
|
|
29
|
-
"@applicaster/zapp-react-native-utils": "12.0.0-alpha.
|
|
25
|
+
"@applicaster/zapp-react-dom-ui-components": "12.0.0-alpha.4354608902",
|
|
26
|
+
"@applicaster/zapp-react-native-bridge": "12.0.0-alpha.4354608902",
|
|
27
|
+
"@applicaster/zapp-react-native-redux": "12.0.0-alpha.4354608902",
|
|
28
|
+
"@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.4354608902",
|
|
29
|
+
"@applicaster/zapp-react-native-utils": "12.0.0-alpha.4354608902",
|
|
30
30
|
"abortcontroller-polyfill": "^1.7.5",
|
|
31
31
|
"history": "^4.7.2",
|
|
32
32
|
"react-router-dom": "^5.1.2",
|