@applicaster/zapp-react-native-ui-components 12.0.0-alpha.4201443043 → 12.0.0-alpha.4324313105

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 (26) hide show
  1. package/Components/BaseFocusable/index.tsx +1 -1
  2. package/Components/Cell/Cell.tsx +5 -5
  3. package/Components/Cell/CellWithFocusable.tsx +5 -17
  4. package/Components/FocusableGroup/index.tsx +0 -1
  5. package/Components/HandlePlayable/HandlePlayable.tsx +0 -3
  6. package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +2 -2
  7. package/Components/Layout/TV/TransitionOverlay.tsx +64 -0
  8. package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +50 -10
  9. package/Components/Layout/TV/__tests__/index.test.tsx +74 -18
  10. package/Components/Layout/TV/index.tsx +108 -9
  11. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +80 -109
  12. package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.android.tsx +1 -4
  13. package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.tsx +1 -4
  14. package/Components/PlayerContainer/PlayerContainer.tsx +1 -3
  15. package/Components/River/TV/River.tsx +23 -0
  16. package/Components/ScreenResolver/index.tsx +1 -3
  17. package/Components/VideoLive/LiveImageManager.ts +1 -15
  18. package/Components/VideoModal/PlayerDetails.tsx +3 -3
  19. package/Contexts/ZappPipesContext/ZappPipesEntryContext.ts +1 -1
  20. package/package.json +5 -5
  21. package/Components/Navigator/StackNavigator.tsx +0 -48
  22. package/Components/Navigator/index.ts +0 -1
  23. package/Components/Screen/TV/hooks/index.ts +0 -3
  24. package/Components/Screen/TV/hooks/useInitialFocus.ts +0 -70
  25. package/Components/Screen/TV/hooks/useRestoreFocus.ts +0 -22
  26. package/Components/Screen/TV/index.web.tsx +0 -179
@@ -66,7 +66,7 @@ export class BaseFocusable<
66
66
  const { initialFocus } = this.props;
67
67
 
68
68
  if (initialFocus) {
69
- focusManager.setFocus(this.getId());
69
+ focusManager.setupInitialFocus(this.getId());
70
70
  }
71
71
  }
72
72
 
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import { join, path, merge } from "ramda";
2
+ import * as R from "ramda";
3
3
  import { View } from "react-native";
4
4
 
5
5
  import { Focusable } from "@applicaster/zapp-react-native-ui-components/Components/Focusable";
