@applicaster/zapp-react-native-ui-components 12.0.0-rc.99 → 13.0.0-alpha.2322412833

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 (67) hide show
  1. package/Components/Cell/Cell.tsx +33 -18
  2. package/Components/Cell/CellWithFocusable.tsx +1 -1
  3. package/Components/Cell/TvOSCellComponent.tsx +3 -4
  4. package/Components/Focusable/__tests__/index.android.test.tsx +72 -0
  5. package/Components/Focusable/index.android.tsx +15 -9
  6. package/Components/FocusableList/FocusableChild.ts +2 -2
  7. package/Components/FocusableList/index.tsx +11 -12
  8. package/Components/FocusableScrollView/index.tsx +1 -1
  9. package/Components/FreezeWithCallback/Freeze.tsx +31 -0
  10. package/Components/FreezeWithCallback/LICENSE +21 -0
  11. package/Components/FreezeWithCallback/Suspender.tsx +17 -0
  12. package/Components/FreezeWithCallback/__tests__/index.test.tsx +170 -0
  13. package/Components/FreezeWithCallback/index.tsx +3 -0
  14. package/Components/Image/Image.android.tsx +1 -1
  15. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +11 -7
  16. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +1 -7
  17. package/Components/MasterCell/DefaultComponents/CellBadge/index.tsx +6 -1
  18. package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +12 -0
  19. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +6 -5
  20. package/Components/MasterCell/DefaultComponents/Image/Image.web.tsx +2 -2
  21. package/Components/MasterCell/DefaultComponents/ImageBorderContainer/index.ts +71 -0
  22. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
  23. package/Components/MasterCell/DefaultComponents/index.ts +2 -0
  24. package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +7 -1
  25. package/Components/MasterCell/dataAdapter.ts +21 -7
  26. package/Components/MasterCell/index.tsx +5 -3
  27. package/Components/MasterCell/utils/index.ts +3 -4
  28. package/Components/NativeFocusables/{index.js → index.ts} +4 -2
  29. package/Components/PlayerContainer/PlayerContainer.tsx +14 -8
  30. package/Components/Screen/TV/hooks/index.ts +0 -2
  31. package/Components/Screen/TV/index.web.tsx +32 -19
  32. package/Components/Screen/__tests__/Screen.test.tsx +0 -49
  33. package/Components/Screen/index.tsx +2 -20
  34. package/Components/Screen/navigationHandler.ts +1 -3
  35. package/Components/Screen/orientationHandler.ts +18 -7
  36. package/Components/Screen/utils.ts +16 -0
  37. package/Components/ScreenResolver/index.tsx +6 -11
  38. package/Components/Transitioner/Scene.tsx +9 -2
  39. package/Components/Transitioner/Transitioner.tsx +38 -23
  40. package/Components/Transitioner/__tests__/Scene.test.js +7 -0
  41. package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +1 -0
  42. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +5 -0
  43. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +3 -9
  44. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +87 -41
  45. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +20 -9
  46. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +41 -22
  47. package/Components/VideoModal/PlayerDetails.tsx +16 -2
  48. package/Components/VideoModal/PlayerWrapper.tsx +101 -67
  49. package/Components/VideoModal/VideoModal.tsx +33 -27
  50. package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +7 -0
  51. package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -0
  52. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +78 -16
  53. package/Components/ZappFrameworkComponents/BarView/BarView.tsx +7 -3
  54. package/Components/ZappFrameworkComponents/BarView/Buttons/BackButton.tsx +7 -2
  55. package/Components/ZappFrameworkComponents/BarView/Buttons/CloseButton.tsx +7 -2
  56. package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +87 -0
  57. package/Components/ZappFrameworkComponents/Buttons/ActionButton.tsx +9 -4
  58. package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +4 -4
  59. package/Contexts/CachedDimensionsContext/index.ts +13 -9
  60. package/Contexts/ConfirmDialogState/index.ts +1 -1
  61. package/Contexts/ScreenContext/index.tsx +6 -1
  62. package/Decorators/Analytics/{index.js → index.tsx} +11 -11
  63. package/README.md +1 -13
  64. package/const.ts +6 -0
  65. package/index.js +3 -0
  66. package/package.json +5 -5
  67. package/Components/Screen/TV/hooks/useRestoreFocus.ts +0 -22
