@applicaster/zapp-react-native-ui-components 12.0.0-alpha.4408649484 → 12.0.0-alpha.4440903139

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.
Files changed (68) hide show
  1. package/Components/Cell/Cell.tsx +21 -5
  2. package/Components/Focusable/__tests__/index.android.test.tsx +72 -0
  3. package/Components/Focusable/index.android.tsx +15 -9
  4. package/Components/FocusableList/FocusableChild.ts +2 -4
  5. package/Components/FocusableList/index.tsx +11 -12
  6. package/Components/FocusableScrollView/index.tsx +1 -1
  7. package/Components/FreezeWithCallback/Freeze.tsx +31 -0
  8. package/Components/FreezeWithCallback/LICENSE +21 -0
  9. package/Components/FreezeWithCallback/Suspender.tsx +17 -0
  10. package/Components/FreezeWithCallback/__tests__/index.test.tsx +170 -0
  11. package/Components/FreezeWithCallback/index.tsx +3 -0
  12. package/Components/Image/Image.android.tsx +1 -1
  13. package/Components/Layout/TV/ScreenContainer.tsx +3 -8
  14. package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +1 -1
  15. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -1
  16. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +1 -7
  17. package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +12 -0
  18. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +6 -5
  19. package/Components/MasterCell/DefaultComponents/Image/Image.web.tsx +2 -2
  20. package/Components/MasterCell/DefaultComponents/ImageBorderContainer/index.ts +71 -0
  21. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +20 -0
  22. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
  23. package/Components/MasterCell/DefaultComponents/index.ts +2 -0
  24. package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +7 -1
  25. package/Components/MasterCell/dataAdapter.ts +21 -7
  26. package/Components/MasterCell/index.tsx +5 -3
  27. package/Components/PlayerContainer/PlayerContainer.tsx +16 -13
  28. package/Components/Screen/TV/hooks/index.ts +0 -2
  29. package/Components/Screen/TV/index.web.tsx +34 -25
  30. package/Components/Screen/__tests__/Screen.test.tsx +0 -49
  31. package/Components/Screen/index.tsx +27 -76
  32. package/Components/Screen/navigationHandler.ts +6 -3
  33. package/Components/Screen/orientationHandler.ts +18 -7
  34. package/Components/Screen/utils.ts +16 -0
  35. package/Components/ScreenResolver/index.tsx +6 -11
  36. package/Components/Transitioner/Scene.tsx +20 -12
  37. package/Components/Transitioner/Transitioner.tsx +38 -23
  38. package/Components/Transitioner/__tests__/Scene.test.js +7 -0
  39. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +8 -4
  40. package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +1 -0
  41. package/Components/VideoLive/PlayerLiveImageComponent.tsx +52 -24
  42. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +31 -24
  43. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +2 -14
  44. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +33 -8
  45. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +9 -2
  46. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +34 -8
  47. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +28 -8
  48. package/Components/VideoModal/ModalAnimation/utils.ts +1 -0
  49. package/Components/VideoModal/PlayerDetails.tsx +16 -2
  50. package/Components/VideoModal/PlayerWrapper.tsx +40 -10
  51. package/Components/VideoModal/VideoModal.tsx +33 -27
  52. package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +7 -0
  53. package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -0
  54. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +102 -10
  55. package/Components/VideoModal/hooks/useModalSize.ts +10 -12
  56. package/Components/ZappFrameworkComponents/BarView/BarView.tsx +7 -3
  57. package/Components/ZappFrameworkComponents/BarView/Buttons/BackButton.tsx +7 -2
  58. package/Components/ZappFrameworkComponents/BarView/Buttons/CloseButton.tsx +7 -2
  59. package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +87 -0
  60. package/Components/ZappFrameworkComponents/Buttons/ActionButton.tsx +9 -4
  61. package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +4 -4
  62. package/Contexts/CachedDimensionsContext/index.ts +13 -9
  63. package/Contexts/ConfirmDialogState/index.ts +1 -1
  64. package/Contexts/ScreenContext/index.tsx +6 -1
  65. package/const.ts +6 -0
  66. package/index.js +3 -0
  67. package/package.json +5 -5
  68. package/Components/Screen/TV/hooks/useRestoreFocus.ts +0 -22
