@applicaster/zapp-react-native-ui-components 13.0.0-alpha.9946926334 → 13.0.0-rc.100

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 (172) hide show
  1. package/Components/AppContainer/__tests__/AppContainer.test.js +4 -6
  2. package/Components/AudioPlayer/AudioPlayer.tsx +7 -0
  3. package/Components/AudioPlayer/__tests__/Runtime.test.js +5 -8
  4. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +54 -111
  5. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +36 -20
  6. package/Components/AudioPlayer/__tests__/artWork.test.js +3 -5
  7. package/Components/AudioPlayer/__tests__/audioPlayer.test.js +3 -5
  8. package/Components/AudioPlayer/__tests__/audioPlayerLayout.test.js +7 -8
  9. package/Components/AudioPlayer/__tests__/channel.test.js +3 -5
  10. package/Components/AudioPlayer/__tests__/summary.test.js +3 -5
  11. package/Components/AudioPlayer/__tests__/title.test.js +3 -5
  12. package/Components/AudioPlayer/helpers.tsx +1 -0
  13. package/Components/BaseFocusable/index.ios.ts +1 -1
  14. package/Components/BaseFocusable/index.tsx +2 -3
  15. package/Components/Cell/Cell.tsx +11 -16
  16. package/Components/Cell/CellWithFocusable.tsx +50 -59
  17. package/Components/Cell/CellWrapper.tsx +18 -0
  18. package/Components/Cell/TvOSCellComponent.tsx +20 -26
  19. package/Components/Cell/__tests__/CellWIthFocusable.test.js +13 -6
  20. package/Components/Cell/index.js +3 -1
  21. package/Components/Cell/styles.ts +17 -0
  22. package/Components/CellRendererResolver/__tests__/cellRendererResolver.test.js +46 -48
  23. package/Components/CellRendererResolver/index.ts +2 -1
  24. package/Components/ComponentResolver/__tests__/__snapshots__/componentResolver.test.js.snap +1 -42
  25. package/Components/ComponentResolver/__tests__/componentResolver.test.js +16 -22
  26. package/Components/ContentScreen/__tests__/contentScreen.test.js +3 -3
  27. package/Components/ErrorScreen/index.tsx +14 -6
  28. package/Components/Focusable/Focusable.tsx +1 -0
  29. package/Components/Focusable/FocusableTvOS.tsx +6 -2
  30. package/Components/Focusable/Touchable.tsx +19 -20
  31. package/Components/Focusable/index.android.tsx +10 -3
  32. package/Components/FocusableCell/index.tsx +1 -1
  33. package/Components/FocusableGroup/FocusableTvOS.tsx +34 -86
  34. package/Components/FocusableGroup/index.tsx +0 -3
  35. package/Components/FocusableList/index.tsx +26 -10
  36. package/Components/FocusableScrollView/index.tsx +43 -13
  37. package/Components/HandlePlayable/HandlePlayable.tsx +21 -27
  38. package/Components/Layout/TV/LayoutBackground.tsx +28 -0
  39. package/Components/Layout/TV/NavBarContainer.tsx +19 -23
  40. package/Components/Layout/TV/ScreenContainer.tsx +8 -2
  41. package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +5 -0
  42. package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +2 -1
  43. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +3 -2
  44. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +3 -2
  45. package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +15 -10
  46. package/Components/Layout/TV/__tests__/index.test.tsx +8 -2
  47. package/Components/Layout/TV/index.tsx +6 -20
  48. package/Components/Layout/TV/index.web.tsx +4 -1
  49. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -3
  50. package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +66 -0
  51. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +4 -1
  52. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +10 -15
  53. package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +11 -7
  54. package/Components/MasterCell/DefaultComponents/ImageBorderContainer/__tests__/index.test.ts +93 -0
  55. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -2
  56. package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +1 -1
  57. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
  58. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/const.ts +3 -0
  59. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +6 -6
  60. package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +2 -8
  61. package/Components/MasterCell/__tests__/__snapshots__/elementMapper.test.js.snap +4 -12
  62. package/Components/MasterCell/__tests__/__snapshots__/masterCell.test.js.snap +0 -229
  63. package/Components/MasterCell/__tests__/elementMapper.test.js +18 -5
  64. package/Components/MasterCell/__tests__/masterCell.test.js +26 -26
  65. package/Components/MasterCell/hooks/useAsyncRendering/MasterCellAsyncRenderManager.ts +2 -2
  66. package/Components/MasterCell/hooks/useAsyncRendering/index.ts +2 -2
  67. package/Components/MasterCell/utils/behaviorProvider.ts +136 -0
  68. package/Components/MasterCell/utils/index.ts +9 -135
  69. package/Components/ModalComponent/BottomSheetModalContent.tsx +45 -19
  70. package/Components/ModalComponent/Button/Item.tsx +6 -5
  71. package/Components/ModalComponent/Button/assets.ts +1 -1
  72. package/Components/ModalComponent/Button/index.tsx +30 -43
  73. package/Components/ModalComponent/Header/index.tsx +3 -3
  74. package/Components/ModalComponent/utils.ts +55 -7
  75. package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +2 -2
  76. package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +2 -2
  77. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -5
  78. package/Components/OfflineHandler/utils/index.ts +1 -1
  79. package/Components/PlayerContainer/PlayerContainer.tsx +43 -21
  80. package/Components/PlayerContainer/PlayerContainerContext.tsx +9 -0
  81. package/Components/PlayerContainer/ProgramInfo/index.tsx +2 -2
  82. package/Components/PlayerImageBackground/index.tsx +1 -1
  83. package/Components/River/ComponentsMap/ComponentsMap.tsx +42 -65
  84. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +78 -51
  85. package/Components/River/RiverFooter.tsx +39 -9
  86. package/Components/River/RiverItem.tsx +39 -3
  87. package/Components/River/TV/index.tsx +6 -1
  88. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +100 -31
  89. package/Components/River/__tests__/__snapshots__/river.test.js.snap +20 -82
  90. package/Components/River/__tests__/componentsMap.test.js +17 -5
  91. package/Components/River/__tests__/river.test.js +75 -40
  92. package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +11 -4
  93. package/Components/RouteManager/__tests__/routeManager.test.js +29 -14
  94. package/Components/RouteManager/__tests__/testId.test.js +8 -6
  95. package/Components/Screen/TV/index.web.tsx +5 -6
  96. package/Components/Screen/hooks.ts +53 -0
  97. package/Components/Screen/index.tsx +16 -42
  98. package/Components/ScreenResolver/__tests__/screenResolver.test.js +91 -70
  99. package/Components/Tabs/Tab.tsx +11 -9
  100. package/Components/TextInputTv/index.tsx +4 -3
  101. package/Components/TopMarginApplicator/TopMarginApplicator.tsx +2 -3
  102. package/Components/TrackedView/index.tsx +1 -0
  103. package/Components/Transitioner/AnimationManager.js +15 -15
  104. package/Components/Transitioner/Scene.tsx +53 -24
  105. package/Components/Transitioner/Transitioner.tsx +3 -3
  106. package/Components/Transitioner/__tests__/Scene.test.js +25 -14
  107. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +9 -49
  108. package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +2 -2
  109. package/Components/Transitioner/__tests__/transitioner.test.js +13 -4
  110. package/Components/Transitioner/index.js +8 -4
  111. package/Components/VideoLive/LiveImageManager.ts +27 -1
  112. package/Components/VideoLive/PlayerLiveImageComponent.tsx +36 -24
  113. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +51 -1
  114. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +1 -5
  115. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +1 -1
  116. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +51 -31
  117. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +8 -4
  118. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +48 -22
  119. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +12 -6
  120. package/Components/VideoModal/ModalAnimation/__tests__/getMoveUpValue.test.ts +108 -0
  121. package/Components/VideoModal/ModalAnimation/const.ts +5 -0
  122. package/Components/VideoModal/ModalAnimation/index.ts +2 -0
  123. package/Components/VideoModal/ModalAnimation/utils.ts +38 -2
  124. package/Components/VideoModal/OpaqueLayer.tsx +33 -0
  125. package/Components/VideoModal/PlayerDetails.tsx +18 -10
  126. package/Components/VideoModal/PlayerWrapper.tsx +43 -39
  127. package/Components/VideoModal/VideoModal.tsx +17 -11
  128. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -1
  129. package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -40
  130. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +0 -90
  131. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +89 -0
  132. package/Components/VideoModal/hooks/index.ts +7 -0
  133. package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +49 -0
  134. package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +91 -0
  135. package/Components/VideoModal/hooks/utils/index.ts +33 -0
  136. package/Components/VideoModal/utils.ts +4 -5
  137. package/Components/Viewport/ViewportAware/__tests__/__snapshots__/viewportAware.test.js.snap +24 -36
  138. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -18
  139. package/Components/Viewport/__tests__/utils.test.js +5 -4
  140. package/Components/ZappUIComponent/Placeholder.tsx +3 -1
  141. package/Components/ZappUIComponent/__tests__/{ZappUIComponent.test.js → ZappUIComponent.test.tsx} +26 -10
  142. package/Components/ZappUIComponent/index.tsx +4 -17
  143. package/Components/default-cell-renderer/__tests__/defaultCellRenderer.test.tsx +20 -17
  144. package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/__tests__/DefaultCell.test.tsx +15 -11
  145. package/Contexts/ComponentsMapOffsetContext/index.tsx +49 -0
  146. package/Contexts/FocusableGroupContext/withFocusableContext.tsx +4 -10
  147. package/Contexts/HeaderOffsetContext/index.tsx +4 -6
  148. package/Contexts/ScreenContext/index.tsx +6 -12
  149. package/Contexts/ScreenLayoutContext/index.tsx +5 -3
  150. package/Decorators/Navigator/__tests__/navigator.test.js +16 -16
  151. package/Decorators/Navigator/index.tsx +1 -1
  152. package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +18 -24
  153. package/Decorators/RiverResolver/index.tsx +6 -8
  154. package/Decorators/ZappPipesDataConnector/__tests__/Hero.js +1 -1
  155. package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +29 -22
  156. package/Decorators/ZappPipesDataConnector/index.tsx +6 -2
  157. package/package.json +7 -11
  158. package/tsconfig.json +2 -3
  159. package/.babelrc +0 -8
  160. package/Components/Cell/CellStyles/FallbackCellStyle/index.js +0 -157
  161. package/Components/Cell/CellStyles/Hero/index.js +0 -111
  162. package/Components/Cell/CellStyles/ScreenSelector/index.js +0 -68
  163. package/Components/Cell/CellStyles/cellStylesResolver.ts +0 -19
  164. package/Components/Cell/CellStyles/colors.js +0 -40
  165. package/Components/Cell/CellStyles/index.js +0 -15
  166. package/Components/CellRendererResolver/__tests__/__snapshots__/cellRendererResolver.test.js.snap +0 -53
  167. package/Components/RouteManager/__tests__/__snapshots__/testId.test.js.snap +0 -17
  168. package/Components/ScreenResolver/__tests__/__snapshots__/screenResolver.test.js.snap +0 -17
  169. package/Components/ZappUIComponent/__tests__/__snapshots__/ZappUIComponent.test.js.snap +0 -91
  170. package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +0 -338
  171. package/Decorators/Navigator/__tests__/__snapshots__/navigator.test.js.snap +0 -18
  172. package/Decorators/RiverResolver/__tests__/__snapshots__/riverResolver.test.tsx.snap +0 -28
