@applicaster/zapp-react-native-ui-components 15.0.0-rc.13 → 15.0.0-rc.132

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 (189) hide show
  1. package/Components/AnimatedInOut/index.tsx +69 -26
  2. package/Components/BaseFocusable/index.ios.ts +12 -2
  3. package/Components/Cell/Cell.tsx +14 -3
  4. package/Components/Cell/CellWithFocusable.tsx +9 -0
  5. package/Components/Cell/FocusableWrapper.tsx +3 -0
  6. package/Components/Cell/TvOSCellComponent.tsx +30 -6
  7. package/Components/Focusable/Focusable.tsx +4 -2
  8. package/Components/Focusable/FocusableTvOS.tsx +18 -1
  9. package/Components/Focusable/__tests__/__snapshots__/FocusableTvOS.test.tsx.snap +1 -0
  10. package/Components/FocusableGroup/FocusableTvOS.tsx +32 -1
  11. package/Components/GeneralContentScreen/GeneralContentScreen.tsx +39 -28
  12. package/Components/GeneralContentScreen/__tests__/GeneralContentScreen.test.tsx +104 -0
  13. package/Components/GeneralContentScreen/utils/__tests__/getScreenDataSource.test.ts +19 -0
  14. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +1 -1
  15. package/Components/GeneralContentScreen/utils/getScreenDataSource.ts +9 -0
  16. package/Components/GeneralContentScreen/utils/useCurationAPI.ts +22 -6
  17. package/Components/HandlePlayable/HandlePlayable.tsx +33 -94
  18. package/Components/HandlePlayable/const.ts +3 -0
  19. package/Components/HandlePlayable/utils.ts +105 -0
  20. package/Components/HookRenderer/HookRenderer.tsx +40 -10
  21. package/Components/HookRenderer/__tests__/HookRenderer.test.tsx +60 -0
  22. package/Components/Layout/TV/LayoutBackground.tsx +5 -2
  23. package/Components/Layout/TV/NavBarContainer.tsx +1 -10
  24. package/Components/Layout/TV/ScreenContainer.tsx +2 -6
  25. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +7 -12
  26. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +7 -12
  27. package/Components/Layout/TV/index.tsx +3 -4
  28. package/Components/Layout/TV/index.web.tsx +3 -4
  29. package/Components/LinkHandler/LinkHandler.tsx +2 -2
  30. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/model.test.ts +80 -0
  31. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/placement.test.ts +187 -0
  32. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/selectors.test.ts +45 -0
  33. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/style.test.ts +49 -0
  34. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/model.ts +47 -0
  35. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/placement.ts +170 -0
  36. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/selectors.ts +26 -0
  37. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/style.ts +29 -0
  38. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/types.ts +37 -0
  39. package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +16 -1
  40. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +30 -2
  41. package/Components/MasterCell/DefaultComponents/Button.tsx +0 -15
  42. package/Components/MasterCell/DefaultComponents/Image/Image.android.tsx +5 -1
  43. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +11 -3
  44. package/Components/MasterCell/DefaultComponents/Image/Image.web.tsx +9 -1
  45. package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +15 -14
  46. package/Components/MasterCell/DefaultComponents/LiveImage/__tests__/prepareEntry.test.ts +352 -0
  47. package/Components/MasterCell/DefaultComponents/LiveImage/executePreloadHooks.ts +136 -0
  48. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +43 -22
  49. package/Components/MasterCell/DefaultComponents/PressableView.tsx +196 -0
  50. package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +40 -39
  51. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/Image.test.tsx +95 -0
  52. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/__snapshots__/Image.test.tsx.snap +86 -0
  53. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/index.test.ts +141 -0
  54. package/Components/MasterCell/DefaultComponents/SecondaryImage/hooks/__tests__/useGetImageDimensions.test.ts +7 -6
  55. package/Components/MasterCell/DefaultComponents/SecondaryImage/index.ts +1 -1
  56. package/Components/MasterCell/DefaultComponents/Text/index.tsx +10 -14
  57. package/Components/MasterCell/DefaultComponents/index.ts +2 -0
  58. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Asset.ts +46 -0
  59. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Button.ts +126 -0
  60. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/ButtonContainerView.ts +23 -0
  61. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Spacer.ts +16 -0
  62. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabel.ts +67 -0
  63. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabelsContainer.ts +32 -0
  64. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/PressableView.test.tsx +191 -0
  65. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/builders.test.ts +140 -0
  66. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/index.test.ts +222 -0
  67. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/helpers.ts +105 -0
  68. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/index.ts +104 -0
  69. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/__tests__/insertButtons.test.ts +118 -0
  70. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/index.ts +73 -0
  71. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/__tests__/index.test.ts +86 -0
  72. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +35 -48
  73. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/getPluginIdentifier.test.ts +115 -29
  74. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +39 -144
  75. package/Components/MasterCell/elementMapper.tsx +1 -0
  76. package/Components/MasterCell/hoc/__tests__/withAsyncRender.test.tsx +219 -0
  77. package/Components/MasterCell/hoc/withAsyncRender.tsx +9 -7
  78. package/Components/MasterCell/index.tsx +2 -0
  79. package/Components/MasterCell/utils/__tests__/resolveColor.test.js +82 -3
  80. package/Components/MasterCell/utils/index.ts +61 -31
  81. package/Components/MeasurmentsPortal/MeasurementsPortal.tsx +102 -87
  82. package/Components/MeasurmentsPortal/__tests__/MeasurementsPortal.test.tsx +355 -0
  83. package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +17 -9
  84. package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +16 -8
  85. package/Components/OfflineHandler/NotificationView/NotificationView.tsx +2 -2
  86. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +17 -18
  87. package/Components/OfflineHandler/NotificationView/utils.ts +34 -0
  88. package/Components/OfflineHandler/__tests__/index.test.tsx +27 -18
  89. package/Components/PlayerContainer/PlayerContainer.tsx +43 -64
  90. package/Components/PlayerImageBackground/index.tsx +3 -22
  91. package/Components/PreloaderWrapper/__tests__/index.test.tsx +26 -0
  92. package/Components/PreloaderWrapper/index.tsx +15 -0
  93. package/Components/River/ComponentsMap/ComponentsMap.tsx +16 -0
  94. package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +1 -1
  95. package/Components/River/RefreshControl.tsx +36 -13
  96. package/Components/River/RiverItem.tsx +26 -20
  97. package/Components/River/TV/River.tsx +31 -14
  98. package/Components/River/TV/index.tsx +8 -4
  99. package/Components/River/TV/utils/__tests__/toStringOrEmpty.test.ts +30 -0
  100. package/Components/River/TV/utils/index.ts +4 -0
  101. package/Components/River/TV/withFocusableGroupForContent.tsx +71 -0
  102. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +2 -0
  103. package/Components/River/__tests__/componentsMap.test.js +38 -0
  104. package/Components/Screen/TV/index.web.tsx +4 -2
  105. package/Components/Screen/__tests__/Screen.test.tsx +66 -42
  106. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +68 -44
  107. package/Components/Screen/hooks.ts +75 -6
  108. package/Components/Screen/index.tsx +9 -4
  109. package/Components/Screen/navigationHandler.ts +49 -24
  110. package/Components/Screen/orientationHandler.ts +10 -13
  111. package/Components/ScreenFeedLoader/ScreenFeedLoader.tsx +46 -0
  112. package/Components/ScreenFeedLoader/__tests__/ScreenFeedLoader.test.tsx +94 -0
  113. package/Components/ScreenFeedLoader/index.ts +1 -0
  114. package/Components/ScreenResolver/__tests__/screenResolver.test.js +24 -0
  115. package/Components/ScreenResolver/hooks/index.ts +3 -0
  116. package/Components/ScreenResolver/hooks/useGetComponent.ts +15 -0
  117. package/Components/ScreenResolver/hooks/useScreenComponentResolver.tsx +90 -0
  118. package/Components/ScreenResolver/index.tsx +15 -111
  119. package/Components/ScreenResolver/utils/__tests__/getScreenTypeProps.test.ts +45 -0
  120. package/Components/ScreenResolver/utils/getScreenTypeProps.ts +43 -0
  121. package/Components/ScreenResolver/utils/index.ts +1 -0
  122. package/Components/ScreenResolver/withDefaultScreenContext.tsx +16 -0
  123. package/Components/ScreenResolverFeedProvider/ScreenResolverFeedProvider.tsx +25 -0
  124. package/Components/ScreenResolverFeedProvider/__tests__/ScreenResolverFeedProvider.test.tsx +44 -0
  125. package/Components/ScreenResolverFeedProvider/index.ts +1 -0
  126. package/Components/ScreenRevealManager/ScreenRevealManager.ts +40 -8
  127. package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +86 -69
  128. package/Components/ScreenRevealManager/withScreenRevealManager.tsx +44 -26
  129. package/Components/Tabs/TV/Tabs.tsx +20 -3
  130. package/Components/Tabs/TabContent.tsx +7 -4
  131. package/Components/Transitioner/Scene.tsx +10 -3
  132. package/Components/Transitioner/index.js +3 -3
  133. package/Components/VideoLive/LiveImageManager.ts +199 -54
  134. package/Components/VideoLive/PlayerLiveImageComponent.tsx +31 -33
  135. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +2 -17
  136. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +1 -0
  137. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +118 -171
  138. package/Components/VideoModal/ModalAnimation/index.ts +2 -13
  139. package/Components/VideoModal/ModalAnimation/utils.ts +1 -327
  140. package/Components/VideoModal/PlayerWrapper.tsx +14 -88
  141. package/Components/VideoModal/VideoModal.tsx +1 -5
  142. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -0
  143. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +15 -7
  144. package/Components/VideoModal/hooks/useModalSize.ts +10 -5
  145. package/Components/VideoModal/playerWrapperStyle.ts +70 -0
  146. package/Components/VideoModal/playerWrapperUtils.ts +91 -0
  147. package/Components/VideoModal/utils.ts +19 -9
  148. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +0 -2
  149. package/Components/Viewport/ViewportAware/index.tsx +16 -7
  150. package/Components/Viewport/ViewportEvents/__tests__/viewportEvents.test.js +1 -1
  151. package/Components/ZappUIComponent/index.tsx +12 -6
  152. package/Components/default-cell-renderer/viewTrees/mobile/index.ts +0 -3
  153. package/Components/index.js +1 -1
  154. package/Contexts/ScreenContext/__tests__/index.test.tsx +57 -0
  155. package/Contexts/ScreenContext/index.tsx +71 -19
  156. package/Contexts/ScreenTrackedViewPositionsContext/__tests__/index.test.tsx +1 -1
  157. package/Contexts/ZappHookModalContext/index.tsx +37 -61
  158. package/Contexts/ZappPipesContext/ZappPipesContextFactory.tsx +18 -7
  159. package/Contexts/index.ts +0 -2
  160. package/Decorators/Analytics/index.tsx +6 -5
  161. package/Decorators/ConfigurationWrapper/__tests__/__snapshots__/withConfigurationProvider.test.tsx.snap +1 -0
  162. package/Decorators/ConfigurationWrapper/const.ts +1 -0
  163. package/Decorators/ZappPipesDataConnector/ResolverSelector.tsx +25 -7
  164. package/Decorators/ZappPipesDataConnector/__tests__/ResolverSelector.test.tsx +212 -5
  165. package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +39 -21
  166. package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +1 -1
  167. package/Decorators/ZappPipesDataConnector/index.tsx +2 -2
  168. package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +1 -1
  169. package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +18 -7
  170. package/Helpers/DataSourceHelper/__tests__/itemLimitForData.test.ts +80 -0
  171. package/Helpers/DataSourceHelper/index.ts +19 -0
  172. package/events/index.ts +3 -0
  173. package/events/scrollEndReached.ts +15 -0
  174. package/index.d.ts +7 -0
  175. package/package.json +6 -5
  176. package/Components/MasterCell/DefaultComponents/Text/utils/__tests__/withAdjustedLineHeight.test.ts +0 -46
  177. package/Components/MasterCell/DefaultComponents/Text/utils/index.ts +0 -21
  178. package/Components/PlayerContainer/ErrorDisplay/ErrorDisplay.tsx +0 -57
  179. package/Components/PlayerContainer/ErrorDisplay/index.ts +0 -9
  180. package/Components/River/TV/withTVEventHandler.tsx +0 -27
  181. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +0 -60
  182. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +0 -417
  183. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.web.tsx +0 -294
  184. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +0 -176
  185. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.web.tsx +0 -93
  186. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +0 -500
  187. package/Components/VideoModal/ModalAnimation/__tests__/getMoveUpValue.test.ts +0 -108
  188. package/Helpers/DataSourceHelper/index.js +0 -19
  189. /package/Components/HookRenderer/{index.tsx → index.ts} +0 -0
