@applicaster/zapp-react-dom-app 14.0.0-alpha.5114565431 → 14.0.0-alpha.5219335081

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 {
@@ -313,13 +316,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
313
316
  const { navigator } = this.props;
314
317
  const { rivers } = this.props;
315
318
 
316
- const homeId = R.compose(
317
- R.prop("id"),
318
- R.find(R.prop("home")),
319
- R.values
320
- )(rivers);
319
+ const homeRiver = getHomeRiver(rivers);
321
320
 
322
- const homePath = `/river/${homeId}`;
321
+ const homePath = `/river/${homeRiver?.id}`;
323
322
 
324
323
  return homePath === navigator.currentRoute;
325
324
  }
@@ -327,7 +326,7 @@ class InteractionManagerClass extends React.Component<Props, State> {
327
326
  goToHome() {
328
327
  const { navigator } = this.props;
329
328
  const { rivers } = this.props;
330
- const homeRiver = R.find(R.propEq("home", true), R.values(rivers));
329
+ const homeRiver = getHomeRiver(rivers);
331
330
 
332
331
  navigator.replace(homeRiver);
333
332
  }
@@ -388,7 +387,9 @@ class InteractionManagerClass extends React.Component<Props, State> {
388
387
  note: backspace affects the keyboard input, so it behaves differently
389
388
  */
390
389
  onBackPress(event) {
391
- const { displayState, setDisplayState, navigator } = this.props;
390
+ const { displayState, setDisplayState, navigator, backToTopAction } =
391
+ this.props;
392
+
392
393
  const { isDialogVisible } = confirmationDialogStore.getState();
393
394
  const { isKeyboardVisible } = this.state;
394
395
 
@@ -407,8 +408,32 @@ class InteractionManagerClass extends React.Component<Props, State> {
407
408
  return;
408
409
  }
409
410
 
411
+ const { action, payload } = backToTopAction();
412
+
410
413
  switch (displayState) {
411
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;
412
437
  case DISPLAY_STATES.PLAYER:
413
438
  if (isDialogVisible) {
414
439
  this.onConfirmDialogClose();
@@ -648,8 +673,13 @@ class InteractionManagerClass extends React.Component<Props, State> {
648
673
  onConfirmDialogClose() {
649
674
  this.confirmDialog.hideDialog();
650
675
 
651
- // restore initial focus after closing dialog
652
- 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);
653
683
  }
654
684
 
655
685
  handleInputFocus = (event: FocusEvent) => {
@@ -847,5 +877,6 @@ export const InteractionManager = R.compose(
847
877
  withXray,
848
878
  connectToStore(R.pick(["rivers"])),
849
879
  PlayerContentContext.withConsumer,
850
- DisplayStateContext.withConsumer
880
+ DisplayStateContext.withConsumer,
881
+ withBackToTopActionHOC
851
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";
@@ -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";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-dom-app",
3
- "version": "14.0.0-alpha.5114565431",
3
+ "version": "14.0.0-alpha.5219335081",
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.5114565431",
26
- "@applicaster/zapp-react-native-bridge": "14.0.0-alpha.5114565431",
27
- "@applicaster/zapp-react-native-redux": "14.0.0-alpha.5114565431",
28
- "@applicaster/zapp-react-native-ui-components": "14.0.0-alpha.5114565431",
29
- "@applicaster/zapp-react-native-utils": "14.0.0-alpha.5114565431",
25
+ "@applicaster/zapp-react-dom-ui-components": "14.0.0-alpha.5219335081",
26
+ "@applicaster/zapp-react-native-bridge": "14.0.0-alpha.5219335081",
27
+ "@applicaster/zapp-react-native-redux": "14.0.0-alpha.5219335081",
28
+ "@applicaster/zapp-react-native-ui-components": "14.0.0-alpha.5219335081",
29
+ "@applicaster/zapp-react-native-utils": "14.0.0-alpha.5219335081",
30
30
  "abortcontroller-polyfill": "^1.7.5",
31
31
  "typeface-montserrat": "^0.0.54",
32
32
  "video.js": "7.14.3",
@@ -37,7 +37,6 @@
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
41
  "react-native": "*",
43
42
  "react-native-svg": "*",