@@ -1,32 +1,34 @@
1
1
  import React from "react";
2
- import { Animated, StyleSheet, View, Platform } from "react-native";
2
+ import { Animated, Platform, StyleSheet, View } from "react-native";
3
3
 
4
4
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
5
5
  import {
6
+ GestureHandlerRootView,
6
7
  NativeViewGestureHandler,
7
8
  PanGestureHandler,
8
9
  State,
9
10
  TapGestureHandler,
10
- GestureHandlerRootView,
11
11
  } from "react-native-gesture-handler";
12
12
 
13
13
  import { PlayerContainerContext } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainerContext";
14
14
  import {
15
- useModalAnimationContext,
16
15
  PlayerAnimationStateEnum,
16
+ useModalAnimationContext,
17
17
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
18
18
  import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
19
19
  import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
20
20
 
21
21
  import {
22
- setScrollModalAnimatedValue,
23
22
  resetScrollAnimatedValues,
23
+ setScrollModalAnimatedValue,
24
24
  } from "./utils";
25
25
 
26
+ import { DURATION_TO_MINIMIZE } from "./const";
27
+
26
28
  const getAnimatedConfig = (toValue) => {
27
29
  return {
28
30
  toValue,
29
- duration: 200,
31
+ duration: DURATION_TO_MINIMIZE,
30
32
  useNativeDriver: true,
31
33
  };
32
34
  };
@@ -62,25 +64,34 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
62
64
  } = useModalAnimationContext();