@@ -7,8 +7,6 @@ import { AppState, AppStateStatus, View } from "react-native";
7
7
  import { TrackedView } from "../TrackedView";
8
8
  import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks/layout";
9
9
 
10
- import { playerFactory } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/playerFactory";
11
-
12
10
  import {
13
11
  isApplePlatform,
14
12
  isTV,
@@ -22,15 +20,15 @@ import { AnimatedInOut } from "@applicaster/zapp-react-native-ui-components/Comp
22
20
  import { overlayFadeIn } from "./animationUtils";
23
21
  import { loggerLiveImageComponent } from "./loggerHelper";
24
22
  import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer";
25
- import { PlayerRole } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/conts";
26
23
  import { getAutoplaySettings } from "./utils";
27
24
  import { isString } from "@applicaster/zapp-react-native-utils/stringUtils";
28
25
  import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
26
+ import { PreloadHookConfig } from "../MasterCell/DefaultComponents/LiveImage/executePreloadHooks";
29
27
 
30
28
  const { log_error, log_debug } = loggerLiveImageComponent;
31
29
 
32
- const isMeasurement = (item: ZappEntry) =>
33
- isString(item.id) && item.id.startsWith("pre-measurement-");
30
+ const isMeasurement = (itemId: string | number | null): boolean =>
31
+ isString(itemId) && itemId.startsWith("pre-measurement-");
34
32
 
35
33
  // Pixels by which the view can slightly extend outside the viewport and still be considered fully visible.
36
34
  const CLIP_THRESHOLD = 10;
@@ -44,6 +42,7 @@ type Props = {
44
42
  screenConfig: Record<string, any>;
45
43
  audioMutedByDefault?: boolean;
46
44
  uri: string; // cover image url
45
+ preloadHooks?: PreloadHookConfig[];
47
46
  };
48
47
 
49
48
  const PlayerLiveImageComponent = (props: Props) => {
@@ -116,43 +115,36 @@ const PlayerLiveImageComponent = (props: Props) => {
116
115
  }
117
116
 
118
117
  entryToViewIdMapping.current[nativeTag] = { itemId: item.id };
119
- }, [trackViewRef.current, item.id, mode]);
118
+ }, [item.id, mode]);
120
119
 
