@applicaster/zapp-react-native-ui-components 13.0.0-alpha.1124981321 → 13.0.0-alpha.1173186260

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 (157) hide show
  1. package/Components/AppContainer/__tests__/AppContainer.test.js +4 -6
  2. package/Components/AudioPlayer/AudioPlayer.tsx +7 -4
  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 -1
  13. package/Components/BaseFocusable/index.tsx +1 -2
  14. package/Components/Cell/Cell.tsx +4 -13
  15. package/Components/Cell/CellWithFocusable.tsx +50 -59
  16. package/Components/Cell/CellWrapper.tsx +18 -0
  17. package/Components/Cell/TvOSCellComponent.tsx +20 -22
  18. package/Components/Cell/__tests__/CellWIthFocusable.test.js +13 -6
  19. package/Components/Cell/index.js +3 -1
  20. package/Components/Cell/styles.ts +17 -0
  21. package/Components/CellRendererResolver/__tests__/cellRendererResolver.test.js +46 -48
  22. package/Components/CellRendererResolver/index.ts +2 -1
  23. package/Components/ComponentResolver/__tests__/__snapshots__/componentResolver.test.js.snap +1 -42
  24. package/Components/ComponentResolver/__tests__/componentResolver.test.js +16 -22
  25. package/Components/ContentScreen/__tests__/contentScreen.test.js +3 -3
  26. package/Components/ErrorScreen/index.tsx +14 -6
  27. package/Components/Focusable/Focusable.tsx +1 -0
  28. package/Components/Focusable/FocusableTvOS.tsx +5 -1
  29. package/Components/Focusable/index.android.tsx +10 -3
  30. package/Components/FocusableCell/index.tsx +1 -1
  31. package/Components/FocusableGroup/FocusableTvOS.tsx +34 -86
  32. package/Components/FocusableGroup/index.tsx +0 -3
  33. package/Components/FocusableList/index.tsx +26 -9
  34. package/Components/FocusableScrollView/index.tsx +43 -13
  35. package/Components/GeneralContentScreen/GeneralContentScreen.tsx +3 -0
  36. package/Components/GeneralContentScreen/utils/useCurationAPI.ts +4 -2
  37. package/Components/GeneralContentScreen/utils/useEventAlerts.ts +30 -0
  38. package/Components/HandlePlayable/HandlePlayable.tsx +21 -27
  39. package/Components/Layout/TV/LayoutBackground.tsx +28 -0
  40. package/Components/Layout/TV/NavBarContainer.tsx +19 -23
  41. package/Components/Layout/TV/ScreenContainer.tsx +8 -2
  42. package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +5 -0
  43. package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +2 -1
  44. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +3 -2
  45. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +3 -2
  46. package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +15 -10
  47. package/Components/Layout/TV/__tests__/index.test.tsx +8 -2
  48. package/Components/Layout/TV/index.tsx +6 -20
  49. package/Components/Layout/TV/index.web.tsx +4 -1
  50. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -3
  51. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +4 -3
  52. package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +11 -7
  53. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -2
  54. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/const.ts +3 -0
  55. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +6 -6
  56. package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +2 -8
  57. package/Components/MasterCell/__tests__/__snapshots__/elementMapper.test.js.snap +4 -12
  58. package/Components/MasterCell/__tests__/__snapshots__/masterCell.test.js.snap +0 -229
  59. package/Components/MasterCell/__tests__/elementMapper.test.js +18 -5
  60. package/Components/MasterCell/__tests__/masterCell.test.js +26 -26
  61. package/Components/MasterCell/hooks/useAsyncRendering/MasterCellAsyncRenderManager.ts +2 -2
  62. package/Components/MasterCell/utils/behaviorProvider.ts +136 -0
  63. package/Components/MasterCell/utils/index.ts +8 -134
  64. package/Components/ModalComponent/BottomSheetModalContent.tsx +59 -43
  65. package/Components/ModalComponent/Button/Item.tsx +6 -5
  66. package/Components/ModalComponent/Button/assets.ts +1 -1
  67. package/Components/ModalComponent/Button/index.tsx +45 -62
  68. package/Components/ModalComponent/Header/index.tsx +12 -11
  69. package/Components/ModalComponent/utils.ts +55 -7
  70. package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +2 -2
  71. package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +2 -2
  72. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -5
  73. package/Components/OfflineHandler/utils/index.ts +1 -1
  74. package/Components/PlayerContainer/PlayerContainer.tsx +42 -15
  75. package/Components/PlayerContainer/ProgramInfo/index.tsx +2 -2
  76. package/Components/PlayerImageBackground/index.tsx +1 -1
  77. package/Components/River/ComponentsMap/ComponentsMap.tsx +42 -65
  78. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +78 -51
  79. package/Components/River/RiverFooter.tsx +39 -9
  80. package/Components/River/RiverItem.tsx +39 -3
  81. package/Components/River/TV/index.tsx +6 -1
  82. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +100 -31
  83. package/Components/River/__tests__/__snapshots__/river.test.js.snap +20 -82
  84. package/Components/River/__tests__/componentsMap.test.js +3 -4
  85. package/Components/River/__tests__/river.test.js +75 -40
  86. package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +11 -4
  87. package/Components/RouteManager/__tests__/routeManager.test.js +29 -14
  88. package/Components/RouteManager/__tests__/testId.test.js +8 -6
  89. package/Components/Screen/TV/__tests__/index.web.test.tsx +26 -0
  90. package/Components/Screen/TV/index.web.tsx +5 -6
  91. package/Components/Screen/__tests__/Screen.test.tsx +22 -14
  92. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +2 -2
  93. package/Components/Screen/hooks.ts +3 -6
  94. package/Components/Screen/index.tsx +4 -4
  95. package/Components/ScreenResolver/__tests__/screenResolver.test.js +91 -70
  96. package/Components/Tabs/Tab.tsx +5 -3
  97. package/Components/TextInputTv/index.tsx +2 -1
  98. package/Components/TopMarginApplicator/TopMarginApplicator.tsx +2 -3
  99. package/Components/TrackedView/index.tsx +1 -0
  100. package/Components/Transitioner/AnimationManager.js +15 -15
  101. package/Components/Transitioner/Scene.tsx +1 -1
  102. package/Components/Transitioner/Transitioner.tsx +3 -3
  103. package/Components/Transitioner/__tests__/Scene.test.js +25 -14
  104. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +12 -68
  105. package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +2 -2
  106. package/Components/Transitioner/__tests__/transitioner.test.js +13 -4
  107. package/Components/VideoLive/PlayerLiveImageComponent.tsx +7 -3
  108. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +1 -0
  109. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +1 -1
  110. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +46 -30
  111. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +3 -3
  112. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +45 -21
  113. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +12 -6
  114. package/Components/VideoModal/ModalAnimation/__tests__/getMoveUpValue.test.ts +108 -0
  115. package/Components/VideoModal/ModalAnimation/const.ts +5 -0
  116. package/Components/VideoModal/ModalAnimation/index.ts +2 -0
  117. package/Components/VideoModal/ModalAnimation/utils.ts +30 -0
  118. package/Components/VideoModal/PlayerDetails.tsx +18 -10
  119. package/Components/VideoModal/PlayerWrapper.tsx +37 -24
  120. package/Components/VideoModal/VideoModal.tsx +19 -4
  121. package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -40
  122. package/Components/VideoModal/utils.ts +3 -4
  123. package/Components/Viewport/ViewportAware/__tests__/__snapshots__/viewportAware.test.js.snap +24 -36
  124. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -18
  125. package/Components/Viewport/__tests__/utils.test.js +5 -4
  126. package/Components/ZappUIComponent/Placeholder.tsx +3 -1
  127. package/Components/ZappUIComponent/__tests__/{ZappUIComponent.test.js → ZappUIComponent.test.tsx} +26 -10
  128. package/Components/ZappUIComponent/index.tsx +4 -17
  129. package/Components/default-cell-renderer/__tests__/defaultCellRenderer.test.tsx +20 -17
  130. package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/__tests__/DefaultCell.test.tsx +15 -11
  131. package/Contexts/ComponentsMapOffsetContext/index.tsx +49 -0
  132. package/Contexts/FocusableGroupContext/withFocusableContext.tsx +4 -10
  133. package/Contexts/HeaderOffsetContext/index.tsx +4 -6
  134. package/Contexts/ScreenContext/index.tsx +3 -10
  135. package/Contexts/ScreenLayoutContext/index.tsx +5 -3
  136. package/Decorators/Navigator/__tests__/navigator.test.js +16 -16
  137. package/Decorators/Navigator/index.tsx +1 -1
  138. package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +18 -24
  139. package/Decorators/RiverResolver/index.tsx +6 -8
  140. package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +29 -22
  141. package/Decorators/ZappPipesDataConnector/index.tsx +4 -30
  142. package/package.json +7 -11
  143. package/tsconfig.json +2 -3
  144. package/.babelrc +0 -8
  145. package/Components/Cell/CellStyles/FallbackCellStyle/index.js +0 -157
  146. package/Components/Cell/CellStyles/Hero/index.js +0 -111
  147. package/Components/Cell/CellStyles/ScreenSelector/index.js +0 -68
  148. package/Components/Cell/CellStyles/cellStylesResolver.ts +0 -19
  149. package/Components/Cell/CellStyles/colors.js +0 -40
  150. package/Components/Cell/CellStyles/index.js +0 -15
  151. package/Components/CellRendererResolver/__tests__/__snapshots__/cellRendererResolver.test.js.snap +0 -53
  152. package/Components/RouteManager/__tests__/__snapshots__/testId.test.js.snap +0 -17
  153. package/Components/ScreenResolver/__tests__/__snapshots__/screenResolver.test.js.snap +0 -17
  154. package/Components/ZappUIComponent/__tests__/__snapshots__/ZappUIComponent.test.js.snap +0 -91
  155. package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +0 -338
  156. package/Decorators/Navigator/__tests__/__snapshots__/navigator.test.js.snap +0 -18
  157. package/Decorators/RiverResolver/__tests__/__snapshots__/riverResolver.test.tsx.snap +0 -28
