@applicaster/zapp-react-dom-app 14.0.0-alpha.1384310723 → 14.0.0-alpha.1428720541

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,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("@applicaster/zapp-react-native-utils/reactHooks/state", () => ({
14
+ useIsHomeScreen: jest.fn(),
15
+ useIsRootScreen: jest.fn(),
16
+ useIsTabsScreen: jest.fn(),
17
+ }));
18
+
19
+ import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils";
20
+ import {
21
+ useIsHomeScreen,
22
+ useIsRootScreen,
23
+ useIsTabsScreen,
24
+ } from "@applicaster/zapp-react-native-utils/reactHooks/state";
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
+ (useIsRootScreen as jest.Mock).mockReturnValue(true);
51
+ (useIsHomeScreen as jest.Mock).mockReturnValue(true);
52
+ (useIsTabsScreen 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
+ (useIsRootScreen as jest.Mock).mockReturnValue(true);
72
+ (useIsHomeScreen as jest.Mock).mockReturnValue(false);
73
+ (useIsTabsScreen 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
+ (useIsRootScreen as jest.Mock).mockReturnValue(true);
88
+ (useIsHomeScreen as jest.Mock).mockReturnValue(false);
89
+ (useIsTabsScreen 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
+ (useIsRootScreen as jest.Mock).mockReturnValue(true);
111
+ (useIsHomeScreen as jest.Mock).mockReturnValue(false);
112
+ (useIsTabsScreen 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
+ (useIsRootScreen as jest.Mock).mockReturnValue(false);
136
+ (useIsHomeScreen as jest.Mock).mockReturnValue(false);
137
+ (useIsTabsScreen 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,4 @@
1
+ export {
2
+ withBackToTopActionHOC,
3
+ type BackToTopAction,
4
+ } from "./withBackToTopAction";
@@ -0,0 +1,48 @@
1
+ import * as React from "react";
2
+ import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils";
3
+ import {
4
+ useIsHomeScreen,
5
+ useIsRootScreen,
6
+ useIsTabsScreen,
7
+ } from "@applicaster/zapp-react-native-utils/reactHooks/state";
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 = useIsHomeScreen();
20
+ const isRoot = useIsRootScreen();
21
+ const isTabsScreen = useIsTabsScreen();
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,7 +1,7 @@
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,
@@ -50,6 +50,8 @@ import {
50
50
  import { OnScreenKeyboard } from "@applicaster/zapp-react-dom-ui-components/Components/OnScreenKeyboard";
51
51
  import { KeyboardLongPressManager } from "@applicaster/zapp-react-dom-ui-components/Utils/KeyboardLongPressManager";
52
52
  import { KeyInputHandler } from "@applicaster/zapp-react-native-utils/appUtils/keyInputHandler/KeyInputHandler";
53
+ import { getHomeRiver } from "@applicaster/zapp-react-native-utils/reactHooks/state";
54
+ import { withBackToTopActionHOC, BackToTopAction } from "./hoc";
53
55
 
54
56
  const { withXray } = getXray();
55
57
  const globalAny: any = global;
@@ -70,6 +72,7 @@ type Props = {
70
72
  rivers: {};
71
73
  xray: XRayContext;
72
74
  confirmDialog: typeof confirmationDialogStore;
75
+ backToTopAction: BackToTopAction;
73
76
  };
74
77
 
75
78
  interface State {
@@ -139,14 +142,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
139
142
  this.handleInputBlur = this.handleInputBlur.bind(this);
140
143
  this.handleKeyboardInput = this.handleKeyboardInput.bind(this);
141
144
  this.handleKeyboardDismiss = this.handleKeyboardDismiss.bind(this);
142
- this.onKeyDownListener = this.onKeyDown.bind(this);
143
- this.onKeyUp = this.onKeyUp.bind(this);
144
145
  this.onMouseMoveListener = this.onMouseMove.bind(this);
145
146
  this.onScrollListener = this.onScroll.bind(this);
146
147
  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
148
 
151
149
  this.handlePhysicalKeyboardDismiss =
152
150
  this.handlePhysicalKeyboardDismiss.bind(this);
@@ -318,13 +316,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
318
316
  const { navigator } = this.props;
319
317
  const { rivers } = this.props;
320
318
 
321
- const homeId = R.compose(
322
- R.prop("id"),
323
- R.find(R.prop("home")),
324
- R.values
325
- )(rivers);
319
+ const homeRiver = getHomeRiver(rivers);
326
320
 
327
- const homePath = `/river/${homeId}`;
321
+ const homePath = `/river/${homeRiver?.id}`;
328
322
 
329
323
  return homePath === navigator.currentRoute;
330
324
  }
@@ -332,7 +326,7 @@ class InteractionManagerClass extends React.Component<Props, State> {
332
326
  goToHome() {
333
327
  const { navigator } = this.props;
334
328
  const { rivers } = this.props;
335
- const homeRiver = R.find(R.propEq("home", true), R.values(rivers));
329
+ const homeRiver = getHomeRiver(rivers);
336
330
 
337
331
  navigator.replace(homeRiver);
338
332
  }
@@ -393,7 +387,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
393
387
  note: backspace affects the keyboard input, so it behaves differently
394
388
  */
395
389
  onBackPress(event) {
396
- const { displayState, setDisplayState, navigator } = this.props;
390
+ const { displayState, setDisplayState, navigator, backToTopAction } =
391
+ this.props;
392
+
397
393
  const { isDialogVisible } = confirmationDialogStore.getState();
398
394
  const { isKeyboardVisible } = this.state;
399
395
 
@@ -412,8 +408,32 @@ class InteractionManagerClass extends React.Component<Props, State> {
412
408
  return;
413
409
  }
414
410
 
411
+ const { action, payload } = backToTopAction();
412
+
415
413
  switch (displayState) {
416
414
  case DISPLAY_STATES.DEFAULT:
415
+ if (action === "PLATFORM_BACK") {
416
+ this.platformBack();
417
+ }
418
+
419
+ if (action === "GO_HOME") {
420
+ this.goToHome();
421
+ }
422
+
423
+ if (action === "FOCUS_TOP_NAVIGATION") {
424
+ focusManager.focusTopNavigation(
425
+ payload.isTabsScreen,
426
+ payload.selectedEntry
427
+ );
428
+ }
429
+
430
+ if (action === "GO_BACK") {
431
+ if (navigator.canGoBack()) {
432
+ navigator.goBack();
433
+ }
434
+ }
435
+
436
+ break;
417
437
  case DISPLAY_STATES.PLAYER:
418
438
  if (isDialogVisible) {
419
439
  this.onConfirmDialogClose();
@@ -653,8 +673,13 @@ class InteractionManagerClass extends React.Component<Props, State> {
653
673
  onConfirmDialogClose() {
654
674
  this.confirmDialog.hideDialog();
655
675
 
656
- // restore initial focus after closing dialog
657
- focusManager.setInitialFocus();
676
+ const context: FocusManager.FocusContext = {
677
+ source: "cancel",
678
+ preserveScroll: true,
679
+ };
680
+
681
+ // restore initial focus after closing dialog(with preserve scrolling)
682
+ focusManager.setInitialFocus(undefined, context);
658
683
  }
659
684
 
660
685
  handleInputFocus = (event: FocusEvent) => {
@@ -852,5 +877,6 @@ export const InteractionManager = R.compose(
852
877
  withXray,
853
878
  connectToStore(R.pick(["rivers"])),
854
879
  PlayerContentContext.withConsumer,
855
- DisplayStateContext.withConsumer
880
+ DisplayStateContext.withConsumer,
881
+ withBackToTopActionHOC
856
882
  )(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";
@@ -63,7 +63,8 @@ async function gatherData(uuid) {
63
63
  ...NativeModules?.QuickBrickCommunicationModule,
64
64
  // Device data retrieved from native device apis
65
65
  ...deviceData,
66
- uuid: uuid || uuidv4(),
66
+ uuid: uuid || uuidv4(), // Created on first session, persisted in local thereafter
67
+ sessionId: uuidv4(), // Created on every session
67
68
  locale: `{language=${languageLocale}, country=${countryLocale}}`,
68
69
  };
69
70
 
@@ -37,6 +37,7 @@ export const desiredKeysMap = {
37
37
  osVersion: "osVersion",
38
38
  platform: "platform",
39
39
  quickBrickVersion: "quickBrickVersion",
40
+ sessionId: "sessionId",
40
41
  sdkVersion: "sdk_version",
41
42
  store: "store",
42
43
  timeZoneOffset: "timeZoneOffset",
@@ -1,4 +1,4 @@
1
- import { connectToStore } from "@applicaster/zapp-react-native-redux";
1
+ import { connectToStore } from "@applicaster/zapp-react-native-redux/utils/connectToStore";
2
2
  import * as R from "ramda";
3
3
 
4
4
  import { SplashComponent } from "./Splash";
@@ -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
- expect(storage.getItem(keyWithDefaultNameSpace)).resolves.toEqual(
65
- value
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
- expect(storage.getItem(keyName)).resolves.toEqual(namespaceValue);
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
- "namespaceValue"
102
+ namespaceValue
112
103
  );
113
104
  }
114
105
  );
@@ -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-alpha.1384310723",
3
+ "version": "14.0.0-alpha.1428720541",
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.1384310723",
26
- "@applicaster/zapp-react-native-bridge": "14.0.0-alpha.1384310723",
27
- "@applicaster/zapp-react-native-redux": "14.0.0-alpha.1384310723",
28
- "@applicaster/zapp-react-native-ui-components": "14.0.0-alpha.1384310723",
29
- "@applicaster/zapp-react-native-utils": "14.0.0-alpha.1384310723",
25
+ "@applicaster/zapp-react-dom-ui-components": "14.0.0-alpha.1428720541",
26
+ "@applicaster/zapp-react-native-bridge": "14.0.0-alpha.1428720541",
27
+ "@applicaster/zapp-react-native-redux": "14.0.0-alpha.1428720541",
28
+ "@applicaster/zapp-react-native-ui-components": "14.0.0-alpha.1428720541",
29
+ "@applicaster/zapp-react-native-utils": "14.0.0-alpha.1428720541",
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": "*"