63
65
 
64
66
  const [enableGesture, setIEnableGesture] = React.useState<boolean>(true);
65
- const { isLanguageOverlayVisible } = React.useContext(PlayerContainerContext);
67
+
68
+ const { isLanguageOverlayVisible, isSeekBarTouch } = React.useContext(
69
+ PlayerContainerContext
70
+ );
66
71
 
67
72
  const { maximiseVideoModal, minimiseVideoModal, videoModalState } =
68
73
  useNavigation();
69
74
 
70
- const { mode: videoModalMode, item: videoModalItem } = videoModalState;
71
- const isMaximazedModal = videoModalMode === "MAXIMIZED";
72
- const isMinimizedModal = videoModalMode === "MINIMIZED";
75
+ const {
76
+ mode: videoModalMode,
77
+ previousMode: previousVideoModalMode,
78
+ item: videoModalItem,
79
+ } = videoModalState;
80
+
81
+ const isMaximizedModal: boolean = videoModalMode === "MAXIMIZED";
82
+ const isMinimizedModal: boolean = videoModalMode === "MINIMIZED";
73
83
  const previousItemId = usePrevious(videoModalItem?.id);
74
84
 
75
85
  const isNotMinimizeMaximazeAnimation =
76
86
  playerAnimationState !== PlayerAnimationStateEnum.minimize &&
77
- playerAnimationState !== PlayerAnimationStateEnum.maximaze;
87
+ playerAnimationState !== PlayerAnimationStateEnum.maximize;
78
88
 
79
89
  const isEnablePanGesture =
80
90
  enableGesture &&
81
91
  !isLanguageOverlayVisible &&
82
92
  isNotMinimizeMaximazeAnimation &&
