@applicaster/zapp-react-native-ui-components 13.0.0-alpha.8532113155 → 13.0.0-alpha.9103242840

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 (63) hide show
  1. package/Components/BaseFocusable/index.ios.ts +1 -1
  2. package/Components/BaseFocusable/index.tsx +1 -1
  3. package/Components/Cell/Cell.tsx +4 -7
  4. package/Components/Cell/CellWithFocusable.tsx +59 -43
  5. package/Components/Cell/TvOSCellComponent.tsx +20 -22
  6. package/Components/Cell/__tests__/CellWIthFocusable.test.js +6 -13
  7. package/Components/Cell/index.js +3 -1
  8. package/Components/Focusable/FocusableTvOS.tsx +5 -1
  9. package/Components/Focusable/Touchable.tsx +20 -19
  10. package/Components/FocusableList/index.tsx +26 -9
  11. package/Components/FocusableScrollView/index.tsx +39 -12
  12. package/Components/Layout/TV/NavBarContainer.tsx +8 -7
  13. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +1 -1
  14. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +1 -1
  15. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +1 -4
  16. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +11 -5
  17. package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +1 -1
  18. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
  19. package/Components/MasterCell/hooks/useAsyncRendering/MasterCellAsyncRenderManager.ts +2 -2
  20. package/Components/MasterCell/utils/index.ts +1 -1
  21. package/Components/ModalComponent/Header/index.tsx +3 -3
  22. package/Components/River/ComponentsMap/ComponentsMap.tsx +65 -39
  23. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +51 -78
  24. package/Components/River/RiverFooter.tsx +9 -39
  25. package/Components/River/RiverItem.tsx +2 -37
  26. package/Components/River/TV/index.tsx +6 -1
  27. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +31 -100
  28. package/Components/River/__tests__/componentsMap.test.js +5 -17
  29. package/Components/Screen/index.tsx +39 -13
  30. package/Components/Tabs/Tab.tsx +6 -6
  31. package/Components/TextInputTv/index.tsx +2 -2
  32. package/Components/Transitioner/AnimationManager.js +8 -8
  33. package/Components/Transitioner/Scene.tsx +23 -52
  34. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +43 -59
  35. package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +2 -2
  36. package/Components/Transitioner/index.js +4 -8
  37. package/Components/VideoLive/LiveImageManager.ts +1 -27
  38. package/Components/VideoLive/PlayerLiveImageComponent.tsx +21 -29
  39. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +1 -51
  40. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +5 -0
  41. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +6 -7
  42. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +3 -2
  43. package/Components/VideoModal/ModalAnimation/utils.ts +2 -2
  44. package/Components/VideoModal/PlayerWrapper.tsx +35 -16
  45. package/Components/VideoModal/VideoModal.tsx +23 -14
  46. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -1
  47. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +90 -0
  48. package/Components/VideoModal/hooks/utils/index.ts +0 -33
  49. package/Components/VideoModal/utils.ts +1 -1
  50. package/Contexts/ComponentsMapOffsetContext/index.tsx +46 -0
  51. package/Contexts/ScreenContext/index.tsx +2 -3
  52. package/Decorators/ZappPipesDataConnector/__tests__/Hero.js +1 -1
  53. package/Decorators/ZappPipesDataConnector/index.tsx +1 -31
  54. package/package.json +5 -5
  55. package/Components/Cell/CellWithFocusable.ios.tsx +0 -126
  56. package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +0 -66
  57. package/Components/MasterCell/DefaultComponents/ImageBorderContainer/__tests__/index.test.ts +0 -93
  58. package/Components/Screen/hooks.ts +0 -56
  59. package/Components/VideoModal/OpaqueLayer.tsx +0 -33
  60. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +0 -89
  61. package/Components/VideoModal/hooks/index.ts +0 -7
  62. package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +0 -49
  63. package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +0 -91
@@ -8,8 +8,6 @@ import { loggerLiveImageManager } from "./loggerHelper";
8
8
  import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
9
9
  import { Component } from "react";
10
10
 
11
- const TIMEOUT_FOR_DELAY_CHECK_PLAYER_POSITION = 500; // ms
12
-
13
11
  const { log_debug, log_info, log_error } = loggerLiveImageManager;
14
12
 
15
13
  export type LiveImageManagerEvent =