121
- const { screenConfig, playerPluginId } = props;
120
+ const { screenConfig, playerPluginId, preloadHooks } = props;
122
121
 
123
122
  const liveImageItem: LiveImage = React.useMemo(() => {
124
- const playerFactoryItem = playerFactory({
125
- player: ref,
123
+ return new LiveImage({
126
124
  playerId,
127
- autoplay: false,
128
- entry: item,
129
- muted, // Initial muted state, not needed in dependencies
130
- playerPluginId: playerPluginId,
131
- screenConfig: screenConfig,
132
- playerRole: PlayerRole.Cell,
133
- });
134
-
135
- if (playerFactoryItem) {
136
- return new LiveImage({
125
+ preloadHooks,
126
+ factoryConfig: {
127
+ player: ref,
137
128
  playerId,
138
- player: playerFactoryItem.controller,
139
- component: playerFactoryItem?.Component,
140
- });
141
- } else {
142
- throw new Error("Player factory item is null");
143
- }
144
- }, [playerId, item.id, playerPluginId, screenConfig]);
129
+ muted,
130
+ playerPluginId: playerPluginId,
131
+ screenConfig: screenConfig,
132
+ entry: item,
133
+ },
134
+ tag: item.title?.toString(),
135
+ });
136
+ }, [playerId, preloadHooks, muted, playerPluginId, screenConfig, item]);
145
137
 
