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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/Components/Cell/Cell.tsx +29 -10
  2. package/Components/Focusable/__tests__/index.android.test.tsx +72 -0
  3. package/Components/Focusable/index.android.tsx +15 -9
  4. package/Components/FocusableList/FocusableChild.ts +2 -2
  5. package/Components/FocusableList/index.tsx +11 -12
  6. package/Components/FocusableScrollView/index.tsx +1 -1
  7. package/Components/FreezeWithCallback/Freeze.tsx +31 -0
  8. package/Components/FreezeWithCallback/LICENSE +21 -0
  9. package/Components/FreezeWithCallback/Suspender.tsx +17 -0
  10. package/Components/FreezeWithCallback/__tests__/index.test.tsx +170 -0
  11. package/Components/FreezeWithCallback/index.tsx +3 -0
  12. package/Components/Image/Image.android.tsx +1 -1
  13. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +11 -7
  14. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +1 -7
  15. package/Components/MasterCell/DefaultComponents/CellBadge/index.tsx +6 -1
  16. package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +12 -0
  17. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +6 -5
  18. package/Components/MasterCell/DefaultComponents/Image/Image.web.tsx +2 -2
  19. package/Components/MasterCell/DefaultComponents/ImageBorderContainer/index.ts +71 -0
  20. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
  21. package/Components/MasterCell/DefaultComponents/index.ts +2 -0
  22. package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +7 -1
  23. package/Components/MasterCell/dataAdapter.ts +21 -7
  24. package/Components/MasterCell/index.tsx +5 -3
  25. package/Components/MasterCell/utils/index.ts +3 -4
  26. package/Components/PlayerContainer/PlayerContainer.tsx +14 -8
  27. package/Components/Screen/TV/hooks/index.ts +0 -2
  28. package/Components/Screen/TV/index.web.tsx +32 -19
  29. package/Components/Screen/__tests__/Screen.test.tsx +0 -49
  30. package/Components/Screen/index.tsx +2 -20
  31. package/Components/Screen/navigationHandler.ts +1 -3
  32. package/Components/Screen/orientationHandler.ts +18 -7
  33. package/Components/Screen/utils.ts +16 -0
  34. package/Components/ScreenResolver/index.tsx +6 -11
  35. package/Components/Transitioner/Scene.tsx +9 -2
  36. package/Components/Transitioner/Transitioner.tsx +38 -23
  37. package/Components/Transitioner/__tests__/Scene.test.js +7 -0
  38. package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +1 -0
  39. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +5 -0
  40. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +3 -9
  41. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +87 -41
  42. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +20 -9
  43. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +41 -22
  44. package/Components/VideoModal/PlayerDetails.tsx +16 -2
  45. package/Components/VideoModal/PlayerWrapper.tsx +101 -67
  46. package/Components/VideoModal/VideoModal.tsx +33 -27
  47. package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +7 -0
  48. package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -0
  49. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +78 -16
  50. package/Components/ZappFrameworkComponents/BarView/BarView.tsx +7 -3
  51. package/Components/ZappFrameworkComponents/BarView/Buttons/BackButton.tsx +7 -2
  52. package/Components/ZappFrameworkComponents/BarView/Buttons/CloseButton.tsx +7 -2
  53. package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +87 -0
  54. package/Components/ZappFrameworkComponents/Buttons/ActionButton.tsx +9 -4
  55. package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +4 -4
  56. package/Contexts/CachedDimensionsContext/index.ts +13 -9
  57. package/Contexts/ConfirmDialogState/index.ts +1 -1
  58. package/Contexts/ScreenContext/index.tsx +6 -1
  59. package/README.md +1 -13
  60. package/const.ts +6 -0
  61. package/index.js +3 -0
  62. package/package.json +5 -5
  63. package/Components/Screen/TV/hooks/useRestoreFocus.ts +0 -22
@@ -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
  };
