@applicaster/zapp-react-native-ui-components 13.0.6-alpha.9045435588 → 14.0.0-alpha.1015356256

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 (27) hide show
  1. package/Components/AudioPlayer/tv/Layout.tsx +4 -2
  2. package/Components/Cell/index.js +6 -2
  3. package/Components/Focusable/Focusable.tsx +8 -2
  4. package/Components/Focusable/FocusableiOS.tsx +1 -1
  5. package/Components/Focusable/__tests__/index.android.test.tsx +3 -0
  6. package/Components/Focusable/index.android.tsx +12 -8
  7. package/Components/GeneralContentScreen/GeneralContentScreen.tsx +0 -2
  8. package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -27
  9. package/Components/MasterCell/DefaultComponents/Text/index.tsx +1 -0
  10. package/Components/PlayerContainer/PlayerContainer.tsx +17 -15
  11. package/Components/River/TV/River.tsx +0 -3
  12. package/Components/TopMarginApplicator/TopMarginApplicator.tsx +16 -15
  13. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +9 -1
  14. package/Components/VideoModal/PlayerDetails.tsx +24 -2
  15. package/Components/VideoModal/PlayerWrapper.tsx +26 -142
  16. package/Components/VideoModal/VideoModal.tsx +3 -17
  17. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -7
  18. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +44 -240
  19. package/Components/VideoModal/hooks/index.ts +0 -2
  20. package/Components/VideoModal/hooks/useModalSize.ts +18 -2
  21. package/Components/VideoModal/utils.ts +6 -0
  22. package/Components/Viewport/VisibilitySensor/VisibilitySensor.tsx +3 -3
  23. package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/index.ts +3 -3
  24. package/index.d.ts +0 -1
  25. package/package.json +5 -9
  26. package/Components/VideoModal/hooks/useBackgroundColor.ts +0 -10
  27. package/Decorators/Navigator/__tests__/react-router-native-mock.js +0 -11