83
- (isMaximazedModal || isMinimizedModal);
93
+ !isSeekBarTouch &&
94
+ (isMaximizedModal || isMinimizedModal);
84
95
 
85
96
  const isAudioItem = React.useMemo(
86
97
  () =>
@@ -117,7 +128,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
117
128
  const preparedTranslationY =
118
129
  Math.abs(translationY) - lastScrollYValue.current;
119
130
 
120
- if (videoModalMode === "MAXIMIZED") {
131
+ if (isMaximizedModal) {
121
132
  const endOffsetY =
122
133
  lastSnap + preparedTranslationY + dragToss * velocityY + 150;
123
134
 
@@ -139,8 +150,8 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
139
150
  translateYOffset.flattenOffset();
140
151
  dragScrollY.setValue(0);
141
152
 
142
- setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
143
- } else {
153
+ setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
154
+ } else if (destSnapPoint !== modalSnapPoints[0] && isMaximizedModal) {
144
155
  setPlayerAnimationState(PlayerAnimationStateEnum.minimize);
145
156
  }
146
157
  } else {
@@ -154,7 +165,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
154
165
 
155
166
  dragScrollY.setValue(0);
156
167
 
157
- setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
168
+ setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
158
169
  } else {
159
170
  resetPlayerAnimationState();
160
171
  }
@@ -164,7 +175,13 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
164
175
  resetPlayerAnimationState();
165
176
  }
166
177
  },
167
- [lastSnap, modalSnapPoints, playerAnimationState, videoModalMode]
178
+ [
179
+ lastSnap,
180
+ modalSnapPoints,
181
+ playerAnimationState,
182
+ isMinimizedModal,
183
+ isMaximizedModal,
184
+ ]
168
185
  );
169
186
 
170
187
  const onScroll = React.useCallback(({ nativeEvent }) => {
@@ -215,17 +232,18 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
215
232
  }, []);
216
233
 
217
234
  React.useEffect(() => {
218
- const { mode, previousMode, item } = videoModalState;
219
-
220
235
  if (
221
- mode === "MAXIMIZED" &&
236
+ videoModalMode === "MAXIMIZED" &&
222
237
  !enableGesture &&
223
238
  scrollPosition.current === 0
224
239
  ) {
225
240
  setIEnableGesture(true);
226
241
  }
227
242
 
228
- if (mode === "MINIMIZED" && previousMode === "MAXIMIZED") {
243
+ if (
244
+ videoModalMode === "MINIMIZED" &&
245
+ previousVideoModalMode === "MAXIMIZED"
246
+ ) {
229
247
  // set animation to the minimize values if moving from the player to another screen
230
248
  if (playerAnimationState === null) {
231
249
  setScrollModalAnimatedValue(
@@ -243,14 +261,16 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
243
261
  }
244
262
  } else if (
245
263
  playerAnimationState === null &&
246
- ((previousItemId === item?.id &&
247
- mode === "MAXIMIZED" &&
248
- (previousMode === "MINIMIZED" || previousMode === "MAXIMIZED")) ||
249
- (previousItemId !== item?.id && mode !== "FULLSCREEN"))
264
+ ((previousItemId === videoModalItem?.id &&
265
+ videoModalMode === "MAXIMIZED" &&
266
+ (previousVideoModalMode === "MINIMIZED" ||
267
+ previousVideoModalMode === "MAXIMIZED")) ||
268
+ (previousItemId !== videoModalItem?.id &&
269
+ videoModalMode !== "FULLSCREEN"))
250
270
  ) {
251
- setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
271
+ setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
252
272
  }
253
- }, [videoModalState]);
273
+ }, [videoModalMode, previousVideoModalMode, videoModalItem]);
254
274
 
