@applicaster/zapp-react-native-ui-components 15.0.0-alpha.1257410812 → 15.0.0-alpha.1305114721

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 (100) hide show
  1. package/Components/GeneralContentScreen/GeneralContentScreen.tsx +39 -28
  2. package/Components/GeneralContentScreen/__tests__/GeneralContentScreen.test.tsx +104 -0
  3. package/Components/GeneralContentScreen/utils/__tests__/getScreenDataSource.test.ts +19 -0
  4. package/Components/GeneralContentScreen/utils/getScreenDataSource.ts +9 -0
  5. package/Components/HandlePlayable/HandlePlayable.tsx +16 -29
  6. package/Components/HandlePlayable/utils.ts +31 -0
  7. package/Components/HookRenderer/HookRenderer.tsx +40 -10
  8. package/Components/HookRenderer/__tests__/HookRenderer.test.tsx +60 -0
  9. package/Components/Layout/TV/NavBarContainer.tsx +1 -10
  10. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +7 -12
  11. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +7 -12
  12. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/model.test.ts +80 -0
  13. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/placement.test.ts +187 -0
  14. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/selectors.test.ts +45 -0
  15. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/style.test.ts +49 -0
  16. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/model.ts +47 -0
  17. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/placement.ts +170 -0
  18. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/selectors.ts +26 -0
  19. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/style.ts +29 -0
  20. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/types.ts +37 -0
  21. package/Components/MasterCell/DefaultComponents/Button.tsx +0 -15
  22. package/Components/MasterCell/DefaultComponents/LiveImage/__tests__/prepareEntry.test.ts +352 -0
  23. package/Components/MasterCell/DefaultComponents/LiveImage/executePreloadHooks.ts +136 -0
  24. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +33 -16
  25. package/Components/MasterCell/DefaultComponents/PressableView.tsx +196 -0
  26. package/Components/MasterCell/DefaultComponents/Text/index.tsx +2 -6
  27. package/Components/MasterCell/DefaultComponents/index.ts +2 -0
  28. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Asset.ts +46 -0
  29. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Button.ts +126 -0
  30. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/ButtonContainerView.ts +23 -0
  31. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Spacer.ts +16 -0
  32. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabel.ts +67 -0
  33. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabelsContainer.ts +32 -0
  34. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/PressableView.test.tsx +191 -0
  35. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/builders.test.ts +140 -0
  36. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/index.test.ts +222 -0
  37. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/helpers.ts +105 -0
  38. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/index.ts +104 -0
  39. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/__tests__/insertButtons.test.ts +118 -0
  40. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/index.ts +73 -0
  41. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/__tests__/index.test.ts +86 -0
  42. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +35 -52
  43. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/getPluginIdentifier.test.ts +92 -103
  44. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +37 -148
  45. package/Components/MasterCell/elementMapper.tsx +1 -0
  46. package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +17 -9
  47. package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +16 -8
  48. package/Components/OfflineHandler/NotificationView/utils.ts +34 -0
  49. package/Components/PlayerContainer/PlayerContainer.tsx +1 -18
  50. package/Components/PreloaderWrapper/__tests__/index.test.tsx +26 -0
  51. package/Components/PreloaderWrapper/index.tsx +15 -0
  52. package/Components/River/ComponentsMap/ComponentsMap.tsx +16 -0
  53. package/Components/River/RefreshControl.tsx +36 -13
  54. package/Components/River/RiverItem.tsx +26 -20
  55. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +2 -0
  56. package/Components/River/__tests__/componentsMap.test.js +38 -0
  57. package/Components/Screen/__tests__/Screen.test.tsx +1 -0
  58. package/Components/Screen/hooks.ts +73 -3
  59. package/Components/Screen/index.tsx +7 -1
  60. package/Components/ScreenFeedLoader/ScreenFeedLoader.tsx +46 -0
  61. package/Components/ScreenFeedLoader/__tests__/ScreenFeedLoader.test.tsx +94 -0
  62. package/Components/ScreenFeedLoader/index.ts +1 -0
  63. package/Components/ScreenResolver/__tests__/screenResolver.test.js +24 -0
  64. package/Components/ScreenResolver/hooks/index.ts +3 -0
  65. package/Components/ScreenResolver/hooks/useGetComponent.ts +15 -0
  66. package/Components/ScreenResolver/hooks/useScreenComponentResolver.tsx +90 -0
  67. package/Components/ScreenResolver/index.tsx +15 -117
  68. package/Components/ScreenResolver/utils/__tests__/getScreenTypeProps.test.ts +45 -0
  69. package/Components/ScreenResolver/utils/getScreenTypeProps.ts +43 -0
  70. package/Components/ScreenResolver/utils/index.ts +1 -0
  71. package/Components/ScreenResolver/withDefaultScreenContext.tsx +16 -0
  72. package/Components/ScreenResolverFeedProvider/ScreenResolverFeedProvider.tsx +25 -0
  73. package/Components/ScreenResolverFeedProvider/__tests__/ScreenResolverFeedProvider.test.tsx +44 -0
  74. package/Components/ScreenResolverFeedProvider/index.ts +1 -0
  75. package/Components/Tabs/TabContent.tsx +7 -4
  76. package/Components/Transitioner/Scene.tsx +9 -15
  77. package/Components/VideoLive/LiveImageManager.ts +199 -54
  78. package/Components/VideoLive/PlayerLiveImageComponent.tsx +31 -33
  79. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +2 -17
  80. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +0 -2
  81. package/Components/Viewport/ViewportAware/index.tsx +16 -7
  82. package/Components/ZappUIComponent/index.tsx +12 -6
  83. package/Components/default-cell-renderer/viewTrees/mobile/index.ts +0 -3
  84. package/Components/index.js +1 -1
  85. package/Contexts/ScreenContext/__tests__/index.test.tsx +57 -0
  86. package/Contexts/ScreenContext/index.tsx +71 -19
  87. package/Contexts/ZappPipesContext/ZappPipesContextFactory.tsx +18 -7
  88. package/Decorators/ZappPipesDataConnector/ResolverSelector.tsx +25 -7
  89. package/Decorators/ZappPipesDataConnector/__tests__/ResolverSelector.test.tsx +212 -5
  90. package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +39 -21
  91. package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +18 -7
  92. package/events/index.ts +2 -0
  93. package/events/scrollEndReached.ts +15 -0
  94. package/package.json +5 -5
  95. package/Components/MasterCell/DefaultComponents/Text/utils/__tests__/withAdjustedLineHeight.test.ts +0 -46
  96. package/Components/MasterCell/DefaultComponents/Text/utils/index.ts +0 -21
  97. package/Components/PlayerContainer/ErrorDisplay/ErrorDisplay.tsx +0 -57
  98. package/Components/PlayerContainer/ErrorDisplay/index.ts +0 -9
  99. package/Components/PlayerContainer/useRestrictMobilePlayback.tsx +0 -101
  100. /package/Components/HookRenderer/{index.tsx → index.ts} +0 -0