@@ -110,22 +110,24 @@ export function AudioPlayerTVLayout({
110
110
  ...style,
111
111
  },
112
112
  samsung_tv: {
113
+ position: "absolute",
113
114
  margin: "auto",
114
115
  display: "flex",
115
116
  flexWrap: "wrap",
117
+ height: "100vh",
116
118
  width: "100vw",
117
- flex: 1,
118
119
  alignItems: "center",
119
120
  justifyContent: "center",
120
121
  flexDirection: directionStyles(isRTL).flexDirection,
121
122
  backgroundColor: backgroundColorStyle,
122
123
  },
123
124
  lg_tv: {
125
+ position: "absolute",
124
126
  margin: "auto",
125
127
  display: "flex",
126
128
  flexWrap: "wrap",
129
+ height: "100vh",
127
130
  width: "100vw",
128
- flex: 1,
129
131
  alignItems: "center",
130
132
  justifyContent: "center",
131
133
  flexDirection: directionStyles(isRTL).flexDirection,
@@ -3,11 +3,15 @@ import * as R from "ramda";
3
3
  import { connectToStore } from "@applicaster/zapp-react-native-redux";
4
4
  import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
5
5
 
6
- import { HorizontalScrollContext, RiverOffsetContext } from "../../Contexts";
6
+ import {
7
+ HorizontalScrollContext,
8
+ RiverOffsetContext,
9
+ ScreenScrollingContext,
10
+ } from "../../Contexts";
11
+
7
12
  import { CellComponent } from "./Cell";
8
13
  import { TvOSCellComponent } from "./TvOSCellComponent";
9
14
  import { withConsumer } from "../../Contexts/HeaderOffsetContext";
10
- import { ScreenScrollingContext } from "../../Contexts/ScreenScrollingContext";
11
15
 
12
16
  import { ScreenLayoutContextConsumer } from "../../Contexts/ScreenLayoutContext";
13
17
  import { createContext } from "@applicaster/zapp-react-native-utils/reactUtils/createContext";
@@ -5,6 +5,7 @@ import { BaseFocusable } from "../BaseFocusable";
5
5
  import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
6
6
  import { LONG_KEY_PRESS_TIMEOUT } from "@applicaster/quick-brick-core/const";
7
7
  import { withFocusableContext } from "../../Contexts/FocusableGroupContext/withFocusableContext";
8
+ import { StyleSheet, ViewStyle } from "react-native";
8
9
  import { AccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager";
9
10
 
10
11
  type Props = {
@@ -22,7 +23,12 @@ type Props = {
22
23
  handleFocus?: ({ mouse }: { mouse: boolean }) => void;
23
24
  children: (boolean, string) => React.ComponentType<any>;
24
25
  selected?: boolean;
25
- style?: React.CSSProperties;
26
+ style?: ViewStyle[] | ViewStyle;
27
+ "aria-label"?: string;
28
+ "aria-description"?: string;
29
+ "aria-role"?: string;
30
+ role?: string;
31
+ tabindex?: number;
26
32
  };
27
33
 
28
34
  class Focusable extends BaseFocusable<Props> {
@@ -146,7 +152,7 @@ class Focusable extends BaseFocusable<Props> {
146
152
  onMouseUp={this.pressOut}
147
153
  data-testid={focusableId}
148
154
  focused-teststate={focused ? "focused" : "default"}
149
- style={style}
155
+ style={StyleSheet.flatten(style) as any as React.CSSProperties}
150
156
  {...accessibilityProps}
151
157
  >
152
158
  {children(focused, { mouse: this.mouse })}
@@ -12,4 +12,4 @@ function FocusableiOSComponent({ children }: Props) {
12
12
  return children;
13
13
  }
14
14
 
15
- export const FocusableiOS = React.forwardRef(FocusableiOSComponent);
15
+ export const FocusableiOS = FocusableiOSComponent;
@@ -38,6 +38,9 @@ describe("Focusable", () => {
38
38
  });
39
39
 
40
40
  it("updates disableFocus state when disableFocus prop changes", () => {
41
+ const unregister = jest.fn();
42
+ mockFocusManager.registerFocusable.mockReturnValue(unregister);
43
+
41
44
  const { rerender } = render(
42
45
  <Focusable id="test-id" disableFocus={false}>
43
46
  <Touchable testID="touchable" />
@@ -43,11 +43,13 @@ export const FocusableContext = React.createContext<
43
43
  // eslint-disable-next-line
44
44
  setIsFocusable: (enableFocus: boolean) => void;
45
45
  ref: FocusManager.FocusableRef;
46
+ parentFocusableId: Option<string>;
46
47
  } & ParentFocus
47
48
  >({
48
49
  focused: false,
49
50
  setIsFocusable: () => {},
50
51
  ref: { current: null },
52
+ parentFocusableId: undefined,
51
53
  });
52
54
 
53
55
  export const useFocusable = () => React.useContext(FocusableContext);
@@ -74,7 +76,7 @@ function FocusableComponent(props: Props, forwardedRef) {
74
76
 
75
77
  const isRTL = useIsRTL();
76
78
  const focusManager = useFocusManager();
77
- const { ref: parentFocusable } = useFocusable();
79
+ const { ref: parentFocusableRef, parentFocusableId } = useFocusable();
78
80
  const touchableRef = React.useRef(null);
79
81
 
80
82
  const [focused, setFocused] = React.useState(() =>
@@ -98,13 +100,14 @@ function FocusableComponent(props: Props, forwardedRef) {
98
100
  }
99
101
  }, [disableFocus]);
100
102
 
101
- React.useEffect(() => {
103
+ React.useLayoutEffect(() => {
102
104
  if (id) {
103
- const unregister = focusManager.registerFocusable(
105
+ const unregister = focusManager.registerFocusable({
104
106
  touchableRef,
105
- parentFocusable,
106
- isFocusableCell
107
- );
107
+ parentFocusableRef,
108
+ isFocusableCell,
109
+ parentFocusableId,
110
+ });
108
111
 
109
112
  onRegister();
110
113
 
@@ -112,7 +115,7 @@ function FocusableComponent(props: Props, forwardedRef) {
112
115
  unregister();
113
116
  };
114
117
  }
115
- }, [id, onRegister, isFocusableCell]);
118
+ }, [id, onRegister, isFocusableCell, parentFocusableId]);
116
119
 
117
120
  if (R.isNil(id)) {
118
121
  // eslint-disable-next-line no-console
@@ -164,8 +167,9 @@ function FocusableComponent(props: Props, forwardedRef) {
164
167
  ...parentFocus,
165
168
  ref: touchableRef,
166
169
  setIsFocusable,
170
+ parentFocusableId: id,
167
171
  };
168
- }, [parentFocus, focused]);
172
+ }, [parentFocus, focused, id]);
169
173
 
170
174
  return (
171
175
  <Touchable
@@ -30,7 +30,6 @@ export const GeneralContentScreen = ({
30
30
  isScreenWrappedInContainer,
31
31
  componentsMapExtraProps = {},
32
32
  focused,
33
- extraOffset,
34
33
  parentFocus,
35
34
  containerHeight,
36
35
  preferredFocus = false,
@@ -122,7 +121,6 @@ export const GeneralContentScreen = ({
122
121
  isScreenWrappedInContainer={isScreenWrappedInContainer}
123
122
  parentFocus={parentFocus}
124
123
  focused={focused}
125
- extraOffset={extraOffset}
126
124
  containerHeight={containerHeight}
127
125
  preferredFocus={preferredFocus}
128
126
  {...componentsMapExtraProps}
@@ -2,7 +2,6 @@ import React, { useMemo } from "react";
2
2
  import { ImageStyle } from "react-native";
3
3
  import { Focusable } from "@applicaster/zapp-react-native-ui-components/Components/Focusable";
4
4
  import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
5
- import * as R from "ramda";
6
5
  import { getXray } from "@applicaster/zapp-react-native-utils/logger";
7
6
  import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
8
7
  import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
@@ -67,32 +66,10 @@ export function FocusableView({ style, children, item, ...otherProps }: Props) {
67
66
  const handleFocus = (focusable) => {
68
67
  const focusedButtonId = getFocusedButtonId(focusable);
69
68
 
70
- wrapperRef?.current?.measure((x, y, width, height, pageX, pageY) => {
71
- const top = pageY;
72
- const bottom = top + height;
73
- const left = pageX;
74
- const right = left + width;
75
-
76
- const boundingRect = {
77
- x,
78
- y,
79
- pageX,
80
- pageY,
81
- width,
82
- height,
83
- top,
84
- bottom,
85
- left,
86
- right,
87
- };
88
-
89
- otherProps?.onToggleFocus?.({
90
- focusable: {
91
- getRect: R.always(boundingRect),
92
- },
93
- focusedButtonId,
94
- mouse: focusable.mouse,
95
- });
69
+ otherProps?.onToggleFocus?.({
70
+ focusable: wrapperRef.current,
71
+ focusedButtonId,
72
+ mouse: focusable.mouse,
96
73
  });
97
74
 
98
75
  if (ttsLabel) {
@@ -52,6 +52,7 @@ const _Text = ({
52
52
  withScaledLineHeight(withFocusedStyles({ style, otherProps })),
53
53
  { height },
54
54
  ]}
55
+ allowFontScaling={false}
55
56
  {...withoutLabel(otherProps)}
56
57
  >
57
58
  {dateTransformEnabled
@@ -88,7 +88,7 @@ export const VideoModalMode = {
88
88
  MAXIMIZED: "MAXIMIZED",
89
89
  MINIMIZED: "MINIMIZED",
90
90
  FULLSCREEN: "FULLSCREEN",
91
- };
91
+ } as const;
92
92
 
93
93
  export type PlayNextData = {
94
94
  state: PlayNextState;
@@ -105,11 +105,6 @@ const isTvOS = isTvOSPlatform();
105
105
  // height for container with additional content below player
106
106
  const INLINE_CONTAINER_CONTENT_HEIGHT = 400;
107
107
 
108
- // Default Y offset for anchor points on non-Android TV platforms
109
- const DEFAULT_OFFSET_Y = -600;
110
-
111
- const EXTRA_ANCHOR_POINT_Y_OFFSET = isAndroidTV ? 0 : DEFAULT_OFFSET_Y;
112
-
113
108
  const withBorderHack = () => {
114
109
  if (isAndroidTV) {
115
110
  /* @HACK: see GH#7269 */
@@ -132,7 +127,7 @@ const webStyles = {
132
127
  playerScreen: {
133
128
  flex: 1,
134
129
  height: "100vh",
135
- background: "black",
130
+ backgroundColor: "black",
136
131
  },
137
132
  playerWrapper: {
138
133
  height: "100%",
@@ -150,7 +145,6 @@ const nativeStyles = {
150
145
  },
151
146
  playerScreen: {
152
147
  flex: 1,
153
- backgroundColor: "black",
154
148
  overflow: "hidden",
155
149
  },
156
150
  playerWrapper: {
@@ -570,8 +564,9 @@ const PlayerContainerComponent = (props: Props) => {
570
564
  const isInlineTV = isInlineTVUtil(screenData);
571
565
 
572
566
  const inline =
573
- [VideoModalMode.MAXIMIZED, VideoModalMode.MINIMIZED].includes(mode) ||
574
- isInlineTV;
567
+ [VideoModalMode.MAXIMIZED, VideoModalMode.MINIMIZED].includes(
568
+ mode as any
569
+ ) || isInlineTV;
575
570
 
576
571
  const value = React.useMemo(
577
572
  () => ({ playerId: state.playerId }),
@@ -592,7 +587,11 @@ const PlayerContainerComponent = (props: Props) => {
592
587
  );
593
588
  }
594
589
 
595
- if (screen_background_color && mode !== VideoModalMode.FULLSCREEN) {
590
+ if (
591
+ screen_background_color &&
592
+ mode !== VideoModalMode.FULLSCREEN &&
593
+ isTV()
594
+ ) {
596
595
  updatedStyles.playerScreen.backgroundColor = screen_background_color;
597
596
  }
598
597
 
@@ -622,6 +621,8 @@ const PlayerContainerComponent = (props: Props) => {
622
621
  playNextData,
623
622
  };
624
623
 
624
+ const pointerEventsProp = mode === "MINIMIZED" ? "box-none" : "auto";
625
+
625
626
  return (
626
627
  <PlayerStateContext.Provider value={value}>
627
628
  <PlayerContainerContextProvider
@@ -642,14 +643,17 @@ const PlayerContainerComponent = (props: Props) => {
642
643
  preferredFocus
643
644
  shouldUsePreferredFocus
644
645
  groupId={groupId}
646
+ pointerEvents={pointerEventsProp}
645
647
  >
646
648
  {/* Video player and components */}
647
649
  <View
648
650
  style={styles.playerScreen}
649
651
  testID={"player-screen-container"}
652
+ pointerEvents={pointerEventsProp}
650
653
  >
651
654
  {/* Player container */}
652
655
  <View
656
+ pointerEvents={pointerEventsProp}
653
657
  style={[
654
658
  styles.playerWrapper,
655
659
  // eslint-disable-next-line react-native/no-inline-styles, react-native/no-color-literals
@@ -721,13 +725,11 @@ const PlayerContainerComponent = (props: Props) => {
721
725
  key={item.id}
722
726
  groupId={FocusableGroupMainContainerId}
723
727
  cellTapAction={onCellTap}
724
- extraAnchorPointYOffset={
725
- EXTRA_ANCHOR_POINT_Y_OFFSET
726
- }
728
+ extraAnchorPointYOffset={0}
727
729
  isScreenWrappedInContainer={true}
728
730
  containerHeight={styles.inlineRiver.height}
729
731
  componentsMapExtraProps={{
730
- isNestedComponentsMap: R.T,
732
+ isNestedComponentsMap: true,
731
733
  }}
732
734
  />
733
735
  )}
@@ -26,7 +26,6 @@ type Props = {
26
26
  componentsMapExtraProps?: any;
27
27
  isInsideContainer?: boolean;
28
28
  extraAnchorPointYOffset: number;
29
- extraOffset: number;
30
29
  river?: ZappRiver | ZappEntry;
31
30
  };
32
31
 
@@ -39,7 +38,6 @@ export const River = (props: Props) => {
39
38
  componentsMapExtraProps,
40
39
  isInsideContainer,
41
40
  extraAnchorPointYOffset,
42
- extraOffset,
43
41
  } = props;
44
42
 
45
43
  const { title: screenTitle, summary: screenSummary } = useNavbarState();
@@ -120,7 +118,6 @@ export const River = (props: Props) => {
120
118
  <GeneralContentScreen
121
119
  feed={feedData}
122
120
  screenId={screenId}
123
- extraOffset={extraOffset}
124
121
  isScreenWrappedInContainer={isInsideContainer}
125
122
  extraAnchorPointYOffset={extraAnchorPointYOffset}
126
123
  componentsMapExtraProps={componentsMapExtraProps}
@@ -1,17 +1,17 @@
1
1
  import React from "react";
2
- import { View, ViewProps, ViewStyle } from "react-native";
2
+ import { View, ViewStyle } from "react-native";
3
3
  import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
4
4
  import { useCurrentScreenData } from "@applicaster/zapp-react-native-utils/reactHooks";
5
5
  import { isFirstComponentScreenPicker } from "@applicaster/zapp-react-native-utils/componentsUtils";
6
+ import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
6
7
 
7
8
  interface IProps {
8
9
  targetScreenId?: string;
9
10
  children?: React.ReactNode;
10
11
  style?: ViewStyle;
11
- extraOffset?: number;
12
+ extraVerticalOffset: Option<number>;
12
13
  }
13
14
 
14
- type CombinedProps = IProps & ViewProps;
15
15
  /**
16
16
  * The MarginTop is essentially a feature used for managing the visibility of components on your screen.
17
17
  * A more accurate term for this might be something like a 'component visibility threshold' or 'cut-off point'.
@@ -47,7 +47,7 @@ export const useMarginTop = (targetScreenId: string): number => {
47
47
 
48
48
  // Empty string means that value is blank in the CMS. Fallback to theme
49
49
  if (String(screenData?.styles?.screen_margin_top) === "") {
50
- return Number(theme.screen_margin_top);
50
+ return toNumberWithDefault(0, theme.screen_margin_top);
51
51
  }
52
52
 
53
53
  /**
@@ -58,28 +58,29 @@ export const useMarginTop = (targetScreenId: string): number => {
58
58
  */
59
59
  if (screenData?.styles?.screen_margin_top === undefined) {
60
60
  if (isGeneralContentScreen || supportsUiComponents) {
61
- return Number(theme.screen_margin_top);
61
+ return toNumberWithDefault(0, theme.screen_margin_top);
62
62
  }
63
63
 
64
64
  return 0;
65
65
  }
66
66
 
67
- return Number(screenData?.styles?.screen_margin_top);
67
+ return toNumberWithDefault(0, screenData?.styles?.screen_margin_top);
68
68
  };
69
69
 
70
- export const TopMarginApplicator: React.FC<CombinedProps> = (
71
- props: CombinedProps
72
- ) => {
73
- const extraOffset = props?.extraOffset ?? 0;
70
+ export const TopMarginApplicator: React.FC<IProps> = ({
71
+ targetScreenId,
72
+ style,
73
+ children,
74
+ extraVerticalOffset,
75
+ }: IProps) => {
76
+ const extraOffset = toNumberWithDefault(0, extraVerticalOffset);
74
77
 
75
78
  // HACK: Remove extraOffset when focusIssue with absolute elements is fixed on tvos
76
- const marginTop = useMarginTop(props.targetScreenId) + extraOffset;
77
- const style = { ...((props.style as {}) || {}), marginTop };
79
+ const marginTop = useMarginTop(targetScreenId);
78
80
 
79
- // Then, spread the rest of the props on your returned JSX.
80
81
  return (
81
- <View {...props} style={style}>
82
- {props.children}
82
+ <View style={[style, { marginTop: marginTop + extraOffset }]}>
83
+ {children}
83
84
  </View>
84
85
  );
85
86
  };
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect } from "react";
2
- import { Animated } from "react-native";
2
+ import { Animated, Dimensions } from "react-native";
3
3
 
4
4
  import {
5
5
  useSafeAreaInsets,
@@ -23,6 +23,7 @@ export enum PlayerAnimationStateEnum {
23
23
  export type PlayerAnimationStateT = number | PlayerAnimationStateEnum | null;
24
24
 
25
25
  export type ModalAnimationContextT = {
26
+ yTranslate: React.MutableRefObject<Animated.Value | null>;
26
27
  isActiveGesture: boolean;
27
28
  playerAnimationState: PlayerAnimationStateT;
28
29
  setPlayerAnimationState: (value: PlayerAnimationStateT) => void;
@@ -48,6 +49,7 @@ export type ModalAnimationContextT = {
48
49
  };
49
50
 
50
51
  export const ReactContext = React.createContext<ModalAnimationContextT>({
52
+ yTranslate: React.createRef<Animated.Value | null>(),
51
53
  isActiveGesture: false,
52
54
  playerAnimationState: null,
53
55
  setPlayerAnimationState: () => null,
@@ -73,6 +75,10 @@ export const ReactContext = React.createContext<ModalAnimationContextT>({
73
75
  });
74
76
 
75
77
  const Provider = ({ children }: { children: React.ReactNode }) => {
78
+ const yTranslate = React.useRef(
79
+ new Animated.Value(Dimensions.get("window").height)
80
+ );
81
+
76
82
  const [playerAnimationState, setPlayerAnimationState] =
77
83
  React.useState<PlayerAnimationStateT>(null);
78
84
 
@@ -100,6 +106,7 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
100
106
  // Reset player animation state when video modal is closed
101
107
  if (!visible) {
102
108
  resetPlayerAnimationState();
109
+ yTranslate.current?.setValue(Dimensions.get("window").height);
103
110
  }
104
111
  }, [visible, resetPlayerAnimationState]);
105
112
 
@@ -141,6 +148,7 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
141
148
  return (
142
149
  <ReactContext.Provider
143
150
  value={{
151
+ yTranslate,
144
152
  startComponentsAnimation,
145
153
  setStartComponentsAnimation,
146
154
  isActiveGesture: playerAnimationState !== null,
@@ -11,6 +11,8 @@ import { useTargetScreenData } from "@applicaster/zapp-react-native-utils/reactH
11
11
  import { ComponentsMap } from "@applicaster/zapp-react-native-ui-components/Components/River/ComponentsMap";
12
12
  import { useSafeAreaInsets } from "react-native-safe-area-context";
13
13
  import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
14
+ import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
15
+ import { useDelayedPlayerDetails } from "./hooks";
14
16
 
15
17
  const { width: SCREEN_WIDTH } = Dimensions.get("screen");
16
18
 
@@ -26,6 +28,10 @@ type Props = {
26
28
  isTabletLandscape?: boolean;
27
29
  isAudioPlayer?: boolean;
28
30
  isTablet?: boolean;
31
+ inline?: any;
32
+ docked?: boolean;
33
+ isModal?: boolean;
34
+ pip?: boolean;
29
35
  };
30
36
 
31
37
  const containerStyle = ({
@@ -42,8 +48,24 @@ export const PlayerDetails = ({
42
48
  configuration,
43
49
  isTabletLandscape = false,
44
50
  isAudioPlayer,
45
- isTablet = false,
51
+ inline,
52
+ docked,
53
+ isModal,
54
+ pip,
46
55
  }: Props) => {
56
+ const isInlineModal = inline && isModal;
57
+
58
+ // Mounting the PlayerDetails component is a resource-intensive process.
59
+ // Therefore, for performance reasons, we mount it with a delay to make the rotation process as smooth as possible.
60
+ // The flow is as follows: the rotation occurs first, and then, after a short delay, we mount the PlayerDetails component.
61
+ // This helps to avoid blocking the rotation and any animations related to the rotation.
62
+ const isShowPlayerDetails = useDelayedPlayerDetails({
63
+ isInline: isInlineModal,
64
+ isDocked: docked,
65
+ isPip: pip,
66
+ });
67
+
68
+ const isTablet = useIsTablet();
47
69
  const screenData = useTargetScreenData(entry);
48
70
  const insets = useSafeAreaInsets();
49
71
 
@@ -79,7 +101,7 @@ export const PlayerDetails = ({
79
101
  }
80
102
  }, [isAudioPlayer]);
81
103
 
82
- if (isNilOrEmpty(screenData?.ui_components)) {
104
+ if (isNilOrEmpty(screenData?.ui_components) || !isShowPlayerDetails) {
83
105
  return null;
84
106
  }
85
107