@@ -64,9 +62,6 @@ export class LiveImageManager implements PlayerLifecycleListener {
64
62
  protected currentlyPlaying: LiveImage | null = null;
65
63
  protected primaryPlayer: Player | null = null;
66
64
 
67
- private checkPlayerPositionTimeout: ReturnType<typeof setTimeout> | null =
68
- null;
69
-
70
65
  protected listeners: Record<
71
66
  string,
72
67
  Record<LiveImageManagerEvent, (event?: Record<string, any>) => void>
@@ -123,11 +118,6 @@ export class LiveImageManager implements PlayerLifecycleListener {
123
118
  });
124
119
  };
125
120
 
126
- private cancelCheckPlayerPositionTimeout = () => {
127
- clearTimeout(this.checkPlayerPositionTimeout);
128
- this.checkPlayerPositionTimeout = null;
129
- };
130
-
131
121
  public onViewportEnter = (item: LiveImage) => {
132
122
  log_debug(
133
123
  `onViewportEnter: live-image ${playerInfo(
@@ -135,21 +125,7 @@ export class LiveImageManager implements PlayerLifecycleListener {
135
125
  )}, primary ${playerInfo(this.primaryPlayer)}`
136
126
  );
137
127
 
138
- if (!isTV()) {
139
- // mobile only
140
- // we have to delay running checkPlayerPosition, because sometimes on fast scrolling we get wrong order onEnter, then onLeave.
141
- // which could cause select wrong item to play
142
-
143
- this.cancelCheckPlayerPositionTimeout();
144
-
145
- this.checkPlayerPositionTimeout = setTimeout(() => {
146
- this.cancelCheckPlayerPositionTimeout();
147
-
148
- this.checkPlayerPosition(item);
149
- }, TIMEOUT_FOR_DELAY_CHECK_PLAYER_POSITION);
150
- } else {
151
- this.checkPlayerPosition(item);
152
- }
128
+ this.checkPlayerPosition(item);
153
129
  };
154
130
 