@@ -1,6 +1,5 @@
1
1
  import * as React from "react";
2
- import * as R from "ramda";
3
- import { useDispatch } from "react-redux";
2
+ import { path, prop } from "ramda";
4
3
  import {
5
4
  findPluginByType,
6
5
  findPluginByIdentifier,
@@ -15,7 +14,6 @@ import { componentsLogger } from "../../Helpers/logger";
15
14
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
16
15
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
17
16
  import { useScreenAnalytics } from "@applicaster/zapp-react-native-utils/analyticsUtils/helpers/hooks";
18
- import { setAppStateHasFinishedTransitioning } from "@applicaster/zapp-react-native-redux/appState";
19
17
 
20
18
  const logger = componentsLogger.addSubsystem("ScreenResolver");
21
19
 
@@ -54,11 +52,8 @@ export function ScreenResolverComponent(props: Props) {
54
52
 
55
53
  const [, setScreenContext] = ZappPipesScreenContext.useZappPipesContext();
56
54
 
57
- const dispatch = useDispatch();
58
-
59
55
  React.useEffect(() => {
60
56
  setScreenContext(rivers[screenId]);
61
- dispatch(setAppStateHasFinishedTransitioning());
62
57
  }, [screenId]);
63
58
 
64
59
  const ScreenPlugin =
@@ -100,14 +95,14 @@ export function ScreenResolverComponent(props: Props) {
100
95
  }
101
96
 
102
97
  const ScreenComponent =
103
- R.path(["module", "Component"], ScreenPlugin) ||
104
- R.prop("module", ScreenPlugin) ||
105
- R.prop("Component", ScreenPlugin) ||
98
+ path(["module", "Component"], ScreenPlugin) ||
99
+ prop("module", ScreenPlugin) ||
100
+ prop("Component", ScreenPlugin) ||
106
101
  ScreenPlugin;
107
102
 
108
103
  const configuration =
109
- R.prop("configuration", ScreenPlugin) ||
110
- R.prop("__plugin_configuration", ScreenComponent);
104
+ prop("configuration", ScreenPlugin) ||
105
+ prop("__plugin_configuration", ScreenComponent);
111
106
 
112
107
  if (ScreenComponent) {
113
108
  return (
@@ -1,6 +1,9 @@
1
1
  import React from "react";
2
2
  import { Animated, ViewProps, ViewStyle } from "react-native";
3
3
  import { useSafeAreaFrame } from "react-native-safe-area-context";
4
+
5
+ import { useScreenOrientationHandler } from "@applicaster/zapp-react-native-ui-components/Components/Screen/orientationHandler";
6
+
4
7
  import { PathnameContext } from "../../Contexts/PathnameContext";
5
8
  import { ScreenDataContext } from "../../Contexts/ScreenDataContext";
6
9
  import { ScreenContextProvider } from "../../Contexts/ScreenContext";
@@ -42,6 +45,11 @@ export function Scene({
42
45
  }: Props) {
43
46
  const [initialScreenData, setInitialScreenData] = React.useState(screenData);
44
47
 
48
+ useScreenOrientationHandler({
49
+ screenData,
50
+ isActive,
51
+ });
52
+
45
53
  React.useLayoutEffect(() => {
46
54
  if (isActive) {
47
55
  setInitialScreenData(screenData);
@@ -49,13 +57,12 @@ export function Scene({
49
57
  }, [screenData, isActive]);
50
58
 
51
59
  const frame = useSafeAreaFrame();
52
-
53
60
  const isAnimating = animating && overlayStyle;
54
61
 
55
62
  const dimensions = isAnimating
56
63
  ? {
57
- height: "100%",
58
64
  width: "100%",
65
+ height: "100%",
59
66
  }
60
67
  : frame;
61
68
 
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { View } from "react-native";
3
- import * as R from "ramda";
3
+ import { update, compose, tail, append, take, identity, isNil } from "ramda";
4
4
 
5
5
  import { AnimationManager } from "./AnimationManager";
6
6
  import { Scene } from "./Scene";
@@ -46,10 +46,14 @@ function prepareScene(children) {
46
46
  */
47
47
  function scenesForBackTransition(props: SceneProps, { scenes }) {
48
48
  return scenes.length > 1
49
- ? R.identity(scenes)
49
+ ? identity(scenes)
50
50
  : [prepareScene(props.children), scenes[0]];
51
51
  }
52
52
 
53
+ const isModalClosed = (navigator) => {
54
+ return !!isNil(navigator?.modalData);
55
+ };
56
+
53
57
  type Props = {
54
58
  transitionConfig: any;
55
59
  children: React.ReactNode;
@@ -110,7 +114,7 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
110
114
  pushTransitionStart() {
111
115
  this.setState(
112
116
  {
113
- scenes: R.append(prepareScene(this.props.children), this.state.scenes),
117
+ scenes: append(prepareScene(this.props.children), this.state.scenes),
114
118
  ...this.animationManager.stateForAction(this.state, NAV_ACTION_PUSH),
115
119
  },
116
120
  () => {
@@ -166,21 +170,23 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
166
170
 
167
171
  transitionWithoutAnimation(resetState) {
168
172
  const { scenes } = this.state;
169
-
170
- const newState = resetState
171
- ? {
172
- scenes: [prepareScene(this.props.children)],
173
- to: {
174
- index: 0,
175
- },
176
- }
177
- : {
178
- scenes: R.update(
179
- scenes.length - 1,
180
- prepareScene(this.props.children),
181
- scenes
182
- ),
183
- };
173
+ const newScene = prepareScene(this.props.children);
174
+ const isLastSceneHook = scenes[scenes.length - 1].key.startsWith("/hook");
175
+
176
+ let newState;
177
+
178
+ if (resetState) {
179
+ newState = {
180
+ scenes: [newScene],
181
+ to: { index: 0 },
182
+ };
183
+ } else if (isLastSceneHook || scenes.length === 1) {
184
+ newState = { scenes: update(scenes.length - 1, newScene, scenes) };
185
+ } else {
186
+ newState = {
187
+ scenes: compose(tail, append(newScene))(scenes),
188
+ };
189
+ }
184
190
 
185
191
  this.setState(newState);
186
192
  }
@@ -223,7 +229,10 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
223
229
  this.shouldSkipAnimationForRoute(previousRoute) ||
224
230
  this.shouldSkipAnimationForRoute(currentRoute)
225
231
  ) {
226
- return this.transitionWithoutAnimation();
232
+ // we are going back, in this case we need to have only one scene using resetState
233
+ const resetState = isGoingBack ? true : undefined;
234
+
235
+ return this.transitionWithoutAnimation(resetState);
227
236
  }
228
237
 
229
238
  switch (this.props.navigator.previousAction) {
@@ -266,7 +275,7 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
266
275
  backTransitionEnd(stepsBack) {
267
276
  this.setState({
268
277
  animating: false,
269
- scenes: R.take(this.state.scenes.length - stepsBack, this.state.scenes),
278
+ scenes: take(this.state.scenes.length - stepsBack, this.state.scenes),
270
279
  });
271
280
  }
272
281
 
@@ -282,7 +291,7 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
282
291
  <View style={styles.container}>
283
292
  {scenes[to.index] && (
284
293
  <Scene
285
- {...{ style: to.style }}
294
+ {...{ style: to?.style || {} }}
286
295
  pathname={pathname}
287
296
  isActive={pathname === this.props.navigator.currentRoute}
288
297
  contentStyle={contentStyle}
@@ -308,7 +317,10 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
308
317
  <Scene
309
318
  key={scenes[from.index].key}
310
319
  pathname={scenes[from.index].key}
311
- isActive={scenes[from.index].key === this.props.navigator.currentRoute}
320
+ isActive={
321
+ scenes[from.index].key === this.props.navigator.currentRoute &&
322
+ isModalClosed(this.props.navigator)
323
+ }
312
324
  style={from.style}
313
325
  pointerEvents="none"
314
326
  overlayStyle={from.overlayStyle}
@@ -324,7 +336,10 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
324
336
  const toScene = scenes[to.index] && (
325
337
  <Scene
326
338
  pathname={scenes[to.index].key}
327
- isActive={scenes[to.index].key === this.props.navigator.currentRoute}
339
+ isActive={
340
+ scenes[to.index].key === this.props.navigator.currentRoute &&
341
+ isModalClosed(this.props.navigator)
342
+ }
328
343
  key={scenes[to.index].key}
329
344
  style={to.style}
330
345
  overlayStyle={to.overlayStyle}
@@ -16,6 +16,13 @@ jest.mock("react-native-safe-area-context", () => ({
16
16
  })),
17
17
  }));
18
18
 
19
+ jest.mock(
20
+ "@applicaster/zapp-react-native-ui-components/Components/Screen/orientationHandler",
21
+ () => ({
22
+ useScreenOrientationHandler: jest.fn(),
23
+ })
24
+ );
25
+
19
26
  const { Scene } = require("../Scene");
20
27
 
21
28
  const wrapper = shallow(
@@ -12,6 +12,7 @@ exports[`<TransitionerComponent /> renders correctly 1`] = `
12
12
  <Scene
13
13
  isActive={true}
14
14
  screenUniqueId="mocked-uuid"
15
+ style={Object {}}
15
16
  >
16
17
  <View
17
18
  foo="bar"
@@ -31,6 +31,11 @@ exports[`PlayerLiveImageComponent should render correctly with default props 1`]
31
31
  playerId="player1"
32
32
  resizeMode="cover"
33
33
  screenConfig={Object {}}
34
+ source={
35
+ Object {
36
+ "uri": "",
37
+ }
38
+ }
34
39
  style={Object {}}
35
40
  />
36
41
  </View>
@@ -45,15 +45,9 @@ export const AnimatedPlayerModalWrapper = (props: Props) => {
45
45
  }
46
46
 
47
47
  React.useEffect(() => {
48
- const translateYListener = translateY.addListener(() => {
49
- (playerAnimationState === PlayerAnimationStateEnum.minimize ||
50
- playerAnimationState === PlayerAnimationStateEnum.maximaze) &&
51
- setStartComponentsAnimation(true);
52
- });
53
-
54
- return () => {
55
- translateYListener && translateY.removeListener(translateYListener);
56
- };
48
+ (playerAnimationState === PlayerAnimationStateEnum.minimize ||
49
+ playerAnimationState === PlayerAnimationStateEnum.maximaze) &&
50
+ setStartComponentsAnimation(true);
57
51
  }, [playerAnimationState]);
58
52
 
59
53
  return (
@@ -61,29 +61,32 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
61
61
  setStartComponentsAnimation,
62
62
  } = useModalAnimationContext();
63
63
 
64
+ const [enableGesture, setIEnableGesture] = React.useState<boolean>(true);
64
65
  const { isLanguageOverlayVisible } = React.useContext(PlayerContainerContext);
65
66
 
66
67
  const { maximiseVideoModal, minimiseVideoModal, videoModalState } =
67
68
  useNavigation();
68
69
 
69
- const isMaximazedModal = videoModalState.mode === "MAXIMIZED";
70
- const isMinimizedModal = videoModalState.mode === "MINIMIZED";
71
- const previousItemId = usePrevious(videoModalState.item?.id);
70
+ const { mode: videoModalMode, item: videoModalItem } = videoModalState;
71
+ const isMaximazedModal = videoModalMode === "MAXIMIZED";
72
+ const isMinimizedModal = videoModalMode === "MINIMIZED";
73
+ const previousItemId = usePrevious(videoModalItem?.id);
72
74
 
73
75
  const isNotMinimizeMaximazeAnimation =
74
76
  playerAnimationState !== PlayerAnimationStateEnum.minimize &&
75
77
  playerAnimationState !== PlayerAnimationStateEnum.maximaze;
76
78
 
77
79
  const isEnablePanGesture =
80
+ enableGesture &&
78
81
  !isLanguageOverlayVisible &&
79
82
  isNotMinimizeMaximazeAnimation &&
80
83
  (isMaximazedModal || isMinimizedModal);
81
84
 
82
85
  const isAudioItem = React.useMemo(
83
86
  () =>
84
- videoModalState.item?.content?.type?.includes?.("audio") ||
85
- videoModalState.item?.type?.value === "audio",
86
- [videoModalState.item]
87
+ videoModalItem?.content?.type?.includes?.("audio") ||
88
+ videoModalItem?.type?.value === "audio",
89
+ [videoModalItem]
87
90
  );
88
91
 
89
92
  // Refs for components
@@ -114,7 +117,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
114
117
  const preparedTranslationY =
115
118
  Math.abs(translationY) - lastScrollYValue.current;
116
119
 
117
- if (videoModalState.mode === "MAXIMIZED") {
120
+ if (videoModalMode === "MAXIMIZED") {
118
121
  const endOffsetY =
119
122
  lastSnap + preparedTranslationY + dragToss * velocityY + 150;
120
123
 
@@ -161,22 +164,38 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
161
164
  resetPlayerAnimationState();
162
165
  }
163
166
  },
164
- [lastSnap, modalSnapPoints, playerAnimationState, videoModalState.mode]
167
+ [lastSnap, modalSnapPoints, playerAnimationState, videoModalMode]
165
168
  );
166
169
 
167
170
  const onScroll = React.useCallback(({ nativeEvent }) => {
168
171
  scrollPosition.current = nativeEvent.contentOffset.y;
169
172
  }, []);
170
173
 
174
+ // Workaround for onMomentumScrollEnd issue
175
+ // https://github.com/facebook/react-native/issues/32696#issuecomment-1104217223
176
+ const canMomentum = React.useRef(false);
177
+
178
+ const onMomentumScrollBegin = React.useCallback(() => {
179
+ canMomentum.current = true;
180
+ }, []);
181
+
171
182
  const onMomentumScrollEnd = React.useCallback(
172
183
  ({ nativeEvent }) => {
173
- if (nativeEvent.contentOffset.y === 0 && !isActiveGesture) {
174
- resetScrollAnimatedValues(
175
- lastScrollY,
176
- lastScrollYValue,
177
- dragScrollY,
178
- dragVideoPlayerY
179
- );
184
+ if (canMomentum.current && !isActiveGesture) {
185
+ if (nativeEvent.contentOffset.y === 0) {
186
+ resetScrollAnimatedValues(
187
+ lastScrollY,
188
+ lastScrollYValue,
189
+ dragScrollY,
190
+ dragVideoPlayerY
191
+ );
192
+
193
+ setIEnableGesture(true);
194
+ } else {
195
+ setIEnableGesture(false);
196
+ }
197
+
198
+ canMomentum.current = false;
180
199
  }
181
200
  },
182
201
  [isActiveGesture]
@@ -196,23 +215,42 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
196
215
  }, []);
197
216
 
198
217
  React.useEffect(() => {
218
+ const { mode, previousMode, item } = videoModalState;
219
+
199
220
  if (
200
- videoModalState.mode === "MINIMIZED" &&
201
- videoModalState.previousMode === "MAXIMIZED"
221
+ mode === "MAXIMIZED" &&
222
+ !enableGesture &&
223
+ scrollPosition.current === 0
202
224
  ) {
203
- resetPlayerAnimationState();
225
+ setIEnableGesture(true);
204
226
  }
205
227
 
206
- if (
207
- (videoModalState.mode === "MAXIMIZED" &&
208
- videoModalState.previousMode === "MINIMIZED" &&
209
- previousItemId === videoModalState.item?.id) ||
210
- previousItemId !== videoModalState.item?.id
228
+ if (mode === "MINIMIZED" && previousMode === "MAXIMIZED") {
229
+ // set animation to the minimize values if moving from the player to another screen
230
+ if (playerAnimationState === null) {
231
+ setScrollModalAnimatedValue(
232
+ translateYOffset,
233
+ modalSnapPoints[1],
234
+ setLastSnap
235
+ );
236
+
237
+ resetScrollAnimatedValues(
238
+ lastScrollY,
239
+ lastScrollYValue,
240
+ dragScrollY,
241
+ dragVideoPlayerY
242
+ );
243
+ }
244
+ } else if (
245
+ playerAnimationState === null &&
246
+ ((previousItemId === item?.id &&
247
+ mode === "MAXIMIZED" &&
248
+ (previousMode === "MINIMIZED" || previousMode === "MAXIMIZED")) ||
249
+ (previousItemId !== item?.id && mode !== "FULLSCREEN"))
211
250
  ) {
212
251
  setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
213
- setTimeout(() => resetPlayerAnimationState());
214
252
  }
215
- }, [videoModalState, previousItemId]);
253
+ }, [videoModalState]);
216
254
 
217
255
  React.useEffect(() => {
218
256
  if (playerAnimationState === PlayerAnimationStateEnum.minimize) {
@@ -237,22 +275,22 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
237
275
  translateYOffset,
238
276
  getAnimatedConfig(modalSnapPoints[1])
239
277
  ).start(() => {
240
- setTimeout(() => {
241
- minimiseVideoModal();
278
+ minimiseVideoModal();
242
279
 
243
- setScrollModalAnimatedValue(
244
- translateYOffset,
245
- modalSnapPoints[1],
246
- setLastSnap
247
- );
280
+ setScrollModalAnimatedValue(
281
+ translateYOffset,
282
+ modalSnapPoints[1],
283
+ setLastSnap
284
+ );
248
285
 
249
- resetScrollAnimatedValues(
250
- lastScrollY,
251
- lastScrollYValue,
252
- dragScrollY,
253
- dragVideoPlayerY
254
- );
255
- }, 150);
286
+ resetScrollAnimatedValues(
287
+ lastScrollY,
288
+ lastScrollYValue,
289
+ dragScrollY,
290
+ dragVideoPlayerY
291
+ );
292
+
293
+ resetPlayerAnimationState();
256
294
  });
257
295
  } else if (playerAnimationState === PlayerAnimationStateEnum.maximaze) {
258
296
  Animated.timing(translateYOffset, getAnimatedConfig(0)).start(() => {
@@ -269,7 +307,9 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
269
307
  resetPlayerAnimationState();
270
308
  });
271
309
  }
310
+ }, [playerAnimationState]);
272
311
 
312
+ React.useEffect(() => {
273
313
  const lastScrollYListenerId = lastScrollY.addListener(({ value }) => {
274
314
  lastScrollYValue.current = value;
275
315
  });
@@ -295,7 +335,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
295
335
  lastScrollY.removeListener(lastScrollYListenerId);
296
336
  dragScrollY.removeListener(dragListenerId);
297
337
  };
298
- }, [playerAnimationState, isAudioItem, modalSnapPoints, isMinimizedModal]);
338
+ }, [playerAnimationState, isAudioItem, isMinimizedModal]);
299
339
 
300
340
  const Wrapper = React.useMemo(
301
341
  () => (Platform.OS === "android" ? GestureHandlerRootView : View),
@@ -333,6 +373,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
333
373
  bounces={false}
334
374
  onScrollBeginDrag={onRegisterLastScroll}
335
375
  onScroll={onScroll}
376
+ onMomentumScrollBegin={onMomentumScrollBegin}
336
377
  onMomentumScrollEnd={onMomentumScrollEnd}
337
378
  scrollEventThrottle={1}
338
379
  showsVerticalScrollIndicator={false}
@@ -349,7 +390,12 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
349
390
  };
350
391
 
351
392
  export const AnimatedScrollModal = ({ children }: Props) => {
352
- const Component = !isTV() ? AnimatedScrollModalComponent : React.Fragment;
393
+ const {
394
+ videoModalState: { visible },
395
+ } = useNavigation();
396
+
397
+ const Component =
398
+ !isTV() && visible ? AnimatedScrollModalComponent : React.Fragment;
353
399
 
354
400
  return <Component>{children}</Component>;
355
401
  };
@@ -37,14 +37,22 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
37
37
  setStartComponentsAnimation,
38
38
  } = useModalAnimationContext();
39
39
 
40
- const { videoModalState } = useNavigation();
40
+ const {
41
+ videoModalState: { mode: videoModalMode },
42
+ } = useNavigation();
43
+
41
44
  const { isLanguageOverlayVisible } = React.useContext(PlayerContainerContext);
45
+ const isMaximazedModal = videoModalMode === "MAXIMIZED";
46
+ const isMinimizedModal = videoModalMode === "MINIMIZED";
42
47
 
43
- const isMaximazedModal = videoModalState.mode === "MAXIMIZED";
44
- const isMinimizedModal = videoModalState.mode === "MINIMIZED";
48
+ const isNotMinimizeMaximazeAnimation =
49
+ playerAnimationState !== PlayerAnimationStateEnum.minimize &&
50
+ playerAnimationState !== PlayerAnimationStateEnum.maximaze;
45
51
 
46
52
  const isEnablePanGesture =
47
- !isLanguageOverlayVisible && (isMaximazedModal || isMinimizedModal);
53
+ !isLanguageOverlayVisible &&
54
+ isNotMinimizeMaximazeAnimation &&
55
+ (isMaximazedModal || isMinimizedModal);
48
56
 
49
57
  const onGestureEvent = Animated.event(
50
58
  [{ nativeEvent: { translationY: dragVideoPlayerY } }],
@@ -59,7 +67,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
59
67
  const preparedTranslationY = Math.abs(translationY);
60
68
  const dragToss = 0.05;
61
69
 
62
- if (videoModalState.mode === "MAXIMIZED") {
70
+ if (videoModalMode === "MAXIMIZED") {
63
71
  if (translationY > 0) {
64
72
  const endOffsetY =
65
73
  lastSnap + preparedTranslationY + dragToss * velocityY + 200;
@@ -84,7 +92,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
84
92
  setPlayerAnimationState(PlayerAnimationStateEnum.minimize);
85
93
  }
86
94
  }
87
- } else if (videoModalState.mode === "MINIMIZED") {
95
+ } else if (videoModalMode === "MINIMIZED") {
88
96
  if (translationY < 0) {
89
97
  // from mini to full
90
98
  setLastSnap(modalSnapPoints[0]);
@@ -100,7 +108,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
100
108
  }
101
109
  }
102
110
  },
103
- [lastSnap, modalSnapPoints, videoModalState.mode]
111
+ [lastSnap, modalSnapPoints, videoModalMode]
104
112
  );
105
113
 
106
114
  React.useEffect(() => {
@@ -145,7 +153,6 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
145
153
  return (
146
154
  <PanGestureHandler
147
155
  enabled={isEnablePanGesture}
148
- shouldCancelWhenOutside={isMaximazedModal}
149
156
  onGestureEvent={onGestureEvent}
150
157
  onHandlerStateChange={onHandlerStateChange}
151
158
  >
@@ -155,7 +162,11 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
155
162
  };
156
163
 
157
164
  export const AnimatedVideoPlayerComponent = ({ children }: Props) => {
158
- const Component = !isTV() ? AnimatedVideoPlayer : React.Fragment;
165
+ const {
166
+ videoModalState: { visible },
167
+ } = useNavigation();
168
+
169
+ const Component = !isTV() && visible ? AnimatedVideoPlayer : React.Fragment;
159
170
 
160
171
  return <Component>{children}</Component>;
161
172
  };