@applicaster/zapp-react-dom-app 14.0.0-alpha.5974411329 → 14.0.0-alpha.6000342231

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.
@@ -0,0 +1,183 @@
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
+ isTabsScreenContentFocused: jest.fn(),
11
+ },
12
+ }));
13
+
14
+ jest.mock("../hooks", () => ({
15
+ useCurrentScreenIsHome: jest.fn(),
16
+ useCurrentScreenIsRoot: jest.fn(),
17
+ useCurrentScreenIsTabs: jest.fn(),
18
+ }));
19
+
20
+ import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils";
21
+ import {
22
+ useCurrentScreenIsHome,
23
+ useCurrentScreenIsRoot,
24
+ useCurrentScreenIsTabs,
25
+ } from "../hooks";
26
+
27
+ jest.mock("@applicaster/zapp-react-native-utils/reactHooks", () => ({
28
+ useNavigation: jest.fn(),
29
+ }));
30
+
31
+ import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
32
+
33
+ describe("withBackToTopActionHOC", () => {
34
+ let receivedProps: any;
35
+
36
+ const BaseComponent = (props) => {
37
+ receivedProps = props; // capture injected props
38
+
39
+ return <></>;
40
+ };
41
+
42
+ const Wrapped = withBackToTopActionHOC(BaseComponent);
43
+
44
+ beforeEach(() => {
45
+ jest.clearAllMocks();
46
+ });
47
+
48
+ it("returns PLATFORM_BACK when on root screen, and startup hooks", () => {
49
+ expect.assertions(1);
50
+
51
+ (useCurrentScreenIsRoot as jest.Mock).mockReturnValue(true);
52
+
53
+ (useNavigation as jest.Mock).mockReturnValue({
54
+ startUpHooks: ["some_startup_hook"],
55
+ });
56
+
57
+ render(<Wrapped />);
58
+
59
+ expect(receivedProps.backToTopAction()).toBe("PLATFORM_BACK");
60
+ });
61
+
62
+ it("returns PLATFORM_BACK when on root screen, focus on menu, and is home", () => {
63
+ expect.assertions(1);
64
+
65
+ (useCurrentScreenIsRoot as jest.Mock).mockReturnValue(true);
66
+ (useCurrentScreenIsHome as jest.Mock).mockReturnValue(true);
67
+ (useCurrentScreenIsTabs as jest.Mock).mockReturnValue(false);
68
+
69
+ (useNavigation as jest.Mock).mockReturnValue({
70
+ startUpHooks: [],
71
+ });
72
+
73
+ (focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(true);
74
+ (focusManager.isFocusOnContent as jest.Mock).mockReturnValue(false);
75
+
76
+ render(<Wrapped />);
77
+
78
+ expect(receivedProps.backToTopAction()).toBe("PLATFORM_BACK");
79
+ });
80
+
81
+ it("returns GO_HOME when on root screen, focus on menu, and not home", () => {
82
+ expect.assertions(1);
83
+
84
+ (useCurrentScreenIsRoot as jest.Mock).mockReturnValue(true);
85
+ (useCurrentScreenIsHome as jest.Mock).mockReturnValue(false);
86
+ (useCurrentScreenIsTabs as jest.Mock).mockReturnValue(false);
87
+
88
+ (useNavigation as jest.Mock).mockReturnValue({
89
+ startUpHooks: [],
90
+ });
91
+
92
+ (focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(true);
93
+ (focusManager.isFocusOnContent as jest.Mock).mockReturnValue(false);
94
+
95
+ render(<Wrapped />);
96
+ expect(receivedProps.backToTopAction()).toBe("GO_HOME");
97
+ });
98
+
99
+ it("returns FOCUS_ON_SELECTED_TOP_MENU_ITEM when on root screen and focus on content without tabs_screen", () => {
100
+ (useCurrentScreenIsRoot as jest.Mock).mockReturnValue(true);
101
+ (useCurrentScreenIsHome as jest.Mock).mockReturnValue(false);
102
+ (useCurrentScreenIsTabs as jest.Mock).mockReturnValue(false);
103
+
104
+ (useNavigation as jest.Mock).mockReturnValue({
105
+ startUpHooks: [],
106
+ });
107
+
108
+ (focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(false);
109
+ (focusManager.isFocusOnContent as jest.Mock).mockReturnValue(true);
110
+
111
+ render(<Wrapped />);
112
+
113
+ expect(receivedProps.backToTopAction()).toBe(
114
+ "FOCUS_ON_SELECTED_TOP_MENU_ITEM"
115
+ );
116
+ });
117
+
118
+ it("returns FOCUS_ON_SELECTED_TAB_ITEM when on root screen and focus on content with tabs_screen", () => {
119
+ (useCurrentScreenIsRoot as jest.Mock).mockReturnValue(true);
120
+ (useCurrentScreenIsHome as jest.Mock).mockReturnValue(false);
121
+ (useCurrentScreenIsTabs as jest.Mock).mockReturnValue(true);
122
+
123
+ (useNavigation as jest.Mock).mockReturnValue({
124
+ startUpHooks: [],
125
+ });
126
+
127
+ (focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(false);
128
+ (focusManager.isFocusOnContent as jest.Mock).mockReturnValue(true);
129
+
130
+ (focusManager.isTabsScreenContentFocused as jest.Mock).mockReturnValue(
131
+ true
132
+ );
133
+
134
+ render(<Wrapped />);
135
+
136
+ expect(receivedProps.backToTopAction()).toBe("FOCUS_ON_SELECTED_TAB_ITEM");
137
+ });
138
+
139
+ it("returns GO_BACK in default case", () => {
140
+ expect.assertions(1);
141
+
142
+ (useCurrentScreenIsRoot as jest.Mock).mockReturnValue(false);
143
+ (useCurrentScreenIsHome as jest.Mock).mockReturnValue(false);
144
+ (useCurrentScreenIsTabs as jest.Mock).mockReturnValue(false);
145
+
146
+ (useNavigation as jest.Mock).mockReturnValue({
147
+ startUpHooks: [],
148
+ });
149
+
150
+ (focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(false);
151
+ (focusManager.isFocusOnContent as jest.Mock).mockReturnValue(false);
152
+
153
+ (focusManager.isTabsScreenContentFocused as jest.Mock).mockReturnValue(
154
+ false
155
+ );
156
+
157
+ render(<Wrapped />);
158
+ expect(receivedProps.backToTopAction()).toBe("GO_BACK");
159
+ });
160
+
161
+ it("returns FORCE_GO_BACK in hook case", () => {
162
+ expect.assertions(1);
163
+
164
+ (useCurrentScreenIsRoot as jest.Mock).mockReturnValue(false);
165
+ (useCurrentScreenIsHome as jest.Mock).mockReturnValue(false);
166
+ (useCurrentScreenIsTabs as jest.Mock).mockReturnValue(false);
167
+
168
+ (useNavigation as jest.Mock).mockReturnValue({
169
+ startUpHooks: [],
170
+ currentRoute: "/hooks/some_route",
171
+ });
172
+
173
+ (focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(false);
174
+ (focusManager.isFocusOnContent as jest.Mock).mockReturnValue(false);
175
+
176
+ (focusManager.isTabsScreenContentFocused as jest.Mock).mockReturnValue(
177
+ false
178
+ );
179
+
180
+ render(<Wrapped />);
181
+ expect(receivedProps.backToTopAction()).toBe("FORCE_GO_BACK");
182
+ });
183
+ });
@@ -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,4 @@
1
+ export {
2
+ withBackToTopActionHOC,
3
+ type BackToTopAction,
4
+ } from "./withBackToTopAction";
@@ -0,0 +1,83 @@
1
+ import * as React from "react";
2
+ import { isFilledArray } from "@applicaster/zapp-react-native-utils/arrayUtils";
3
+ import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils";
4
+
5
+ import { useSubscriberFor } from "@applicaster/zapp-react-native-utils/reactHooks/useSubscriberFor";
6
+ import { QBUIComponentEvents } from "@applicaster/zapp-react-native-ui-components/events";
7
+
8
+ import {
9
+ useCurrentScreenIsHome,
10
+ useCurrentScreenIsRoot,
11
+ useCurrentScreenIsTabs,
12
+ } from "./hooks";
13
+ import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
14
+
15
+ export type BACK_TO_TOP_ACTION =
16
+ | "PLATFORM_BACK"
17
+ | "GO_HOME"
18
+ | "GO_BACK"
19
+ | "FOCUS_ON_SELECTED_TOP_MENU_ITEM"
20
+ | "FORCE_GO_BACK"
21
+ | "FOCUS_ON_SELECTED_TAB_ITEM";
22
+
23
+ export type BackToTopAction = () => BACK_TO_TOP_ACTION;
24
+
25
+ export function withBackToTopActionHOC(Component) {
26
+ return function WrappedComponent(props) {
27
+ const isHome = useCurrentScreenIsHome();
28
+ const isRoot = useCurrentScreenIsRoot();
29
+ const isTabsScreen = useCurrentScreenIsTabs();
30
+
31
+ const navigator = useNavigation();
32
+
33
+ const isStartUpHook = isFilledArray(navigator.startUpHooks);
34
+
35
+ const isHook = navigator.currentRoute?.includes("hook");
36
+
37
+ const emitFocusOnSelectedTab = useSubscriberFor(
38
+ QBUIComponentEvents.focusOnSelectedTab
39
+ );
40
+
41
+ const emitFocusOnSelectedTopMenuItem = useSubscriberFor(
42
+ QBUIComponentEvents.focusOnSelectedTopMenuItem
43
+ );
44
+
45
+ const backToTopAction = React.useCallback((): BACK_TO_TOP_ACTION => {
46
+ if (isRoot && isStartUpHook) {
47
+ return "PLATFORM_BACK";
48
+ }
49
+
50
+ if (isRoot && focusManager.isFocusOnMenu() && isHome) {
51
+ return "PLATFORM_BACK";
52
+ }
53
+
54
+ if (isRoot && focusManager.isFocusOnMenu() && !isHome) {
55
+ return "GO_HOME";
56
+ }
57
+
58
+ if (isRoot && isTabsScreen && focusManager.isTabsScreenContentFocused()) {
59
+ return "FOCUS_ON_SELECTED_TAB_ITEM";
60
+ }
61
+
62
+ if (isRoot && focusManager.isFocusOnContent()) {
63
+ return "FOCUS_ON_SELECTED_TOP_MENU_ITEM";
64
+ }
65
+
66
+ if (isHook) {
67
+ return "FORCE_GO_BACK";
68
+ }
69
+
70
+ // default
71
+ return "GO_BACK";
72
+ }, [isHome, isRoot, isTabsScreen, isStartUpHook, isHook]);
73
+
74
+ return (
75
+ <Component
76
+ {...props}
77
+ backToTopAction={backToTopAction}
78
+ emitFocusOnSelectedTab={emitFocusOnSelectedTab}
79
+ emitFocusOnSelectedTopMenuItem={emitFocusOnSelectedTopMenuItem}
80
+ />
81
+ );
82
+ };
83
+ }
@@ -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,17 +53,20 @@ 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;
56
61
 
57
- const { log_debug, log_warning } = createLogger({
62
+ const { log_debug, log_warning, log_info } = createLogger({
58
63
  category: "InteractionManager",
59
64
  subsystem: "zapp-react-dom-app",
60
65
  });
61
66
 
62
67
  const shouldUseOnScreenKeyboard = () =>
63
- isVizioPlatform() || window.applicaster.useOnScreenKeyboard;
68
+ isVizioPlatform() ||
69
+ toBooleanWithDefaultFalse(window?.applicaster?.useOnScreenKeyboard);
64
70
 
65
71
  type Props = {
66
72
  displayState: string;
@@ -70,6 +76,9 @@ type Props = {
70
76
  rivers: {};
71
77
  xray: XRayContext;
72
78
  confirmDialog: typeof confirmationDialogStore;
79
+ backToTopAction: BackToTopAction;
80
+ emitFocusOnSelectedTopMenuItem: Callback;
81
+ emitFocusOnSelectedTab: Callback;
73
82
  };
74
83
 
75
84
  interface State {
@@ -80,8 +89,8 @@ interface State {
80
89
 
81
90
  type KeyCode = { code: string; keyCode: number | string };
82
91
 
83
- export const alertConfirmationMesage =
84
- "Are you sure you want to exit application?";
92
+ const VIDEO_PLAYER_CONTROLS_NAVIGATION_MESSAGE =
93
+ "Video player controls - use left/right to navigate";
85
94
 
86
95
  class InteractionManagerClass extends React.Component<Props, State> {
87
96
  onKeyDownListener: (keyCode: KeyCode) => void;
@@ -98,6 +107,8 @@ class InteractionManagerClass extends React.Component<Props, State> {
98
107
  private confirmDialog: ConfirmationDialogState =
99
108
  confirmationDialogStore.getState();
100
109
 
110
+ accessibilityManager: AccessibilityManager;
111
+
101
112
  state: State = {
102
113
  isKeyboardVisible: false,
103
114
  keyboardInput: "",
@@ -149,6 +160,7 @@ class InteractionManagerClass extends React.Component<Props, State> {
149
160
  this.confirmDialog.setConfirmAction(this.performExit);
150
161
  this.confirmDialog.setCancelAction(this.onConfirmDialogClose);
151
162
  this.longPressDetector = new KeyboardLongPressManager();
163
+ this.accessibilityManager = AccessibilityManager.getInstance();
152
164
  }
153
165
 
154
166
  componentDidMount() {
@@ -254,7 +266,6 @@ class InteractionManagerClass extends React.Component<Props, State> {
254
266
  */
255
267
  showConfirmationDialog({
256
268
  title: "",
257
- message: alertConfirmationMesage,
258
269
  confirmCompletion: this.performExit,
259
270
  });
260
271
  }
@@ -277,7 +288,6 @@ class InteractionManagerClass extends React.Component<Props, State> {
277
288
  } else {
278
289
  showConfirmationDialog({
279
290
  title: "",
280
- message: alertConfirmationMesage,
281
291
  confirmCompletion: this.performExit,
282
292
  cancelCompletion: this.onConfirmDialogClose,
283
293
  });
@@ -313,13 +323,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
313
323
  const { navigator } = this.props;
314
324
  const { rivers } = this.props;
315
325
 
316
- const homeId = R.compose(
317
- R.prop("id"),
318
- R.find(R.prop("home")),
319
- R.values
320
- )(rivers);
326
+ const homeRiver = getHomeRiver(rivers);
321
327
 
322
- const homePath = `/river/${homeId}`;
328
+ const homePath = `/river/${homeRiver?.id}`;
323
329
 
324
330
  return homePath === navigator.currentRoute;
325
331
  }
@@ -327,7 +333,7 @@ class InteractionManagerClass extends React.Component<Props, State> {
327
333
  goToHome() {
328
334
  const { navigator } = this.props;
329
335
  const { rivers } = this.props;
330
- const homeRiver = R.find(R.propEq("home", true), R.values(rivers));
336
+ const homeRiver = getHomeRiver(rivers);
331
337
 
332
338
  navigator.replace(homeRiver);
333
339
  }
@@ -388,7 +394,15 @@ class InteractionManagerClass extends React.Component<Props, State> {
388
394
  note: backspace affects the keyboard input, so it behaves differently
389
395
  */
390
396
  onBackPress(event) {
391
- const { displayState, setDisplayState, navigator } = this.props;
397
+ const {
398
+ displayState,
399
+ setDisplayState,
400
+ navigator,
401
+ backToTopAction,
402
+ emitFocusOnSelectedTopMenuItem,
403
+ emitFocusOnSelectedTab,
404
+ } = this.props;
405
+
392
406
  const { isDialogVisible } = confirmationDialogStore.getState();
393
407
  const { isKeyboardVisible } = this.state;
394
408
 
@@ -407,8 +421,56 @@ class InteractionManagerClass extends React.Component<Props, State> {
407
421
  return;
408
422
  }
409
423
 
424
+ const action = backToTopAction();
425
+
410
426
  switch (displayState) {
411
427
  case DISPLAY_STATES.DEFAULT:
428
+ if (action === "PLATFORM_BACK") {
429
+ log_info(action);
430
+
431
+ this.platformBack();
432
+ }
433
+
434
+ if (action === "GO_HOME") {
435
+ log_info(action);
436
+
437
+ this.goToHome();
438
+ }
439
+
440
+ if (action === "FOCUS_ON_SELECTED_TOP_MENU_ITEM") {
441
+ log_info(action);
442
+
443
+ // we don't have enough context at this point to set focus properly on selected top-menu-item, just emit event about it.
444
+ // TopMenu component is supposed to handle this event.
445
+ emitFocusOnSelectedTopMenuItem();
446
+ }
447
+
448
+ if (action === "FOCUS_ON_SELECTED_TAB_ITEM") {
449
+ log_info(action);
450
+
451
+ // we don't have enough context at this point to set focus properly on selected tab-menu-item, just emit event about it
452
+ // Tabs component is supposed to handle this event.
453
+ emitFocusOnSelectedTab();
454
+ }
455
+
456
+ if (action === "GO_BACK") {
457
+ log_info(action);
458
+
459
+ if (navigator.canGoBack()) {
460
+ navigator.goBack();
461
+ }
462
+ }
463
+
464
+ if (action === "FORCE_GO_BACK") {
465
+ log_info(action);
466
+
467
+ const fallbackToHome = false;
468
+ const fromHook = true;
469
+
470
+ navigator.goBack(fallbackToHome, fromHook);
471
+ }
472
+
473
+ break;
412
474
  case DISPLAY_STATES.PLAYER:
413
475
  if (isDialogVisible) {
414
476
  this.onConfirmDialogClose();
@@ -548,6 +610,13 @@ class InteractionManagerClass extends React.Component<Props, State> {
548
610
  ) {
549
611
  if (displayState === DISPLAY_STATES.PLAYER) {
550
612
  setDisplayState(DISPLAY_STATES.HUD);
613
+
614
+ this.accessibilityManager.addHeading(
615
+ VIDEO_PLAYER_CONTROLS_NAVIGATION_MESSAGE
616
+ );
617
+
618
+ focusManager.recoverFocus();
619
+ this.resetHudTimeout();
551
620
  } else {
552
621
  focusManager.pressIn();
553
622
  focusManager.press();
@@ -592,6 +661,12 @@ class InteractionManagerClass extends React.Component<Props, State> {
592
661
  this.resetHudTimeout();
593
662
  }
594
663
 
664
+ if (displayState === DISPLAY_STATES.PLAYER) {
665
+ this.accessibilityManager.addHeading(
666
+ VIDEO_PLAYER_CONTROLS_NAVIGATION_MESSAGE
667
+ );
668
+ }
669
+
595
670
  return true;
596
671
  }
597
672
  }
@@ -648,8 +723,13 @@ class InteractionManagerClass extends React.Component<Props, State> {
648
723
  onConfirmDialogClose() {
649
724
  this.confirmDialog.hideDialog();
650
725
 
651
- // restore initial focus after closing dialog
652
- focusManager.setInitialFocus();
726
+ const context: FocusManager.FocusContext = {
727
+ source: "cancel",
728
+ preserveScroll: true,
729
+ };
730
+
731
+ // restore initial focus after closing dialog(with preserve scrolling)
732
+ focusManager.setInitialFocus(undefined, context);
653
733
  }
654
734
 
655
735
  handleInputFocus = (event: FocusEvent) => {
@@ -847,5 +927,6 @@ export const InteractionManager = R.compose(
847
927
  withXray,
848
928
  connectToStore(R.pick(["rivers"])),
849
929
  PlayerContentContext.withConsumer,
850
- DisplayStateContext.withConsumer
930
+ DisplayStateContext.withConsumer,
931
+ withBackToTopActionHOC
851
932
  )(InteractionManagerClass);
@@ -1,4 +1,5 @@
1
1
  import * as React from "react";
2
+ import { createPortal } from "react-dom";
2
3
 
3
4
  import { Background } from "@applicaster/zapp-react-dom-ui-components/Components/Background";
4
5
  import { ConfirmDialog } from "@applicaster/zapp-react-dom-ui-components/Components/ConfirmDialog";
@@ -29,7 +30,7 @@ export function Layout({ children }: Props) {
29
30
  >
30
31
  {children}
31
32
  </LayoutComponent>
32
- <ConfirmDialog />
33
+ {createPortal(<ConfirmDialog />, document.body)}
33
34
  </>
34
35
  );
35
36
  }
@@ -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,6 +64,7 @@ async function gatherData(uuid) {
63
64
  ...NativeModules?.QuickBrickCommunicationModule,
64
65
  // Device data retrieved from native device apis
65
66
  ...deviceData,
67
+ userAgent: deviceData.userAgent || getUserAgent(),
66
68
  uuid: uuid || uuidv4(), // Created on first session, persisted in local thereafter
67
69
  sessionId: uuidv4(), // Created on every session
68
70
  locale: `{language=${languageLocale}, country=${countryLocale}}`,
@@ -79,21 +81,23 @@ async function gatherData(uuid) {
79
81
  * @param {Object} desiredKeys - The map of original key names to desired key names.
80
82
  */
81
83
  function storeData(data, desiredKeys) {
82
- // Pick only the keys we want and need, map them to the correct name, and reject any unusuable data
83
- const filteredData = R.compose(
84
- R.reject(isEmptyOrNil),
85
- R.reject(R.either(R.is(Object), R.is(Function))),
86
- mapKeys(renameKeys),
87
- R.pick(Object.keys(desiredKeys))
88
- )(data);
89
-
90
- R.forEachObjIndexed((value, key) => {
91
- if (key === "uuid") {
92
- localStorage.setItem(key, value);
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);
93
97
  }
94
98
 
95
- sessionStorage.setItem(key, value);
96
- }, filteredData);
99
+ sessionStorage.setItem(renamedKey, value);
100
+ });
97
101
  }
98
102
 
99
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-dom-app",
3
- "version": "14.0.0-alpha.5974411329",
3
+ "version": "14.0.0-alpha.6000342231",
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.5974411329",
26
- "@applicaster/zapp-react-native-bridge": "14.0.0-alpha.5974411329",
27
- "@applicaster/zapp-react-native-redux": "14.0.0-alpha.5974411329",
28
- "@applicaster/zapp-react-native-ui-components": "14.0.0-alpha.5974411329",
29
- "@applicaster/zapp-react-native-utils": "14.0.0-alpha.5974411329",
25
+ "@applicaster/zapp-react-dom-ui-components": "14.0.0-alpha.6000342231",
26
+ "@applicaster/zapp-react-native-bridge": "14.0.0-alpha.6000342231",
27
+ "@applicaster/zapp-react-native-redux": "14.0.0-alpha.6000342231",
28
+ "@applicaster/zapp-react-native-ui-components": "14.0.0-alpha.6000342231",
29
+ "@applicaster/zapp-react-native-utils": "14.0.0-alpha.6000342231",
30
30
  "abortcontroller-polyfill": "^1.7.5",
31
31
  "typeface-montserrat": "^0.0.54",
32
32
  "video.js": "7.14.3",