155
131
  public onViewportLeave = (item: LiveImage) => {
@@ -270,8 +246,6 @@ export class LiveImageManager implements PlayerLifecycleListener {
270
246
  };
271
247
 
272
248
  public checkPlayerPosition = (item: LiveImage) => {
273
- this.cancelCheckPlayerPositionTimeout();
274
-
275
249
  log_debug(
276
250
  `checkPlayerPosition: live-image playerId: ${playerInfo(
277
251
  item.player
@@ -44,10 +44,7 @@ type Props = {
44
44
  };
45
45
 
46
46
  const PlayerLiveImageComponent = (props: Props) => {
47
- const dimensions = useDimensions("screen", {
48
- fullDimensions: true,
49
- updateForInactiveScreens: false,
50
- });
47
+ const dimensions = useDimensions("screen", { fullDimensions: true });
51
48
 
52
49
  const { item, style, playerId } = props;
53
50
 
@@ -138,16 +135,13 @@ const PlayerLiveImageComponent = (props: Props) => {
138
135
  } else {
139
136
  throw new Error("Player factory item is null");
140
137
  }
141
- }, [playerId, item.id, playerPluginId, screenConfig]);
138
+ }, [playerId, item, playerPluginId, screenConfig]);
142
139
 
143
140
  React.useEffect(() => {
144
141
  liveImageItem.setMode = setModeDebounced;
145
142
  }, [setModeDebounced, liveImageItem]);
146
143
 
147
- const { start, end } = React.useMemo(
148
- () => getAutoplaySettings(item),
149
- [item.id]
150
- );
144
+ const { start, end } = React.useMemo(() => getAutoplaySettings(item), [item]);
151
145
 
152
146
  const controller = liveImageItem.getPlayer();
153
147
  const player = usePlayer(playerId);
@@ -180,7 +174,7 @@ const PlayerLiveImageComponent = (props: Props) => {
180
174
 
181
175
  unregister();
182
176
  };
183
- }, [item.id, liveImageItem]);
177
+ }, [item, liveImageItem]);
184
178
 
185
179
  React.useEffect(() => {
186
180
  if (!player) {
@@ -250,27 +244,25 @@ const PlayerLiveImageComponent = (props: Props) => {
250
244
  }, [item.id]);
251
245
 
252
246
  React.useEffect(() => {
253
- if (isMeasurement(item) || !playerManager) {
254
- return;
255
- }
247
+ if (playerManager) {
248
+ const isPlayerRegistered = playerManager.isPlayerRegistered(playerId);
256
249
 
257
- const isPlayerRegistered = playerManager.isPlayerRegistered(playerId);
258
-
259
- if (isPlayerRegistered) {
260
- log_error(
261
- `PlayerLiveImageComponent: player ${playerId} already registered`
262
- );
263
- } else {
264
- playerManager.registerPlayer({
265
- id: playerId,
266
- playerController: controller,
267
- });
250
+ if (isPlayerRegistered) {
251
+ log_error(
252
+ `PlayerLiveImageComponent: player ${playerId} already registered`
253
+ );
254
+ } else {
255
+ playerManager.registerPlayer({
256
+ id: playerId,
257
+ playerController: controller,
258
+ });
268
259
 
269
- return () => {
270
- playerManager.unregisterPlayer(playerId);
271
- };
260
+ return () => {
261
+ playerManager.unregisterPlayer(playerId);
262
+ };
263
+ }
272
264
  }
273
- }, [liveImageItem, playerId, controller, item.id]);
265
+ }, [liveImageItem, playerId, controller]);
274
266
 
275
267
  const onPositionUpdated = React.useCallback(
276
268
  (data) => {
@@ -310,7 +302,7 @@ const PlayerLiveImageComponent = (props: Props) => {
310
302
  LiveImageManager.instance.checkPlayerPosition(liveImageItem);
311
303
  }
312
304
  },
313
- [liveImageItem, dimensions.height, dimensions.width]
305
+ [liveImageItem, dimensions]
314
306
  );
315
307
 
316
308
  const platformSpecificProps = isApplePlatform()
@@ -4,7 +4,6 @@ import { render } from "@testing-library/react-native";
4
4
  import * as PlayerFactory from "@applicaster/zapp-react-native-utils/appUtils/playerManager/playerFactory";
5
5
  import { ThemeContext } from "@applicaster/zapp-react-native-utils/theme";
6
6
  import * as navigationHooks from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
7
- import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
8
7
 
9
8
  import { PlayerLiveImage } from "../PlayerLiveImageComponent";
10
9
  import * as useNavigationHooks from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation";
@@ -33,7 +32,7 @@ const mockStore = configureStore();
33
32
 
34
33
  const store = mockStore({ appData: {} });
35
34
 
36
- const Wrapper = ({ children }: { children: React.ReactNode }) => (
35
+ const Wrapper = ({ children }: { children: React.ReactChildren }) => (
37
36
  /* @ts-ignore */
38
37
  <Provider store={store}>
39
38
  <ThemeContext.Provider
@@ -119,53 +118,4 @@ describe("PlayerLiveImageComponent", () => {
119
118
 
120
119
  // TODO: implement this test
121
120
  });
122
-
123
- it("should register the player for normal item", () => {
124
- render(
125
- <Wrapper>
126
- <PlayerLiveImage {...defaultProps} />
127
- </Wrapper>
128
- );
129
-
130
- const isPlayerRegistered = playerManager.isPlayerRegistered(
131
- defaultProps.playerId
132
- );
133
-
134
- expect(isPlayerRegistered).toBe(true);
135
- });
136
-
137
- it("should unregister the player for normal item", () => {
138
- const component = render(
139
- <Wrapper>
140
- <PlayerLiveImage {...defaultProps} />
141
- </Wrapper>
142
- );
143
-
144
- component.unmount();
145
-
146
- const isPlayerRegistered = playerManager.isPlayerRegistered(
147
- defaultProps.playerId
148
- );
149
-
150
- expect(isPlayerRegistered).toBe(false);
151
- });
152
-
153
- it("should not register the player for 'pre-measurement' item", () => {
154
- const props = {
155
- ...defaultProps,
156
- item: {
157
- ...defaultProps.item,
158
- id: "pre-measurement-1",
159
- },
160
- };
161
-
162
- render(
163
- <Wrapper>
164
- <PlayerLiveImage {...props} />
165
- </Wrapper>
166
- );
167
-
168
- const isPlayerRegistered = playerManager.isPlayerRegistered(props.playerId);
169
- expect(isPlayerRegistered).toBe(false);
170
- });
171
121
  });
@@ -31,6 +31,11 @@ exports[`PlayerLiveImageComponent should render correctly with default props 1`]
31
31
  playerId="player1"
32
32
  resizeMode="cover"
33
33
  screenConfig={{}}
34
+ source={
35
+ {
36
+ "uri": "",
37
+ }
38
+ }
34
39
  style={{}}
35
40
  />
36
41
  </View>
@@ -100,11 +100,10 @@ export const AnimationView = ({
100
100
  const moveUpValue = additionalData.saveArea
101
101
  ? -insets.top + (isAudioItem ? 0 : progressBarHeight)
102
102
  : isTablet
103
- ? isTabletLandscape &&
104
- (!isAudioItem || (isAudioItem && inlineAudioPlayer))
105
- ? -tabletLandscapePlayerTopPosition + progressBarHeight
106
- : -130
107
- : -50 + progressBarHeight;
103
+ ? isTabletLandscape && (!isAudioItem || (isAudioItem && inlineAudioPlayer))
104
+ ? -tabletLandscapePlayerTopPosition + progressBarHeight
105
+ : -130
106
+ : -50 + progressBarHeight;
108
107
 
109
108
  const moveComponentHorizontalValue = additionalData.moveValue
110
109
  ? isRTL
@@ -435,8 +434,8 @@ export const AnimationComponent = (props: Props) => {
435
434
  const Component = useAnimation
436
435
  ? AnimationView
437
436
  : style
438
- ? View
439
- : React.Fragment;
437
+ ? View
438
+ : React.Fragment;
440
439
 
441
440
  if (
442
441
  additionalData.extraAnimation &&
@@ -118,10 +118,11 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
118
118
  If bottomTabBarHeight is equal 0 it means an app does not use bottomTabBar.
119
119
  Because of this we need to minus bottom SafeArea offset.
120
120
  */
121
-
122
121
  const minValue =
123
122
  height -
124
- (minimisedHeight + bottomTabBarHeight + progressBarHeight + bottomSafeArea);
123
+ minimisedHeight -
124
+ (bottomTabBarHeight || bottomSafeArea) -
125
+ progressBarHeight;
125
126
 
126
127
  const modalSnapPoints = React.useMemo(() => [0, minValue], [minValue]);
127
128
  // Last snap state which will helps us to make smooth responder to scrollview animation
@@ -108,8 +108,8 @@ export const calculateAnimationValue = (animationType, dragPosition, data) => {
108
108
  : { forWidth: 3, forHeight: 3 }
109
109
  : { forWidth: 2, forHeight: 2 }
110
110
  : isTabletLandscape
111
- ? { forWidth: 8, forHeight: 6.5 }
112
- : { forWidth: 3.5, forHeight: 2 };
111
+ ? { forWidth: 8, forHeight: 6.5 }
112
+ : { forWidth: 3.5, forHeight: 2 };
113
113
 
114
114
  const minWidth =
115
115
  isAudioItem && !inlineAudioPlayer ? minimisedHeight : minimisedWidth;
@@ -10,8 +10,7 @@ import { Edge, SafeAreaView } from "react-native-safe-area-context";
10
10
  import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
11
11
  import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
12
12
  import { PlayerDetails } from "./PlayerDetails";
13
- import { playerDimensionsHack } from "./utils";
14
- import { useDelayedPlayerDetails } from "./hooks";
13
+ import { playerDimesionsHack } from "./utils";
15
14
 
16
15
  import {
17
16
  AnimatedScrollModal,
@@ -122,6 +121,34 @@ const getTabletWidth = (
122
121
  return Number(width) - sidebarWidth;
123
122
  };
124
123
 
124
+ const showDetails = (
125
+ isMobile: boolean,
126
+ docked: boolean,
127
+ isInlineModal,
128
+ pip
129
+ ): boolean => {
130
+ if (pip) {
131
+ return false;
132
+ }
133
+
134
+ if (!isInlineModal) {
135
+ return false;
136
+ }
137
+
138
+ // for mobile we always show details. Mounting of it very heavy operation.
139
+ if (isMobile) {
140
+ return true;
141
+ }
142
+
143
+ // workaround for tablets we need to mount/unmount in order to avoid PlayerDetails content dissappearing
144
+ // FIXME - find out the reason of dissapearing of content
145
+ if (docked) {
146
+ return false;
147
+ }
148
+
149
+ return true;
150
+ };
151
+
125
152
  const PlayerWrapperComponent = (props: Props) => {
126
153
  const {
127
154
  entry,
@@ -140,15 +167,7 @@ const PlayerWrapperComponent = (props: Props) => {
140
167
 
141
168
  const isInlineModal = inline && isModal;
142
169
 
143
- // Mounting the PlayerDetails component is a resource-intensive process.
144
- // Therefore, for performance reasons, we mount it with a delay to make the rotation process as smooth as possible.
145
- // The flow is as follows: the rotation occurs first, and then, after a short delay, we mount the PlayerDetails component.
146
- // This helps to avoid blocking the rotation and any animations related to the rotation.
147
- const isShowPlayerDetails = useDelayedPlayerDetails({
148
- isInline: isInlineModal,
149
- isDocked: docked,
150
- isPip: pip,
151
- });
170
+ // const style = getStyles(baseStyle, !isTablet, isInlineModal, pip);
152
171
 
153
172
  const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
154
173
 
@@ -184,8 +203,8 @@ const PlayerWrapperComponent = (props: Props) => {
184
203
  const WrapperView = React.useMemo(() => (isTV() ? View : SafeAreaView), []);
185
204
 
186
205
  const childrenStyles = React.useMemo(
187
- () => ({ ...playerDimensions, ...playerDimensionsHack }),
188
- [containerDimensions, playerDimensionsHack]
206
+ () => ({ ...playerDimensions, ...playerDimesionsHack }),
207
+ [containerDimensions, playerDimesionsHack]
189
208
  );
190
209
 
191
210
  return (
@@ -194,7 +213,7 @@ const PlayerWrapperComponent = (props: Props) => {
194
213
  style={[
195
214
  safeAreaStyles(configuration, isTablet),
196
215
  style,
197
- playerDimensionsHack,
216
+ playerDimesionsHack,
198
217
  ]}
199
218
  >
200
219
  <AnimationComponent
@@ -208,7 +227,7 @@ const PlayerWrapperComponent = (props: Props) => {
208
227
  defaultStyles.playerContainer,
209
228
  containerDimensions,
210
229
  containerStyle,
211
- playerDimensionsHack,
230
+ playerDimesionsHack,
212
231
  ]}
213
232
  >
214
233
  <AnimationComponent
@@ -227,7 +246,7 @@ const PlayerWrapperComponent = (props: Props) => {
227
246
  </View>
228
247
 
229
248
  <AnimatedScrollModal>
230
- {isShowPlayerDetails && (
249
+ {showDetails(!isTablet, docked, isInlineModal, pip) && (
231
250
  <AnimationComponent
232
251
  animationType={ComponentAnimationType.componentFade}
233
252
  style={defaultStyles.flex}
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
- import { equals } from "ramda";
3
- import { StyleSheet, StatusBar } from "react-native";
2
+ import * as R from "ramda";
3
+ import { StyleSheet, View, StatusBar } from "react-native";
4
4
 
5
5
  import { HandlePlayable } from "@applicaster/zapp-react-native-ui-components/Components/HandlePlayable";
6
6
  import {
@@ -17,20 +17,17 @@ import {
17
17
  import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks/device/useIsTablet";
18
18
 
19
19
  import { withModalNavigationContextProvider } from "../../Contexts/ModalNavigationContext";
20
- import {
21
- useModalSize,
22
- useBackgroundColor,
23
- useInitialPlayerState,
24
- } from "./hooks";
25
-
20
+ import { useModalSize } from "./hooks/useModalSize";
21
+ import { useBackgroundColor } from "./hooks/useBackgroundColor";
22
+ import { useInitialPlayerState } from "./hooks/useInitialPlayerState";
26
23
  import { APP_EVENTS } from "@applicaster/zapp-react-native-utils/appUtils/events";
24
+ import { Spinner } from "../Spinner";
27
25
  import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext";
28
26
  import { ROUTE_TYPES } from "@applicaster/zapp-react-native-utils/navigationUtils/routeTypes";
29
27
  import { useSubscriberFor } from "@applicaster/zapp-react-native-utils/reactHooks/useSubscriberFor";
30
28
  import { requiresAuthentication } from "@applicaster/zapp-react-native-utils/configurationUtils";
31
29
  import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
32
30
  import { ScreenContextProvider } from "../../Contexts/ScreenContext";
33
- import { OpaqueLayer } from "./OpaqueLayer";
34
31
 
35
32
  import { AnimatedPlayerModalWrapper } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
36
33
 
@@ -42,6 +39,17 @@ const styles = StyleSheet.create({
42
39
  bottom: 0,
43
40
  position: "absolute",
44
41
  },
42
+ // eslint-disable-next-line react-native/no-color-literals
43
+ loaderContainer: {
44
+ top: 0,
45
+ left: 0,
46
+ right: 0,
47
+ bottom: 0,
48
+ position: "absolute",
49
+ alignItems: "center",
50
+ justifyContent: "center",
51
+ backgroundColor: "rgba(64,64,64,.5)",
52
+ },
45
53
  });
46
54
 
47
55
  const VideoModalComponent = () => {
@@ -92,7 +100,7 @@ const VideoModalComponent = () => {
92
100
 
93
101
  const onHooksSuccess = ({ payload }) => {
94
102
  // set new modified entry
95
- if (!equals(payload, item)) {
103
+ if (!R.equals(payload, item)) {
96
104
  onVideoModalHookSuccessAnalyticsEvent();
97
105
  setVideoModalItem(payload);
98
106
  }
@@ -128,10 +136,7 @@ const VideoModalComponent = () => {
128
136
 
129
137
  <PathnameContext.Provider value={pathname}>
130
138
  <ScreenContextProvider pathname={pathname}>
131
- {/* Hide content underneath when we switch to next video in fullscreen mode */}
132
- {mode === "FULLSCREEN" && <OpaqueLayer />}
133
-
134
- {itemIdHooksFinished === item?.id && (
139
+ {itemIdHooksFinished === item?.id ? (
135
140
  <AnimatedPlayerModalWrapper
136
141
  style={[
137
142
  styles.container,
@@ -148,6 +153,10 @@ const VideoModalComponent = () => {
148
153
  mode={mode}
149
154
  />
150
155
  </AnimatedPlayerModalWrapper>
156
+ ) : (
157
+ <View style={styles.loaderContainer}>
158
+ <Spinner />
159
+ </View>
151
160
  )}
152
161
  </ScreenContextProvider>
153
162
  </PathnameContext.Provider>
@@ -62,7 +62,7 @@ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
62
62
  })),
63
63
  }));
64
64
 
65
- jest.mock("../utils", () => ({ playerDimensionsHack: {} }));
65
+ jest.mock("../utils", () => ({ playerDimesionsHack: {} }));
66
66
 
67
67
  const { PlayerWrapper } = require("../PlayerWrapper");
68
68
 
@@ -71,6 +71,36 @@ exports[`PlayerWrapper renders inline 1`] = `
71
71
  }
72
72
  testID="test-player-container"
73
73
  />
74
+ <View
75
+ animationType="componentFade"
76
+ style={
77
+ {
78
+ "flex": 1,
79
+ }
80
+ }
81
+ >
82
+ <View
83
+ configuration={
84
+ {
85
+ "tablet_landscape_player_container_background_color": "red",
86
+ "tablet_landscape_sidebar_width": "35%",
87
+ }
88
+ }
89
+ entry={
90
+ {
91
+ "id": "test",
92
+ }
93
+ }
94
+ isTablet={false}
95
+ isTabletLandscape={false}
96
+ style={
97
+ {
98
+ "flex": 1,
99
+ "paddingTop": 20,
100
+ }
101
+ }
102
+ />
103
+ </View>
74
104
  </View>
75
105
  </RNCSafeAreaView>
76
106
  </RNCSafeAreaProvider>
@@ -147,6 +177,36 @@ exports[`PlayerWrapper renders inline and docked 1`] = `
147
177
  }
148
178
  testID="test-player-container"
149
179
  />
180
+ <View
181
+ animationType="componentFade"
182
+ style={
183
+ {
184
+ "flex": 1,
185
+ }
186
+ }
187
+ >
188
+ <View
189
+ configuration={
190
+ {
191
+ "tablet_landscape_player_container_background_color": "red",
192
+ "tablet_landscape_sidebar_width": "35%",
193
+ }
194
+ }
195
+ entry={
196
+ {
197
+ "id": "test",
198
+ }
199
+ }
200
+ isTablet={false}
201
+ isTabletLandscape={false}
202
+ style={
203
+ {
204
+ "flex": 1,
205
+ "paddingTop": 20,
206
+ }
207
+ }
208
+ />
209
+ </View>
150
210
  </View>
151
211
  </RNCSafeAreaView>
152
212
  </RNCSafeAreaProvider>
@@ -239,6 +299,36 @@ exports[`PlayerWrapper renders inline on tablet in landscape orientation 1`] = `
239
299
  }
240
300
  />
241
301
  </View>
302
+ <View
303
+ animationType="componentFade"
304
+ style={
305
+ {
306
+ "flex": 1,
307
+ }
308
+ }
309
+ >
310
+ <View
311
+ configuration={
312
+ {
313
+ "tablet_landscape_player_container_background_color": "red",
314
+ "tablet_landscape_sidebar_width": "35%",
315
+ }
316
+ }
317
+ entry={
318
+ {
319
+ "id": "test",
320
+ }
321
+ }
322
+ isTablet={true}
323
+ isTabletLandscape={true}
324
+ style={
325
+ {
326
+ "flex": 1,
327
+ "paddingTop": 20,
328
+ }
329
+ }
330
+ />
331
+ </View>
242
332
  </View>
243
333
  </RNCSafeAreaView>
244
334
  </RNCSafeAreaProvider>
@@ -35,36 +35,3 @@ export const orientationWasChangedFromPortraitToLandscape = ({
35
35
  isOrientationLandscape(toOrientation)
36
36
  );
37
37
  };
38
-
39
- export const showDetails = ({
40
- isMobile,
41
- isInline,
42
- isDocked,
43
- isPip,
44
- }: {
45
- isMobile: boolean;
46
- isInline: boolean;
47
- isDocked: boolean;
48
- isPip: boolean;
49
- }): boolean => {
50
- if (isPip) {
51
- return false;
52
- }
53
-
54
- if (isDocked) {
55
- return false;
56
- }
57
-
58
- // for mobile with inline mode(rotation is portrait) we always show details.
59
- if (isMobile && isInline) {
60
- return true;
61
- }
62
-
63
- // for mobile with landscape rotation(player is fullscreen) we always hide details. Mounting of it is very heavy operation.
64
- if (isMobile && !isInline) {
65
- return false;
66
- }
67
-
68
- // for tablets we always show details
69
- return true;
70
- };
@@ -52,7 +52,7 @@ const fullSize = {
52
52
  height: "100%",
53
53
  };
54
54
 
55
- export const playerDimensionsHack = platformSelect({
55
+ export const playerDimesionsHack = platformSelect({
56
56
  android_tv: fullSize,
57
57
  amazon: fullSize,
58
58
  lg_tv: fullSize,
@@ -0,0 +1,46 @@
1
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
2
+ import React, { PropsWithChildren } from "react";
3
+
4
+ export const ComponentsMapOffsetContext = React.createContext({
5
+ setComponentsMapOffset: (_offset: number) => void 0,
6
+ componentsMapOffset: 0,
7
+ });
8
+
9
+ export const ComponentsMapOffsetContextProvider = ({
10
+ children,
11
+ }: PropsWithChildren<{}>) => {
12
+ const theme = useTheme<BaseThemePropertiesTV>();
13
+
14
+ const [componentsMapOffset, setComponentsMapOffset] = React.useState(
15
+ theme?.screen_margin_top
16
+ );
17
+
18
+ const contextValue = {
19
+ componentsMapOffset,
20
+ setComponentsMapOffset,
21
+ };
22
+
23
+ return (
24
+ <ComponentsMapOffsetContext.Provider value={contextValue}>
25
+ {children}
26
+ </ComponentsMapOffsetContext.Provider>
27
+ );
28
+ };
29
+
30
+ export const withComponentsMapOffsetContext = (Component: any) =>
31
+ function ComponentsMapOffsetContextProviderWrapper(props: {}) {
32
+ return (
33
+ <ComponentsMapOffsetContextProvider>
34
+ <Component {...props} />
35
+ </ComponentsMapOffsetContextProvider>
36
+ );
37
+ };
38
+
39
+ export const withComponentsMapOffsetContextConsumer = (Component: any) =>
40
+ function ComponentsMapOffsetContextConsumerWrapper(props: {}) {
41
+ const { componentsMapOffset } = React.useContext(
42
+ ComponentsMapOffsetContext
43
+ );
44
+
45
+ return <Component {...props} componentsMapOffset={componentsMapOffset} />;
46
+ };