@applicaster/zapp-react-native-ui-components 12.0.0-alpha.4433422595 → 12.0.0-alpha.4462655310

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 (78) hide show
  1. package/Components/BaseFocusable/index.tsx +2 -2
  2. package/Components/Cell/Cell.tsx +5 -9
  3. package/Components/Cell/CellWithFocusable.tsx +17 -5
  4. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +13 -6
  5. package/Components/GeneralContentScreen/utils/useCurationAPI.ts +1 -1
  6. package/Components/HandlePlayable/HandlePlayable.tsx +3 -0
  7. package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +10 -50
  8. package/Components/Layout/TV/__tests__/index.test.tsx +19 -75
  9. package/Components/Layout/TV/index.tsx +26 -116
  10. package/Components/Layout/TV/index.web.tsx +33 -0
  11. package/Components/Layout/index.tsx +15 -11
  12. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -0
  13. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +88 -112
  14. package/Components/MasterCell/DefaultComponents/DynamicBadge.tsx +4 -2
  15. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +5 -3
  16. package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +5 -1
  17. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +14 -1
  18. package/Components/MasterCell/DefaultComponents/Text/index.tsx +14 -2
  19. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
  20. package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +24 -9
  21. package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.android.tsx +4 -1
  22. package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.tsx +4 -1
  23. package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +1 -3
  24. package/Components/MasterCell/hooks/useAsyncRendering/index.ts +1 -1
  25. package/Components/MasterCell/utils/index.ts +33 -35
  26. package/Components/MeasurmentsPortal/BasicMeasurementsPortal.tsx +11 -7
  27. package/Components/MeasurmentsPortal/MeasurementsPortal.tsx +10 -1
  28. package/Components/Navigator/StackNavigator.tsx +48 -0
  29. package/Components/Navigator/index.ts +1 -0
  30. package/Components/PlayerContainer/PlayerContainer.tsx +23 -3
  31. package/Components/PlayerImageBackground/index.tsx +34 -8
  32. package/Components/River/ComponentsMap/ComponentsMap.tsx +92 -22
  33. package/Components/River/RefreshControl.tsx +55 -1
  34. package/Components/River/TV/River.tsx +0 -23
  35. package/Components/River/__tests__/componentsMap.test.js +6 -0
  36. package/Components/RouteManager/index.tsx +2 -2
  37. package/Components/Screen/TV/hooks/index.ts +3 -0
  38. package/Components/Screen/TV/hooks/useInitialFocus.ts +70 -0
  39. package/Components/Screen/TV/hooks/useRestoreFocus.ts +22 -0
  40. package/Components/Screen/TV/index.web.tsx +119 -28
  41. package/Components/Screen/__tests__/Screen.test.tsx +3 -0
  42. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +4 -0
  43. package/Components/Screen/index.tsx +64 -25
  44. package/Components/ScreenResolver/index.tsx +3 -1
  45. package/Components/Transitioner/Scene.tsx +24 -19
  46. package/Components/Transitioner/Transitioner.tsx +21 -28
  47. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +6 -2
  48. package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +1 -0
  49. package/Components/VideoLive/LiveImageManager.ts +18 -1
  50. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +20 -5
  51. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +0 -5
  52. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +78 -0
  53. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +352 -0
  54. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +158 -0
  55. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +461 -0
  56. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +154 -0
  57. package/Components/VideoModal/ModalAnimation/index.ts +15 -0
  58. package/Components/VideoModal/ModalAnimation/utils.ts +299 -0
  59. package/Components/VideoModal/PlayerDetails.tsx +3 -3
  60. package/Components/VideoModal/PlayerWrapper.tsx +77 -47
  61. package/Components/VideoModal/VideoModal.tsx +23 -40
  62. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +13 -1
  63. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +151 -119
  64. package/Components/VideoModal/utils.ts +8 -5
  65. package/Components/Viewport/ViewportTracker/ViewportTracker.tsx +31 -40
  66. package/Components/Viewport/ViewportTracker/index.tsx +1 -0
  67. package/Components/Viewport/utils.js +1 -1
  68. package/Contexts/MenuToggleContext/{index.js → index.ts} +16 -0
  69. package/Contexts/ScreenContext/__tests__/__snapshots__/index.test.tsx.snap +3 -0
  70. package/Contexts/ScreenContext/__tests__/index.test.tsx +27 -0
  71. package/Contexts/ScreenContext/index.tsx +94 -25
  72. package/Contexts/ScreenDataContext/index.tsx +20 -0
  73. package/Contexts/ZappPipesContext/ZappPipesEntryContext.ts +1 -1
  74. package/events/index.ts +1 -0
  75. package/package.json +5 -5
  76. package/Components/Layout/TV/TransitionOverlay.tsx +0 -64
  77. package/Components/VideoModal/hooks/usePosition.ts +0 -50
  78. /package/Contexts/{index.js → index.ts} +0 -0