@@ -60,9 +60,14 @@ export const AnimationView = ({
60
60
  const {
61
61
  width: screenWidth,
62
62
  deviceInfo: { isTablet, isTabletLandscape },
63
- } = useDimensions("window", { deviceInfo: true });
63
+ } = useDimensions("window", {
64
+ deviceInfo: true,
65
+ updateForInactiveScreens: true,
66
+ });
64
67
 
65
68
  const { videoModalState } = useNavigation();
69
+ const { mode: videoModalMode, item: videoModalItem } = videoModalState;
70
+
66
71
  const insets = useSafeAreaInsets();
67
72
  const bottomTabBarHeight = useGetBottomTabBarHeight() + (insets.bottom || 0);
68
73
  const minimisedWidth = defaultAspectRatioWidth(minimisedHeight);
@@ -85,9 +90,9 @@ export const AnimationView = ({
85
90
 
86
91
  const isAudioItem = React.useMemo(
87
92
  () =>
88
- videoModalState.item?.content?.type?.includes?.("audio") ||
89
- videoModalState.item?.type?.value === "audio",
90
- [videoModalState.item]
93
+ videoModalItem?.content?.type?.includes?.("audio") ||
94
+ videoModalItem?.type?.value === "audio",
95
+ [videoModalItem]
91
96
  );
92
97
 
93
98
  const inlineAudioPlayer = additionalData.inlineAudioPlayer;
@@ -226,10 +231,8 @@ export const AnimationView = ({
226
231
  );
227
232
 
228
233
  const getInitialValue = React.useCallback(() => {
229
- const mode =
230
- videoModalState.mode === "PIP"
231
- ? videoModalState.previousMode
232
- : videoModalState.mode;
234
+ const { mode: videoModalMode, previousMode } = videoModalState;
235
+ const mode = videoModalMode === "PIP" ? previousMode : videoModalMode;
233
236
 
234
237
  switch (mode) {
235
238
  case "MINIMIZED":
@@ -263,7 +266,7 @@ export const AnimationView = ({
263
266
  isTablet,
264
267
  isTabletLandscape,
265
268
  isRTL,
266
- fromMiniPlayer: videoModalState.mode === "MINIMIZED",
269
+ fromMiniPlayer: videoModalMode === "MINIMIZED",
267
270
  inlineAudioPlayer,
268
271
  }),
269
272
  [
@@ -273,7 +276,7 @@ export const AnimationView = ({
273
276
  defaultValue,
274
277
  moveUpValue,
275
278
  moveComponentHorizontalValue,
276
- videoModalState.mode,
279
+ videoModalMode,
277
280
  ]
278
281
  );
279
282
 
@@ -301,19 +304,40 @@ export const AnimationView = ({
301
304
  typeof additionalData.height === "number" && additionalData.height;
302
305
  }
303
306
 
304
- if (defaultValue.x === 0 && width && height) {
307
+ if (
308
+ videoModalMode === "MAXIMIZED" &&
309
+ defaultValue.x !== screenWidth &&
310
+ width &&
311
+ height
312
+ ) {
305
313
  const value = { x: width, y: height };
306
314
  setDefaultValue(value);
307
315
  animatedValue.setValue(value);
308
316
  }
309
317
  }
310
- }, [additionalData, screenWidth]);
318
+ }, [screenWidth]);
319
+
320
+ React.useEffect(() => {
321
+ const { mode, previousMode } = videoModalState;
322
+
323
+ if (mode === "MINIMIZED" && previousMode === "MAXIMIZED") {
324
+ // set animation to the minimize values if moving from the player to another screen
325
+ if (playerAnimationState === null) {
326
+ const value = getAnimationValue(
327
+ animationType,
328
+ PlayerAnimationStateEnum.minimize
329
+ ).toValue;
330
+
331
+ animatedValue.setValue(value);
332
+ }
333
+ }
334
+ }, [videoModalState]);
311
335
 
312
336
  React.useEffect(() => {
313
337
  if (
314
338
  playerAnimationState === PlayerAnimationStateEnum.minimize &&
315
339
  startComponentsAnimation &&
316
- videoModalState.mode === "MAXIMIZED"
340
+ videoModalMode === "MAXIMIZED"
317
341
  ) {
318
342
  Animated.timing(
319
343
  animatedValue,
@@ -322,12 +346,7 @@ export const AnimationView = ({
322
346
  } else if (playerAnimationState === PlayerAnimationStateEnum.maximaze) {
323
347
  animatedValue.setValue(defaultValue);
324
348
  }
325
- }, [
326
- playerAnimationState,
327
- startComponentsAnimation,
328
- videoModalState.mode,
329
- defaultValue,
330
- ]);
349
+ }, [playerAnimationState, startComponentsAnimation, defaultValue]);
331
350
 
332
351
  React.useEffect(() => {
333
352
  const dragVideoPlayerYListenerId = dragVideoPlayerY.addListener(
@@ -389,9 +408,9 @@ export const AnimationView = ({
389
408
  ref={animationComponentRef}
390
409
  style={[
391
410
  ...preparedStyles,
392
- (videoModalState.mode === "MAXIMIZED" ||
393
- videoModalState.mode === "MINIMIZED" ||
394
- (videoModalState.mode === "PIP" && isAppActive)) &&
411
+ (videoModalMode === "MAXIMIZED" ||
412
+ videoModalMode === "MINIMIZED" ||
413
+ (videoModalMode === "PIP" && isAppActive)) &&
395
414
  getAnimationStyle(animationType, animatedValue),
396
415
  ]}
397
416
  >
@@ -1,9 +1,17 @@
1
1
  import React, { useEffect, useRef } from "react";
2
- import { StyleProp, ViewStyle, Animated, Easing } from "react-native";
2
+ import {
3
+ StyleProp,
4
+ ViewStyle,
5
+ Animated,
6
+ Easing,
7
+ Dimensions,
8
+ } from "react-native";
3
9
  import { useTargetScreenData } from "@applicaster/zapp-react-native-utils/reactHooks/screen";
4
10
  import { ComponentsMap } from "@applicaster/zapp-react-native-ui-components/Components/River/ComponentsMap";
5
11
  import { useSafeAreaInsets } from "react-native-safe-area-context";
6
12
 
13
+ const { width: SCREEN_WIDTH } = Dimensions.get("screen");
14
+
7
15
  type Configuration = {
8
16
  [key: string]: any;
9
17
  modal_background_color?: string;
@@ -15,6 +23,7 @@ type Props = {
15
23
  configuration: Configuration;
16
24
  isTabletLandscape: boolean;
17
25
  isAudioPlayer?: boolean;
26
+ isTablet: boolean;
18
27
  };
19
28
 
20
29
  const containerStyle = ({
@@ -31,6 +40,7 @@ export const PlayerDetails = ({
31
40
  configuration,
32
41
  isTabletLandscape,
33
42
  isAudioPlayer,
43
+ isTablet,
34
44
  }: Props) => {
35
45
  const screenData = useTargetScreenData(entry);
36
46
  const insets = useSafeAreaInsets();
@@ -77,7 +87,11 @@ export const PlayerDetails = ({
77
87
  transform: [{ translateY }],
78
88
  opacity,
79
89
  },
80
- // isAudioPlayer && audioMarginStyle,
90
+ {
91
+ // workaround for avoid wrong text-height after going back to portrait rotation
92
+ // we don't see this view in landscape mode, so we are able to use fixed width from portrait mode
93
+ width: isTablet ? undefined : SCREEN_WIDTH,
94
+ },
81
95
  ]}
82
96
  >
83
97
  {screenData && (