@applicaster/zapp-react-dom-app 13.0.0-alpha.4138374149 → 13.0.0-alpha.4186449353
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 +114 -61
- package/App/Loader/__tests__/__snapshots__/loadDomPlugins.test.js.snap +6 -6
- package/App/Loader/loadLocale.js +2 -2
- package/App/Loader/utils/platform.js +46 -26
- package/Polyfills/Storage/__tests__/__snapshots__/storage.test.js.snap +4 -4
- package/index.js +0 -7
- package/package.json +17 -8
- package/App/Router/index.js +0 -17
- package/App/Splash/Spinner.js +0 -30
- package/App/Splash/spinner-styles.css +0 -81
|
@@ -23,8 +23,6 @@ import {
|
|
|
23
23
|
|
|
24
24
|
import { showConfirmationDialog } from "@applicaster/zapp-react-native-utils/alertUtils";
|
|
25
25
|
|
|
26
|
-
import { withUseSeek } from "@applicaster/zapp-react-native-utils/reactHooks/player";
|
|
27
|
-
|
|
28
26
|
import {
|
|
29
27
|
DISPLAY_STATES,
|
|
30
28
|
DisplayStateContext,
|
|
@@ -48,6 +46,7 @@ import {
|
|
|
48
46
|
|
|
49
47
|
import { OnScreenKeyboard } from "@applicaster/zapp-react-dom-ui-components/Components/OnScreenKeyboard";
|
|
50
48
|
import { KeyboardLongPressManager } from "@applicaster/zapp-react-dom-ui-components/Utils/KeyboardLongPressManager";
|
|
49
|
+
import { KeyInputHandler } from "@applicaster/zapp-react-native-utils/appUtils/keyInputHandler/KeyInputHandler";
|
|
51
50
|
|
|
52
51
|
const { withXray } = getXray();
|
|
53
52
|
const globalAny: any = global;
|
|
@@ -62,14 +61,6 @@ type Props = {
|
|
|
62
61
|
navigator: QuickBrickAppNavigator;
|
|
63
62
|
rivers: {};
|
|
64
63
|
xray: XRayContext;
|
|
65
|
-
seekMethods: {
|
|
66
|
-
onRewindPress: () => void;
|
|
67
|
-
onRewindLongPress: () => void;
|
|
68
|
-
onForwardPress: () => void;
|
|
69
|
-
onForwardLongPress: () => void;
|
|
70
|
-
onRewindPressOut: () => void;
|
|
71
|
-
onForwardPressOut: () => void;
|
|
72
|
-
};
|
|
73
64
|
confirmDialog: typeof confirmationDialogStore;
|
|
74
65
|
};
|
|
75
66
|
|
|
@@ -149,13 +140,16 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
149
140
|
this.onConfirmDialogOpen = this.onConfirmDialogOpen.bind(this);
|
|
150
141
|
this.onConfirmDialogClose = this.onConfirmDialogClose.bind(this);
|
|
151
142
|
|
|
143
|
+
this.handlePhysicalKeyboardDismiss =
|
|
144
|
+
this.handlePhysicalKeyboardDismiss.bind(this);
|
|
145
|
+
|
|
152
146
|
this.confirmDialog.setConfirmAction(this.performExit);
|
|
153
147
|
this.confirmDialog.setCancelAction(this.onConfirmDialogClose);
|
|
154
148
|
this.longPressDetector = new KeyboardLongPressManager();
|
|
155
149
|
}
|
|
156
150
|
|
|
157
151
|
componentDidMount() {
|
|
158
|
-
window.addEventListener("keydown", this.onKeyDownListener);
|
|
152
|
+
window.addEventListener("keydown", this.onKeyDownListener, true);
|
|
159
153
|
window.addEventListener("keyup", this.onKeyUp);
|
|
160
154
|
window.addEventListener("mousemove", this.onMouseMoveListener);
|
|
161
155
|
|
|
@@ -181,10 +175,20 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
181
175
|
|
|
182
176
|
window.addEventListener("onLongPress", this.handleLongPress.bind(this));
|
|
183
177
|
|
|
178
|
+
window.addEventListener(
|
|
179
|
+
"onPressRelease",
|
|
180
|
+
this.handleLongPressRelease.bind(this)
|
|
181
|
+
);
|
|
182
|
+
|
|
184
183
|
window.addEventListener(
|
|
185
184
|
"onLongPressRelease",
|
|
186
185
|
this.handleLongPressRelease.bind(this)
|
|
187
186
|
);
|
|
187
|
+
|
|
188
|
+
document.addEventListener(
|
|
189
|
+
"keyboardDismissedByPhysicalKeypress",
|
|
190
|
+
this.handlePhysicalKeyboardDismiss
|
|
191
|
+
);
|
|
188
192
|
}
|
|
189
193
|
|
|
190
194
|
componentWillUnmount() {
|
|
@@ -213,6 +217,11 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
213
217
|
"onLongPressRelease",
|
|
214
218
|
this.handleLongPressRelease
|
|
215
219
|
);
|
|
220
|
+
|
|
221
|
+
document.removeEventListener(
|
|
222
|
+
"keyboardDismissedByPhysicalKeypress",
|
|
223
|
+
this.handlePhysicalKeyboardDismiss
|
|
224
|
+
);
|
|
216
225
|
}
|
|
217
226
|
|
|
218
227
|
performExit() {
|
|
@@ -339,9 +348,34 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
339
348
|
}
|
|
340
349
|
|
|
341
350
|
onKeyUp(event: KeyboardEvent) {
|
|
351
|
+
const { setDisplayState } = this.props;
|
|
352
|
+
|
|
342
353
|
if (this.keySupportsLongPress(event)) {
|
|
343
354
|
this.longPressDetector.endKeyPressMonitoring(event.code);
|
|
344
355
|
}
|
|
356
|
+
|
|
357
|
+
if (
|
|
358
|
+
keyCode(event).matches(KEYS.Enter) ||
|
|
359
|
+
(__DEV__ && keyCode(event).matches(KEYS.X))
|
|
360
|
+
) {
|
|
361
|
+
focusManager.pressOut();
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
if (
|
|
365
|
+
keyCode(event).matches(KEYS.Forward) ||
|
|
366
|
+
(__DEV__ && keyCode(event).matches(KEYS.C))
|
|
367
|
+
) {
|
|
368
|
+
setDisplayState(DISPLAY_STATES.HUD);
|
|
369
|
+
KeyInputHandler.getInstance().onForwardPressOut();
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (
|
|
373
|
+
keyCode(event).matches(KEYS.Rewind) ||
|
|
374
|
+
(__DEV__ && keyCode(event).matches(KEYS.Z))
|
|
375
|
+
) {
|
|
376
|
+
setDisplayState(DISPLAY_STATES.HUD);
|
|
377
|
+
KeyInputHandler.getInstance().onRewindPressOut();
|
|
378
|
+
}
|
|
345
379
|
}
|
|
346
380
|
|
|
347
381
|
onKeyDown(event) {
|
|
@@ -365,13 +399,14 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
365
399
|
this.longPressDetector.monitorKeyPress(event.code, event);
|
|
366
400
|
}
|
|
367
401
|
|
|
368
|
-
//
|
|
369
|
-
if (event.repeat) return;
|
|
402
|
+
// Only handle repeat events for arrow keys
|
|
403
|
+
if (event.repeat && !keyCode(event).matchesAny(...ARROW_KEYS)) return;
|
|
370
404
|
|
|
371
405
|
/**
|
|
372
406
|
When the player is displayed, we listen to Native Play / Pause / Stop
|
|
373
407
|
buttons. Any other key press will display the transport controls
|
|
374
408
|
*/
|
|
409
|
+
|
|
375
410
|
if (
|
|
376
411
|
displayState === DISPLAY_STATES.PLAYER ||
|
|
377
412
|
displayState === DISPLAY_STATES.HUD
|
|
@@ -404,36 +439,35 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
404
439
|
return;
|
|
405
440
|
}
|
|
406
441
|
|
|
407
|
-
if (
|
|
442
|
+
if (
|
|
443
|
+
keyCode(event).matches(KEYS.Forward) ||
|
|
444
|
+
(__DEV__ && keyCode(event).matches(KEYS.C))
|
|
445
|
+
) {
|
|
408
446
|
setDisplayState(DISPLAY_STATES.HUD);
|
|
409
|
-
|
|
447
|
+
KeyInputHandler.getInstance().onForwardPress();
|
|
410
448
|
|
|
411
449
|
return;
|
|
412
450
|
}
|
|
413
451
|
|
|
414
|
-
if (
|
|
452
|
+
if (
|
|
453
|
+
keyCode(event).matches(KEYS.Rewind) ||
|
|
454
|
+
(__DEV__ && keyCode(event).matches(KEYS.Z))
|
|
455
|
+
) {
|
|
415
456
|
setDisplayState(DISPLAY_STATES.HUD);
|
|
416
|
-
|
|
457
|
+
KeyInputHandler.getInstance().onRewindPress();
|
|
417
458
|
|
|
418
459
|
return;
|
|
419
460
|
}
|
|
420
461
|
}
|
|
421
462
|
|
|
422
463
|
/**
|
|
423
|
-
When pressing
|
|
464
|
+
When pressing escape or the Native "Back" button:
|
|
424
465
|
if on the transport controls: we show the player
|
|
425
466
|
if on the player : we show the UI
|
|
426
467
|
if on the UI : we exit the app
|
|
468
|
+
note: backspace affects the keyboard input, so it not handled here
|
|
427
469
|
*/
|
|
428
|
-
|
|
429
|
-
if (
|
|
430
|
-
keyCode(event).matchesAny(
|
|
431
|
-
KEYS.Back,
|
|
432
|
-
KEYS.Escape,
|
|
433
|
-
KEYS.EscapeDevice,
|
|
434
|
-
KEYS.Backspace
|
|
435
|
-
)
|
|
436
|
-
) {
|
|
470
|
+
if (keyCode(event).matchesAny(KEYS.Back, KEYS.Escape, KEYS.EscapeDevice)) {
|
|
437
471
|
switch (displayState) {
|
|
438
472
|
case DISPLAY_STATES.DEFAULT:
|
|
439
473
|
case DISPLAY_STATES.PLAYER:
|
|
@@ -451,7 +485,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
451
485
|
const isHookInHomescreen = entryData?.payload?.home;
|
|
452
486
|
|
|
453
487
|
const isHookFlowBlocker =
|
|
454
|
-
entryData?.hookPlugin?.module?.isFlowBlocker
|
|
488
|
+
typeof entryData?.hookPlugin?.module?.isFlowBlocker === "function"
|
|
489
|
+
? entryData?.hookPlugin?.module?.isFlowBlocker()
|
|
490
|
+
: entryData?.hookPlugin?.module?.isFlowBlocker;
|
|
455
491
|
|
|
456
492
|
if (isHookInHomescreen && isHookFlowBlocker) {
|
|
457
493
|
this.platformBack();
|
|
@@ -473,10 +509,14 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
473
509
|
}
|
|
474
510
|
}
|
|
475
511
|
|
|
476
|
-
if (
|
|
512
|
+
if (
|
|
513
|
+
keyCode(event).matches(KEYS.Enter) ||
|
|
514
|
+
(__DEV__ && keyCode(event).matches(KEYS.X))
|
|
515
|
+
) {
|
|
477
516
|
if (displayState === DISPLAY_STATES.PLAYER) {
|
|
478
517
|
setDisplayState(DISPLAY_STATES.HUD);
|
|
479
518
|
} else {
|
|
519
|
+
focusManager.pressIn();
|
|
480
520
|
focusManager.press();
|
|
481
521
|
}
|
|
482
522
|
|
|
@@ -509,12 +549,6 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
509
549
|
focusManager.moveFocus(direction);
|
|
510
550
|
}
|
|
511
551
|
|
|
512
|
-
if (!isDialogVisible) {
|
|
513
|
-
// run focus recovery on user interaction attempt
|
|
514
|
-
// probably we failed to set initial focus for some reason
|
|
515
|
-
focusManager.recoverFocus();
|
|
516
|
-
}
|
|
517
|
-
|
|
518
552
|
if (
|
|
519
553
|
displayState === DISPLAY_STATES.PLAYER ||
|
|
520
554
|
displayState === DISPLAY_STATES.HUD
|
|
@@ -590,6 +624,7 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
590
624
|
|
|
591
625
|
if (
|
|
592
626
|
(target.tagName === "INPUT" && target.type === "text") ||
|
|
627
|
+
(target.tagName === "INPUT" && target.type === "password") ||
|
|
593
628
|
target.tagName === "TEXTAREA"
|
|
594
629
|
) {
|
|
595
630
|
this.setState({
|
|
@@ -618,7 +653,7 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
618
653
|
}
|
|
619
654
|
}
|
|
620
655
|
|
|
621
|
-
handleKeyboardDismiss
|
|
656
|
+
handleKeyboardDismiss() {
|
|
622
657
|
this.isDismissing = true;
|
|
623
658
|
|
|
624
659
|
this.setState(
|
|
@@ -629,9 +664,10 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
629
664
|
},
|
|
630
665
|
() => {
|
|
631
666
|
this.isDismissing = false;
|
|
667
|
+
focusManager.recoverFocus();
|
|
632
668
|
}
|
|
633
669
|
);
|
|
634
|
-
}
|
|
670
|
+
}
|
|
635
671
|
|
|
636
672
|
handleKeyboardInput = (value: string) => {
|
|
637
673
|
const { activeInputRef } = this.state;
|
|
@@ -688,53 +724,71 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
688
724
|
}, SEQUENCE_ENTRY_TIME);
|
|
689
725
|
}
|
|
690
726
|
|
|
727
|
+
// TODO: Delete it on next PR if not needed
|
|
691
728
|
private handleLongPress = (event: CustomEvent) => {
|
|
692
729
|
const { keyCode } = event.detail;
|
|
693
|
-
const { displayState } = this.props;
|
|
694
|
-
const playerState = displayState === DISPLAY_STATES.PLAYER;
|
|
695
|
-
const hudState = displayState === DISPLAY_STATES.HUD;
|
|
696
|
-
const playbackState = playerState || hudState;
|
|
697
730
|
this.longPressActive = true;
|
|
698
731
|
this.cancelHudTimeout();
|
|
699
732
|
|
|
700
733
|
switch (keyCode) {
|
|
701
|
-
case KEYS.Forward.code:
|
|
702
|
-
playbackState && this.props.seekMethods.onForwardLongPress();
|
|
703
|
-
break;
|
|
704
|
-
|
|
705
|
-
case KEYS.Rewind.code:
|
|
706
|
-
playbackState && this.props.seekMethods.onRewindLongPress();
|
|
707
|
-
break;
|
|
708
|
-
|
|
709
734
|
case KEYS.Enter.code:
|
|
735
|
+
case KEYS.X.code:
|
|
710
736
|
focusManager.longPress();
|
|
711
737
|
break;
|
|
712
738
|
}
|
|
713
739
|
};
|
|
714
740
|
|
|
741
|
+
// TODO: Delete it on next PR if not needed
|
|
715
742
|
private handleLongPressRelease = (event: CustomEvent) => {
|
|
716
743
|
const { keyCode } = event.detail;
|
|
717
744
|
this.longPressActive = false;
|
|
718
745
|
this.resetHudTimeout();
|
|
719
746
|
|
|
720
747
|
switch (keyCode) {
|
|
721
|
-
case KEYS.Forward.code:
|
|
722
|
-
this.props.seekMethods.onForwardPressOut();
|
|
723
|
-
break;
|
|
724
|
-
|
|
725
|
-
case KEYS.Rewind.code:
|
|
726
|
-
this.props.seekMethods.onRewindPressOut();
|
|
727
|
-
break;
|
|
728
|
-
|
|
729
748
|
case KEYS.Enter.code:
|
|
730
|
-
|
|
749
|
+
case KEYS.X.code:
|
|
750
|
+
// focusManager.pressOut();
|
|
731
751
|
break;
|
|
732
752
|
}
|
|
733
753
|
};
|
|
734
754
|
|
|
735
755
|
private keySupportsLongPress(event: KeyboardEvent): boolean {
|
|
736
|
-
return [
|
|
737
|
-
|
|
756
|
+
return [
|
|
757
|
+
KEYS.Forward.code,
|
|
758
|
+
KEYS.Rewind.code,
|
|
759
|
+
KEYS.Enter.code,
|
|
760
|
+
KEYS.Z.code,
|
|
761
|
+
KEYS.X.code,
|
|
762
|
+
KEYS.C.code,
|
|
763
|
+
].includes(event.code);
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
handlePhysicalKeyboardDismiss(event: CustomEvent) {
|
|
767
|
+
const { value, position, inputElement } = event.detail;
|
|
768
|
+
|
|
769
|
+
this.isDismissing = true;
|
|
770
|
+
|
|
771
|
+
this.setState(
|
|
772
|
+
{
|
|
773
|
+
isKeyboardVisible: false,
|
|
774
|
+
keyboardInput: "",
|
|
775
|
+
activeInputRef: null,
|
|
776
|
+
},
|
|
777
|
+
() => {
|
|
778
|
+
if (inputElement) {
|
|
779
|
+
inputElement.value = value;
|
|
780
|
+
inputElement.focus();
|
|
781
|
+
inputElement.setSelectionRange(position, position);
|
|
782
|
+
|
|
783
|
+
const keyboardEvent = new CustomEvent("keyboardUpdate", {
|
|
784
|
+
detail: { value },
|
|
785
|
+
});
|
|
786
|
+
|
|
787
|
+
document.dispatchEvent(keyboardEvent);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
this.isDismissing = false;
|
|
791
|
+
}
|
|
738
792
|
);
|
|
739
793
|
}
|
|
740
794
|
|
|
@@ -754,7 +808,6 @@ class InteractionManagerClass extends React.Component<Props, State> {
|
|
|
754
808
|
|
|
755
809
|
export const InteractionManager = R.compose(
|
|
756
810
|
withNavigator,
|
|
757
|
-
withUseSeek,
|
|
758
811
|
withXray,
|
|
759
812
|
connectToStore(R.pick(["rivers"])),
|
|
760
813
|
PlayerContentContext.withConsumer,
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`loadDomPlugins when there are plugins requiring to write to the dom skips plugins without init method 1`] = `
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
[
|
|
5
|
+
[
|
|
6
6
|
"could not initialize plugin Plugin with Dom node & no init method - it doesn't have an init method",
|
|
7
|
-
|
|
8
|
-
"plugin":
|
|
9
|
-
"configuration":
|
|
7
|
+
{
|
|
8
|
+
"plugin": {
|
|
9
|
+
"configuration": {
|
|
10
10
|
"foo": "bar",
|
|
11
11
|
},
|
|
12
|
-
"module":
|
|
12
|
+
"module": {
|
|
13
13
|
"requiresAppendingDomNode": true,
|
|
14
14
|
},
|
|
15
15
|
"name": "Plugin with Dom node & no init method",
|
package/App/Loader/loadLocale.js
CHANGED
|
@@ -4,8 +4,8 @@ import { QuickBrickCommunicationModule } from "../../Polyfills/QuickBrickCommuni
|
|
|
4
4
|
import { loadLocaleImpl, getLanguageCode } from "./utils";
|
|
5
5
|
|
|
6
6
|
type Locale = {
|
|
7
|
-
language: string
|
|
8
|
-
country: string
|
|
7
|
+
language: string;
|
|
8
|
+
country: string;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
async function getBrowserLocale() {
|
|
@@ -11,11 +11,28 @@ import {
|
|
|
11
11
|
PLATFORMS,
|
|
12
12
|
} from "./const";
|
|
13
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
|
+
*/
|
|
14
23
|
export const getUserAgent = () =>
|
|
15
24
|
window?.navigator?.userAgent || global?.navigator?.userAgent;
|
|
16
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Checks if the device is HD (1280 width).
|
|
28
|
+
* @returns {boolean} True if the device is HD, false otherwise.
|
|
29
|
+
*/
|
|
17
30
|
export const isHD = () => window.innerWidth === 1280;
|
|
18
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Checks if the platform is LG.
|
|
34
|
+
* @returns {boolean} True if the platform is LG, false otherwise.
|
|
35
|
+
*/
|
|
19
36
|
export const isLgPlatform = () => {
|
|
20
37
|
const userAgent = getUserAgent();
|
|
21
38
|
|
|
@@ -23,10 +40,13 @@ export const isLgPlatform = () => {
|
|
|
23
40
|
return false;
|
|
24
41
|
}
|
|
25
42
|
|
|
26
|
-
// Note: LG uses the number 0 in their userAgent, possibly because of Palm WebOS
|
|
27
43
|
return hasWebOS || userAgent.includes(PLATFORMS.webos);
|
|
28
44
|
};
|
|
29
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Checks if the platform is Samsung.
|
|
48
|
+
* @returns {boolean} True if the platform is Samsung, false otherwise.
|
|
49
|
+
*/
|
|
30
50
|
export const isSamsungPlatform = () => {
|
|
31
51
|
const userAgent = getUserAgent();
|
|
32
52
|
|
|
@@ -42,42 +62,39 @@ export const isSamsungPlatform = () => {
|
|
|
42
62
|
};
|
|
43
63
|
|
|
44
64
|
/**
|
|
45
|
-
* Checks if
|
|
46
|
-
*
|
|
47
|
-
* Use this method when you need to identify the platform on runtime
|
|
48
|
-
* before the VIZIO Companion Library has loaded
|
|
65
|
+
* Checks if the platform is Vizio by using the user agent string.
|
|
66
|
+
* @returns {boolean} True if the platform is Vizio, false otherwise.
|
|
49
67
|
*/
|
|
50
68
|
export const isVizioPlatform = () => {
|
|
51
69
|
const userAgent = getUserAgent();
|
|
52
70
|
|
|
53
|
-
|
|
71
|
+
return (
|
|
54
72
|
userAgent.includes(PLATFORMS.vizio) ||
|
|
55
73
|
userAgent.includes(PLATFORMS.smartcast) ||
|
|
56
|
-
userAgent.includes(PLATFORMS.conjure)
|
|
57
|
-
|
|
58
|
-
return isVizioAgent;
|
|
74
|
+
userAgent.includes(PLATFORMS.conjure)
|
|
75
|
+
);
|
|
59
76
|
};
|
|
60
77
|
|
|
61
78
|
/**
|
|
62
|
-
* Checks if
|
|
63
|
-
*
|
|
64
|
-
* because it mainly checks whether we have access to apis, which may not be available yet
|
|
79
|
+
* Checks if the Vizio APIs are available.
|
|
80
|
+
* @returns {boolean} True if the Vizio APIs are available, false otherwise.
|
|
65
81
|
*/
|
|
66
82
|
export const hasVizioAPIs = () => {
|
|
67
|
-
|
|
83
|
+
return (
|
|
68
84
|
typeof window.VIZIO !== "undefined" &&
|
|
69
|
-
window?.applicaster?.vizioLibraryDidLoad
|
|
70
|
-
|
|
71
|
-
return hasAPIs;
|
|
85
|
+
window?.applicaster?.vizioLibraryDidLoad
|
|
86
|
+
);
|
|
72
87
|
};
|
|
73
88
|
|
|
74
89
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* @returns {"tv" | "web" | "other"} value
|
|
90
|
+
* Determines the device type based on the platform.
|
|
91
|
+
* @returns {DeviceType} The device type ("tv", "web", or "other").
|
|
78
92
|
*/
|
|
79
93
|
export const getDeviceType = () => {
|
|
80
|
-
|
|
94
|
+
/** @type {CustomPlatformTypes} */
|
|
95
|
+
const platformOS = Platform.OS;
|
|
96
|
+
|
|
97
|
+
switch (platformOS) {
|
|
81
98
|
case "samsung_tv":
|
|
82
99
|
return isSamsungPlatform() ? "tv" : "web";
|
|
83
100
|
case "lg_tv":
|
|
@@ -88,14 +105,15 @@ export const getDeviceType = () => {
|
|
|
88
105
|
};
|
|
89
106
|
|
|
90
107
|
/**
|
|
91
|
-
*
|
|
92
|
-
* @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.
|
|
93
111
|
*/
|
|
94
112
|
export const renameKeys = (key) => desiredKeysMap?.[key] || key;
|
|
95
113
|
|
|
96
114
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
115
|
+
* Retrieves the connection info from WebOS.
|
|
116
|
+
* @returns {Promise<{networkType: string} | null>} A promise that resolves with the connection info or null.
|
|
99
117
|
*/
|
|
100
118
|
export const getWebOSConnectionInfo = () => {
|
|
101
119
|
return new Promise((resolve, reject) => {
|
|
@@ -108,7 +126,6 @@ export const getWebOSConnectionInfo = () => {
|
|
|
108
126
|
webOS.service.request("luna://com.palm.connectionmanager", {
|
|
109
127
|
method: "getStatus",
|
|
110
128
|
parameters: { subscribe: false },
|
|
111
|
-
|
|
112
129
|
onSuccess: (args) => {
|
|
113
130
|
const types = Object.keys(args)
|
|
114
131
|
.filter((key) => args[key].state === "connected")
|
|
@@ -116,7 +133,6 @@ export const getWebOSConnectionInfo = () => {
|
|
|
116
133
|
|
|
117
134
|
resolve({ networkType: types });
|
|
118
135
|
},
|
|
119
|
-
|
|
120
136
|
onFailure: (error) => {
|
|
121
137
|
console.error(
|
|
122
138
|
"getWebOSConnectionInfo: There was an error getting connection info",
|
|
@@ -129,6 +145,10 @@ export const getWebOSConnectionInfo = () => {
|
|
|
129
145
|
});
|
|
130
146
|
};
|
|
131
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
|
+
*/
|
|
132
152
|
export const getTizenConnectionInfo = () => {
|
|
133
153
|
return new Promise((resolve, reject) => {
|
|
134
154
|
if (!isSamsungPlatform) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`storageObject when the requested storage exists getAllItems returns all keys 1`] = `
|
|
4
|
-
|
|
4
|
+
{
|
|
5
5
|
"baz_::_foo": "baz",
|
|
6
6
|
"baz_::_otherKey": "otherValue",
|
|
7
7
|
"foo": "bar",
|
|
@@ -10,7 +10,7 @@ Object {
|
|
|
10
10
|
`;
|
|
11
11
|
|
|
12
12
|
exports[`storageObject when the requested storage exists getAllItems returns all keys 2`] = `
|
|
13
|
-
|
|
13
|
+
{
|
|
14
14
|
"baz_::_foo": "baz",
|
|
15
15
|
"baz_::_otherKey": "otherValue",
|
|
16
16
|
"foo": "bar",
|
|
@@ -19,14 +19,14 @@ Object {
|
|
|
19
19
|
`;
|
|
20
20
|
|
|
21
21
|
exports[`storageObject when the requested storage exists getAllItems returns all keys in the namespace if provided 1`] = `
|
|
22
|
-
|
|
22
|
+
{
|
|
23
23
|
"foo": "baz",
|
|
24
24
|
"otherKey": "otherValue",
|
|
25
25
|
}
|
|
26
26
|
`;
|
|
27
27
|
|
|
28
28
|
exports[`storageObject when the requested storage exists getAllItems returns all keys in the namespace if provided 2`] = `
|
|
29
|
-
|
|
29
|
+
{
|
|
30
30
|
"foo": "baz",
|
|
31
31
|
"otherKey": "otherValue",
|
|
32
32
|
}
|
package/index.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
/// <reference types="@applicaster/applicaster-types" />
|
|
2
2
|
import * as R from "ramda";
|
|
3
|
-
import { useHistory, useLocation } from "react-router-dom";
|
|
4
3
|
|
|
5
4
|
import { createQuickBrickApp } from "@applicaster/quick-brick-core";
|
|
6
5
|
import * as QuickBrickManager from "@applicaster/zapp-react-native-bridge/QuickBrick";
|
|
7
6
|
import * as Contexts from "@applicaster/zapp-react-native-ui-components/Contexts";
|
|
8
7
|
import { OfflineHandler } from "@applicaster/zapp-react-native-ui-components/Components/OfflineHandler";
|
|
9
8
|
import { getXray } from "@applicaster/zapp-react-native-utils/logger";
|
|
10
|
-
import { ZappDomRouter } from "./App/Router";
|
|
11
9
|
import { Layout } from "./App/Layout";
|
|
12
10
|
import { SplashLoader } from "./App/Loader/SplashLoader";
|
|
13
11
|
import { appLoader } from "./App/Loader";
|
|
@@ -24,11 +22,6 @@ const contextProviders = R.map(R.prop("withProvider"), R.values(Contexts));
|
|
|
24
22
|
if (withXray) contextProviders.push(withXray);
|
|
25
23
|
|
|
26
24
|
export const ZappApp = createQuickBrickApp({
|
|
27
|
-
navigations: {
|
|
28
|
-
Router: ZappDomRouter,
|
|
29
|
-
useLocation,
|
|
30
|
-
useHistory,
|
|
31
|
-
},
|
|
32
25
|
QuickBrickManager,
|
|
33
26
|
Layout,
|
|
34
27
|
OfflineHandler,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-dom-app",
|
|
3
|
-
"version": "13.0.0-alpha.
|
|
3
|
+
"version": "13.0.0-alpha.4186449353",
|
|
4
4
|
"description": "Zapp App Component for Applicaster's Quick Brick React Native App",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -22,13 +22,12 @@
|
|
|
22
22
|
},
|
|
23
23
|
"homepage": "https://github.com/applicaster/zapp-react-dom-app#readme",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@applicaster/zapp-react-dom-ui-components": "13.0.0-alpha.
|
|
26
|
-
"@applicaster/zapp-react-native-bridge": "13.0.0-alpha.
|
|
27
|
-
"@applicaster/zapp-react-native-redux": "13.0.0-alpha.
|
|
28
|
-
"@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.
|
|
29
|
-
"@applicaster/zapp-react-native-utils": "13.0.0-alpha.
|
|
25
|
+
"@applicaster/zapp-react-dom-ui-components": "13.0.0-alpha.4186449353",
|
|
26
|
+
"@applicaster/zapp-react-native-bridge": "13.0.0-alpha.4186449353",
|
|
27
|
+
"@applicaster/zapp-react-native-redux": "13.0.0-alpha.4186449353",
|
|
28
|
+
"@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.4186449353",
|
|
29
|
+
"@applicaster/zapp-react-native-utils": "13.0.0-alpha.4186449353",
|
|
30
30
|
"abortcontroller-polyfill": "^1.7.5",
|
|
31
|
-
"history": "^4.7.2",
|
|
32
31
|
"react-router-dom": "^5.1.2",
|
|
33
32
|
"typeface-montserrat": "^0.0.54",
|
|
34
33
|
"video.js": "7.14.3",
|
|
@@ -36,9 +35,19 @@
|
|
|
36
35
|
"videojs-contrib-quality-levels": "3.0.0"
|
|
37
36
|
},
|
|
38
37
|
"peerDependencies": {
|
|
38
|
+
"@applicaster/zapp-pipes-v2-client": "*",
|
|
39
|
+
"@react-native-community/netinfo": "*",
|
|
40
|
+
"@types/node": "*",
|
|
39
41
|
"core-js": "3.29.1",
|
|
42
|
+
"immer": "*",
|
|
40
43
|
"react": "17.0.2",
|
|
41
44
|
"react-dom": "17.0.2",
|
|
42
|
-
"react-native
|
|
45
|
+
"react-native": "*",
|
|
46
|
+
"react-native-safe-area-context": "*",
|
|
47
|
+
"react-native-svg": "*",
|
|
48
|
+
"react-native-web": "0.18.11",
|
|
49
|
+
"uglify-js": "*",
|
|
50
|
+
"validate-color": "*",
|
|
51
|
+
"zustand": "*"
|
|
43
52
|
}
|
|
44
53
|
}
|
package/App/Router/index.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import PropTypes from "prop-types";
|
|
3
|
-
|
|
4
|
-
import { Router } from "react-router";
|
|
5
|
-
import { createMemoryHistory } from "history";
|
|
6
|
-
|
|
7
|
-
const history = createMemoryHistory();
|
|
8
|
-
|
|
9
|
-
export const ZappDomRouter = ({ children, ...otherProps }) => (
|
|
10
|
-
<Router history={history} {...otherProps}>
|
|
11
|
-
{children}
|
|
12
|
-
</Router>
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
ZappDomRouter.propTypes = {
|
|
16
|
-
children: PropTypes.node.isRequired,
|
|
17
|
-
};
|
package/App/Splash/Spinner.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
|
|
3
|
-
import "./spinner-styles.css";
|
|
4
|
-
|
|
5
|
-
export const Spinner = (color) => {
|
|
6
|
-
const spinnerColor = {
|
|
7
|
-
background: color.color,
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
return (
|
|
11
|
-
<div>
|
|
12
|
-
<div id="progress">
|
|
13
|
-
<div className="spinner">
|
|
14
|
-
<div style={spinnerColor} className="bar1" />
|
|
15
|
-
<div style={spinnerColor} className="bar2" />
|
|
16
|
-
<div style={spinnerColor} className="bar3" />
|
|
17
|
-
<div style={spinnerColor} className="bar4" />
|
|
18
|
-
<div style={spinnerColor} className="bar5" />
|
|
19
|
-
<div style={spinnerColor} className="bar6" />
|
|
20
|
-
<div style={spinnerColor} className="bar7" />
|
|
21
|
-
<div style={spinnerColor} className="bar8" />
|
|
22
|
-
<div style={spinnerColor} className="bar9" />
|
|
23
|
-
<div style={spinnerColor} className="bar10" />
|
|
24
|
-
<div style={spinnerColor} className="bar11" />
|
|
25
|
-
<div style={spinnerColor} className="bar12" />
|
|
26
|
-
</div>
|
|
27
|
-
</div>
|
|
28
|
-
</div>
|
|
29
|
-
);
|
|
30
|
-
};
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
div.spinner {
|
|
2
|
-
position: absolute;
|
|
3
|
-
width: 100px;
|
|
4
|
-
height: 100px;
|
|
5
|
-
display: inline-block;
|
|
6
|
-
top: 50%;
|
|
7
|
-
left: 50%;
|
|
8
|
-
margin: -60px 0 0 -70px;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
div.spinner div {
|
|
12
|
-
width: 6%;
|
|
13
|
-
height: 16%;
|
|
14
|
-
position: absolute;
|
|
15
|
-
left: 49%;
|
|
16
|
-
top: 43%;
|
|
17
|
-
opacity: 0;
|
|
18
|
-
-webkit-border-radius: 50px;
|
|
19
|
-
-webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.2);
|
|
20
|
-
-webkit-animation: fade 1s linear infinite;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
@-webkit-keyframes fade {
|
|
24
|
-
from {
|
|
25
|
-
opacity: 1;
|
|
26
|
-
}
|
|
27
|
-
to {
|
|
28
|
-
opacity: 0.25;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
div.spinner div.bar1 {
|
|
33
|
-
-webkit-transform: rotate(0deg) translate(0, -130%);
|
|
34
|
-
-webkit-animation-delay: 0s;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
div.spinner div.bar2 {
|
|
38
|
-
-webkit-transform: rotate(30deg) translate(0, -130%);
|
|
39
|
-
-webkit-animation-delay: -0.9167s;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
div.spinner div.bar3 {
|
|
43
|
-
-webkit-transform: rotate(60deg) translate(0, -130%);
|
|
44
|
-
-webkit-animation-delay: -0.833s;
|
|
45
|
-
}
|
|
46
|
-
div.spinner div.bar4 {
|
|
47
|
-
-webkit-transform: rotate(90deg) translate(0, -130%);
|
|
48
|
-
-webkit-animation-delay: -0.7497s;
|
|
49
|
-
}
|
|
50
|
-
div.spinner div.bar5 {
|
|
51
|
-
-webkit-transform: rotate(120deg) translate(0, -130%);
|
|
52
|
-
-webkit-animation-delay: -0.667s;
|
|
53
|
-
}
|
|
54
|
-
div.spinner div.bar6 {
|
|
55
|
-
-webkit-transform: rotate(150deg) translate(0, -130%);
|
|
56
|
-
-webkit-animation-delay: -0.5837s;
|
|
57
|
-
}
|
|
58
|
-
div.spinner div.bar7 {
|
|
59
|
-
-webkit-transform: rotate(180deg) translate(0, -130%);
|
|
60
|
-
-webkit-animation-delay: -0.5s;
|
|
61
|
-
}
|
|
62
|
-
div.spinner div.bar8 {
|
|
63
|
-
-webkit-transform: rotate(210deg) translate(0, -130%);
|
|
64
|
-
-webkit-animation-delay: -0.4167s;
|
|
65
|
-
}
|
|
66
|
-
div.spinner div.bar9 {
|
|
67
|
-
-webkit-transform: rotate(240deg) translate(0, -130%);
|
|
68
|
-
-webkit-animation-delay: -0.333s;
|
|
69
|
-
}
|
|
70
|
-
div.spinner div.bar10 {
|
|
71
|
-
-webkit-transform: rotate(270deg) translate(0, -130%);
|
|
72
|
-
-webkit-animation-delay: -0.2497s;
|
|
73
|
-
}
|
|
74
|
-
div.spinner div.bar11 {
|
|
75
|
-
-webkit-transform: rotate(300deg) translate(0, -130%);
|
|
76
|
-
-webkit-animation-delay: -0.167s;
|
|
77
|
-
}
|
|
78
|
-
div.spinner div.bar12 {
|
|
79
|
-
-webkit-transform: rotate(330deg) translate(0, -130%);
|
|
80
|
-
-webkit-animation-delay: -0.0833s;
|
|
81
|
-
}
|