@@ -0,0 +1,90 @@
1
+ import * as React from "react";
2
+ import { path, prop } from "ramda";
3
+ import {
4
+ findPluginByType,
5
+ findPluginByIdentifier,
6
+ } from "@applicaster/zapp-react-native-utils/pluginUtils";
7
+ import { HandlePlayable } from "../../HandlePlayable";
8
+ import { HookRenderer } from "../../HookRenderer";
9
+ import { LinkHandler } from "../../LinkHandler";
10
+ import { Favorites } from "../../Favorites";
11
+ import { usePlugins } from "@applicaster/zapp-react-native-redux/hooks";
12
+ import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
13
+
14
+ import { useCallbackActions } from "@applicaster/zapp-react-native-utils/zappFrameworkUtils/HookCallback/useCallbackActions";
15
+ import { useGetComponent } from "./useGetComponent";
16
+ import { getScreenTypeProps } from "../utils";
17
+
18
+ export enum PresentationType {
19
+ Standalone = "Standalone",
20
+ Hook = "Hook",
21
+ }
22
+
23
+ const screenTypeComponents = {
24
+ favorites: Favorites,
25
+ link: LinkHandler,
26
+ playable: HandlePlayable,
27
+ hooks: HookRenderer,
28
+ };
29
+
30
+ export const useScreenComponentResolver = (screenType, props) => {
31
+ const plugins = usePlugins();
32
+ const { hookPlugin } = props.screenData || {};
33
+ const component = useGetComponent(screenType);
34
+
35
+ const screenAction = useCallbackActions(
36
+ hookPlugin || props.screenData,
37
+ props.screenData.callback
38
+ );
39
+
40
+ const {
41
+ videoModalState: { mode },
42
+ } = useNavigation();
43
+
44
+ const componentProps = {
45
+ ...props,
46
+ mode,
47
+ screenAction,
48
+ };
49
+
50
+ const ScreenTypeComponent = screenTypeComponents?.[screenType];
51
+
52
+ if (ScreenTypeComponent) {
53
+ return (
54
+ <ScreenTypeComponent
55
+ {...getScreenTypeProps(screenType, componentProps)}
56
+ />
57
+ );
58
+ }
59
+
60
+ const ScreenPlugin =
61
+ findPluginByType(screenType, plugins, { skipWarning: true }) ||
62
+ findPluginByIdentifier(screenType, plugins) ||
63
+ findPluginByIdentifier(hookPlugin && hookPlugin.identifier, plugins) ||
64
+ component;
65
+
66
+ const ScreenComponent =
67
+ path(["module", "Component"], ScreenPlugin) ||
68
+ prop("module", ScreenPlugin) ||
69
+ prop("Component", ScreenPlugin) ||
70
+ ScreenPlugin;
71
+
72
+ const configuration =
73
+ prop("configuration", ScreenPlugin) ||
74
+ prop("__plugin_configuration", ScreenComponent);
75
+
76
+ if (!ScreenComponent) {
77
+ return null;
78
+ }
79
+
80
+ return (
81
+ <ScreenComponent
82
+ {...props}
83
+ callback={props.resultCallback || screenAction}
84
+ screenId={props.screenId}
85
+ screenData={props.screenData}
86
+ presentationType={PresentationType.Standalone}
87
+ configuration={configuration}
88
+ />
89
+ );
90
+ };
@@ -1,29 +1,17 @@
1
1
  import * as React from "react";