@@ -31,10 +31,10 @@ function Image({
31
31
 
32
32
  return (
33
33
  <RnImage
34
- defaultSource={placeholderImage || ""}
34
+ defaultSource={placeholderImage || null}
35
35
  style={style}
36
36
  source={updatedSource}
37
- {...R.omit(["source"], otherProps)}
37
+ {...R.omit(["source", "placeholderImage"], otherProps)}
38
38
  />
39
39
  );
40
40
  }
@@ -0,0 +1,71 @@
1
+ import { ImageStyle } from "react-native";
2
+
3
+ import {
4
+ getImageContainerMarginStyles,
5
+ ifElseFocusedSelected,
6
+ } from "@applicaster/zapp-react-native-utils/cellUtils";
7
+ import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
8
+
9
+ export const ImageBorderContainer = ({
10
+ value,
11
+ state,
12
+ imageStyles,
13
+ }: {
14
+ value: (key: string) => string;
15
+ state: CellState;
16
+ imageStyles: ImageStyle;
17
+ }) => {
18
+ const imageMargins = getImageContainerMarginStyles({ value });
19
+
20
+ return {
21
+ type: "BorderContainerView",
22
+ style: {
23
+ position: "absolute",
24
+ // Image border now separated from the image, so cell padding affects the border position
25
+ marginTop:
26
+ toNumberWithDefaultZero(imageMargins.marginTop) +
27
+ toNumberWithDefaultZero(value("cell_padding_top")),
28
+ marginLeft:
29
+ toNumberWithDefaultZero(imageMargins.marginLeft) +
30
+ toNumberWithDefaultZero(value("cell_padding_left")),
31
+ marginRight:
32
+ toNumberWithDefaultZero(imageMargins.marginRight) +
33
+ toNumberWithDefaultZero(value("cell_padding_right")),
34
+ marginBottom:
35
+ toNumberWithDefaultZero(imageMargins.marginBottom) +
36
+ toNumberWithDefaultZero(value("cell_padding_bottom")),
37
+ zIndex: 1,
38
+ borderWidth: value("image_border_size"),
39
+ borderColor: ifElseFocusedSelected(
40
+ state,
41
+ value("image_focused_border_color"),
42
+ value("image_selected_border_color"),
43
+ value("image_focused_selected_border_color"),
44
+ value("image_border_color")
45
+ ),
46
+ borderRadius: toNumberWithDefaultZero(value("image_corner_radius")),
47
+ },
48
+ additionalProps: {
49
+ pointerEvents: "none",
50
+ borderPosition: value("image_border_position"),
51
+ borderPaddingTop: toNumberWithDefaultZero(
52
+ value("image_border_padding_top")
53
+ ),
54
+ borderPaddingRight: toNumberWithDefaultZero(
55
+ value("image_border_padding_right")
56
+ ),
57
+ borderPaddingBottom: toNumberWithDefaultZero(
58
+ value("image_border_padding_bottom")
59
+ ),
60
+ borderPaddingLeft: toNumberWithDefaultZero(
61
+ value("image_border_padding_left")
62
+ ),
63
+ },
64
+ elements: [
65
+ {
66
+ type: "View",
67
+ style: imageStyles,
68
+ },
69
+ ],
70
+ };
71
+ };
@@ -108,6 +108,26 @@ const prepareEntry = (entry) => {
108
108
  };
109
109
  }
110
110
 
111
+ const previewPlayback =
112
+ entry.extensions?.["brightcove"]?.["preview_playback"];
113
+
114
+ if (previewPlayback) {
115
+ return {
116
+ ...entry,
117
+ extensions: {
118
+ ...entry.extensions,
119
+ brightcove: {
120
+ ...entry?.extensions?.["brightcove"],
121
+ video_id: previewPlayback,
122
+ },
123
+ },
124
+ };
125
+ }
126
+
127
+ if (entry.extensions?.["brightcove"]?.["video_id"]) {
128
+ return entry;
129
+ }
130
+
111
131
  const src = entry.content?.src;
112
132
 
113
133
  if (!src) {
@@ -39,6 +39,6 @@ describe("image with no source", () => {
39
39
  );
40
40
 
41
41
  const testInstance = testRenderer.root;
42
- expect(testInstance.findByType(Image).props.source).toBeUndefined();
42
+ expect(testInstance.findByType(Image).props.source).toEqual({ uri: "" });
43
43
  });
