@applicaster/zapp-react-native-ui-components 14.0.12-alpha.2403570255 → 14.0.12-alpha.3738385159

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.
@@ -1,13 +1,17 @@
1
1
  import * as React from "react";
2
2
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
3
- import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
3
+ import {
4
+ useDimensions,
5
+ useIsTablet as isTablet,
6
+ useNavigation,
7
+ } from "@applicaster/zapp-react-native-utils/reactHooks";
4
8
 
5
9
  import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
6
10
  import { PlayerContainer } from "../PlayerContainer";
7
11
  import { useModalSize } from "../VideoModal/hooks";
8
12
  import { ViewStyle } from "react-native";
13
+ import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
9
14
  import { findCastPlugin, getPlayer } from "./utils";
10
- import { useWaitForValidOrientation } from "../Screen/hooks";
11
15
 
12
16
  type Props = {
13
17
  item: ZappEntry;
@@ -22,6 +26,13 @@ type PlayableComponent = {
22
26
  Component: React.ComponentType<any>;
23
27
  };
24
28
 
29
+ const dimensionsContext: "window" | "screen" = platformSelect({
30
+ android_tv: "window",
31
+ amazon: "window",
32
+ // eslint-disable-next-line react-hooks/rules-of-hooks
33
+ default: isTablet() ? "window" : "screen", // on tablet, window represents correct values, on phone it's not as the screen could be rotated
34
+ });
35
+
25
36
  export function HandlePlayable({
26
37
  item,
27
38
  isModal,
@@ -83,23 +94,27 @@ export function HandlePlayable({
83
94
  });
84
95
  }, [casting]);
85
96
 
86
- const modalSize = useModalSize();
87
-
88
- const isOrientationReady = useWaitForValidOrientation();
97
+ const { width: screenWidth, height: screenHeight } =
98
+ useDimensions(dimensionsContext);
89
99
 
90
- const style = React.useMemo(() => {
91
- const isFullScreenReady =
92
- mode === "PIP" || (mode === "FULLSCREEN" && isOrientationReady);
93
-
94
- const getDimensionValue = (value: string | number) => {
95
- return isModal ? value : isFullScreenReady ? "100%" : 0; // do not show player, until full screen mode is ready
96
- };
100
+ const modalSize = useModalSize();
97
101
 
98
- return {
99
- width: getDimensionValue(modalSize.width),
100
- height: getDimensionValue(modalSize.height),
101
- } as ViewStyle;
102
- }, [modalSize, isModal, mode, isOrientationReady]);
102
+ const style = React.useMemo(
103
+ () =>
104
+ ({
105
+ width: isModal
106
+ ? modalSize.width
107
+ : mode === "PIP"
108
+ ? "100%"
109
+ : screenWidth,
110
+ height: isModal
111
+ ? modalSize.height
112
+ : mode === "PIP"
113
+ ? "100%"
114
+ : screenHeight,
115
+ }) as ViewStyle,
116
+ [screenWidth, screenHeight, modalSize, isModal, mode]
117
+ );
103
118
 
104
119
  const Component = playable?.Component;
105
120
 
@@ -14,7 +14,6 @@ const mockIsOrientationCompatible = jest.fn(() => true);
14
14
 
15
15
  jest.mock("react-native-safe-area-context", () => ({
16
16
  useSafeAreaInsets: () => ({ top: 44 }),
17
- useSafeAreaFrame: () => ({ x: 0, y: 0, width: 375, height: 812 }),
18
17
  }));
19
18
 
20
19
  jest.mock("../../RouteManager", () => ({
@@ -5,85 +5,15 @@ import {
5
5
  } from "@applicaster/zapp-react-native-utils/appUtils/orientationHelper";
6
6
  import {
7
7
  useCurrentScreenData,
8
+ useDimensions,
8
9
  useRoute,
9
10
  useIsTablet,
10
- useIsScreenActive,
11
11
  } from "@applicaster/zapp-react-native-utils/reactHooks";
12
12
  import { useMemo, useEffect, useState } from "react";
13
- import { useSafeAreaFrame } from "react-native-safe-area-context";
14
-
15
- type MemoizedSafeAreaFrameWithActiveStateOptions = {
16
- updateForInactiveScreens?: boolean;
17
- isActive: boolean;
18
- };
19
-
20
- /**
21
- * Base hook that wraps useSafeAreaFrame with memoization and inactive screen filtering.
22
- * Requires isActive to be passed explicitly - use useMemoizedSafeAreaFrame for automatic detection.
23
- *
24
- * @param options.updateForInactiveScreens - If false, frame won't update when screen is inactive (default: true)
25
- * @param options.isActive - Whether the screen is currently active
26
- * @returns The memoized safe area frame { x, y, width, height }
27
- */
28
- export const useMemoizedSafeAreaFrameWithActiveState = (
29
- options: MemoizedSafeAreaFrameWithActiveStateOptions
30
- ) => {
31
- const { updateForInactiveScreens = true, isActive } = options;
32
- const frame = useSafeAreaFrame();
33
-
34
- const [memoFrame, setMemoFrame] = useState(frame);
35
-
36
- useEffect(() => {
37
- const shouldUpdate = isActive || updateForInactiveScreens;
38
-
39
- const dimensionsChanged =
40
- frame.width !== memoFrame.width || frame.height !== memoFrame.height;
41
-
42
- if (shouldUpdate && dimensionsChanged) {
43
- setMemoFrame(frame);
44
- }
45
- }, [
46
- frame.width,
47
- frame.height,
48
- isActive,
49
- updateForInactiveScreens,
50
- frame,
51
- memoFrame.width,
52
- memoFrame.height,
53
- ]);
54
-
55
- return memoFrame;
56
- };
57
-
58
- type MemoizedSafeAreaFrameOptions = {
59
- updateForInactiveScreens?: boolean;
60
- };
61
-
62
- /**
63
- * Hook that wraps useSafeAreaFrame with memoization and inactive screen filtering.
64
- * Uses useIsScreenActive() internally to determine active state - use useMemoizedSafeAreaFrameWithActiveState
65
- * if you need to pass isActive explicitly.
66
- *
67
- * @param options.updateForInactiveScreens - If false, frame won't update when screen is inactive (default: true)
68
- * @returns The memoized safe area frame { x, y, width, height }
69
- */
70
- export const useMemoizedSafeAreaFrame = (
71
- options: MemoizedSafeAreaFrameOptions = {}
72
- ) => {
73
- const { updateForInactiveScreens = true } = options;
74
- const isActive = useIsScreenActive();
75
-
76
- return useMemoizedSafeAreaFrameWithActiveState({
77
- updateForInactiveScreens,
78
- isActive,
79
- });
80
- };
81
13
 
82
14
  export const useWaitForValidOrientation = () => {
83
- // Use memoized safe area frame to synchronize with Scene's dimension source
84
- // This prevents race conditions where the orientation check passes before
85
- // Scene's memoFrame has updated to the new dimensions
86
- const { width: screenWidth, height } = useMemoizedSafeAreaFrame({
15
+ const { width: screenWidth, height } = useDimensions("screen", {
16
+ fullDimensions: true,
87
17
  updateForInactiveScreens: false,
88
18
  });
89
19
 
@@ -93,13 +93,7 @@ export function Screen(_props: Props) {
93
93
  const isActive = useIsScreenActive();
94
94
 
95
95
  const ref = React.useRef(null);
96
- const isOrientationReady = useWaitForValidOrientation();
97
-
98
- // Playable screens handle their own orientation via the native player plugin,
99
- // so we skip the orientation wait gate to avoid a deadlock where the screen
100
- // waits for landscape but blocks rendering that would trigger the rotation.
101
- const isPlayableRoute = pathname?.includes("/playable");
102
- const isReady = isOrientationReady || isPlayableRoute;
96
+ const isReady = useWaitForValidOrientation();
103
97
 
104
98
  React.useEffect(() => {
105
99
  if (ref.current && isActive && isReady) {
@@ -1,9 +1,9 @@
1
- import React from "react";
1
+ import React, { useEffect } 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";
4
5
 
5
6
  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,13 +94,19 @@ function SceneComponent({
94
94
  isActive,
95
95
  });
96
96
 
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
- });
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]);
104
110
 
105
111
  const isAnimating = animating && overlayStyle;
106
112
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "14.0.12-alpha.2403570255",
3
+ "version": "14.0.12-alpha.3738385159",
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",
@@ -28,10 +28,10 @@
28
28
  },
29
29
  "homepage": "https://github.com/applicaster/quickbrick#readme",
30
30
  "dependencies": {
31
- "@applicaster/applicaster-types": "14.0.12-alpha.2403570255",
32
- "@applicaster/zapp-react-native-bridge": "14.0.12-alpha.2403570255",
33
- "@applicaster/zapp-react-native-redux": "14.0.12-alpha.2403570255",
34
- "@applicaster/zapp-react-native-utils": "14.0.12-alpha.2403570255",
31
+ "@applicaster/applicaster-types": "14.0.12-alpha.3738385159",
32
+ "@applicaster/zapp-react-native-bridge": "14.0.12-alpha.3738385159",
33
+ "@applicaster/zapp-react-native-redux": "14.0.12-alpha.3738385159",
34
+ "@applicaster/zapp-react-native-utils": "14.0.12-alpha.3738385159",
35
35
  "fast-json-stable-stringify": "^2.1.0",
36
36
  "promise": "^8.3.0",
37
37
  "url": "^0.11.0",