@@ -1,9 +1,18 @@
1
1
  import React from "react";
2
2
  import { Text, View } from "react-native";
3
- import { shallow } from "enzyme";
4
- import { shallowToJson } from "enzyme-to-json";
5
3
 
6
4
  import { TransitionerComponent } from "../Transitioner";
5
+ import { render } from "@testing-library/react-native";
6
+
7
+ jest.mock("../Scene", () => {
8
+ const View = jest.requireActual("react-native").View;
9
+
10
+ return {
11
+ Scene(props) {
12
+ return <View {...props} />;
13
+ },
14
+ };
15
+ });
7
16
 
8
17
  const children = (
9
18
  <View foo="bar">
@@ -33,12 +42,12 @@ jest.mock("uuid");
33
42
 
34
43
  describe("<TransitionerComponent />", () => {
35
44
  it("renders correctly", () => {
36
- const wrapper = shallow(
45
+ const wrapper = render(
37
46
  <TransitionerComponent {...transitionerComponentProps}>
38
47
  {children}
39
48
  </TransitionerComponent>
40
49
  );
41
50
 
42
- expect(shallowToJson(wrapper)).toMatchSnapshot();
51
+ expect(wrapper.toJSON()).toMatchSnapshot();
43
52
  });
44
53
  });
@@ -1,6 +1,7 @@
1
1
  // /// <reference types="@applicaster/applicaster-types" />
2
2
  //
3
3
  import * as React from "react";
4
+ import { useEffect } from "react";
4
5
 
5
6
  import { AppState, AppStateStatus, View } from "react-native";
6
7
  import { TrackedView } from "../TrackedView";
@@ -25,13 +26,15 @@ import { PlayerRole } from "@applicaster/zapp-react-native-utils/appUtils/player
25
26
  import { getAutoplaySettings } from "./utils";
26
27
  import { isString } from "@applicaster/zapp-react-native-utils/stringUtils";
27
28
  import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
28
- import { useEffect } from "react";
29
29
 
30
30
  const { log_error, log_debug } = loggerLiveImageComponent;
31
31
 
32
32
  const isMeasurement = (item: ZappEntry) =>
33
33
  isString(item.id) && item.id.startsWith("pre-measurement-");
34
34
 
35
+ // Pixels by which the view can slightly extend outside the viewport and still be considered fully visible.
36
+ const CLIP_THRESHOLD = 10;
37
+
35
38
  type Props = {
36
39
  item: ZappEntry;
37
40
  style: Record<string, any>;
@@ -328,9 +331,10 @@ const PlayerLiveImageComponent = (props: Props) => {
328
331
  <TrackedView
329
332
  testId={`tracked-view-${playerId}-${item.title}`}
330
333
  onPositionUpdated={onPositionUpdated}
334
+ clipThreshold={CLIP_THRESHOLD}
331
335
  >
332
336
  <View ref={trackViewRef}>
333
- {isVideoMode && (
337
+ {isVideoMode ? (
334
338
  <Player
335
339
  autoplay={false}
336
340
  ref={_assignRoot}
@@ -342,7 +346,7 @@ const PlayerLiveImageComponent = (props: Props) => {
342
346
  resizeMode={"cover"}
343
347
  {...platformSpecificProps}
344
348
  />
345
- )}
349
+ ) : null}
346
350
  {
347
351
  <AnimatedInOut
348
352
  visible={isBackgroundImageVisible}
@@ -2,6 +2,7 @@
2
2
 
3
3
  exports[`PlayerLiveImageComponent should render correctly with default props 1`] = `
4
4
  <TrackedView
5
+ clipThreshold={10}
5
6
  onPositionUpdated={[Function]}
6
7
  testId="tracked-view-player1-Test"
7
8
  >
@@ -46,7 +46,7 @@ export const AnimatedPlayerModalWrapper = (props: Props) => {
46
46
 
47
47
  React.useEffect(() => {
48
48
  (playerAnimationState === PlayerAnimationStateEnum.minimize ||
49
- playerAnimationState === PlayerAnimationStateEnum.maximaze) &&
49
+ playerAnimationState === PlayerAnimationStateEnum.maximize) &&
50
50
  setStartComponentsAnimation(true);
51
51
  }, [playerAnimationState]);
52
52
 
@@ -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
  };
@@ -70,21 +72,26 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
70
72
  const { maximiseVideoModal, minimiseVideoModal, videoModalState } =
71
73
  useNavigation();
72
74
 
73
- const { mode: videoModalMode, item: videoModalItem } = videoModalState;
74
- const isMaximazedModal = videoModalMode === "MAXIMIZED";
75
- 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";
76
83
  const previousItemId = usePrevious(videoModalItem?.id);
77
84
 
78
85
  const isNotMinimizeMaximazeAnimation =
79
86
  playerAnimationState !== PlayerAnimationStateEnum.minimize &&
80
- playerAnimationState !== PlayerAnimationStateEnum.maximaze;
87
+ playerAnimationState !== PlayerAnimationStateEnum.maximize;
81
88
 
82
89
  const isEnablePanGesture =
83
90
  enableGesture &&
84
91
  !isLanguageOverlayVisible &&
85
92
  isNotMinimizeMaximazeAnimation &&
86
93
  !isSeekBarTouch &&
87
- (isMaximazedModal || isMinimizedModal);
94
+ (isMaximizedModal || isMinimizedModal);
88
95
 
89
96
  const isAudioItem = React.useMemo(
90
97
  () =>
@@ -121,7 +128,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
121
128
  const preparedTranslationY =
122
129
  Math.abs(translationY) - lastScrollYValue.current;
123
130
 
124
- if (videoModalMode === "MAXIMIZED") {
131
+ if (isMaximizedModal) {
125
132
  const endOffsetY =
126
133
  lastSnap + preparedTranslationY + dragToss * velocityY + 150;
127
134
 
@@ -143,8 +150,8 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
143
150
  translateYOffset.flattenOffset();
144
151
  dragScrollY.setValue(0);
145
152
 
146
- setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
147
- } else {
153
+ setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
154
+ } else if (destSnapPoint !== modalSnapPoints[0] && isMaximizedModal) {
148
155
  setPlayerAnimationState(PlayerAnimationStateEnum.minimize);
149
156
  }
150
157
  } else {
@@ -158,7 +165,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
158
165
 
159
166
  dragScrollY.setValue(0);
160
167
 
161
- setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
168
+ setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
162
169
  } else {
163
170
  resetPlayerAnimationState();
164
171
  }
@@ -168,7 +175,13 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
168
175
  resetPlayerAnimationState();
169
176
  }
170
177
  },
171
- [lastSnap, modalSnapPoints, playerAnimationState, videoModalMode]
178
+ [
179
+ lastSnap,
180
+ modalSnapPoints,
181
+ playerAnimationState,
182
+ isMinimizedModal,
183
+ isMaximizedModal,
184
+ ]
172
185
  );
173
186
 
174
187
  const onScroll = React.useCallback(({ nativeEvent }) => {
@@ -219,17 +232,18 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
219
232
  }, []);
220
233
 
221
234
  React.useEffect(() => {
222
- const { mode, previousMode, item } = videoModalState;
223
-
224
235
  if (
225
- mode === "MAXIMIZED" &&
236
+ videoModalMode === "MAXIMIZED" &&
226
237
  !enableGesture &&
227
238
  scrollPosition.current === 0
228
239
  ) {
229
240
  setIEnableGesture(true);
230
241
  }
231
242
 
232
- if (mode === "MINIMIZED" && previousMode === "MAXIMIZED") {
243
+ if (
244
+ videoModalMode === "MINIMIZED" &&
245
+ previousVideoModalMode === "MAXIMIZED"
246
+ ) {
233
247
  // set animation to the minimize values if moving from the player to another screen
234
248
  if (playerAnimationState === null) {
235
249
  setScrollModalAnimatedValue(
@@ -247,14 +261,16 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
247
261
  }
248
262
  } else if (
249
263
  playerAnimationState === null &&
250
- ((previousItemId === item?.id &&
251
- mode === "MAXIMIZED" &&
252
- (previousMode === "MINIMIZED" || previousMode === "MAXIMIZED")) ||
253
- (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"))
254
270
  ) {
255
- setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
271
+ setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
256
272
  }
257
- }, [videoModalState]);
273
+ }, [videoModalMode, previousVideoModalMode, videoModalItem]);
258
274
 
259
275
  React.useEffect(() => {
260
276
  if (playerAnimationState === PlayerAnimationStateEnum.minimize) {
@@ -296,7 +312,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
296
312
 
297
313
  resetPlayerAnimationState();
298
314
  });
299
- } else if (playerAnimationState === PlayerAnimationStateEnum.maximaze) {
315
+ } else if (playerAnimationState === PlayerAnimationStateEnum.maximize) {
300
316
  Animated.timing(translateYOffset, getAnimatedConfig(0)).start(() => {
301
317
  maximiseVideoModal();
302
318
  setScrollModalAnimatedValue(translateYOffset, 0, setLastSnap);
@@ -346,6 +362,8 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
346
362
  []
347
363
  );
348
364
 
365
+ const scrollEnabled = isMaximizedModal && isNotMinimizeMaximazeAnimation;
366
+
349
367
  return (
350
368
  <Wrapper style={generalStyles.container}>
351
369
  <TapGestureHandler
@@ -359,7 +377,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
359
377
  enabled={isEnablePanGesture}
360
378
  ref={panHandlerRef}
361
379
  simultaneousHandlers={[scrollRef, tapHandlerRef]}
362
- shouldCancelWhenOutside={isMaximazedModal}
380
+ shouldCancelWhenOutside={isMaximizedModal}
363
381
  onGestureEvent={onGestureEvent}
364
382
  onHandlerStateChange={onHandlerStateChange}
365
383
  activeOffsetY={[-5, 5]}
@@ -371,9 +389,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
371
389
  simultaneousHandlers={panHandlerRef}
372
390
  >
373
391
  <Animated.ScrollView
374
- scrollEnabled={
375
- isMaximazedModal && isNotMinimizeMaximazeAnimation
376
- }
392
+ scrollEnabled={scrollEnabled}
377
393
  bounces={false}
378
394
  onScrollBeginDrag={onRegisterLastScroll}
379
395
  onScroll={onScroll}
@@ -50,7 +50,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
50
50
 
51
51
  const isNotMinimizeMaximazeAnimation =
52
52
  playerAnimationState !== PlayerAnimationStateEnum.minimize &&
53
- playerAnimationState !== PlayerAnimationStateEnum.maximaze;
53
+ playerAnimationState !== PlayerAnimationStateEnum.maximize;
54
54
 
55
55
  const isEnablePanGesture =
56
56
  !isLanguageOverlayVisible &&
@@ -89,7 +89,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
89
89
  setLastSnap(destSnapPoint);
90
90
 
91
91
  if (destSnapPoint === modalSnapPoints[0]) {
92
- setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
92
+ setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
93
93
  } else {
94
94
  lastScrollY.setValue(0);
95
95
  lastScrollYValue.current = 0;
@@ -105,7 +105,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
105
105
  modalSnapPoints[1] - preparedTranslationY
106
106
  );
107
107
 
108
- setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
108
+ setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
109
109
  } else {
110
110
  resetPlayerAnimationState();
111
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;
@@ -91,20 +94,21 @@ export const AnimationView = ({
91
94
  const isAudioItem = React.useMemo(
92
95
  () =>
93
96
  videoModalItem?.content?.type?.includes?.("audio") ||
94
- videoModalItem?.type?.value === "audio",
97
+ videoModalItem?.type?.value?.includes?.("audio"),
95
98
  [videoModalItem]
96
99
  );
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 &&
104
- (!isAudioItem || (isAudioItem && inlineAudioPlayer))
105
- ? -tabletLandscapePlayerTopPosition + progressBarHeight
106
- : -130
107
- : -50 + progressBarHeight;
103
+ const moveUpValue = getMoveUpValue({
104
+ additionalData,
105
+ insets,
106
+ isAudioItem,
107
+ progressBarHeight,
108
+ isTablet,
109
+ isTabletLandscape,
110
+ tabletLandscapePlayerTopPosition,
111
+ });
108
112
 
109
113
  const moveComponentHorizontalValue = additionalData.moveValue
110
114
  ? isRTL
@@ -119,7 +123,10 @@ export const AnimationView = ({
119
123
  (animationType, state) => {
120
124
  const defaultConfig = {
121
125
  toValue: 0,
122
- duration: state === PlayerAnimationStateEnum.minimize ? 150 : 100,
126
+ duration:
127
+ state === PlayerAnimationStateEnum.minimize
128
+ ? DURATION_TO_MINIMIZE
129
+ : DEFAULT_DURATION_FOR_ANIMATION,
123
130
  useNativeDriver: true,
124
131
  };
125
132
 
@@ -228,6 +235,8 @@ export const AnimationView = ({
228
235
  isAudioItem,
229
236
  moveUpValue,
230
237
  moveComponentHorizontalValue,
238
+ isRTL,
239
+ inlineAudioPlayer,
231
240
  ]
232
241
  );
233
242
 
@@ -246,7 +255,7 @@ export const AnimationView = ({
246
255
  default:
247
256
  return getAnimationValue(
248
257
  animationType,
249
- PlayerAnimationStateEnum.maximaze
258
+ PlayerAnimationStateEnum.maximize
250
259
  ).toValue;
251
260
  }
252
261
  }, [defaultValue, videoModalState]);
@@ -278,6 +287,11 @@ export const AnimationView = ({
278
287
  moveUpValue,
279
288
  moveComponentHorizontalValue,
280
289
  videoModalMode,
290
+ isAudioItem,
291
+ isTablet,
292
+ isTabletLandscape,
293
+ isRTL,
294
+ inlineAudioPlayer,
281
295
  ]
282
296
  );
283
297
 
@@ -306,7 +320,7 @@ export const AnimationView = ({
306
320
  }
307
321
 
308
322
  if (
309
- videoModalMode === "MAXIMIZED" &&
323
+ (videoModalMode === "MAXIMIZED" || videoModalMode === "MINIMIZED") &&
310
324
  defaultValue.x !== screenWidth &&
311
325
  width &&
312
326
  height
@@ -332,7 +346,13 @@ export const AnimationView = ({
332
346
  animatedValue.setValue(value);
333
347
  }
334
348
  }
335
- }, [videoModalState]);
349
+ }, [
350
+ animatedValue,
351
+ animationType,
352
+ getAnimationValue,
353
+ playerAnimationState,
354
+ videoModalState,
355
+ ]);
336
356
 
337
357
  React.useEffect(() => {
338
358
  if (
@@ -344,7 +364,7 @@ export const AnimationView = ({
344
364
  animatedValue,
345
365
  getAnimationValue(animationType, playerAnimationState)
346
366
  ).start();
347
- } else if (playerAnimationState === PlayerAnimationStateEnum.maximaze) {
367
+ } else if (playerAnimationState === PlayerAnimationStateEnum.maximize) {
348
368
  animatedValue.setValue(defaultValue);
349
369
  }
350
370
  }, [playerAnimationState, startComponentsAnimation, defaultValue]);
@@ -405,7 +425,7 @@ export const AnimationView = ({
405
425
 
406
426
  return (
407
427
  <Animated.View
408
- onLayout={additionalData.useLayoutMeasure && measureView}
428
+ onLayout={additionalData.useLayoutMeasure ? measureView : undefined}
409
429
  ref={animationComponentRef}
410
430
  style={[
411
431
  ...preparedStyles,
@@ -427,6 +447,10 @@ export const AnimationComponent = (props: Props) => {
427
447
  videoModalState: { visible },
428
448
  } = useNavigation();
429
449
 
450
+ if (additionalData?.disableAnimatedComponent) {
451
+ return <>{props.children}</>;
452
+ }
453
+
430
454
  const useAnimation =
431
455
  visible && !additionalData.disableAnimatedComponent && !isTV();
432
456
 
@@ -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";