146
138
  React.useEffect(() => {
147
139
  liveImageItem.setMode = setModeDebounced;
148
140
  }, [setModeDebounced, liveImageItem]);
149
141
 
142
+ // todo: no need for it to be react, can be moved into `player.addListener`
150
143
  const { start, end } = React.useMemo(
151
144
  () => getAutoplaySettings(item),
152
145
  [item.id]
153
146
  );
154
147
 
155
- const controller = liveImageItem.getPlayer();
156
148
  const player = usePlayer(playerId);
157
149
 
158
150
  const _assignRoot = (component) => {
@@ -169,7 +161,7 @@ const PlayerLiveImageComponent = (props: Props) => {
169
161
 
170
162
  React.useEffect(() => {
171
163
  // FIXME - find a more elegant way to disable live-image on cell for measurement
172
- if (isMeasurement(item)) {
164
+ if (isMeasurement(item.id)) {
173
165
  return;
174
166
  }
175
167
 
@@ -253,7 +245,13 @@ const PlayerLiveImageComponent = (props: Props) => {
253
245
  }, [item.id]);
254
246
 
255
247
  React.useEffect(() => {
256
- if (isMeasurement(item) || !playerManager) {
248
+ if (isMeasurement(item.id) || !playerManager) {
249
+ return;
250
+ }
251
+
252
+ const controller = liveImageItem.getPlayer();
253
+
254
+ if (!controller) {
257
255
  return;
258
256
  }
259
257
 
@@ -273,7 +271,7 @@ const PlayerLiveImageComponent = (props: Props) => {
273
271
  playerManager.unregisterPlayer(playerId);
274
272
  };
275
273
  }
276
- }, [liveImageItem, playerId, controller, item.id]);
274
+ }, [liveImageItem, playerId, mode, item.id]);
277
275
 
278
276
  const onPositionUpdated = React.useCallback(
279
277
  (data) => {
@@ -310,7 +308,7 @@ const PlayerLiveImageComponent = (props: Props) => {
310
308
  ? LiveImageManager.instance.onViewportEnter(liveImageItem)
311
309
  : LiveImageManager.instance.onViewportLeave(liveImageItem);
312
310
  } else {
313
- LiveImageManager.instance.checkPlayerPosition(liveImageItem);
311
+ LiveImageManager.instance.onViewPositionChanged(liveImageItem);
314
312
  }
315
313
  },
316
314
  [liveImageItem, dimensions.height, dimensions.width]
@@ -338,11 +336,11 @@ const PlayerLiveImageComponent = (props: Props) => {
338
336
  <Player
339
337
  autoplay={false}
340
338
  ref={_assignRoot}
341
- entry={item} // Must be passed first in list
339
+ entry={liveImageItem.processedEntry || item} // Must be passed first in list
342
340
  style={videoStyles}
343
341
  playerId={playerId}
344
342
  muted={muted}
345
- listener={controller?.getListener()}
343
+ listener={liveImageItem.getPlayer()?.getListener()}
346
344
  resizeMode={"cover"}
347
345
  {...platformSpecificProps}
348
346
  />
@@ -120,29 +120,14 @@ describe("PlayerLiveImageComponent", () => {
120
120
  // TODO: implement this test
121
121
  });
122
122
 
123
- it("should register the player for normal item", () => {
123
+ it("should not register the player at mount (lazy creation)", () => {
124
124
  render(
125
125
  <Wrapper>
126
126
  <PlayerLiveImage {...defaultProps} />
127
127
  </Wrapper>
128
128
  );
129
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
-
130
+ // Player is not registered until playback starts (lazy creation)
146
131
  const isPlayerRegistered = playerManager.isPlayerRegistered(
147
132
  defaultProps.playerId
148
133
  );
@@ -9,6 +9,7 @@ exports[`PlayerLiveImageComponent should render correctly with default props 1`]
9
9
  <View>
10
10
  <View
11
11
  collapsable={false}
12
+ renderToHardwareTextureAndroid={false}
12
13
  style={
13
14
  {
14
15
  "opacity": 1,
@@ -1,212 +1,159 @@
1
- import React, { useEffect, useMemo } from "react";
1
+ import React, { useMemo } from "react";
2
2
  import { Animated, Dimensions } from "react-native";
3
3
 
4
- import {
5
- useSafeAreaInsets,
6
- useSafeAreaFrame,
7
- } from "react-native-safe-area-context";
8
- import { useGetBottomTabBarHeight } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useGetBottomTabBarHeight";
9
4
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation";
10
- import { isLive } from "@applicaster/zapp-react-native-utils/playerUtils";
11
5
 
12
- import { PROGRESS_BAR_HEIGHT } from "./utils";
13
6
  import { useConfiguration } from "../utils";
14
- import { useIsTabletLandscape } from "@applicaster/zapp-react-native-utils/reactHooks/device/useMemoizedIsTablet";
15
-
16
- export enum PlayerAnimationStateEnum {
17
- minimize = "minimize",
18
- maximize = "maximize",
19
- drag_player = "drag_player",
20
- drag_scroll = "drag_scroll",
21
- appear_as_docked = "appear_as_docked",
22
- }
7
+ import {
8
+ useAppData,
9
+ usePlugins,
10
+ } from "@applicaster/zapp-react-native-redux/hooks";
11
+ import { isBottomTabVisible } from "../../Screen/navigationHandler";
23
12
 
24
- export type PlayerAnimationStateT = number | PlayerAnimationStateEnum | null;
13
+ import {
14
+ useSafeAreaFrame,
15
+ useSafeAreaInsets,
16
+ } from "react-native-safe-area-context";
17
+ import {
18
+ isAndroidPlatform,
19
+ isAndroidVersionAtLeast,
20
+ } from "@applicaster/zapp-react-native-utils/reactUtils";
21
+ import { getTabBarHeight } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/getTabBarHeight";
22
+ import { PROGRESS_BAR_HEIGHT } from "./utils";
23
+ import { useIsTablet as getIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
25
24
 
26
25
  export type ModalAnimationContextT = {
27
- yTranslate: React.MutableRefObject<Animated.Value | null>;
28
- isActiveGesture: boolean;
29
- playerAnimationState: PlayerAnimationStateT;
30
- setPlayerAnimationState: (value: PlayerAnimationStateT) => void;
31
- startComponentsAnimation: boolean;
32
- setStartComponentsAnimation: (value: boolean) => void;
33
- resetPlayerAnimationState: () => void;
26
+ yTranslate: React.MutableRefObject<Animated.AnimatedInterpolation<number>>;
27
+ offsetAnimatedValueRef: React.MutableRefObject<Animated.Value>;
28
+ offset: React.MutableRefObject<number>;
29
+ heightAboveMinimised: number;
30
+ gestureTranslationRef: React.MutableRefObject<Animated.Value>;
34
31
  minimisedHeight: number;
35
- animatedValues: {
36
- lastScrollY: Animated.Value;
37
- dragScrollY: Animated.Value;
38
- dragVideoPlayerY: Animated.Value;
39
- translateYOffset: Animated.Value;
40
- };
41
- lastScrollYValue: React.MutableRefObject<number>;
42
- scrollPosition: React.MutableRefObject<number>;
43
- modalSnapPoints: number[];
44
- lastSnap: number;
45
- setLastSnap: (value: number) => void;
46
- tabletLandscapePlayerTopPosition: number;
47
- setTabletLandscapePlayerTopPosition: (value: number) => void;
48
- startComponentsAnimationDistance: number;
49
- progressBarHeight: number;
50
32
  };
51
33
 
52
34
  export const ReactContext = React.createContext<ModalAnimationContextT>({
53
35
  yTranslate: React.createRef<Animated.Value | null>(),
54
- isActiveGesture: false,
55
- playerAnimationState: null,
56
- setPlayerAnimationState: () => null,
57
- startComponentsAnimation: false,
58
- setStartComponentsAnimation: () => null,
59
- resetPlayerAnimationState: () => null,
36
+ offsetAnimatedValueRef: React.createRef<Animated.Value>(),
37
+ offset: React.createRef<number>(),
38
+ heightAboveMinimised: 0,
39
+ gestureTranslationRef: React.createRef<Animated.Value>(),
60
40
  minimisedHeight: 60,
61
- animatedValues: {
62
- lastScrollY: new Animated.Value(0),
63
- dragScrollY: new Animated.Value(0),
64
- dragVideoPlayerY: new Animated.Value(0),
65
- translateYOffset: new Animated.Value(0),
66
- },
67
- lastScrollYValue: null,
68
- scrollPosition: null,
69
- modalSnapPoints: [0, 0],
70
- lastSnap: 0,
71
- setLastSnap: () => null,
72
- tabletLandscapePlayerTopPosition: 0,
73
- setTabletLandscapePlayerTopPosition: () => null,
74
- startComponentsAnimationDistance: 0,
75
- progressBarHeight: 0,
76
41
  });
77
42
 
43
+ const SAFE_AREA_BREAKING_API_VERSION = 35;
44
+
45
+ export const isOldAndroidDevice =
46
+ isAndroidPlatform() &&
47
+ !isAndroidVersionAtLeast(SAFE_AREA_BREAKING_API_VERSION);
48
+
49
+ const bottomTabBarHeight = getTabBarHeight();
50
+
78
51
  const Provider = ({ children }: { children: React.ReactNode }) => {
52
+ const { height } = Dimensions.get("window");
53
+
79
54
  const yTranslate = React.useRef(
80
- new Animated.Value(Dimensions.get("window").height)
55
+ new Animated.Value(height).interpolate<number>({
56
+ inputRange: [0, height],
57
+ outputRange: [0, height],
58
+ })
81
59
  );
82
60
 
83
- const [playerAnimationState, setPlayerAnimationState] =
84
- React.useState<PlayerAnimationStateT>(null);
85
-
86
- const [
87
- tabletLandscapePlayerTopPosition,
88
- setTabletLandscapePlayerTopPosition,
89
- ] = React.useState<number>(0);
90
-
91
- const [startComponentsAnimation, setStartComponentsAnimation] =
92
- React.useState<boolean>(false);
61
+ const { minimised_height: minimisedHeight } = useConfiguration();
93
62
 
94
63
  const {
95
- videoModalState: { mode, visible, item },
64
+ videoModalState: { visible, mode },
65
+ currentRoute,
66
+ screenData,
96
67
  } = useNavigation();
97
68
 
98
- const isLiveItem = isLive(item);
99
- const { minimised_height: minimisedHeight } = useConfiguration();
69
+ const { isTabletPortrait } = useAppData();
100
70
 
101
- const resetPlayerAnimationState = React.useCallback(() => {
102
- setPlayerAnimationState(null);
103
- setStartComponentsAnimation(false);
104
- }, []);
105
-
106
- // Animated values
107
- const lastScrollY = React.useRef(new Animated.Value(0)).current;
108
- const dragScrollY = React.useRef(new Animated.Value(0)).current;
109
- const translateYOffset = React.useRef(new Animated.Value(0)).current;
110
- const dragVideoPlayerY = React.useRef(new Animated.Value(0)).current;
111
-
112
- const { height: safeAreaFrameHeight } = useSafeAreaFrame();
113
- const [height, setHeight] = React.useState<number>(safeAreaFrameHeight);
114
- const progressBarHeight = isLiveItem ? 0 : PROGRESS_BAR_HEIGHT;
115
- const { bottom: bottomSafeArea } = useSafeAreaInsets();
116
- const bottomTabBarHeight = useGetBottomTabBarHeight();
117
- const startComponentsAnimationDistance = Math.round((height * 60) / 100);
118
- const isTabletLandscape = useIsTabletLandscape();
119
- const windowDimensions = Dimensions.get("window");
120
-
121
- useEffect(() => {
122
- // Reset player animation state when video modal is closed
123
- if (!visible) {
124
- resetPlayerAnimationState();
125
-
126
- if (!isTabletLandscape) {
127
- // restore to portrait ( in portrait mode height is bigger)
128
- if (windowDimensions.height > windowDimensions.width) {
129
- yTranslate.current?.setValue(windowDimensions.height);
130
- }
131
- } else {
132
- yTranslate.current?.setValue(windowDimensions.height);
133
- }
134
- }
135
- }, [
136
- visible,
137
- resetPlayerAnimationState,
138
- windowDimensions.height,
139
- isTabletLandscape,
140
- ]);
71
+ const plugins = usePlugins();
72
+
73
+ const bottomTabsVisible = isBottomTabVisible(
74
+ currentRoute,
75
+ screenData,
76
+ plugins
77
+ );
78
+
79
+ const frame = useSafeAreaFrame();
80
+ const insets = useSafeAreaInsets();
81
+
82
+ const [heightAboveMinimised, setHeightAboveMinimised] = React.useState(0);
83
+
84
+ // memoizing heightAboveMinimised value
85
+ const offset = React.useRef(heightAboveMinimised);
86
+
87
+ // Used for memoizing modal y position after start/end of transition
88
+ const offsetAnimatedValueRef = React.useRef(
89
+ new Animated.Value(-offset.current)
90
+ );
91
+
92
+ // Used for gesture handling
93
+ const gestureTranslationRef = React.useRef(new Animated.Value(0));
94
+
95
+ const videoModalStateRef = React.useRef({ visible, mode });
141
96
 
142
97
  React.useEffect(() => {
143
- if (visible && mode === "MAXIMIZED" && height !== safeAreaFrameHeight) {
144
- setHeight(safeAreaFrameHeight);
145
- }
146
- }, [height, safeAreaFrameHeight, mode, visible]);
98
+ videoModalStateRef.current = { visible, mode };
99
+ }, [visible, mode]);
147
100
 
148
- /*
149
- If bottomTabBarHeight is equal 0 it means an app does not use bottomTabBar.
150
- Because of this we need to minus bottom SafeArea offset.
151
- */
101
+ const translateY = useMemo(() => {
102
+ const maxRange = heightAboveMinimised;
152
103
 
153
- const minValue =
154
- height -
155
- (minimisedHeight + bottomTabBarHeight + progressBarHeight + bottomSafeArea);
104
+ const combined: Animated.AnimatedAddition<number> = Animated.add(
105
+ offsetAnimatedValueRef.current,
106
+ gestureTranslationRef.current
107
+ );
108
+
109
+ return combined.interpolate({
110
+ inputRange: [0, maxRange],
111
+ outputRange: [0, maxRange],
112
+ extrapolate: "clamp",
113
+ });
114
+ }, [visible, heightAboveMinimised]);
115
+
116
+ offset.current = heightAboveMinimised;
117
+ yTranslate.current = translateY;
118
+
119
+ React.useEffect(() => {
120
+ const collapsedHeight =
121
+ minimisedHeight +
122
+ (bottomTabsVisible ? bottomTabBarHeight : 0) +
123
+ (isOldAndroidDevice ? 0 : insets.bottom) + // insets.bottom is added to properly display docked modal
124
+ PROGRESS_BAR_HEIGHT;
125
+
126
+ const heightAboveMinimised = frame.height - collapsedHeight;
156
127
 
157
- const modalSnapPoints = React.useMemo(() => [0, minValue], [minValue]);
158
- // Last snap state which will helps us to make smooth responder to scrollview animation
159
- const [lastSnap, setLastSnap] = React.useState<number>(modalSnapPoints[0]);
160
- // Extracted animated values which we will use for calculations
161
- const lastScrollYValue = React.useRef<number>(0);
162
- const scrollPosition = React.useRef<number>(0);
128
+ const isLandscape = frame.width > frame.height;
129
+
130
+ const isTablet = getIsTablet();
131
+
132
+ const shouldIgnoreLandscape = isTablet ? isTabletPortrait : true;
133
+
134
+ if (
135
+ heightAboveMinimised !== offset.current &&
136
+ videoModalStateRef.current.mode !== "PIP" &&
137
+ videoModalStateRef.current.mode !== "FULLSCREEN"
138
+ ) {
139
+ if (isLandscape && shouldIgnoreLandscape) return;
140
+ setHeightAboveMinimised(heightAboveMinimised);
141
+ offset.current = heightAboveMinimised;
142
+ }
143
+ }, [frame.height, insets.bottom, bottomTabsVisible, minimisedHeight]);
163
144
 
164
145
  return (
165
146
  <ReactContext.Provider
166
147
  value={useMemo(
167
148
  () => ({
168
149
  yTranslate,
169
- startComponentsAnimation,
170
- setStartComponentsAnimation,
171
- isActiveGesture: playerAnimationState !== null,
172
- playerAnimationState,
173
- setPlayerAnimationState,
174
- resetPlayerAnimationState,
150
+ offsetAnimatedValueRef,
151
+ offset,
152
+ heightAboveMinimised,
175
153
  minimisedHeight,
176
- animatedValues: {
177
- lastScrollY,
178
- dragScrollY,
179
- dragVideoPlayerY,
180
- translateYOffset,
181
- },
182
- lastScrollYValue,
183
- scrollPosition,
184
- modalSnapPoints,
185
- lastSnap,
186
- setLastSnap,
187
- tabletLandscapePlayerTopPosition,
188
- setTabletLandscapePlayerTopPosition,
189
- startComponentsAnimationDistance,
190
- progressBarHeight,
154
+ gestureTranslationRef,
191
155
  }),
192
- // eslint-disable-next-line react-hooks/exhaustive-deps
193
- [
194
- startComponentsAnimation,
195
- playerAnimationState,
196
- minimisedHeight,
197
- lastScrollY,
198
- dragScrollY,
199
- dragVideoPlayerY,
200
- translateYOffset,
201
- lastSnap,
202
- modalSnapPoints,
203
- lastScrollYValue,
204
- scrollPosition,
205
- tabletLandscapePlayerTopPosition,
206
- startComponentsAnimationDistance,
207
- progressBarHeight,
208
- isLiveItem,
209
- ]
156
+ [minimisedHeight, heightAboveMinimised]
210
157
  )}
211
158
  >
212
159
  {children}
@@ -1,18 +1,7 @@
1
- export { AnimatedPlayerModalWrapper } from "./AnimatedPlayerModalWrapper";
2
-
3
- export { AnimatedScrollModal } from "./AnimatedScrollModal";
4
-
5
- export { AnimatedVideoPlayerComponent } from "./AnimatedVideoPlayerComponent";
6
-
7
- export {
8
- withModalAnimationProvider,
9
- PlayerAnimationStateEnum,
10
- } from "./ModalAnimationContext";
1
+ export { withModalAnimationProvider } from "./ModalAnimationContext";
11
2
 
12
3
  export { useModalAnimationContext } from "./useModalAnimationContext";
13
4
 
14
- export { AnimationComponent } from "./AnimationComponent";
15
-
16
- export { ComponentAnimationType, defaultAspectRatioWidth } from "./utils";
5
+ export { defaultAspectRatioWidth } from "./utils";
17
6
 
18
7
  export { DURATION_TO_MINIMIZE, DURATION_TO_MAXIMIZE } from "./const";