@@ -0,0 +1,461 @@
1
+ import React, { useRef, useState } from "react";
2
+ import { Animated, View, StyleSheet } from "react-native";
3
+
4
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
5
+
6
+ import {
7
+ useModalAnimationContext,
8
+ PlayerAnimationStateEnum,
9
+ } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
10
+
11
+ import {
12
+ useGetBottomTabBarHeight,
13
+ useNavigation,
14
+ useDimensions,
15
+ } from "@applicaster/zapp-react-native-utils/reactHooks";
16
+ import { useIsRTL } from "@applicaster/zapp-react-native-utils/localizationUtils";
17
+ import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
18
+ import { useAppState } from "@applicaster/zapp-react-native-utils/reactHooks/app";
19
+
20
+ import {
21
+ gestureListenerHelper,
22
+ getAnimationStyle,
23
+ defaultAspectRatioWidth,
24
+ getAnimationDefaultValue,
25
+ ComponentAnimationType,
26
+ AUDIO_PLAYER_HORIZONTAL_PADDING,
27
+ } from "./utils";
28
+
29
+ type Props = {
30
+ animationType: string;
31
+ children: React.ReactNode;
32
+ style?: Record<string, any>;
33
+ additionalData?: { [key: string]: any };
34
+ };
35
+
36
+ const styles = StyleSheet.create({
37
+ flex: { flex: 1 },
38
+ });
39
+
40
+ export const AnimationView = ({
41
+ animationType,
42
+ style,
43
+ children,
44
+ additionalData = {},
45
+ }: Props) => {
46
+ const {
47
+ startComponentsAnimation,
48
+ setStartComponentsAnimation,
49
+ playerAnimationState,
50
+ minimisedHeight,
51
+ animatedValues: { dragScrollY, dragVideoPlayerY },
52
+ lastScrollYValue,
53
+ scrollPosition,
54
+ tabletLandscapePlayerTopPosition,
55
+ setTabletLandscapePlayerTopPosition,
56
+ modalSnapPoints,
57
+ } = useModalAnimationContext();
58
+
59
+ const isRTL = useIsRTL();
60
+ const isAppActive = useAppState(true);
61
+
62
+ const {
63
+ height: screenHeight,
64
+ width: screenWidth,
65
+ deviceInfo: { isTablet, isTabletLandscape },
66
+ } = useDimensions("window", { deviceInfo: true });
67
+
68
+ const startAnimationDistance = Math.round((screenHeight * 60) / 100);
69
+ const { videoModalState } = useNavigation();
70
+ const bottomTabBarHeight = useGetBottomTabBarHeight();
71
+ const minimisedWidth = defaultAspectRatioWidth(minimisedHeight);
72
+ const insets = useSafeAreaInsets();
73
+ const animationComponentRef = useRef(null);
74
+
75
+ // retrieving top position of the player for tablet landscape mode
76
+ const measureView = React.useCallback(() => {
77
+ if (isTabletLandscape && tabletLandscapePlayerTopPosition === 0) {
78
+ animationComponentRef.current.measure(
79
+ (x, y, width, height, pageX, pageY) => {
80
+ setTabletLandscapePlayerTopPosition(pageY - 20);
81
+ }
82
+ );
83
+ }
84
+ }, [tabletLandscapePlayerTopPosition]);
85
+
86
+ const [defaultValue, setDefaultValue] = useState<any>(
87
+ getAnimationDefaultValue(animationType, bottomTabBarHeight)
88
+ );
89
+
90
+ const isAudioItem = React.useMemo(
91
+ () =>
92
+ videoModalState.item?.content?.type?.includes?.("audio") ||
93
+ videoModalState.item?.type?.value === "audio",
94
+ [videoModalState.item]
95
+ );
96
+
97
+ const inlineAudioPlayer = additionalData.inlineAudioPlayer;
98
+
99
+ const moveUpValue = additionalData.saveArea
100
+ ? -insets.top
101
+ : isTablet
102
+ ? isTabletLandscape && (!isAudioItem || (isAudioItem && inlineAudioPlayer))
103
+ ? -tabletLandscapePlayerTopPosition
104
+ : -130
105
+ : -50;
106
+
107
+ const moveComponentHorizontalValue = additionalData.moveValue
108
+ ? isRTL
109
+ ? additionalData.moveValue
110
+ : -additionalData.moveValue
111
+ : 0;
112
+
113
+ const animationValueType: string =
114
+ animationType === ComponentAnimationType.player ? "ValueXY" : "Value";
115
+
116
+ const getAnimationValue = React.useCallback(
117
+ (animationType, state) => {
118
+ const defaultConfig = {
119
+ toValue: 0,
120
+ duration: state === PlayerAnimationStateEnum.minimize ? 150 : 100,
121
+ useNativeDriver: true,
122
+ };
123
+
124
+ switch (animationType) {
125
+ case ComponentAnimationType.bottomBar: {
126
+ if (state === PlayerAnimationStateEnum.minimize) {
127
+ return defaultConfig;
128
+ }
129
+
130
+ defaultConfig.toValue = defaultValue;
131
+
132
+ return defaultConfig;
133
+ }
134
+
135
+ case ComponentAnimationType.player: {
136
+ if (state === PlayerAnimationStateEnum.minimize) {
137
+ const minWidth =
138
+ isAudioItem && !inlineAudioPlayer
139
+ ? minimisedHeight
140
+ : minimisedWidth;
141
+
142
+ return {
143
+ ...defaultConfig,
144
+ toValue: { x: minWidth, y: minimisedHeight },
145
+ useNativeDriver: false,
146
+ };
147
+ }
148
+
149
+ return {
150
+ ...defaultConfig,
151
+ toValue: defaultValue,
152
+ useNativeDriver: false,
153
+ };
154
+ }
155
+
156
+ case ComponentAnimationType.componentFade: {
157
+ if (state === PlayerAnimationStateEnum.minimize) {
158
+ defaultConfig.toValue = 0;
159
+
160
+ return defaultConfig;
161
+ }
162
+
163
+ defaultConfig.toValue = defaultValue;
164
+
165
+ return defaultConfig;
166
+ }
167
+
168
+ case ComponentAnimationType.componentAppears: {
169
+ if (state === PlayerAnimationStateEnum.minimize) {
170
+ defaultConfig.toValue = 1;
171
+
172
+ return defaultConfig;
173
+ }
174
+
175
+ defaultConfig.toValue = defaultValue;
176
+
177
+ return defaultConfig;
178
+ }
179
+
180
+ case ComponentAnimationType.moveUpComponent: {
181
+ if (state === PlayerAnimationStateEnum.minimize) {
182
+ defaultConfig.toValue = moveUpValue;
183
+
184
+ return defaultConfig;
185
+ }
186
+
187
+ defaultConfig.toValue = defaultValue;
188
+
189
+ return defaultConfig;
190
+ }
191
+
192
+ case ComponentAnimationType.moveComponentHorizontal: {
193
+ if (state === PlayerAnimationStateEnum.minimize) {
194
+ defaultConfig.toValue = moveComponentHorizontalValue;
195
+
196
+ return defaultConfig;
197
+ }
198
+
199
+ defaultConfig.toValue = defaultValue;
200
+
201
+ return defaultConfig;
202
+ }
203
+
204
+ case ComponentAnimationType.audioPlayerPaddingHorizontal: {
205
+ if (state === PlayerAnimationStateEnum.minimize) {
206
+ defaultConfig.toValue = isRTL
207
+ ? AUDIO_PLAYER_HORIZONTAL_PADDING
208
+ : -AUDIO_PLAYER_HORIZONTAL_PADDING;
209
+
210
+ return defaultConfig;
211
+ }
212
+
213
+ defaultConfig.toValue = 0;
214
+
215
+ return defaultConfig;
216
+ }
217
+
218
+ default:
219
+ return defaultConfig;
220
+ }
221
+ },
222
+ [
223
+ defaultValue,
224
+ minimisedWidth,
225
+ minimisedHeight,
226
+ isAudioItem,
227
+ moveUpValue,
228
+ moveComponentHorizontalValue,
229
+ ]
230
+ );
231
+
232
+ const getInitialValue = React.useCallback(() => {
233
+ const mode =
234
+ videoModalState.mode === "PIP"
235
+ ? videoModalState.previousMode
236
+ : videoModalState.mode;
237
+
238
+ switch (mode) {
239
+ case "MINIMIZED":
240
+ return getAnimationValue(
241
+ animationType,
242
+ PlayerAnimationStateEnum.minimize
243
+ ).toValue;
244
+
245
+ case "MAXIMIZED":
246
+ default:
247
+ return getAnimationValue(
248
+ animationType,
249
+ PlayerAnimationStateEnum.maximaze
250
+ ).toValue;
251
+ }
252
+ }, [defaultValue, videoModalState]);
253
+
254
+ const animatedValue = useRef(
255
+ new Animated[animationValueType](getInitialValue())
256
+ ).current;
257
+
258
+ const calculationData = React.useMemo(
259
+ () => ({
260
+ isAudioItem,
261
+ bottomTabBarHeight,
262
+ minimisedHeight,
263
+ minimisedWidth,
264
+ defaultValue,
265
+ moveUpValue,
266
+ moveComponentHorizontalValue,
267
+ isTablet,
268
+ isTabletLandscape,
269
+ isRTL,
270
+ fromMiniPlayer: videoModalState.mode === "MINIMIZED",
271
+ inlineAudioPlayer,
272
+ }),
273
+ [
274
+ bottomTabBarHeight,
275
+ minimisedHeight,
276
+ minimisedWidth,
277
+ defaultValue,
278
+ moveUpValue,
279
+ moveComponentHorizontalValue,
280
+ videoModalState.mode,
281
+ ]
282
+ );
283
+
284
+ React.useEffect(() => {
285
+ if (additionalData.resetAnimationValue) {
286
+ animatedValue.setValue(defaultValue);
287
+ }
288
+ }, [additionalData.resetAnimationValue, defaultValue]);
289
+
290
+ React.useEffect(() => {
291
+ if (animationType === ComponentAnimationType.player) {
292
+ let width, height;
293
+
294
+ if (additionalData.aspectRatio) {
295
+ width = isTabletLandscape ? additionalData.width : screenWidth;
296
+
297
+ height =
298
+ (isTabletLandscape ? additionalData.width : screenWidth) /
299
+ additionalData.aspectRatio;
300
+ } else {
301
+ width =
302
+ typeof additionalData.width === "number" && additionalData.width;
303
+
304
+ height =
305
+ typeof additionalData.height === "number" && additionalData.height;
306
+ }
307
+
308
+ if (defaultValue.x === 0 && width && height) {
309
+ const value = { x: width, y: height };
310
+ setDefaultValue(value);
311
+ animatedValue.setValue(value);
312
+ }
313
+ }
314
+ }, [additionalData, screenWidth]);
315
+
316
+ React.useEffect(() => {
317
+ if (
318
+ playerAnimationState === PlayerAnimationStateEnum.minimize &&
319
+ startComponentsAnimation &&
320
+ videoModalState.mode === "MAXIMIZED"
321
+ ) {
322
+ Animated.timing(
323
+ animatedValue,
324
+ getAnimationValue(animationType, playerAnimationState)
325
+ ).start();
326
+ } else if (playerAnimationState === PlayerAnimationStateEnum.maximaze) {
327
+ animatedValue.setValue(defaultValue);
328
+ }
329
+ }, [
330
+ playerAnimationState,
331
+ startComponentsAnimation,
332
+ videoModalState.mode,
333
+ defaultValue,
334
+ ]);
335
+
336
+ React.useEffect(() => {
337
+ const dragVideoPlayerYListenerId = dragVideoPlayerY.addListener(
338
+ ({ value }) => {
339
+ if (playerAnimationState === PlayerAnimationStateEnum.drag_player) {
340
+ const preparedValue = Math.round(Math.abs(value));
341
+
342
+ gestureListenerHelper({
343
+ listenerValue: value,
344
+ preparedValue,
345
+ animationType,
346
+ animatedValue,
347
+ calculationData,
348
+ modalSnapPoint: modalSnapPoints[1],
349
+ startAnimationDistance,
350
+ startComponentsAnimation,
351
+ setStartComponentsAnimation,
352
+ getAnimationValue,
353
+ });
354
+ }
355
+ }
356
+ );
357
+
358
+ const dragListenerId = dragScrollY.addListener(({ value }) => {
359
+ if (
360
+ scrollPosition.current === 0 &&
361
+ playerAnimationState === PlayerAnimationStateEnum.drag_scroll
362
+ ) {
363
+ const preparedValue = Math.round(
364
+ Math.abs(value) - lastScrollYValue.current
365
+ );
366
+
367
+ gestureListenerHelper({
368
+ listenerValue: value,
369
+ preparedValue,
370
+ animationType,
371
+ animatedValue,
372
+ calculationData,
373
+ modalSnapPoint: modalSnapPoints[1],
374
+ startAnimationDistance,
375
+ startComponentsAnimation,
376
+ setStartComponentsAnimation,
377
+ getAnimationValue,
378
+ });
379
+ }
380
+ });
381
+
382
+ return () => {
383
+ dragScrollY.removeListener(dragListenerId);
384
+ dragVideoPlayerY.removeListener(dragVideoPlayerYListenerId);
385
+ };
386
+ }, [playerAnimationState, calculationData, startComponentsAnimation]);
387
+
388
+ const preparedStyles = Array.isArray(style) ? style : [style];
389
+
390
+ return (
391
+ <Animated.View
392
+ onLayout={additionalData.useLayoutMeasure && measureView}
393
+ ref={animationComponentRef}
394
+ style={[
395
+ ...preparedStyles,
396
+ additionalData.saveArea ? styles.flex : null,
397
+ (videoModalState.mode === "MAXIMIZED" ||
398
+ videoModalState.mode === "MINIMIZED" ||
399
+ (videoModalState.mode === "PIP" && isAppActive)) &&
400
+ getAnimationStyle(animationType, animatedValue),
401
+ ]}
402
+ >
403
+ {children}
404
+ </Animated.View>
405
+ );
406
+ };
407
+
408
+ export const AnimationComponent = (props: Props) => {
409
+ const { additionalData = {}, style } = props;
410
+
411
+ const {
412
+ videoModalState: { visible },
413
+ } = useNavigation();
414
+
415
+ const useAnimation =
416
+ visible && !additionalData.disableAnimatedComponent && !isTV();
417
+
418
+ const isReactFragment = !useAnimation && !style;
419
+
420
+ const Component = useAnimation
421
+ ? AnimationView
422
+ : style
423
+ ? View
424
+ : React.Fragment;
425
+
426
+ if (
427
+ additionalData.extraAnimation &&
428
+ typeof additionalData.extraAnimation === "object" &&
429
+ !Array.isArray(additionalData.extraAnimation) &&
430
+ !!Object.keys(additionalData.extraAnimation).length
431
+ ) {
432
+ const animationType = Object.keys(additionalData.extraAnimation)[0];
433
+ const animationProps = additionalData.extraAnimation[animationType] || {};
434
+ delete additionalData.extraAnimation[animationType];
435
+
436
+ return (
437
+ // @ts-ignore
438
+ <Component {...(isReactFragment ? null : props)}>
439
+ <AnimationComponent
440
+ {...animationProps}
441
+ animationType={animationType}
442
+ additionalData={{
443
+ ...animationProps.additionalData,
444
+ extraAnimation:
445
+ !!Object.keys(additionalData.extraAnimation).length &&
446
+ additionalData.extraAnimation,
447
+ }}
448
+ >
449
+ {props.children}
450
+ </AnimationComponent>
451
+ </Component>
452
+ );
453
+ }
454
+
455
+ if (isReactFragment) {
456
+ // @ts-ignore
457
+ return <Component>{props.children}</Component>;
458
+ }
459
+
460
+ return <Component {...props}>{props.children}</Component>;
461
+ };
@@ -0,0 +1,154 @@
1
+ import React, { useContext } from "react";
2
+ import { Animated } from "react-native";
3
+
4
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
5
+ import {
6
+ useGetBottomTabBarHeight,
7
+ useDimensions,
8
+ } from "@applicaster/zapp-react-native-utils/reactHooks";
9
+
10
+ import { useConfiguration } from "../utils";
11
+
12
+ export enum PlayerAnimationStateEnum {
13
+ minimize = "minimize",
14
+ maximaze = "maximaze",
15
+ drag_player = "drag_player",
16
+ drag_scroll = "drag_scroll",
17
+ }
18
+
19
+ type PlayerAnimationStateT = number | PlayerAnimationStateEnum | null;
20
+
21
+ export type ModalAnimationContextT = {
22
+ isActiveGesture: boolean;
23
+ playerAnimationState: PlayerAnimationStateT;
24
+ setPlayerAnimationState: (value: PlayerAnimationStateT) => void;
25
+ startComponentsAnimation: boolean;
26
+ setStartComponentsAnimation: (value: boolean) => void;
27
+ resetPlayerAnimationState: () => void;
28
+ minimisedHeight: number;
29
+ animatedValues: {
30
+ lastScrollY: Animated.Value;
31
+ dragScrollY: Animated.Value;
32
+ dragVideoPlayerY: Animated.Value;
33
+ translateYOffset: Animated.Value;
34
+ };
35
+ lastScrollYValue: React.MutableRefObject<number>;
36
+ scrollPosition: React.MutableRefObject<number>;
37
+ modalSnapPoints: number[];
38
+ lastSnap: number;
39
+ setLastSnap: (value: number) => void;
40
+ tabletLandscapePlayerTopPosition: number;
41
+ setTabletLandscapePlayerTopPosition: (value: number) => void;
42
+ };
43
+
44
+ const ReactContext = React.createContext<ModalAnimationContextT>({
45
+ isActiveGesture: false,
46
+ playerAnimationState: null,
47
+ setPlayerAnimationState: () => null,
48
+ startComponentsAnimation: false,
49
+ setStartComponentsAnimation: () => null,
50
+ resetPlayerAnimationState: () => null,
51
+ minimisedHeight: 60,
52
+ animatedValues: {
53
+ lastScrollY: new Animated.Value(0),
54
+ dragScrollY: new Animated.Value(0),
55
+ dragVideoPlayerY: new Animated.Value(0),
56
+ translateYOffset: new Animated.Value(0),
57
+ },
58
+ lastScrollYValue: null,
59
+ scrollPosition: null,
60
+ modalSnapPoints: [0, 0],
61
+ lastSnap: 0,
62
+ setLastSnap: () => null,
63
+ tabletLandscapePlayerTopPosition: 0,
64
+ setTabletLandscapePlayerTopPosition: () => null,
65
+ });
66
+
67
+ export function useModalAnimationContext() {
68
+ return useContext<ModalAnimationContextT>(ReactContext);
69
+ }
70
+
71
+ const Provider = ({ children }: { children: React.ReactNode }) => {
72
+ const [playerAnimationState, setPlayerAnimationState] =
73
+ React.useState<PlayerAnimationStateT>(null);
74
+
75
+ const [
76
+ tabletLandscapePlayerTopPosition,
77
+ setTabletLandscapePlayerTopPosition,
78
+ ] = React.useState<number>(0);
79
+
80
+ const [startComponentsAnimation, setStartComponentsAnimation] =
81
+ React.useState<boolean>(false);
82
+
83
+ const { minimised_height: minimisedHeight } = useConfiguration();
84
+
85
+ const resetPlayerAnimationState = React.useCallback(() => {
86
+ setPlayerAnimationState(null);
87
+ setStartComponentsAnimation(false);
88
+ }, []);
89
+
90
+ // Animated values
91
+ const lastScrollY = React.useRef(new Animated.Value(0)).current;
92
+ const dragScrollY = React.useRef(new Animated.Value(0)).current;
93
+ const translateYOffset = React.useRef(new Animated.Value(0)).current;
94
+ const dragVideoPlayerY = React.useRef(new Animated.Value(0)).current;
95
+
96
+ const { height } = useDimensions("window", { fullDimensions: true });
97
+ const { bottom: bottomSafeArea } = useSafeAreaInsets();
98
+ const bottomTabBarHeight = useGetBottomTabBarHeight();
99
+
100
+ /*
101
+ If bottomTabBarHeight is equal 0 it means an app does not use bottomTabBar.
102
+ Because of this we need to minus bottom SafeArea offset.
103
+ */
104
+ const minValue =
105
+ height - minimisedHeight - (bottomTabBarHeight || bottomSafeArea);
106
+
107
+ const modalSnapPoints = React.useMemo(() => [0, minValue], [minValue]);
108
+ // Last snap state which will helps us to make smooth responder to scrollview animation
109
+ const [lastSnap, setLastSnap] = React.useState<number>(modalSnapPoints[0]);
110
+ // Extracted animated values which we will use for calculations
111
+ const lastScrollYValue = React.useRef<number>(0);
112
+ const scrollPosition = React.useRef<number>(0);
113
+
114
+ return (
115
+ <ReactContext.Provider
116
+ value={{
117
+ startComponentsAnimation,
118
+ setStartComponentsAnimation,
119
+ isActiveGesture: playerAnimationState !== null,
120
+ playerAnimationState,
121
+ setPlayerAnimationState,
122
+ resetPlayerAnimationState,
123
+ minimisedHeight,
124
+ animatedValues: {
125
+ lastScrollY,
126
+ dragScrollY,
127
+ dragVideoPlayerY,
128
+ translateYOffset,
129
+ },
130
+ lastScrollYValue,
131
+ scrollPosition,
132
+ modalSnapPoints,
133
+ lastSnap,
134
+ setLastSnap,
135
+ tabletLandscapePlayerTopPosition,
136
+ setTabletLandscapePlayerTopPosition,
137
+ }}
138
+ >
139
+ {children}
140
+ </ReactContext.Provider>
141
+ );
142
+ };
143
+
144
+ export const withModalAnimationProvider = (Component) => {
145
+ const WithProvider = (props) => {
146
+ return (
147
+ <Provider>
148
+ <Component {...props} />
149
+ </Provider>
150
+ );
151
+ };
152
+
153
+ return WithProvider;
154
+ };
@@ -0,0 +1,15 @@
1
+ export { AnimatedPlayerModalWrapper } from "./AnimatedPlayerModalWrapper";
2
+
3
+ export { AnimatedScrollModal } from "./AnimatedScrollModal";
4
+
5
+ export { AnimatedVideoPlayerComponent } from "./AnimatedVideoPlayerComponent";
6
+
7
+ export {
8
+ withModalAnimationProvider,
9
+ useModalAnimationContext,
10
+ PlayerAnimationStateEnum,
11
+ } from "./ModalAnimationContext";
12
+
13
+ export { AnimationComponent } from "./AnimationComponent";
14
+
15
+ export { ComponentAnimationType, defaultAspectRatioWidth } from "./utils";