2
- import { path, prop } from "ramda";
3
- import {
4
- findPluginByType,
5
- findPluginByIdentifier,
6
- } from "@applicaster/zapp-react-native-utils/pluginUtils";
7
- import { HandlePlayable } from "../HandlePlayable";
8
- import { toPascalCase } from "@applicaster/zapp-react-native-utils/stringUtils";
9
- import { HookRenderer } from "../HookRenderer";
10
- import { LinkHandler } from "../LinkHandler";
11
- import { Favorites } from "../Favorites";
12
- import { ZappPipesScreenContext } from "../../Contexts";
2
+
13
3
  import { componentsLogger } from "../../Helpers/logger";
14
- import {
15
- useAppSelector,
16
- usePlugins,
17
- } from "@applicaster/zapp-react-native-redux/hooks";
18
- import {
19
- useNavigation,
20
- useRivers,
21
- } from "@applicaster/zapp-react-native-utils/reactHooks";
4
+
22
5
  import { useScreenAnalytics } from "@applicaster/zapp-react-native-utils/analyticsUtils/helpers/hooks";
23
6
 
24
- import { useCallbackActions } from "@applicaster/zapp-react-native-utils/zappFrameworkUtils/HookCallback/useCallbackActions";
25
7
  import { ScreenResultCallback } from "@applicaster/zapp-react-native-utils/zappFrameworkUtils/HookCallback/callbackNavigationAction";
26
- import { selectComponents } from "@applicaster/zapp-react-native-redux";
8
+ import { useScreenComponentResolver } from "./hooks/useScreenComponentResolver";
9
+ import { withDefaultScreenContext } from "./withDefaultScreenContext";
10
+
11
+ export enum PresentationType {
12
+ Standalone = "Standalone",
13
+ Hook = "Hook",
14
+ }
27
15
 
28
16
  const logger = componentsLogger.addSubsystem("ScreenResolver");
29
17
 
@@ -44,102 +32,14 @@ type Props = {
44
32
  groupId?: string;
45
33
  };
46
34
 