44
44
  });
@@ -15,6 +15,7 @@ import { BorderContainerView } from "./BorderContainerView";
15
15
  import { CellBadge } from "./CellBadge";
16
16
  import { TvActionButtons } from "./tv/TvActionButtons";
17
17
  import { ButtonContainerView } from "./tv/ButtonContainerView";
18
+ import { ImageBorderContainer } from "./ImageBorderContainer";
18
19
 
19
20
  export const defaultComponents = {
20
21
  View,
@@ -28,6 +29,7 @@ export const defaultComponents = {
28
29
  ProgressBar,
29
30
  Toggle,
30
31
  LiveImage,
32
+ ImageBorderContainer,
31
33
  BorderContainerView,
32
34
  DynamicBadge,
33
35
  SecondaryImage,
@@ -5,6 +5,7 @@ import * as R from "ramda";
5
5
 
6
6
  import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
7
7
  import { normalizeProgressValue } from "./utils";
8
+ import { useIsScreenActive } from "@applicaster/zapp-react-native-utils/reactHooks";
8
9
 
9
10
  const ACTION_NAME = "continue-watching";
10
11
  const DEFAULT_FILL = 0;
@@ -27,6 +28,7 @@ const getProgressValue = (
27
28
 
28
29
  export const useFillInPercent = (entry: ZappEntry): number => {
29
30
  const action = useActions(ACTION_NAME);
31
+ const isActive = useIsScreenActive();
30
32
 
31
33
  const [fillInPercent, setFillInPercent] =
32
34
  React.useState<number>(DEFAULT_FILL);
@@ -39,6 +41,10 @@ export const useFillInPercent = (entry: ZappEntry): number => {
39
41
  }, []);
40
42
 
41
43
  React.useEffect(() => {
44
+ if (!isActive) {
45
+ return;
46
+ }
47
+
42
48
  // refresh progress in UI when it was changed in CW
43
49
  const unsubscribe = action?.addDataSourceListener?.(() => {
44
50
  getProgressValue(action, entry, (progress) => {
@@ -49,7 +55,7 @@ export const useFillInPercent = (entry: ZappEntry): number => {
49
55
  return () => {
50
56
  unsubscribe?.();
51
57
  };
52
- }, []);
58
+ }, [isActive]);
53
59
 
54
60
  return fillInPercent;
55
61
  };
@@ -37,14 +37,28 @@ function retrieveData(entry, func, args) {
37
37
  */
38
38
 
39
39
  export function configInflater(
40
- entry,
41
- { type, style, additionalProps = {}, data = [], elements }
40
+ entry: any,
41
+ {
42
+ type,
43
+ style,
44
+ additionalProps = {},
45
+ data = [],
46
+ elements,
47
+ }: {
48
+ type: any;
49
+ style: any;
50
+ additionalProps?: Record<string, any>;
51
+ data?: Array<{ propName: string; func: Function; args: any[] }>;
52
+ elements?: any[];
53
+ }
42
54
  ) {
43
- const props = R.reduce(
44
- (acc, curr) =>
45
- R.assoc(curr.propName, retrieveData(entry, curr.func, curr.args), acc),
46
- additionalProps,
47
- data
55
+ const props = data.reduce(
56
+ (acc, curr) => {
57
+ acc[curr.propName] = retrieveData(entry, curr.func, curr.args);
58
+
59
+ return acc;
60
+ },
61
+ { ...additionalProps }
48
62
  );
49
63
 
50
64
  let adjustedElements;
@@ -52,6 +52,8 @@ export function masterCellBuilder({
52
52
  const { View } = componentsMap;
53
53
  const elementsBuilder = dataAdapter(cellConfiguration);
54
54
 
55
+ // This is very expensive operation
56
+ // Keep calls to minimum
55
57
  const hasFocusableInside = hasFocusableInsideBuilder(elementsBuilder);
56
58
 
57
59
  /**
@@ -74,8 +76,8 @@ export function masterCellBuilder({
74
76
  const selectedState = screen?.selectedEntry;
75
77
 
76
78
  const entryIsSelected = React.useMemo(
77
- () => selectedState?.id === item?.id,
78
- [selectedState?.id]
79
+ () => !!(selectedState?.id && selectedState?.id === item?.id),
80
+ [selectedState?.id, item?.id]
79
81
  );
80
82
 
81
83
  const elements = React.useMemo(
@@ -84,7 +86,7 @@ export function masterCellBuilder({
84
86
  entry: item,
85
87
  state: getEntryState(state, entryIsSelected),
86
88
  }),
87
- [state, item, entryIsSelected]
89
+ [state, item?.id, entryIsSelected] // Assuming that item won't mutate
88
90
  );
89
91
 
90
92
  const wrapperRef = React.useRef(null);
@@ -124,6 +124,7 @@ const nativeStyles = {
124
124
  playerScreen: {
125
125
  flex: 1,
126
126
  backgroundColor: "black",
127
+ overflow: "hidden",
127
128
  },
128
129
  playerWrapper: {
129
130
  flex: 1,
@@ -252,11 +253,7 @@ const PlayerContainerComponent = (props: Props) => {
252
253
  }
253
254
 
254
255
  showNavBar(true);
255
-
256
- // Hack to close player screen on mobile only (tv handles that in InteractionManager)
257
- if (!isTV()) {
258
- navigator.goBack();
259
- }
256
+ navigator.goBack();
260
257
  }, [isModal, navigator.goBack, showNavBar]);
261
258
 
262
259
  const playEntry = (entry) => navigator.replaceTop(entry, { mode });
@@ -365,13 +362,15 @@ const PlayerContainerComponent = (props: Props) => {
365
362
  const toggleFullscreen = (event) => {
366
363
  const { fullscreen = false } = event || {};
367
364
 
368
- if (fullscreen) {
369
- playerEvent("onFullscreenPlayerWillPresent");
370
- navigator.fullscreenVideoModal();
371
- } else {
372
- playerEvent("onFullscreenPlayerWillDismiss");
373
- navigator.maximiseVideoModal();
374
- }
365
+ setTimeout(() => {
366
+ if (fullscreen) {
367
+ navigator.fullscreenVideoModal();
368
+ playerEvent("onFullscreenPlayerWillPresent");
369
+ } else {
370
+ navigator.maximiseVideoModal();
371
+ playerEvent("onFullscreenPlayerWillDismiss");
372
+ }
373
+ });
375
374
  };
376
375
 
377
376
  const onCellTap = (entry) => {
@@ -466,6 +465,10 @@ const PlayerContainerComponent = (props: Props) => {
466
465
 
467
466
  if (mode === VideoModalMode.FULLSCREEN) {
468
467
  toggleFullscreen({ fullscreen: false });
468
+
469
+ if (!isModal) {
470
+ playerManager.closeNativePlayer();
471
+ }
469
472
  }
470
473
 
471
474
  return !!(
@@ -522,7 +525,7 @@ const PlayerContainerComponent = (props: Props) => {
522
525
  }
523
526
 
524
527
  return () => {
525
- playerEvent("player_did_close");
528
+ playerEvent("player_did_close", { item });
526
529
 
527
530
  if (!isModal) {
528
531
  showNavBar(true);
@@ -1,3 +1 @@
1
1
  export { useInitialFocus } from "./useInitialFocus";
2
-
3
- export { useRestoreFocus } from "./useRestoreFocus";
@@ -1,12 +1,15 @@
1
- import * as React from "react";
1
+ import React from "react";
2
2
  import { last } from "ramda";
3
- import { View, StyleSheet } from "react-native";
3
+ import { StyleSheet, View } from "react-native";
4
4
  import {
5
+ findMenuPlugin,
5
6
  getNavigationProps,
6
7
  getPathAttributes,
7
- resolveNavigationPlugin,
8
8
  } from "@applicaster/zapp-react-native-utils/navigationUtils";
9
- import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
9
+ import {
10
+ useIsScreenActive,
11
+ useNavigation,
12
+ } from "@applicaster/zapp-react-native-utils/reactHooks";
10
13
  import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
11
14
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
12
15
  import {
@@ -17,8 +20,10 @@ import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/he
17
20
 
18
21
  import { NavBarContainer } from "../../Layout/TV/NavBarContainer";
19
22
  import { ScreenResolver } from "../../ScreenResolver";
20
- import { useInitialFocus, useRestoreFocus } from "./hooks";
23
+ import { useInitialFocus } from "./hooks";
21
24
  import { isPlayerPlugin } from "@applicaster/zapp-react-native-utils/pluginUtils";
25
+ import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils";
26
+ import { FreezeWithCallback } from "../../FreezeWithCallback";
22
27
 
23
28
  const styles = StyleSheet.create({
24
29
  container: {
@@ -103,7 +108,6 @@ export const Screen = ({ route, Components }: Props) => {
103
108
  const backgroundColor = useScreenBackgroundColor(screenId);
104
109
 
105
110
  useInitialFocus();
106
- useRestoreFocus();
107
111
 
108
112
  const activeRiver = getActiveRiver({
109
113
  screenId,
@@ -131,11 +135,7 @@ export const Screen = ({ route, Components }: Props) => {
131
135
  fallbackNavigations: navigator.activeRiver.navigations,
132
136
  });
133
137
 
134
- const menuPlugin = resolveNavigationPlugin({
135
- category: "menu",
136
- navigations,
137
- plugins,
138
- }) as QuickBrickPlugin;
138
+ const menuPlugin = findMenuPlugin(navigations, plugins);
139
139
 
140
140
  const NavBar = (Components.NavBar ||
141
141
  menuPlugin.module) as React.ComponentType<any>;
@@ -149,21 +149,30 @@ export const Screen = ({ route, Components }: Props) => {
149
149
  ? routeState?.state?.entry
150
150
  : routeState?.state?.screen;
151
151
 
152
+ const isScreenActive = useIsScreenActive();
153
+
152
154
  return (
153
- <View style={[styles.container, { backgroundColor }]}>
154
- <NavBarContainer isVisible={isNavBarVisible} onReady={noop}>
155
- <NavBar
156
- isVisible={isNavBarVisible}
157
- menuPlugin={menuPlugin}
158
- navigationProps={navigationProps}
155
+ <FreezeWithCallback
156
+ freeze={!isScreenActive}
157
+ onRelease={() => {
158
+ focusManager.setInitialFocus();
159
+ }}
160
+ >
161
+ <View style={[styles.container, { backgroundColor }]}>
162
+ <NavBarContainer isVisible={isNavBarVisible} onReady={noop}>
163
+ <NavBar
164
+ isVisible={isNavBarVisible}
165
+ menuPlugin={menuPlugin}
166
+ navigationProps={navigationProps}
167
+ />
168
+ </NavBarContainer>
169
+ <ScreenResolver
170
+ screenType={screenType}
171
+ screenId={screenId}
172
+ screenData={screenData}
173
+ groupId={route}
159
174
  />
160
- </NavBarContainer>
161
- <ScreenResolver
162
- screenType={screenType}
163
- screenId={screenId}
164
- screenData={screenData}
165
- groupId={route}
166
- />
167
- </View>
175
+ </View>
176
+ </FreezeWithCallback>
168
177
  );
169
178
  };
@@ -99,14 +99,6 @@ jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
99
99
  }),
100
100
  }));
101
101
 
102
- const {
103
- ORIENTATIONS,
104
- } = require("@applicaster/zapp-react-native-utils/appUtils/orientationHelper");
105
-
106
- const {
107
- useCurrentScreenData,
108
- } = require("@applicaster/zapp-react-native-utils/reactHooks/screen");
109
-
110
102
  const {
111
103
  allowedOrientationsForScreen,
112
104
  getOrientation,
@@ -158,45 +150,4 @@ describe("<Screen Component />", () => {
158
150
  expect(wrapper.toJSON()).toMatchSnapshot();
159
151
  });
160
152
  });
161
-
162
- it("invokes the orientation hook when the route changes", () => {
163
- act(() => {
164
- wrapper = create(<Screen {...screenProps} />);
165
- });
166
-
167
- // @ts-ignore
168
- useCurrentScreenData.mockReturnValue({
169
- id: "player-testId",
170
- general: { screen_orientation: ORIENTATIONS.landscapeSensor },
171
- plugin_type: "player",
172
- });
173
-
174
- act(() => {
175
- wrapper.update(
176
- <Screen
177
- {...screenProps}
178
- pathname="/playable"
179
- screenData={{
180
- id: "player-testId",
181
- general: { screen_orientation: ORIENTATIONS.landscapeSensor },
182
- plugin_type: "player",
183
- }}
184
- />
185
- );
186
- });
187
-
188
- useCurrentScreenData.mockReturnValue({
189
- id: "player-testId",
190
- general: { screen_orientation: ORIENTATIONS.landscapeSensor },
191
- });
192
-
193
- act(() => {
194
- wrapper.update(<Screen {...screenProps} />);
195
- });
196
-
197
- expect(allowedOrientationsForScreen).toHaveBeenNthCalledWith(
198
- 1,
199
- ORIENTATIONS.landscapeSensor
200
- );
201
- });
202
153
  });
@@ -1,6 +1,5 @@
1
1
  /// <reference types="@applicaster/applicaster-types" />
2
2
  import React from "react";
3
- import * as R from "ramda";
4
3
  import { View } from "react-native";
5
4
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
6
5
  import {
@@ -11,10 +10,10 @@ import {
11
10
  import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
12
11
  import { getComponentModule } from "@applicaster/zapp-react-native-utils/pluginUtils";
13
12
  import {
14
- getNavigationPropsV2,
15
- resolveNavigationPlugin,
13
+ shouldNavBarDisplayMenu,
14
+ getNavBarProps,
15
+ getScreenId,
16
16
  } from "@applicaster/zapp-react-native-utils/navigationUtils";
17
- import { useSafeAreaInsets } from "react-native-safe-area-context";
18
17
  import {
19
18
  useDimensions,
20
19
  useRoute,
@@ -25,39 +24,18 @@ import {
25
24
  } from "@applicaster/zapp-react-native-utils/reactHooks";
26
25
  import { getNavigationPluginModule } from "@applicaster/zapp-react-native-app/App/Layout/layoutHelpers";
27
26
 
28
- import { ScreenContextProvider } from "../../Contexts/ScreenContext";
29
27
  import { RouteManager } from "../RouteManager";
30
28
  import { useScreenConfiguration } from "../River/useScreenConfiguration";
31
- import { useScreenOrientationHandler } from "./orientationHandler";
32
-
33
- const getScreenId = (
34
- screenData: LegacyNavigationScreenData,
35
- fallbackRiver: ZappRiver
36
- ) => {
37
- return screenData?.targetScreen
38
- ? screenData?.targetScreen?.id ?? fallbackRiver.id
39
- : "screen_id" in screenData
40
- ? screenData.screen_id
41
- : fallbackRiver.id;
29
+ import { isValidColor } from "./utils";
30
+
31
+ const screenStyles = {
32
+ flex: 1,
33
+ paddingTop: 0,
34
+ // paddingBottom: insets.bottom, // Should be applied directly by UI plugin
35
+ // paddingLeft: insets.left, // Should be applied directly by UI plugin
36
+ // paddingRight: insets.right, // Should be applied directly by UI plugin
42
37
  };
43
38
 
44
- function colorIsNotTransparent(color) {
45
- const layers = R.compose(
46
- R.map(R.trim),
47
- R.split(","),
48
- R.replace(")", ""),
49
- R.replace("rgba(", "")
50
- )(color);
51
-
52
- const alpha = Number(layers?.[3]);
53
-
54
- return alpha > 0;
55
- }
56
-
57
- function isValidColor(string) {
58
- return string && string !== "transparent" && colorIsNotTransparent(string);
59
- }
60
-
61
39
  type Props = {
62
40
  pathname: unknown;
63
41
  screenData: unknown;
@@ -71,7 +49,6 @@ export function Screen(_props: Props) {
71
49
  // Gets the data for the current screen configuration
72
50
  const currentScreenData = useCurrentScreenData();
73
51
  const { backgroundColor } = useScreenConfiguration(currentScreenData.id);
74
- const insets = useSafeAreaInsets();
75
52
 
76
53
  const {
77
54
  width: screenWidth,
@@ -96,30 +73,12 @@ export function Screen(_props: Props) {
96
73
 
97
74
  const layoutData = { isTablet, isTabletPortrait, width: screenWidth, height };
98
75
 
99
- const hasMenu =
100
- resolveNavigationPlugin({
101
- category: "menu",
102
- navigations: currentRiver.navigations,
103
- plugins,
104
- })?.identifier === "quick_brick_side_menu";
105
-
106
- const navBarProps = React.useMemo<MobileNavBarPluginProps | null>(() => {
107
- const props = getNavigationPropsV2({
108
- currentRiver,
109
- title,
110
- category: "nav_bar",
111
- });
112
-
113
- if (props) {
114
- return {
115
- ...props,
116
- id: pathname,
117
- pathname: pathname,
118
- };
119
- }
120
-
121
- return null;
122
- }, [currentRiver, pathname]);
76
+ const hasMenu = shouldNavBarDisplayMenu(currentRiver, plugins);
77
+
78
+ const navBarProps = React.useMemo<MobileNavBarPluginProps | null>(
79
+ getNavBarProps(currentRiver, pathname, title),
80
+ [currentRiver, pathname]
81
+ );
123
82
 
124
83
  const NavBar = React.useMemo(
125
84
  () =>
@@ -141,23 +100,17 @@ export function Screen(_props: Props) {
141
100
 
142
101
  const style = React.useMemo(
143
102
  () => ({
144
- flex: 1,
103
+ ...screenStyles,
145
104
  backgroundColor: isValidColor(backgroundColor)
146
105
  ? backgroundColor
147
106
  : theme.app_background_color,
148
- paddingTop: 0,
149
- // paddingBottom: insets.bottom, // Should be applied directly by UI plugin
150
- // paddingLeft: insets.left, // Should be applied directly by UI plugin
151
- // paddingRight: insets.right, // Should be applied directly by UI plugin
152
107
  }),
153
- [insets, screenWidth, theme.app_background_color, backgroundColor]
108
+ [theme.app_background_color, backgroundColor]
154
109
  );
155
110
 
156
111
  const targetScreenData =
157
112
  currentScreenData || (screenData as any)?.targetScreen || screenData;
158
113
 
159
- useScreenOrientationHandler({ screenData: targetScreenData });
160
-
161
114
  const orientation = useGetScreenOrientation(targetScreenData);
162
115
 
163
116
  // We prevent rendering of the screen until UI is actually rotated to screen desired orientation.
@@ -172,15 +125,13 @@ export function Screen(_props: Props) {
172
125
  }
173
126
 
174
127
  return (
175
- <ScreenContextProvider pathname={pathname}>
176
- <View style={style}>
177
- {navBarProps && <NavBar {...navBarProps} hasMenu={hasMenu} />}
178
-
179
- <OfflineFallbackScreen screenData={targetScreenData}>
180
- {/* @TODO RouteManager doesn't use props, can they be removed ? */}
181
- <RouteManager pathname={pathname} screenData={screenData} />
182
- </OfflineFallbackScreen>
183
- </View>
184
- </ScreenContextProvider>
128
+ <View style={style}>
129
+ {navBarProps && <NavBar {...navBarProps} hasMenu={hasMenu} />}
130
+
131
+ <OfflineFallbackScreen screenData={targetScreenData}>
132
+ {/* @TODO RouteManager doesn't use props, can they be removed ? */}
133
+ <RouteManager pathname={pathname} screenData={screenData} />
134
+ </OfflineFallbackScreen>
135
+ </View>
185
136
  );
186
137
  }
@@ -5,6 +5,11 @@
5
5
  * is similar to the navbar, except that it covers scenarios where only the navbar (and not)
6
6
  * the menu, will be hidden
7
7
  *
8
+ * - playable screens
9
+ * - qb_search_screen
10
+ * - screen hooks that specify showNavBar or presentFullScreen
11
+ * - screens or nested screens that have allow_screen_plugin_presentation set to true
12
+ *
8
13
  * @param {String} route current route of the screen
9
14
  * @param {Object} screenData payload associated with the currently presented screen
10
15
  * @returns {Boolean}
@@ -21,9 +26,7 @@ export function isMenuVisible(route, screenData) {
21
26
  if (screenData?.hookPlugin) {
22
27
  const hookPlugin = screenData?.hookPlugin?.module;
23
28
 
24
- return (
25
- hookPlugin?.showNavBar || hookPlugin?.presentFullScreen !== true || false
26
- );
29
+ return hookPlugin?.showNavBar || hookPlugin?.presentFullScreen !== true;
27
30
  }
28
31
 
29
32
  if (