@@ -105,8 +105,8 @@ export class CellComponent extends React.Component<Props> {
105
105
  onPress(item, index);
106
106
  } else {
107
107
  const { item, navigator, component, appData } = this.props;
108
- const itemTargetScreen = path(["screen_type"], item);
109
- const componentTargetScreen = path(["data", "target"], component);
108
+ const itemTargetScreen = R.path(["screen_type"], item);
109
+ const componentTargetScreen = R.path(["data", "target"], component);
110
110
  const itemType = getItemType(item, appData?.layoutVersion);
111
111
 
112
112
  sendSelectCellEvent(item, component, item.title, index);
@@ -116,7 +116,7 @@ export class CellComponent extends React.Component<Props> {
116
116
  componentTargetScreen &&
117
117
  !itemTargetScreen
118
118
  ) {
119
- navigator.push(merge(item, { screen_type: componentTargetScreen }));
119
+ navigator.push(R.merge(item, { screen_type: componentTargetScreen }));
120
120
 
121
121
  return;
122
122
  }
@@ -207,7 +207,7 @@ export class CellComponent extends React.Component<Props> {
207
207
 
208
208
  const { id } = item;
209
209
 
210
- const focusableId = join("-", [component?.id, id, index]);
210
+ const focusableId = R.join("-", [component?.id, id, index]);
211
211
 
212
212
  const handleFocus = (focusable, mouse) => {
213
213
  const focusFn = onFocus || noop;
@@ -6,20 +6,12 @@ import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
6
6
  import { isAppleTV } from "../../Helpers/Platform";
7
7
  import { useCellState } from "../MasterCell/utils";
8
8
 
9
- const useCellFocusedState = (
10
- skipFocusManagerRegistration: boolean,
11
- groupId: string,
12
- id: string
13
- ) => {
9
+ const useCellFocusedState = (groupId: string, id: string) => {
14
10
  const [currentCellFocused, setCurrentCellFocused] = React.useState(false);
15
11
 
16
12
  React.useEffect(() => {
17
- const isGroupItemFocused = () => {
18
- if (!skipFocusManagerRegistration) {
19
- const isFocused = focusManager.isGroupItemFocused(groupId, id);
20
- setCurrentCellFocused(isFocused);
21
- }
22
- };
13
+ const isGroupItemFocused = () =>
14
+ setCurrentCellFocused(focusManager.isGroupItemFocused(groupId, id));
23
15
 
24
16
  const handler = () => {
25
17
  // tvOS hack for properly checking focus
@@ -37,7 +29,7 @@ const useCellFocusedState = (
37
29
  return () => {
38
30
  focusManager.removeHandler(FOCUS_EVENTS.FOCUS, handler);
39
31
  };
40
- }, [groupId, skipFocusManagerRegistration]);
32
+ }, [groupId]);
41
33
 
42
34
  return currentCellFocused;
43
35
  };
@@ -73,11 +65,7 @@ export function CellWithFocusable(props: Props) {
73
65
  selected,
74
66
  } = props;
75
67
 
76
- const isFocused = useCellFocusedState(
77
- skipFocusManagerRegistration,
78
- groupId,
79
- id
80
- );
68
+ const isFocused = useCellFocusedState(groupId, id);
81
69
 
82
70
  const state = useCellState({
83
71
  id: item.id,
@@ -26,7 +26,6 @@ type Props = {
26
26
  nextFocusLeft?: any;
27
27
  nextFocusRight?: any;
28
28
  onLayout?: any;
29
- excludeFromFocusSearching?: boolean;
30
29
  };
31
30
 
32
31
  export class FocusableGroup extends BaseFocusable<Props> {
@@ -19,7 +19,6 @@ type Props = {
19
19
  modalHeight?: number;
20
20
  modalWidth?: number;
21
21
  mode: VideoModalMode;
22
- groupId?: string;
23
22
  };
24
23
 
25
24
  const YOUTUBE_PLUGIN_ID = "youtube-player-qb";
@@ -94,7 +93,6 @@ export function HandlePlayable({
94
93
  modalHeight,
95
94
  modalWidth,
96
95
  mode,
97
- groupId,
98
96
  }: Props): React.ReactElement | null {
99
97
  const state = usePickFromState();
100
98
 
@@ -169,7 +167,6 @@ export function HandlePlayable({
169
167
  isModal={isModal}
170
168
  mode={mode}
171
169
  disableCastAction={playerModuleProperties?.disableCastAction}
172
- groupId={groupId}
173
170
  />
174
171
  );
175
172
  }
@@ -60,7 +60,7 @@ export function ScreenLayoutContextProvider(props: {
60
60
  initialState
61
61
  );
62
62
 
63
- const screenLayoutValue = React.useMemo(
63
+ const screeenLayoutValue = React.useMemo(
64
64
  () => ({
65
65
  ...screenLayout,
66
66
  setScreenLayout,
@@ -69,7 +69,7 @@ export function ScreenLayoutContextProvider(props: {
69
69
  );
70
70
 
71
71
  return (
72
- <ScreenLayoutContext.Provider value={screenLayoutValue}>
72
+ <ScreenLayoutContext.Provider value={screeenLayoutValue}>
73
73
  {props.children}
74
74
  </ScreenLayoutContext.Provider>
75
75
  );
@@ -0,0 +1,64 @@
1
+ import * as React from "react";
2
+ import { View, StyleSheet } from "react-native";
3
+ import { useCurrentScreenData } from "@applicaster/zapp-react-native-utils/reactHooks/screen";
4
+ import { ifEmptyUseFallback } from "@applicaster/zapp-react-native-utils/cellUtils";
5
+ import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
6
+ import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
7
+ import { Spinner } from "@applicaster/zapp-react-native-ui-components/Components/Spinner";
8
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
9
+
10
+ import { useScreenConfiguration } from "../../River/useScreenConfiguration";
11
+
12
+ const styles = StyleSheet.create({
13
+ container: {
14
+ position: "absolute",
15
+ top: 0,
16
+ left: 0,
17
+ right: 0,
18
+ bottom: 0,
19
+
20
+ alignItems: "center",
21
+ justifyContent: "center",
22
+ },
23
+ });
24
+
25
+ export const TransitionOverlay = () => {
26
+ const screen = useCurrentScreenData();
27
+
28
+ const { backgroundColor: screenBackgroundColor } = useScreenConfiguration(
29
+ screen?.id
30
+ );
31
+
32
+ const theme = useTheme();
33
+
34
+ const themeBackgroundColor = React.useMemo(
35
+ () => theme.app_background_color,
36
+ [theme.app_background_color]
37
+ );
38
+
39
+ const backgroundColor = ifEmptyUseFallback(
40
+ screenBackgroundColor,
41
+ themeBackgroundColor
42
+ );
43
+
44
+ const {
45
+ appState: { isTransitioning },
46
+ } = usePickFromState(["appState"]);
47
+
48
+ if (!isWeb() || !isTransitioning) {
49
+ return null;
50
+ }
51
+
52
+ return (
53
+ <View
54
+ style={[
55
+ styles.container,
56
+ {
57
+ backgroundColor,
58
+ },
59
+ ]}
60
+ >
61
+ <Spinner size={"large"} />
62
+ </View>
63
+ );
64
+ };
@@ -2,18 +2,58 @@
2
2
 
3
3
  exports[`Layout TV renders 1`] = `
4
4
  <View
5
- excludeFromFocusSearching={true}
6
- id="/river/A1234"
7
- preferredFocus={true}
5
+ style={
6
+ Object {
7
+ "flex": 1,
8
+ "height": 1080,
9
+ "width": 1920,
10
+ }
11
+ }
12
+ testID="layout-container"
8
13
  >
9
14
  <View
10
- Components={
11
- Object {
12
- "Background": [Function],
13
- "NavBar": [Function],
15
+ backgroundImageUrl="http://applicaster.com"
16
+ testID="background-component"
17
+ >
18
+ <View
19
+ style={
20
+ Array [
21
+ Object {
22
+ "position": "absolute",
23
+ "top": 0,
24
+ "width": 1920,
25
+ "zIndex": 10,
26
+ },
27
+ Object {
28
+ "maxHeight": 10,
29
+ },
30
+ ]
14
31
  }
15
- }
16
- route="/river/A1234"
17
- />
32
+ testID="nav-bar-container"
33
+ >
34
+ <View
35
+ isVisible={true}
36
+ menuPlugin={
37
+ Object {
38
+ "module": [Function],
39
+ "name": "resolved-menu-plug",
40
+ "type": "menu",
41
+ }
42
+ }
43
+ navigationProps={
44
+ Object {
45
+ "assets": undefined,
46
+ "home": undefined,
47
+ "nav_items": undefined,
48
+ "rules": undefined,
49
+ "selected": undefined,
50
+ "styles": undefined,
51
+ "title": "",
52
+ }
53
+ }
54
+ testID="nav-bar-component"
55
+ />
56
+ </View>
57
+ </View>
18
58
  </View>
19
59
  `;
@@ -1,48 +1,79 @@
1
1
  import * as React from "react";
2
- import { omit } from "ramda";
2
+ import * as R from "ramda";
3
3
  import { View } from "react-native";
4
4
  import { render } from "@testing-library/react-native";
5
5
  import { Provider } from "react-redux";
6
+ import { createStore } from "redux";
6
7
  import { NavigationContext } from "@applicaster/zapp-react-native-ui-components/Contexts/NavigationContext";
7
- import configureStore from "redux-mock-store";
8
8
 
9
- const withoutChildren = omit(["children"]);
9
+ import { ThemeContext } from "@applicaster/zapp-react-native-utils/theme";
10
10
 
11
- jest.mock("../../../Screen/TV/index.web", () => ({
12
- Screen: View,
11
+ jest.mock("@applicaster/quick-brick-core/App/ActionSetters", () => ({
12
+ useRiverInitialState: () => ({}),
13
13
  }));
14
14
 
15
+ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/screen");
16
+
15
17
  const Layout = require("..").default;
16
18
 
17
- const mockStore = configureStore()({
19
+ const ResolvedMenuPlug = () => <View testID="resolved-menu-plug" />;
20
+
21
+ const plugins = [
22
+ {
23
+ module: ResolvedMenuPlug,
24
+ type: "menu",
25
+ name: "resolved-menu-plug",
26
+ },
27
+ ];
28
+
29
+ const bgImage = "http://applicaster.com";
30
+ const isNavBarVisible = true;
31
+
32
+ const store = createStore(() => ({
18
33
  appState: { appReady: true },
19
- });
34
+ remoteConfigurations: { sdkAssets: { bgImage } },
35
+ plugins,
36
+ }));
20
37
 
21
38
  describe("Layout TV", () => {
39
+ const themes = {
40
+ myTheme: { screen_margin_top: 10, screen_margin_bottom: 10 },
41
+ };
42
+
43
+ const selectedThemeId = "myTheme";
44
+
22
45
  const navigator = {
46
+ activeRiver: {
47
+ navigations: [{ category: "menu", navigation_type: "menu" }],
48
+ },
49
+ canGoBack: () => false,
23
50
  currentRoute: "/river/A1234",
24
- mainStack: [
25
- {
26
- route: "/river/A1234",
27
- state: "state",
28
- },
29
- ],
51
+ screenData: {
52
+ navigations: [{ category: "menu", navigation_type: "menu" }],
53
+ },
54
+ isNavBarVisible: isNavBarVisible,
30
55
  };
31
56
 
32
57
  const wrapper = ({ children }) => (
33
- <Provider store={mockStore}>
58
+ <Provider store={store}>
34
59
  <NavigationContext.Provider value={navigator}>
35
- {children}
60
+ <ThemeContext.Provider value={{ themes, selectedThemeId }}>
61
+ {children}
62
+ </ThemeContext.Provider>
36
63
  </NavigationContext.Provider>
37
64
  </Provider>
38
65
  );
39
66
 
67
+ const Screen = (props) => (
68
+ <View testID="screen-component" {...R.omit(["children"])(props)} />
69
+ );
70
+
40
71
  const NavBar = (props) => (
41
- <View testID="nav-bar-component" {...withoutChildren(props)} />
72
+ <View testID="nav-bar-component" {...R.omit(["children"])(props)} />
42
73
  );
43
74
 
44
75
  const Background = (props: Record<any, any>) => (
45
- <View testID="background-component" {...withoutChildren(props)}>
76
+ <View testID="background-component" {...R.omit(["children"])(props)}>
46
77
  {props.children}
47
78
  </View>
48
79
  );
@@ -53,8 +84,33 @@ describe("Layout TV", () => {
53
84
  };
54
85
 
55
86
  it("renders", () => {
56
- const { toJSON } = render(<Layout Components={Components} />, { wrapper });
87
+ const { toJSON } = render(
88
+ <Layout Components={Components}>
89
+ <Screen />
90
+ </Layout>,
91
+ { wrapper }
92
+ );
57
93
 
58
94
  expect(toJSON()).toMatchSnapshot();
59
95
  });
96
+
97
+ describe("props passed to background component", () => {
98
+ it("passes correct props", () => {
99
+ const { getByTestId } = render(
100
+ <Layout
101
+ Components={Components}
102
+ ComponentsExtraProps={{
103
+ Background: { testProp: true },
104
+ }}
105
+ >
106
+ <Screen />
107
+ </Layout>,
108
+ { wrapper }
109
+ );
110
+
111
+ const bgComponent = getByTestId("background-component");
112
+ expect(bgComponent.props.backgroundImageUrl).toBe(bgImage);
113
+ expect(bgComponent.props.testProp).toBe(true);
114
+ });
115
+ });
60
116
  });
@@ -1,32 +1,131 @@
1
1
  import * as React from "react";
2
- import { pathOr } from "ramda";
3
-
2
+ import * as R from "ramda";
4
3
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
4
+ import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
5
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
6
+
7
+ import {
8
+ getNavigationProps,
9
+ resolveNavigationPlugin,
10
+ routeIsPlayerScreen,
11
+ } from "@applicaster/zapp-react-native-utils/navigationUtils";
12
+
13
+ import { getBackgroundImageUrl } from "../utils";
14
+ import { LayoutContainer } from "./LayoutContainer";
15
+ import { NavBarContainer } from "./NavBarContainer";
16
+ import { ScreenContainer } from "./ScreenContainer";
17
+ import { TransitionOverlay } from "./TransitionOverlay";
5
18
 
6
19
  import { ScreenLayoutContextProvider } from "./ScreenLayoutContextProvider";
7
- import { StackNavigator } from "../../Navigator";
20
+ import { isApplePlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
21
+ import { PathnameContext } from "../../../Contexts/PathnameContext";
22
+ import { useNavbarState } from "@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenContext";
23
+ import { ScreenDataContext } from "../../../Contexts/ScreenDataContext";
8
24
 
9
25
  type Components = {
10
26
  NavBar: React.ComponentType<any>;
11
27
  Background: React.ComponentType<any>;
12
28
  };
13
29
 
30
+ type ComponentsExtraProps = {
31
+ Background?: Record<string, any>;
32
+ NavBar?: Record<string, any>;
33
+ };
34
+
14
35
  type Props = {
15
36
  Components: Components;
37
+ ComponentsExtraProps?: ComponentsExtraProps;
38
+ children: React.ReactNode;
16
39
  };
17
40
 
18
- const Layout = ({ Components }: Props) => {
19
- const { appState } = usePickFromState(["appState"]);
20
- const appReady = pathOr(false, ["appReady"], appState);
41
+ const Layout = ({ Components, ComponentsExtraProps, children }: Props) => {
42
+ const navigator = useNavigation();
43
+ const theme = useTheme();
44
+ const { title, visible } = useNavbarState();
45
+ const { activeRiver, currentRoute } = navigator;
46
+
47
+ const {
48
+ appState: { appReady = false } = {},
49
+ remoteConfigurations,
50
+ plugins = [],
51
+ } = usePickFromState(["appState", "remoteConfigurations", "plugins"]);
52
+
53
+ const navigationProps = getNavigationProps({
54
+ navigator,
55
+ title,
56
+ category: "menu",
57
+ });
58
+
59
+ const backgroundColor = React.useMemo(() => theme.app_background_color, []);
60
+
61
+ const backgroundImageUrl = React.useMemo(
62
+ () => getBackgroundImageUrl(remoteConfigurations),
63
+ [remoteConfigurations]
64
+ );
65
+
66
+ const menuPlugin = React.useMemo(
67
+ () =>
68
+ resolveNavigationPlugin({
69
+ category: "menu",
70
+ navigations: activeRiver?.navigations,
71
+ plugins,
72
+ }) as QuickBrickPlugin,
73
+ []
74
+ );
75
+
76
+ const NavBar = React.useMemo(
77
+ () => Components.NavBar || (menuPlugin.module as React.ComponentType<any>),
78
+ []
79
+ );
80
+
81
+ const [navBarReady, setNavBarReady] = React.useState(false);
82
+
83
+ const navBarContainer = (
84
+ <NavBarContainer isVisible={visible} onReady={setNavBarReady}>
85
+ <NavBar
86
+ ref={ComponentsExtraProps?.NavBar?.ref}
87
+ isVisible={visible && !routeIsPlayerScreen(currentRoute)}
88
+ menuPlugin={menuPlugin}
89
+ navigationProps={navigationProps}
90
+ {...R.omit(["ref"])(ComponentsExtraProps?.NavBar)}
91
+ />
92
+ </NavBarContainer>
93
+ );
94
+
95
+ const isTVOS = isApplePlatform();
21
96
 
22
97
  if (!appReady) {
23
98
  return null;
24
99
  }
25
100
 
26
101
  return (
27
- <ScreenLayoutContextProvider>
28
- <StackNavigator Components={Components} />
29
- </ScreenLayoutContextProvider>
102
+ <LayoutContainer>
103
+ <ScreenLayoutContextProvider>
104
+ <Components.Background
105
+ backgroundColor={backgroundColor}
106
+ backgroundImageUrl={backgroundImageUrl}
107
+ {...R.omit(["ref"])(ComponentsExtraProps?.Background)}
108
+ >
109
+ <ScreenDataContext.Provider value={navigator.data}>
110
+ <PathnameContext.Provider value={navigator.currentRoute}>
111
+ {!isTVOS ? navBarContainer : null}
112
+ {navBarReady ? (
113
+ /**
114
+ Need to re-mount this component on each navigation event
115
+ It's a hack to work around the fact that we don't support
116
+ correct screen rendering in our navigator (shared currentRoute state)
117
+ **/
118
+ <ScreenContainer>{children}</ScreenContainer>
119
+ ) : null}
120
+ {/** Render NavBarContainer over ScreenContainer to let tvOS native
121
+ focus manager works correctly to focus nav bar items first **/}
122
+ {isTVOS ? navBarContainer : null}
123
+ </PathnameContext.Provider>
124
+ </ScreenDataContext.Provider>
125
+ <TransitionOverlay />
126
+ </Components.Background>
127
+ </ScreenLayoutContextProvider>
128
+ </LayoutContainer>
30
129
  );
31
130
  };
32
131
 
@@ -7,50 +7,24 @@ type BorderPosition = "inside" | "outside" | "center";
7
7
  interface Props {
8
8
  style: ImageStyle | ViewStyle;
9
9
  borderPosition: BorderPosition;
10
+ borderPaddingTop: number;
11
+ borderPaddingRight: number;
12
+ borderPaddingBottom: number;
13
+ borderPaddingLeft: number;
10
14
  children: React.ReactNode;
11
15
  }
12
16
 
13
- const MARGINS = [
14
- "marginTop",
15
- "marginBottom",
16
- "marginLeft",
17
- "marginRight",
18
- ] as const;
17
+ const COLOR_TRANSPARENT = "transparent";
19
18
 
20
- const PADDINGS = [
21
- "paddingTop",
22
- "paddingBottom",
23
- "paddingLeft",
24
- "paddingRight",
25
- ] as const;
19
+ const styles = StyleSheet.create({
20
+ container: {
21
+ overflow: "visible",
22
+ borderWidth: 0,
23
+ borderColor: COLOR_TRANSPARENT,
24
+ },
25
+ });
26
26
 
27
- const isPercentageValue = (value: number | string) => {
28
- if (typeof value === "string" && value.endsWith("%")) {
29
- return true;
30
- }
31
-
32
- return false;
33
- };
34
-
35
- const calculateContainerSpacing = ({
36
- spacingKey,
37
- style,
38
- additionalSpacing,
39
- }: {
40
- spacingKey: typeof MARGINS[number] | typeof PADDINGS[number];
41
- style: ImageStyle | ViewStyle;
42
- additionalSpacing: number;
43
- }) => {
44
- return {
45
- [spacingKey]:
46
- toNumberWithDefaultZero(style[spacingKey]) + additionalSpacing,
47
- };
48
- };
49
-
50
- const getContainerBorderWidth = (
51
- borderPosition: BorderPosition,
52
- borderWidth
53
- ) => {
27
+ const getBorderPadding = (borderPosition: BorderPosition, borderWidth) => {
54
28
  switch (borderPosition) {
55
29
  case "inside":
56
30
  return 0;
@@ -63,104 +37,101 @@ const getContainerBorderWidth = (
63
37
  }
64
38
  };
65
39
 
66
- const getContainerPadding = (borderPosition: BorderPosition, borderWidth) => {
67
- switch (borderPosition) {
68
- case "inside":
69
- return borderWidth;
70
- case "center":
71
- return borderWidth / 2;
72
- case "outside":
73
- return 0;
74
- default:
75
- return 0;
76
- }
77
- };
78
-
79
- const InsideBorder = ({
40
+ const Border = ({
80
41
  style,
42
+ padding,
81
43
  borderPosition,
82
44
  }: {
83
45
  style: ViewStyle;
46
+ padding: ViewStyle;
84
47
  borderPosition: BorderPosition;
85
48
  }) => {
86
- if (borderPosition === "outside") {
49
+ if (!borderPosition) {
87
50
  return null;
88
51
  }
89
52
 
90
- const insideBorderWidth =
91
- borderPosition === "center" ? style.borderWidth / 2 : style.borderWidth;
53
+ const borderWidth = toNumberWithDefaultZero(style.borderWidth);
54
+ const containerPadding = getBorderPadding(borderPosition, borderWidth);
55
+
56
+ const initialBorderRadius = toNumberWithDefaultZero(style.borderRadius);
57
+ const paddingTop = toNumberWithDefaultZero(padding.paddingTop);
58
+ const paddingRight = toNumberWithDefaultZero(padding.paddingRight);
59
+ const paddingBottom = toNumberWithDefaultZero(padding.paddingBottom);
60
+ const paddingLeft = toNumberWithDefaultZero(padding.paddingLeft);
61
+
62
+ const borderRadiusStyle = initialBorderRadius
63
+ ? {
64
+ borderTopLeftRadius:
65
+ initialBorderRadius +
66
+ containerPadding +
67
+ Math.min(paddingTop, paddingLeft),
68
+ borderTopRightRadius:
69
+ initialBorderRadius +
70
+ containerPadding +
71
+ Math.min(paddingTop, paddingRight),
72
+ borderBottomLeftRadius:
73
+ initialBorderRadius +
74
+ containerPadding +
75
+ Math.min(paddingBottom, paddingLeft),
76
+ borderBottomRightRadius:
77
+ initialBorderRadius +
78
+ containerPadding +
79
+ Math.min(paddingBottom, paddingRight),
80
+ }
81
+ : {
82
+ borderTopLeftRadius: 0,
83
+ borderTopRightRadius: 0,
84
+ borderBottomLeftRadius: 0,
85
+ borderBottomRightRadius: 0,
86
+ };
92
87
 
93
88
  return (
94
89
  <View
95
90
  style={{
96
91
  ...StyleSheet.absoluteFillObject,
97
- borderWidth: insideBorderWidth,
92
+ right: -containerPadding - paddingRight,
93
+ bottom: -containerPadding - paddingBottom,
94
+ left: -containerPadding - paddingLeft,
95
+ top: -containerPadding - paddingTop,
96
+ borderWidth,
98
97
  borderColor: style.borderColor,
99
- borderRadius: style.borderRadius,
98
+ ...borderRadiusStyle,
100
99
  }}
101
100
  />
102
101
  );
103
102
  };
104
103
 
105
104
  export const BorderContainerView = (props: Props) => {
106
- const { style, children } = props;
107
- // Return border position prop after re-implementing
108
- const borderPosition = "outside";
109
-
110
- const borderWidth = toNumberWithDefaultZero(style.borderWidth);
111
- const spacing = getContainerPadding(borderPosition, borderWidth);
105
+ const {
106
+ borderPosition,
107
+ borderPaddingTop,
108
+ borderPaddingRight,
109
+ borderPaddingBottom,
110
+ borderPaddingLeft,
111
+ style,
112
+ children,
113
+ } = props;
112
114
 
113
115
  const borderStyleForMissingBorder =
114
116
  style?.borderWidth === 0 || !style?.borderColor ? { borderRadius: 0 } : {};
115
117
 
116
- const updatedMargins = MARGINS.reduce((acc, margin) => {
117
- const marginValue = calculateContainerSpacing({
118
- spacingKey: margin,
119
- style,
120
- additionalSpacing: spacing,
121
- });
122
-
123
- return { ...acc, ...marginValue };
124
- }, {});
125
-
126
- const updatedPaddings = PADDINGS.reduce((acc, padding) => {
127
- const paddingValue = calculateContainerSpacing({
128
- spacingKey: padding,
129
- style,
130
- additionalSpacing: spacing,
131
- });
132
-
133
- return { ...acc, ...paddingValue };
134
- }, {});
135
-
136
- const updatedWidth = style.width
137
- ? isPercentageValue(style.width)
138
- ? style.width
139
- : toNumberWithDefaultZero(style.width) - spacing * 2
140
- : undefined;
141
-
142
- const updatedHeight = style.height
143
- ? isPercentageValue(style.height)
144
- ? style.height
145
- : toNumberWithDefaultZero(style.height) - spacing * 2
146
- : undefined;
147
-
148
- const containerStyle = {
149
- borderWidth: getContainerBorderWidth(borderPosition, borderWidth),
150
- padding: spacing,
151
- ...updatedMargins,
152
- ...updatedPaddings,
153
- width: updatedWidth,
154
- height: updatedHeight,
155
- };
118
+ const padding =
119
+ borderPosition === "outside"
120
+ ? {
121
+ paddingTop: borderPaddingTop,
122
+ paddingRight: borderPaddingRight,
123
+ paddingBottom: borderPaddingBottom,
124
+ paddingLeft: borderPaddingLeft,
125
+ }
126
+ : {};
156
127
 
157
128
  return (
158
- <View {...props} style={[style, containerStyle]}>
129
+ <View
130
+ {...props}
131
+ style={[style, styles.container, borderStyleForMissingBorder]}
132
+ >
159
133
  {children}
160
- <InsideBorder
161
- style={{ ...style, ...borderStyleForMissingBorder }}
162
- borderPosition={borderPosition}
163
- />
134
+ <Border style={style} padding={padding} borderPosition={borderPosition} />
164
135
  </View>
165
136
  );
166
137
  };
@@ -61,10 +61,7 @@ export function ButtonContainerView({
61
61
  <View style={applyRTLStylesIfNeeded(style, isRTL)}>
62
62
  {insertBetween(
63
63
  (index) => (
64
- <HorizontalSeparator
65
- key={`separator_${index}`}
66
- width={horizontalGutter}
67
- />
64
+ <HorizontalSeparator key={index} width={horizontalGutter} />
68
65
  ),
69
66
  cloneElementsWithIds(buttonIds, filteredChildren)
70
67
  )}
@@ -29,10 +29,7 @@ export function ButtonContainerView({
29
29
  <View style={style}>
30
30
  {insertBetween(
31
31
  (index) => (
32
- <HorizontalSeparator
33
- key={`separator_${index}`}
34
- width={horizontalGutter}
35
- />
32
+ <HorizontalSeparator key={index} width={horizontalGutter} />
36
33
  ),
37
34
  filteredChildren
38
35
  )}
@@ -68,7 +68,6 @@ type Props = {
68
68
  mode?: VideoModalMode;
69
69
  loadPipesData: (url: string, options: {}) => void;
70
70
  disableCastAction?: boolean;
71
- groupId?: string;
72
71
  };
73
72
 
74
73
  type ScreenStyles = ZappRiver["styles"] & {
@@ -201,7 +200,6 @@ const PlayerContainerComponent = (props: Props) => {
201
200
  style: videoStyle,
202
201
  mode = VideoModalMode.MAXIMIZED,
203
202
  disableCastAction = false,
204
- groupId,
205
203
  } = props;
206
204
 
207
205
  // Hooks
@@ -251,6 +249,7 @@ const PlayerContainerComponent = (props: Props) => {
251
249
  return;
252
250
  }
253
251
 
252
+ navigator.goBack();
254
253
  showNavBar(true);
255
254
  }, [isModal, navigator.goBack, showNavBar]);
256
255
 
@@ -630,7 +629,6 @@ const PlayerContainerComponent = (props: Props) => {
630
629
  style={styles.focusableGroup}
631
630
  preferredFocus
632
631
  shouldUsePreferredFocus
633
- groupId={groupId}
634
632
  >
635
633
  {/* Video player and components */}
636
634
  <View
@@ -7,10 +7,14 @@ import * as R from "ramda";
7
7
  import {
8
8
  useFeedLoader,
9
9
  useLayoutVersion,
10
+ useNavigationPluginData,
10
11
  } from "@applicaster/zapp-react-native-utils/reactHooks";
11
12
  import { GeneralContentScreen } from "../../GeneralContentScreen";
12
13
  import { ScreenResolver } from "@applicaster/zapp-react-native-ui-components/Components/ScreenResolver";
13
14
  import { utilsLogger } from "@applicaster/zapp-react-native-utils/logger";
15
+ import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils";
16
+ import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
17
+ import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
14
18
  import {
15
19
  useNavbarState,
16
20
  useSetNavbarState,
@@ -47,6 +51,8 @@ export const River = (props: Props) => {
47
51
  const { setTitle: setScreenTitle, setSummary: setScreenSummary } =
48
52
  useSetNavbarState();
49
53
 
54
+ const navigationPluginData = useNavigationPluginData();
55
+
50
56
  const rivers = useRivers();
51
57
  const isV2 = useLayoutVersion({ isV2: true });
52
58
 
@@ -93,6 +99,23 @@ export const River = (props: Props) => {
93
99
  }
94
100
  }, [feedData, screenData, screenTitle, screenSummary]);
95
101
 
102
+ React.useEffect(() => {
103
+ if (
104
+ isWeb() &&
105
+ toBooleanWithDefaultFalse(
106
+ navigationPluginData?.rules?.focus_on_content
107
+ ) &&
108
+ river &&
109
+ river.type !== "general_content"
110
+ ) {
111
+ const groupId = R.pathOr("river", ["groupId"], componentsMapExtraProps);
112
+
113
+ focusManager.setupInitialFocus(groupId, true);
114
+ focusManager.setInitialFocus();
115
+ focusManager.enableAutomaticFocus();
116
+ }
117
+ }, [river, componentsMapExtraProps]);
118
+
96
119
  if (!river) {
97
120
  utilsLogger.error({
98
121
  message: `River ${screenData.id} not found!`,
@@ -32,13 +32,12 @@ type Props = {
32
32
  nextFocusLeft?: React.Ref<any>;
33
33
  nextFocusUp?: React.Ref<any>;
34
34
  };
35
- groupId?: string;
36
35
  };
37
36
 
38
37
  export function ScreenResolverComponent(props: Props) {
39
38
  useScreenAnalytics(props);
40
39
 
41
- const { screenType, screenId, screenData, groupId } = props;
40
+ const { screenType, screenId, screenData } = props;
42
41
 
43
42
  const { hookPlugin } = screenData || {};
44
43
 
@@ -82,7 +81,6 @@ export function ScreenResolverComponent(props: Props) {
82
81
  item={screenData}
83
82
  mode={mode === "PIP" ? "PIP" : "FULLSCREEN"}
84
83
  isModal={false}
85
- groupId={groupId}
86
84
  />
87
85
  );
88
86
  }
@@ -10,11 +10,7 @@ import { Component } from "react";
10
10
 
11
11
  const { log_debug, log_info, log_error } = loggerLiveImageManager;
12
12
 
13
- export type LiveImageManagerEvent =
14
- | "onEnd"
15
- | "onStart"
16
- | "onError"
17
- | "onDestroy";
13
+ export type LiveImageManagerEvent = "onEnd" | "onStart" | "onError";
18
14
 
19
15
  export type LiveImageManagerListenerData = {
20
16
  id: string;
@@ -106,16 +102,6 @@ export class LiveImageManager implements PlayerLifecycleListener {
106
102
  }
107
103
 
108
104
  this.items = this.items.filter((i) => i !== item);
109
-
110
- this.invokeListenersUpdate({
111
- callbackName: "onDestroy",
112
- event: {
113
- item,
114
- playerId: this.currentlyPlaying?.playerId,
115
- primaryPlayerId: this.primaryPlayer?.playerId,
116
- entry: item.getPlayer().getEntry(),
117
- },
118
- });
119
105
  };
120
106
 
121
107
  public onViewportEnter = (item: LiveImage) => {
@@ -42,12 +42,12 @@ export const PlayerDetails = ({
42
42
  : {};
43
43
 
44
44
  // Animation setup
45
- const translateY = useRef(new Animated.Value(100)).current;
45
+ const translateY = useRef(new Animated.Value(50)).current;
46
46
  const opacity = useRef(new Animated.Value(0)).current;
47
47
 
48
48
  const runAnimation = () => {
49
49
  Animated.timing(translateY, {
50
- toValue: 0,
50
+ toValue: -30,
51
51
  duration: 500,
52
52
  easing: Easing.inOut(Easing.ease),
53
53
  useNativeDriver: true,
@@ -63,7 +63,7 @@ export const PlayerDetails = ({
63
63
 
64
64
  useEffect(() => {
65
65
  if (isAudioPlayer) {
66
- setTimeout(() => runAnimation(), 1000);
66
+ setTimeout(() => runAnimation(), 1500);
67
67
  }
68
68
  }, [isAudioPlayer]);
69
69
 
@@ -63,7 +63,7 @@ function prepareContext(
63
63
  const parent = findParent(currentContext, route, getChildren);
64
64
 
65
65
  const newEntry = {
66
- route,
66
+ route: route,
67
67
  id: uuid(),
68
68
  data: newContext,
69
69
  } as SingleEntry;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "12.0.0-alpha.4201443043",
3
+ "version": "12.0.0-alpha.4324313105",
4
4
  "description": "Applicaster Zapp React Native ui components for the Quick Brick App",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -34,10 +34,10 @@
34
34
  "redux-mock-store": "^1.5.3"
35
35
  },
36
36
  "dependencies": {
37
- "@applicaster/applicaster-types": "12.0.0-alpha.4201443043",
38
- "@applicaster/zapp-react-native-bridge": "12.0.0-alpha.4201443043",
39
- "@applicaster/zapp-react-native-redux": "12.0.0-alpha.4201443043",
40
- "@applicaster/zapp-react-native-utils": "12.0.0-alpha.4201443043",
37
+ "@applicaster/applicaster-types": "12.0.0-alpha.4324313105",
38
+ "@applicaster/zapp-react-native-bridge": "12.0.0-alpha.4324313105",
39
+ "@applicaster/zapp-react-native-redux": "12.0.0-alpha.4324313105",
40
+ "@applicaster/zapp-react-native-utils": "12.0.0-alpha.4324313105",
41
41
  "promise": "^8.3.0",
42
42
  "react-router-native": "^5.1.2",
43
43
  "url": "^0.11.0",
@@ -1,48 +0,0 @@
1
- import * as React from "react";
2
- import { isEmpty } from "ramda";
3
-
4
- import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
5
- import { getPathAttributes } from "@applicaster/zapp-react-native-utils/navigationUtils";
6
- import { FocusableGroup } from "@applicaster/zapp-react-native-ui-components/Components/FocusableGroup";
7
- import { ScreenDataContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenDataContext";
8
- import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext";
9
-
10
- import { Screen } from "../Screen/TV/index.web";
11
-
12
- type Components = {
13
- NavBar: React.ComponentType<any>;
14
- Background: React.ComponentType<any>;
15
- };
16
-
17
- type Props = {
18
- Components: Components;
19
- };
20
-
21
- export const StackNavigator = ({ Components }: Props) => {
22
- const { mainStack, currentRoute } = useNavigation();
23
-
24
- const renderScreen = ({ route, state }) => {
25
- const pathAttributes = getPathAttributes({ pathname: route });
26
-
27
- if (isEmpty(pathAttributes)) {
28
- return null;
29
- }
30
-
31
- return (
32
- <FocusableGroup
33
- id={route}
34
- preferredFocus={route === currentRoute}
35
- excludeFromFocusSearching
36
- key={route}
37
- >
38
- <ScreenDataContext.Provider value={state}>
39
- <PathnameContext.Provider value={route}>
40
- <Screen route={route} Components={Components} />
41
- </PathnameContext.Provider>
42
- </ScreenDataContext.Provider>
43
- </FocusableGroup>
44
- );
45
- };
46
-
47
- return <>{mainStack.map(renderScreen)}</>;
48
- };
@@ -1 +0,0 @@
1
- export { StackNavigator } from "./StackNavigator";
@@ -1,3 +0,0 @@
1
- export { useInitialFocus } from "./useInitialFocus";
2
-
3
- export { useRestoreFocus } from "./useRestoreFocus";
@@ -1,70 +0,0 @@
1
- import * as React from "react";
2
- import {
3
- useNavigationPluginData,
4
- useIsNavBarVisible,
5
- useRoute,
6
- } from "@applicaster/zapp-react-native-utils/reactHooks";
7
- import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
8
- import {
9
- setFocusOnContent,
10
- setFocusOnMenu,
11
- } from "@applicaster/zapp-react-native-utils/appUtils/focusManagerAux";
12
-
13
- type Return =
14
- | {
15
- onContent: true;
16
- onMenu: false;
17
- }
18
- | {
19
- onContent: false;
20
- onMenu: true;
21
- };
22
-
23
- const getInitialFocus = (focusOnContent, isNavBarVisible): Return => {
24
- if (focusOnContent) {
25
- return {
26
- onContent: true,
27
- onMenu: false,
28
- };
29
- }
30
-
31
- if (!focusOnContent && isNavBarVisible) {
32
- // put focus on navbar
33
- return {
34
- onContent: false,
35
- onMenu: true,
36
- };
37
- }
38
-
39
- // we don't have navbar, put focus on content anyway
40
- return {
41
- onContent: true,
42
- onMenu: false,
43
- };
44
- };
45
-
46
- export const useInitialFocus = (): void => {
47
- const navigationPluginData = useNavigationPluginData();
48
-
49
- const focusOnContent = toBooleanWithDefaultFalse(
50
- navigationPluginData?.rules?.focus_on_content
51
- );
52
-
53
- const isNavBarVisible = useIsNavBarVisible();
54
-
55
- const { pathname: currentRoute } = useRoute();
56
-
57
- React.useEffect(() => {
58
- const initialFocus = getInitialFocus(focusOnContent, isNavBarVisible);
59
-
60
- if (initialFocus.onContent) {
61
- setFocusOnContent(currentRoute);
62
-
63
- return;
64
- }
65
-
66
- if (initialFocus.onMenu) {
67
- setFocusOnMenu(currentRoute);
68
- }
69
- }, []);
70
- };
@@ -1,22 +0,0 @@
1
- import * as React from "react";
2
- import { isNil } from "ramda";
3
- import { useIsScreenActive } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
4
- import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
5
- import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
6
-
7
- export const useRestoreFocus = (): void => {
8
- const isScreenActive = useIsScreenActive();
9
- const previousIsScreenActive = usePrevious(isScreenActive);
10
-
11
- React.useEffect(() => {
12
- if (isNil(previousIsScreenActive)) {
13
- // it's initial mounting of the screen, do nothing here
14
- return;
15
- }
16
-
17
- if (!previousIsScreenActive && isScreenActive) {
18
- // restore focus when we go back from next screen
19
- focusManager.setInitialFocus();
20
- }
21
- }, [previousIsScreenActive, isScreenActive]);
22
- };
@@ -1,179 +0,0 @@
1
- import * as React from "react";
2
- import { last, pathOr } from "ramda";
3
- import { View, StyleSheet } from "react-native";
4
- import {
5
- getNavigationProps,
6
- getPathAttributes,
7
- resolveNavigationPlugin,
8
- } from "@applicaster/zapp-react-native-utils/navigationUtils";
9
- import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
10
- import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
11
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
12
- import { useScreenBackgroundColor } from "@applicaster/zapp-react-native-utils/reactHooks/screen";
13
- import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
14
-
15
- import { NavBarContainer } from "../../Layout/TV/NavBarContainer";
16
- import { ScreenResolver } from "../../ScreenResolver";
17
- import { useInitialFocus, useRestoreFocus } from "./hooks";
18
-
19
- const styles = StyleSheet.create({
20
- container: {
21
- position: "absolute",
22
- top: 0,
23
- left: 0,
24
- right: 0,
25
- bottom: 0,
26
- },
27
- });
28
-
29
- type Components = {
30
- NavBar: React.ComponentType<any>;
31
- Background: React.ComponentType<any>;
32
- };
33
-
34
- type Props = {
35
- route: string;
36
- Components: Components;
37
- };
38
-
39
- const getPluginType = pathOr("unknown_plugin_type", [
40
- "state",
41
- "screen",
42
- "plugin_type",
43
- ]);
44
-
45
- const isPlayerPlugin = (routeState): boolean =>
46
- getPluginType(routeState) === "player";
47
-
48
- const isLoginPlugin = (routeState): boolean =>
49
- getPluginType(routeState) === "login";
50
-
51
- const getActiveRiver = ({
52
- screenId,
53
- screenType,
54
- routeState,
55
- rivers,
56
- fallbackActiveRiver,
57
- }) => {
58
- if (rivers[screenId]) {
59
- if (screenType === "hooks") {
60
- const navigations = routeState?.state?.entry?.payload?.navigations;
61
-
62
- if (navigations) {
63
- return routeState.state.entry.payload;
64
- }
65
- }
66
-
67
- return routeState?.state?.screen;
68
- }
69
-
70
- // screenId is not presented into rivers, use fallback instead
71
- return fallbackActiveRiver;
72
- };
73
-
74
- const getNavigations = ({
75
- screenId,
76
- screenType,
77
- routeState,
78
- rivers,
79
- fallbackNavigations,
80
- }) => {
81
- if (rivers[screenId]) {
82
- // river presents
83
- if (screenType === "hooks") {
84
- const navigations = routeState?.state?.entry?.payload?.navigations;
85
-
86
- if (navigations) {
87
- return navigations;
88
- }
89
- }
90
-
91
- return routeState?.state?.screen?.navigations;
92
- }
93
-
94
- // screenId is not presented into rivers, use fallback instead
95
- return fallbackNavigations;
96
- };
97
-
98
- export const Screen = ({ route, Components }: Props) => {
99
- if (isNilOrEmpty(route)) {
100
- throw Error("Required props: route is missing");
101
- }
102
-
103
- const navigator = useNavigation();
104
- const { plugins = [], rivers = [] } = usePickFromState(["plugins", "rivers"]);
105
-
106
- const pathAttributes = getPathAttributes({ pathname: route });
107
- const routeState = navigator.getStackForPathname(route);
108
-
109
- const { screenType, screenId } = last(pathAttributes);
110
-
111
- const backgroundColor = useScreenBackgroundColor(screenId);
112
-
113
- useInitialFocus();
114
- useRestoreFocus();
115
-
116
- const activeRiver = getActiveRiver({
117
- screenId,
118
- screenType,
119
- routeState,
120
- rivers,
121
- fallbackActiveRiver: navigator.activeRiver,
122
- });
123
-
124
- const navigationProps = getNavigationProps({
125
- navigator: {
126
- // @ts-ignore
127
- activeRiver,
128
- // @ts-ignore
129
- screenTitle: routeState.state.entry?.title || routeState.screen?.name,
130
- },
131
- category: "menu",
132
- });
133
-
134
- const navigations = getNavigations({
135
- screenId,
136
- screenType,
137
- routeState,
138
- rivers,
139
- fallbackNavigations: navigator.activeRiver.navigations,
140
- });
141
-
142
- const menuPlugin = resolveNavigationPlugin({
143
- category: "menu",
144
- navigations,
145
- plugins,
146
- }) as QuickBrickPlugin;
147
-
148
- const NavBar = (Components.NavBar ||
149
- menuPlugin.module) as React.ComponentType<any>;
150
-
151
- const isPlayer = isPlayerPlugin(routeState);
152
- const isLogin = isLoginPlugin(routeState);
153
-
154
- const isNavBarVisible = !isPlayer && !isLogin;
155
-
156
- const screenData =
157
- screenType === "hooks" || isPlayer
158
- ? routeState?.state?.entry
159
- : routeState?.state?.screen;
160
-
161
- return (
162
- <View style={[styles.container, { backgroundColor }]}>
163
- <NavBarContainer isVisible={isNavBarVisible} onReady={noop}>
164
- <NavBar
165
- groupId={route}
166
- isVisible={isNavBarVisible}
167
- menuPlugin={menuPlugin}
168
- navigationProps={navigationProps}
169
- />
170
- </NavBarContainer>
171
- <ScreenResolver
172
- screenType={screenType}
173
- screenId={screenId}
174
- screenData={screenData}
175
- groupId={route}
176
- />
177
- </View>
178
- );
179
- };