47
- export enum PresentationType {
48
- Standalone = "Standalone",
49
- Hook = "Hook",
50
- }
51
-
52
35
  export function ScreenResolverComponent(props: Props) {
53
- useScreenAnalytics(props);
54
-
55
- const { screenType, screenId, screenData, groupId } = props;
56
-
57
- const { hookPlugin } = screenData || {};
58
-
59
- const plugins = usePlugins();
60
- const rivers = useRivers();
61
-
62
- const components = useAppSelector(selectComponents);
36
+ const { screenType } = props;
37
+ const component = useScreenComponentResolver(screenType, props);
63
38
 
64
- const {
65
- videoModalState: { mode },
66
- } = useNavigation();
67
-
68
- const [, setScreenContext] = ZappPipesScreenContext.useZappPipesContext();
69
-
70
- React.useEffect(() => {
71
- setScreenContext(rivers[screenId]);
72
- }, [rivers, screenId, setScreenContext]);
73
-
74
- const parentCallback = props.resultCallback;
75
-
76
- const screenAction = useCallbackActions(
77
- hookPlugin || screenData,
78
- screenData.callback
79
- );
80
-
81
- const callbackAction = parentCallback || screenAction;
82
-
83
- const ScreenPlugin =
84
- findPluginByType(screenType, plugins, { skipWarning: true }) ||
85
- findPluginByIdentifier(screenType, plugins) ||
86
- findPluginByIdentifier(hookPlugin && hookPlugin.identifier, plugins) ||
87
- components[toPascalCase(screenType)];
88
-
89
- if (screenType === "favorites") {
90
- return <Favorites screenData={screenData} />;
91
- }
92
-
93
- if (screenType === "link") {
94
- return <LinkHandler screenData={screenData} />;
95
- }
96
-
97
- if (screenType === "playable") {
98
- return (
99
- // @ts-ignore
100
- <HandlePlayable
101
- item={screenData}
102
- mode={mode === "PIP" ? "PIP" : "FULLSCREEN"}
103
- isModal={false}
104
- groupId={groupId}
105
- />
106
- );
107
- }
108
-
109
- if (hookPlugin || screenType === "hooks") {
110
- return (
111
- screenData && (
112
- <HookRenderer
113
- callback={callbackAction}
114
- screenData={screenData}
115
- focused={props.focused}
116
- parentFocus={props.parentFocus as ParentFocus}
117
- />
118
- )
119
- );
120
- }
121
-
122
- const ScreenComponent =
123
- path(["module", "Component"], ScreenPlugin) ||
124
- prop("module", ScreenPlugin) ||
125
- prop("Component", ScreenPlugin) ||
126
- ScreenPlugin;
127
-
128
- const configuration =
129
- prop("configuration", ScreenPlugin) ||
130
- prop("__plugin_configuration", ScreenComponent);
39
+ useScreenAnalytics(props);
131
40
 
132
- if (ScreenComponent) {
133
- return (
134
- <ScreenComponent
135
- {...props}
136
- callback={callbackAction}
137
- screenId={screenId}
138
- screenData={screenData}
139
- configuration={configuration}
140
- presentationType={PresentationType.Standalone}
141
- />
142
- );
41
+ if (component) {
42
+ return component;
143
43
  }
144
44
 
145
45
  logger.warning({
@@ -150,6 +50,4 @@ export function ScreenResolverComponent(props: Props) {
150
50
  return null;
151
51
  }
152
52
 
153
- export const ScreenResolver = ZappPipesScreenContext.withProvider(
154
- ScreenResolverComponent
155
- );
53
+ export const ScreenResolver = withDefaultScreenContext(ScreenResolverComponent);
@@ -0,0 +1,45 @@
1
+ import { getScreenTypeProps } from "../getScreenTypeProps";
2
+
3
+ const baseProps = {
4
+ screenData: { id: "entry-1" },
5
+ mode: "PIP",
6
+ screenId: "screen-1",
7
+ groupId: "group-1",
8
+ focused: true,
9
+ parentFocus: { nextFocusDown: { current: null } },
10
+ screenAction: jest.fn(),
11
+ resultCallback: null,
12
+ };
13
+
14
+ describe("getScreenTypeProps", () => {
15
+ it("returns props for favorites/link", () => {
16
+ expect(getScreenTypeProps("favorites", baseProps)).toEqual({
17
+ screenData: baseProps.screenData,
18
+ });
19
+
20
+ expect(getScreenTypeProps("link", baseProps)).toEqual({
21
+ screenData: baseProps.screenData,
22
+ });
23
+ });
24
+
25
+ it("returns props for playable", () => {
26
+ expect(getScreenTypeProps("playable", baseProps)).toEqual({
27
+ item: baseProps.screenData,
28
+ mode: "PIP",
29
+ isModal: false,
30
+ groupId: "group-1",
31
+ });
32
+ });
33
+
34
+ it("returns props for hooks", () => {
35
+ const result = getScreenTypeProps("hooks", baseProps);
36
+
37
+ expect(result).toMatchObject({
38
+ screenData: baseProps.screenData,
39
+ focused: true,
40
+ parentFocus: baseProps.parentFocus,
41
+ });
42
+
43
+ expect(result.callback).toBe(baseProps.screenAction);
44
+ });
45
+ });
@@ -0,0 +1,43 @@
1
+ export const getScreenTypeProps = (
2
+ screenType: "favorites" | "link" | "playable" | "hooks",
3
+ props
4
+ ) => {
5
+ const {
6
+ screenData,
7
+ mode,
8
+ screenId,
9
+ groupId,
10
+ focused,
11
+ parentFocus,
12
+ screenAction,
13
+ resultCallback,
14
+ } = props;
15
+
16
+ switch (screenType) {
17
+ case "favorites":
18
+ case "link":
19
+ return {
20
+ screenData,
21
+ };
22
+ case "playable":
23
+ return {
24
+ item: screenData,
25
+ mode: mode === "PIP" ? "PIP" : "FULLSCREEN",
26
+ isModal: false,
27
+ groupId: groupId,
28
+ };
29
+ case "hooks":
30
+ return {
31
+ screenData,
32
+ callback: resultCallback || screenAction,
33
+ focused,
34
+ parentFocus: parentFocus as ParentFocus,
35
+ };
36
+ default:
37
+ return {
38
+ callback: resultCallback || screenAction,
39
+ screenId: screenId,
40
+ screenData,
41
+ };
42
+ }
43
+ };
@@ -0,0 +1 @@
1
+ export { getScreenTypeProps } from "./getScreenTypeProps";
@@ -0,0 +1,16 @@
1
+ import * as React from "react";
2
+ import { useRivers } from "@applicaster/zapp-react-native-utils/reactHooks";
3
+ import { ZappPipesScreenContext } from "../../Contexts";
4
+
5
+ export function withDefaultScreenContext(Component: React.ComponentType<any>) {
6
+ return function WithDefaultScreenContext(props: any) {
7
+ const screenId = props.screenId;
8
+ const rivers = useRivers();
9
+
10
+ return (
11
+ <ZappPipesScreenContext.Provider initialContextValue={rivers[screenId]}>
12
+ <Component {...props} />
13
+ </ZappPipesScreenContext.Provider>
14
+ );
15
+ };
16
+ }
@@ -0,0 +1,25 @@
1
+ import React from "react";
2
+ import { ScreenFeedLoader } from "../ScreenFeedLoader/ScreenFeedLoader";
3
+
4
+ /** Resolves screen-feed for a given screen `id` by using the provided `useFeedData` hook */
5
+ export const ScreenResolverFeedProvider = ({
6
+ id,
7
+ children,
8
+ useFeedData,
9
+ }: {
10
+ id: string;
11
+ children: React.ReactNode;
12
+ useFeedData: (id: string) => Option<ZappDataSource>;
13
+ }) => {
14
+ const feedData = useFeedData(id);
15
+
16
+ if (feedData?.source) {
17
+ return (
18
+ <ScreenFeedLoader id={id} feedData={feedData}>
19
+ {children}
20
+ </ScreenFeedLoader>
21
+ );
22
+ } else {
23
+ return <>{children}</>;
24
+ }
25
+ };
@@ -0,0 +1,44 @@
1
+ import React from "react";
2
+ import { Text } from "react-native";
3
+ import { render } from "@testing-library/react-native";
4
+ import { ScreenResolverFeedProvider } from "../ScreenResolverFeedProvider";
5
+
6
+ jest.mock("../../ScreenFeedLoader/ScreenFeedLoader", () => ({
7
+ ScreenFeedLoader: ({ children }) => {
8
+ const React = require("react");
9
+ const { View } = require("react-native");
10
+
11
+ return <View testID="feed-loader">{children}</View>;
12
+ },
13
+ }));
14
+
15
+ describe("ScreenResolverFeedProvider", () => {
16
+ it("renders ScreenFeedLoader when screen feed source exists", () => {
17
+ const useFeedData = jest.fn(() => ({
18
+ source: "https://feed",
19
+ mapping: {},
20
+ }));
21
+
22
+ const { getByTestId, getByText } = render(
23
+ <ScreenResolverFeedProvider id="screen-1" useFeedData={useFeedData}>
24
+ <Text>content</Text>
25
+ </ScreenResolverFeedProvider>
26
+ );
27
+
28
+ expect(getByTestId("feed-loader")).toBeDefined();
29
+ expect(getByText("content")).toBeDefined();
30
+ });
31
+
32
+ it("renders children directly when screen feed source is missing", () => {
33
+ const useFeedData = jest.fn(() => ({}));
34
+
35
+ const { queryByTestId, getByText } = render(
36
+ <ScreenResolverFeedProvider id="screen-1" useFeedData={useFeedData}>
37
+ <Text>content</Text>
38
+ </ScreenResolverFeedProvider>
39
+ );
40
+
41
+ expect(queryByTestId("feed-loader")).toBeNull();
42
+ expect(getByText("content")).toBeDefined();
43
+ });
44
+ });
@@ -0,0 +1 @@
1
+ export { ScreenResolverFeedProvider } from "./ScreenResolverFeedProvider";
@@ -1,11 +1,10 @@
1
1
  import React from "react";
2
- import { View, ViewStyle } from "react-native";
2
+ import { View, StyleSheet } from "react-native";
3
3
 
4
4
  import { River } from "@applicaster/zapp-react-native-ui-components/Components";
5
5
  import { withNestedNavigationContextProvider } from "@applicaster/zapp-react-native-ui-components/Contexts/NestedNavigationContext";
6
6
 
7
7
  type Props = {
8
- styles: Record<string, ViewStyle>;
9
8
  minHeight: number;
10
9
  changingTab: boolean;
11
10
  feedUrl: string;
@@ -14,9 +13,14 @@ type Props = {
14
13
  backgroundColor: string;
15
14
  };
16
15
 
16
+ const styles = StyleSheet.create({
17
+ riverWrapper: {
18
+ flex: 1,
19
+ },
20
+ });
21
+
17
22
  function TabContentComponent(props: Props) {
18
23
  const {
19
- styles,
20
24
  minHeight,
21
25
  backgroundColor,
22
26
  changingTab,
@@ -29,7 +33,6 @@ function TabContentComponent(props: Props) {
29
33
  <View
30
34
  style={[
31
35
  styles.riverWrapper,
32
-
33
36
  {
34
37
  backgroundColor,
35
38
  minHeight,
@@ -1,9 +1,9 @@
1
- import React, { useEffect } from "react";
1
+ import React from "react";
2
2
  import { equals } from "ramda";
3
3
  import { Animated, ViewProps, ViewStyle } from "react-native";
4
- import { useSafeAreaFrame } from "react-native-safe-area-context";
5
4
 
6
5
  import { useScreenOrientationHandler } from "@applicaster/zapp-react-native-ui-components/Components/Screen/orientationHandler";
6
+ import { useMemoizedSafeAreaFrameWithActiveState } from "@applicaster/zapp-react-native-ui-components/Components/Screen/hooks";
7
7
 
8
8
  import { PathnameContext } from "../../Contexts/PathnameContext";
9
9
  import { ScreenDataContext } from "../../Contexts/ScreenDataContext";
@@ -94,19 +94,13 @@ function SceneComponent({
94
94
  isActive,
95
95
  });
96
96
 
97
- const frame = useSafeAreaFrame();
98
-
99
- const [memoFrame, setMemoFrame] = React.useState(frame);
100
-
101
- useEffect(() => {
102
- if (isActive) {
103
- setMemoFrame((oldFrame) =>
104
- oldFrame.width === frame.width && oldFrame.height === frame.height
105
- ? oldFrame
106
- : frame
107
- );
108
- }
109
- }, [isActive, frame.width, frame.height]);
97
+ // Use shared memoized frame hook - synchronized with useWaitForValidOrientation
98
+ // to prevent race conditions during orientation changes
99
+ // Pass isActive from props since Scene knows its active state from Transitioner
100
+ const memoFrame = useMemoizedSafeAreaFrameWithActiveState({
101
+ updateForInactiveScreens: false,
102
+ isActive,
103
+ });
110
104
 
111
105
  const isAnimating = animating && overlayStyle;
112
106