255
275
  React.useEffect(() => {
256
276
  if (playerAnimationState === PlayerAnimationStateEnum.minimize) {
@@ -292,7 +312,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
292
312
 
293
313
  resetPlayerAnimationState();
294
314
  });
295
- } else if (playerAnimationState === PlayerAnimationStateEnum.maximaze) {
315
+ } else if (playerAnimationState === PlayerAnimationStateEnum.maximize) {
296
316
  Animated.timing(translateYOffset, getAnimatedConfig(0)).start(() => {
297
317
  maximiseVideoModal();
298
318
  setScrollModalAnimatedValue(translateYOffset, 0, setLastSnap);
@@ -342,6 +362,8 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
342
362
  []
343
363
  );
344
364
 
365
+ const scrollEnabled = isMaximizedModal && isNotMinimizeMaximazeAnimation;
366
+
345
367
  return (
346
368
  <Wrapper style={generalStyles.container}>
347
369
  <TapGestureHandler
@@ -355,7 +377,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
355
377
  enabled={isEnablePanGesture}
356
378
  ref={panHandlerRef}
357
379
  simultaneousHandlers={[scrollRef, tapHandlerRef]}
358
- shouldCancelWhenOutside={isMaximazedModal}
380
+ shouldCancelWhenOutside={isMaximizedModal}
359
381
  onGestureEvent={onGestureEvent}
360
382
  onHandlerStateChange={onHandlerStateChange}
361
383
  activeOffsetY={[-5, 5]}
@@ -367,9 +389,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
367
389
  simultaneousHandlers={panHandlerRef}
368
390
  >
369
391
  <Animated.ScrollView
370
- scrollEnabled={
371
- isMaximazedModal && isNotMinimizeMaximazeAnimation
372
- }
392
+ scrollEnabled={scrollEnabled}
373
393
  bounces={false}
374
394
  onScrollBeginDrag={onRegisterLastScroll}
375
395
  onScroll={onScroll}
@@ -41,17 +41,21 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
41
41
  videoModalState: { mode: videoModalMode },
42
42
  } = useNavigation();
43
43
 
44
- const { isLanguageOverlayVisible } = React.useContext(PlayerContainerContext);
44
+ const { isLanguageOverlayVisible, isSeekBarTouch } = React.useContext(
45
+ PlayerContainerContext
46
+ );
47
+
45
48
  const isMaximazedModal = videoModalMode === "MAXIMIZED";
46
49
  const isMinimizedModal = videoModalMode === "MINIMIZED";
47
50
 
48
51
  const isNotMinimizeMaximazeAnimation =
49
52
  playerAnimationState !== PlayerAnimationStateEnum.minimize &&
50
- playerAnimationState !== PlayerAnimationStateEnum.maximaze;
53
+ playerAnimationState !== PlayerAnimationStateEnum.maximize;
51
54
 
52
55
  const isEnablePanGesture =
53
56
  !isLanguageOverlayVisible &&
54
57
  isNotMinimizeMaximazeAnimation &&
58
+ !isSeekBarTouch &&
55
59
  (isMaximazedModal || isMinimizedModal);
56
60
 
57
61
  const onGestureEvent = Animated.event(
@@ -85,7 +89,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
85
89
  setLastSnap(destSnapPoint);
86
90
 
87
91
  if (destSnapPoint === modalSnapPoints[0]) {
88
- setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
92
+ setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
89
93
  } else {
90
94
  lastScrollY.setValue(0);
91
95
  lastScrollYValue.current = 0;
@@ -101,7 +105,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
101
105
  modalSnapPoints[1] - preparedTranslationY
102
106
  );
103
107
 
104
- setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
108
+ setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
105
109
  } else {
106
110
  resetPlayerAnimationState();
107
111
  }
@@ -4,28 +4,31 @@ import { Animated, View } from "react-native";
4
4
  import { useSafeAreaInsets } from "react-native-safe-area-context";
5
5
 
6
6
  import {
7
- useModalAnimationContext,
8
7
  PlayerAnimationStateEnum,
8
+ useModalAnimationContext,
9
9
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
10
10
 
11
11
  import {
12
+ useDimensions,
12
13
  useGetBottomTabBarHeight,
13
14
  useNavigation,
14
- useDimensions,
15
15
  } from "@applicaster/zapp-react-native-utils/reactHooks";
16
16
  import { useIsRTL } from "@applicaster/zapp-react-native-utils/localizationUtils";
17
17
  import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
18
18
  import { useAppState } from "@applicaster/zapp-react-native-utils/reactHooks/app";
19
19
 
20
20
  import {
21
- gestureListenerHelper,
22
- getAnimationStyle,
21
+ AUDIO_PLAYER_HORIZONTAL_PADDING,
22
+ ComponentAnimationType,
23
23
  defaultAspectRatioWidth,
24
+ gestureListenerHelper,
24
25
  getAnimationDefaultValue,
25
- ComponentAnimationType,
26
- AUDIO_PLAYER_HORIZONTAL_PADDING,
26
+ getAnimationStyle,
27
+ getMoveUpValue,
27
28
  } from "./utils";
28
29
 
30
+ import { DURATION_TO_MINIMIZE, DEFAULT_DURATION_FOR_ANIMATION } from "./const";
31
+
29
32
  type Props = {
30
33
  animationType: string;
31
34
  children: React.ReactNode;
@@ -77,7 +80,7 @@ export const AnimationView = ({
77
80
  const measureView = React.useCallback(() => {
78
81
  if (isTabletLandscape && tabletLandscapePlayerTopPosition === 0) {
79
82
  animationComponentRef.current.measure(
80
- (x, y, width, height, pageX, pageY) => {
83
+ (_x, _y, _width, _height, _pageX, pageY) => {
81
84
  setTabletLandscapePlayerTopPosition(pageY - 20);
82
85
  }
83
86
  );
@@ -97,13 +100,16 @@ export const AnimationView = ({
97
100
 
98
101
  const inlineAudioPlayer = additionalData.inlineAudioPlayer;
99
102
 
100
- const moveUpValue = additionalData.saveArea
101
- ? -insets.top + (isAudioItem ? 0 : progressBarHeight)
102
- : isTablet
103
- ? isTabletLandscape && (!isAudioItem || (isAudioItem && inlineAudioPlayer))
104
- ? -tabletLandscapePlayerTopPosition + progressBarHeight
105
- : -130
106
- : -50 + progressBarHeight;
103
+ const moveUpValue = getMoveUpValue({
104
+ additionalData,
105
+ insets,
106
+ isAudioItem,
107
+ progressBarHeight,
108
+ isTablet,
109
+ isTabletLandscape,
110
+ inlineAudioPlayer,
111
+ tabletLandscapePlayerTopPosition,
112
+ });
107
113
 
108
114
  const moveComponentHorizontalValue = additionalData.moveValue
109
115
  ? isRTL
@@ -118,7 +124,10 @@ export const AnimationView = ({
118
124
  (animationType, state) => {
119
125
  const defaultConfig = {
120
126
  toValue: 0,
121
- duration: state === PlayerAnimationStateEnum.minimize ? 150 : 100,
127
+ duration:
128
+ state === PlayerAnimationStateEnum.minimize
129
+ ? DURATION_TO_MINIMIZE
130
+ : DEFAULT_DURATION_FOR_ANIMATION,
122
131
  useNativeDriver: true,
123
132
  };
124
133
 
@@ -227,6 +236,8 @@ export const AnimationView = ({
227
236
  isAudioItem,
228
237
  moveUpValue,
229
238
  moveComponentHorizontalValue,
239
+ isRTL,
240
+ inlineAudioPlayer,
230
241
  ]
231
242
  );
232
243
 
@@ -245,7 +256,7 @@ export const AnimationView = ({
245
256
  default:
246
257
  return getAnimationValue(
247
258
  animationType,
248
- PlayerAnimationStateEnum.maximaze
259
+ PlayerAnimationStateEnum.maximize
249
260
  ).toValue;
250
261
  }
251
262
  }, [defaultValue, videoModalState]);
@@ -277,6 +288,11 @@ export const AnimationView = ({
277
288
  moveUpValue,
278
289
  moveComponentHorizontalValue,
279
290
  videoModalMode,
291
+ isAudioItem,
292
+ isTablet,
293
+ isTabletLandscape,
294
+ isRTL,
295
+ inlineAudioPlayer,
280
296
  ]
281
297
  );
282
298
 
@@ -305,7 +321,7 @@ export const AnimationView = ({
305
321
  }
306
322
 
307
323
  if (
308
- videoModalMode === "MAXIMIZED" &&
324
+ (videoModalMode === "MAXIMIZED" || videoModalMode === "MINIMIZED") &&
309
325
  defaultValue.x !== screenWidth &&
310
326
  width &&
311
327
  height
@@ -331,7 +347,13 @@ export const AnimationView = ({
331
347
  animatedValue.setValue(value);
332
348
  }
333
349
  }
334
- }, [videoModalState]);
350
+ }, [
351
+ animatedValue,
352
+ animationType,
353
+ getAnimationValue,
354
+ playerAnimationState,
355
+ videoModalState,
356
+ ]);
335
357
 
336
358
  React.useEffect(() => {
337
359
  if (
@@ -343,7 +365,7 @@ export const AnimationView = ({
343
365
  animatedValue,
344
366
  getAnimationValue(animationType, playerAnimationState)
345
367
  ).start();
346
- } else if (playerAnimationState === PlayerAnimationStateEnum.maximaze) {
368
+ } else if (playerAnimationState === PlayerAnimationStateEnum.maximize) {
347
369
  animatedValue.setValue(defaultValue);
348
370
  }
349
371
  }, [playerAnimationState, startComponentsAnimation, defaultValue]);
@@ -404,7 +426,7 @@ export const AnimationView = ({
404
426
 
405
427
  return (
406
428
  <Animated.View
407
- onLayout={additionalData.useLayoutMeasure && measureView}
429
+ onLayout={additionalData.useLayoutMeasure ? measureView : undefined}
408
430
  ref={animationComponentRef}
409
431
  style={[
410
432
  ...preparedStyles,
@@ -426,6 +448,10 @@ export const AnimationComponent = (props: Props) => {
426
448
  videoModalState: { visible },
427
449
  } = useNavigation();
428
450
 
451
+ if (additionalData?.disableAnimatedComponent) {
452
+ return <>{props.children}</>;
453
+ }
454
+
429
455
  const useAnimation =
430
456
  visible && !additionalData.disableAnimatedComponent && !isTV();
431
457
 
@@ -434,8 +460,8 @@ export const AnimationComponent = (props: Props) => {
434
460
  const Component = useAnimation
435
461
  ? AnimationView
436
462
  : style
437
- ? View
438
- : React.Fragment;
463
+ ? View
464
+ : React.Fragment;
439
465
 
440
466
  if (
441
467
  additionalData.extraAnimation &&
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React, { useEffect } from "react";
2
2
  import { Animated } from "react-native";
3
3
 
4
4
  import {
@@ -14,12 +14,12 @@ import { useConfiguration } from "../utils";
14
14
 
15
15
  export enum PlayerAnimationStateEnum {
16
16
  minimize = "minimize",
17
- maximaze = "maximaze",
17
+ maximize = "maximize",
18
18
  drag_player = "drag_player",
19
19
  drag_scroll = "drag_scroll",
20
20
  }
21
21
 
22
- type PlayerAnimationStateT = number | PlayerAnimationStateEnum | null;
22
+ export type PlayerAnimationStateT = number | PlayerAnimationStateEnum | null;
23
23
 
24
24
  export type ModalAnimationContextT = {
25
25
  isActiveGesture: boolean;
@@ -95,6 +95,13 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
95
95
  setStartComponentsAnimation(false);
96
96
  }, []);
97
97
 
98
+ useEffect(() => {
99
+ // Reset player animation state when video modal is closed
100
+ if (!visible) {
101
+ resetPlayerAnimationState();
102
+ }
103
+ }, [visible, resetPlayerAnimationState]);
104
+
98
105
  // Animated values
99
106
  const lastScrollY = React.useRef(new Animated.Value(0)).current;
100
107
  const dragScrollY = React.useRef(new Animated.Value(0)).current;
@@ -118,11 +125,10 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
118
125
  If bottomTabBarHeight is equal 0 it means an app does not use bottomTabBar.
119
126
  Because of this we need to minus bottom SafeArea offset.
120
127
  */
128
+
121
129
  const minValue =
122
130
  height -
123
- minimisedHeight -
124
- (bottomTabBarHeight || bottomSafeArea) -
125
- progressBarHeight;
131
+ (minimisedHeight + bottomTabBarHeight + progressBarHeight + bottomSafeArea);
126
132
 
127
133
  const modalSnapPoints = React.useMemo(() => [0, minValue], [minValue]);
128
134
  // Last snap state which will helps us to make smooth responder to scrollview animation
@@ -0,0 +1,108 @@
1
+ import { getMoveUpValue } from "../utils";
2
+
3
+ describe("getMoveUpValue", () => {
4
+ it("returns correct value when additionalData.saveArea is true and isAudioItem is false", () => {
5
+ const result = getMoveUpValue({
6
+ additionalData: { saveArea: true },
7
+ insets: { top: 20 },
8
+ isAudioItem: false,
9
+ progressBarHeight: 10,
10
+ isTablet: false,
11
+ isTabletLandscape: false,
12
+ inlineAudioPlayer: false,
13
+ tabletLandscapePlayerTopPosition: 100,
14
+ });
15
+
16
+ expect(result).toBe(-20 + 10);
17
+ });
18
+
19
+ it("returns correct value when additionalData.saveArea is true and isAudioItem is true", () => {
20
+ const result = getMoveUpValue({
21
+ additionalData: { saveArea: true },
22
+ insets: { top: 15 },
23
+ isAudioItem: true,
24
+ progressBarHeight: 5,
25
+ isTablet: false,
26
+ isTabletLandscape: false,
27
+ inlineAudioPlayer: false,
28
+ tabletLandscapePlayerTopPosition: 100,
29
+ });
30
+
31
+ expect(result).toBe(-15 + 0);
32
+ });
33
+
34
+ it("returns correct value for audio item (tablet or not)", () => {
35
+ const result = getMoveUpValue({
36
+ additionalData: { marginTop: 30 },
37
+ insets: { top: 0 },
38
+ isAudioItem: true,
39
+ progressBarHeight: 0,
40
+ isTablet: false,
41
+ isTabletLandscape: false,
42
+ inlineAudioPlayer: false,
43
+ tabletLandscapePlayerTopPosition: 0,
44
+ });
45
+
46
+ expect(result).toBe(-30);
47
+ });
48
+
49
+ it("returns correct value for tablet landscape with inline audio player", () => {
50
+ const result = getMoveUpValue({
51
+ additionalData: {},
52
+ insets: { top: 0 },
53
+ isAudioItem: true,
54
+ progressBarHeight: 8,
55
+ isTablet: true,
56
+ isTabletLandscape: true,
57
+ inlineAudioPlayer: true,
58
+ tabletLandscapePlayerTopPosition: 50,
59
+ });
60
+
61
+ expect(result).toBe(-0);
62
+ });
63
+
64
+ it("returns correct value for tablet landscape without audio item", () => {
65
+ const result = getMoveUpValue({
66
+ additionalData: {},
67
+ insets: { top: 0 },
68
+ isAudioItem: false,
69
+ progressBarHeight: 12,
70
+ isTablet: true,
71
+ isTabletLandscape: true,
72
+ inlineAudioPlayer: false,
73
+ tabletLandscapePlayerTopPosition: 60,
74
+ });
75
+
76
+ expect(result).toBe(-60 + 12);
77
+ });
78
+
79
+ it("returns -130 for tablet portrait (not landscape)", () => {
80
+ const result = getMoveUpValue({
81
+ additionalData: {},
82
+ insets: { top: 0 },
83
+ isAudioItem: false,
84
+ progressBarHeight: 0,
85
+ isTablet: true,
86
+ isTabletLandscape: false,
87
+ inlineAudioPlayer: false,
88
+ tabletLandscapePlayerTopPosition: 0,
89
+ });
90
+
91
+ expect(result).toBe(-130);
92
+ });
93
+
94
+ it("returns -50 + progressBarHeight for mobile audio player in docked mode", () => {
95
+ const result = getMoveUpValue({
96
+ additionalData: {},
97
+ insets: { top: 0 },
98
+ isAudioItem: false,
99
+ progressBarHeight: 7,
100
+ isTablet: false,
101
+ isTabletLandscape: false,
102
+ inlineAudioPlayer: false,
103
+ tabletLandscapePlayerTopPosition: 0,
104
+ });
105
+
106
+ expect(result).toBe(-50 + 7);
107
+ });
108
+ });
@@ -0,0 +1,5 @@
1
+ export const DURATION_TO_MINIMIZE = 200; // old value 200
2
+
3
+ export const DURATION_TO_MAXIMIZE = 0;
4
+
5
+ export const DEFAULT_DURATION_FOR_ANIMATION = 200; // old value 100
@@ -14,3 +14,5 @@ export { useModalAnimationContext } from "./useModalAnimationContext";
14
14
  export { AnimationComponent } from "./AnimationComponent";
15
15
 
16
16
  export { ComponentAnimationType, defaultAspectRatioWidth } from "./utils";
17
+
18
+ export { DURATION_TO_MINIMIZE, DURATION_TO_MAXIMIZE } from "./const";
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable padding-line-between-statements */
2
2
 
3
3
  import { PlayerAnimationStateEnum } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
4
+ import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
4
5
 
5
6
  export enum ComponentAnimationType {
6
7
  bottomBar = "bottomBar",
@@ -108,8 +109,8 @@ export const calculateAnimationValue = (animationType, dragPosition, data) => {
108
109
  : { forWidth: 3, forHeight: 3 }
109
110
  : { forWidth: 2, forHeight: 2 }
110
111
  : isTabletLandscape
111
- ? { forWidth: 8, forHeight: 6.5 }
112
- : { forWidth: 3.5, forHeight: 2 };
112
+ ? { forWidth: 8, forHeight: 6.5 }
113
+ : { forWidth: 3.5, forHeight: 2 };
113
114
 
114
115
  const minWidth =
115
116
  isAudioItem && !inlineAudioPlayer ? minimisedHeight : minimisedWidth;
@@ -300,3 +301,38 @@ export const resetScrollAnimatedValues = (
300
301
  dragScrollY.setValue(0);
301
302
  dragVideoPlayerY.setValue(0);
302
303
  };
304
+
305
+ export const getMoveUpValue = ({
306
+ additionalData,
307
+ insets,
308
+ isAudioItem,
309
+ progressBarHeight,
310
+ isTablet,
311
+ isTabletLandscape,
312
+ inlineAudioPlayer,
313
+ tabletLandscapePlayerTopPosition,
314
+ }) => {
315
+ if (additionalData.saveArea) {
316
+ return -insets.top + (isAudioItem ? 0 : progressBarHeight);
317
+ }
318
+
319
+ if (isAudioItem) {
320
+ // for any layouts in audioPlayer
321
+ return -1 * toNumberWithDefaultZero(additionalData?.marginTop);
322
+ }
323
+
324
+ if (isTablet) {
325
+ if (
326
+ isTabletLandscape &&
327
+ (!isAudioItem || (isAudioItem && inlineAudioPlayer))
328
+ ) {
329
+ return -tabletLandscapePlayerTopPosition + progressBarHeight;
330
+ }
331
+
332
+ // for audioPlayer(tablet/isTabletPortrait) in docked mode
333
+ return -130;
334
+ }
335
+
336
+ // for audioPlayer(mobile) in docked mode
337
+ return -50 + progressBarHeight;
338
+ };
@@ -0,0 +1,33 @@
1
+ import * as React from "react";
2
+ import { StyleSheet, View } from "react-native";
3
+
4
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
5
+
6
+ import { Spinner } from "../Spinner";
7
+
8
+ const styles = StyleSheet.create({
9
+ container: {
10
+ ...StyleSheet.absoluteFillObject,
11
+ alignItems: "center",
12
+ justifyContent: "center",
13
+ },
14
+ });
15
+
16
+ export const OpaqueLayer = () => {
17
+ const theme = useTheme();
18
+
19
+ return (
20
+ <View
21
+ style={[
22
+ styles.container,
23
+ {
24
+ // we assume that it's non-transparent and we could show spinner always until it will be covered by player
25
+ // this spinner hides all content under modal
26
+ backgroundColor: theme?.app_background_color,
27
+ },
28
+ ]}
29
+ >
30
+ <Spinner />
31
+ </View>
32
+ );
33
+ };