@applicaster/zapp-react-native-ui-components 12.0.0-rc.47 → 12.0.0-rc.49

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.
@@ -0,0 +1,143 @@
1
+ import React, { useContext } from "react";
2
+ import { Animated } from "react-native";
3
+
4
+ import { useSafeAreaFrame } from "react-native-safe-area-context";
5
+ import { useGetBottomTabBarHeight } from "@applicaster/zapp-react-native-utils/reactHooks";
6
+
7
+ import { useConfiguration } from "../utils";
8
+
9
+ export enum PlayerAnimationStateEnum {
10
+ minimize = "minimize",
11
+ maximaze = "maximaze",
12
+ drag_player = "drag_player",
13
+ drag_scroll = "drag_scroll",
14
+ }
15
+
16
+ type PlayerAnimationStateT = number | PlayerAnimationStateEnum | null;
17
+
18
+ export type ModalAnimationContextT = {
19
+ isActiveGesture: boolean;
20
+ playerAnimationState: PlayerAnimationStateT;
21
+ setPlayerAnimationState: (value: PlayerAnimationStateT) => void;
22
+ startComponentsAnimation: boolean;
23
+ setStartComponentsAnimation: (value: boolean) => void;
24
+ resetPlayerAnimationState: () => void;
25
+ minimisedHeight: number;
26
+ animatedValues: {
27
+ lastScrollY: Animated.Value;
28
+ dragScrollY: Animated.Value;
29
+ dragVideoPlayerY: Animated.Value;
30
+ translateYOffset: Animated.Value;
31
+ };
32
+ lastScrollYValue: React.MutableRefObject<number>;
33
+ scrollPosition: React.MutableRefObject<number>;
34
+ modalSnapPoints: number[];
35
+ lastSnap: number;
36
+ setLastSnap: (value: number) => void;
37
+ tabletLandscapePlayerTopPosition: number;
38
+ setTabletLandscapePlayerTopPosition: (value: number) => void;
39
+ };
40
+
41
+ const ReactContext = React.createContext<ModalAnimationContextT>({
42
+ isActiveGesture: false,
43
+ playerAnimationState: null,
44
+ setPlayerAnimationState: () => null,
45
+ startComponentsAnimation: false,
46
+ setStartComponentsAnimation: () => null,
47
+ resetPlayerAnimationState: () => null,
48
+ minimisedHeight: 60,
49
+ animatedValues: {
50
+ lastScrollY: new Animated.Value(0),
51
+ dragScrollY: new Animated.Value(0),
52
+ dragVideoPlayerY: new Animated.Value(0),
53
+ translateYOffset: new Animated.Value(0),
54
+ },
55
+ lastScrollYValue: null,
56
+ scrollPosition: null,
57
+ modalSnapPoints: [0, 0],
58
+ lastSnap: 0,
59
+ setLastSnap: () => null,
60
+ tabletLandscapePlayerTopPosition: 0,
61
+ setTabletLandscapePlayerTopPosition: () => null,
62
+ });
63
+
64
+ export function useModalAnimationContext() {
65
+ return useContext<ModalAnimationContextT>(ReactContext);
66
+ }
67
+
68
+ const Provider = ({ children }: { children: React.ReactNode }) => {
69
+ const [playerAnimationState, setPlayerAnimationState] =
70
+ React.useState<PlayerAnimationStateT>(null);
71
+
72
+ const [
73
+ tabletLandscapePlayerTopPosition,
74
+ setTabletLandscapePlayerTopPosition,
75
+ ] = React.useState<number>(0);
76
+
77
+ const [startComponentsAnimation, setStartComponentsAnimation] =
78
+ React.useState<boolean>(false);
79
+
80
+ const { minimised_height: minimisedHeight } = useConfiguration();
81
+
82
+ const resetPlayerAnimationState = React.useCallback(() => {
83
+ setPlayerAnimationState(null);
84
+ setStartComponentsAnimation(false);
85
+ }, []);
86
+
87
+ // Animated values
88
+ const lastScrollY = React.useRef(new Animated.Value(0)).current;
89
+ const dragScrollY = React.useRef(new Animated.Value(0)).current;
90
+ const translateYOffset = React.useRef(new Animated.Value(0)).current;
91
+ const dragVideoPlayerY = React.useRef(new Animated.Value(0)).current;
92
+
93
+ const { height } = useSafeAreaFrame();
94
+ const bottomTabBarHeight = useGetBottomTabBarHeight();
95
+ const minValue = height - minimisedHeight - bottomTabBarHeight;
96
+ const modalSnapPoints = React.useMemo(() => [0, minValue], [minValue]);
97
+ // Last snap state which will helps us to make smooth responder to scrollview animation
98
+ const [lastSnap, setLastSnap] = React.useState<number>(modalSnapPoints[0]);
99
+ // Extracted animated values which we will use for calculations
100
+ const lastScrollYValue = React.useRef<number>(0);
101
+ const scrollPosition = React.useRef<number>(0);
102
+
103
+ return (
104
+ <ReactContext.Provider
105
+ value={{
106
+ startComponentsAnimation,
107
+ setStartComponentsAnimation,
108
+ isActiveGesture: playerAnimationState !== null,
109
+ playerAnimationState,
110
+ setPlayerAnimationState,
111
+ resetPlayerAnimationState,
112
+ minimisedHeight,
113
+ animatedValues: {
114
+ lastScrollY,
115
+ dragScrollY,
116
+ dragVideoPlayerY,
117
+ translateYOffset,
118
+ },
119
+ lastScrollYValue,
120
+ scrollPosition,
121
+ modalSnapPoints,
122
+ lastSnap,
123
+ setLastSnap,
124
+ tabletLandscapePlayerTopPosition,
125
+ setTabletLandscapePlayerTopPosition,
126
+ }}
127
+ >
128
+ {children}
129
+ </ReactContext.Provider>
130
+ );
131
+ };
132
+
133
+ export const withModalAnimationProvider = (Component) => {
134
+ const WithProvider = (props) => {
135
+ return (
136
+ <Provider>
137
+ <Component {...props} />
138
+ </Provider>
139
+ );
140
+ };
141
+
142
+ return WithProvider;
143
+ };
@@ -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";
@@ -0,0 +1,299 @@
1
+ /* eslint-disable padding-line-between-statements */
2
+
3
+ import { PlayerAnimationStateEnum } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
4
+
5
+ export enum ComponentAnimationType {
6
+ bottomBar = "bottomBar",
7
+ player = "player",
8
+ componentFade = "componentFade",
9
+ componentAppears = "componentAppears",
10
+ moveUpComponent = "moveUpComponent",
11
+ moveComponentHorizontal = "moveComponentHorizontal",
12
+ audioPlayerPaddingHorizontal = "audioPlayerPaddingHorizontal",
13
+ }
14
+
15
+ export const AUDIO_PLAYER_HORIZONTAL_PADDING = 15;
16
+
17
+ export const defaultAspectRatioWidth = (height: number): number =>
18
+ (height / 9) * 16;
19
+
20
+ export const getAnimationStyle = (component, animatedValue) => {
21
+ switch (component) {
22
+ case ComponentAnimationType.bottomBar: {
23
+ return { zIndex: 99, transform: [{ translateY: animatedValue }] };
24
+ }
25
+
26
+ case ComponentAnimationType.player: {
27
+ return { width: animatedValue.x, height: animatedValue.y };
28
+ }
29
+
30
+ case ComponentAnimationType.componentFade:
31
+ case ComponentAnimationType.componentAppears: {
32
+ return { opacity: animatedValue };
33
+ }
34
+
35
+ case ComponentAnimationType.moveUpComponent: {
36
+ return { transform: [{ translateY: animatedValue }] };
37
+ }
38
+
39
+ case ComponentAnimationType.audioPlayerPaddingHorizontal:
40
+ case ComponentAnimationType.moveComponentHorizontal: {
41
+ return { transform: [{ translateX: animatedValue }] };
42
+ }
43
+
44
+ default:
45
+ return null;
46
+ }
47
+ };
48
+
49
+ export const getAnimationDefaultValue = (component, bottomTabBarHeight) => {
50
+ switch (component) {
51
+ case ComponentAnimationType.bottomBar: {
52
+ return bottomTabBarHeight;
53
+ }
54
+
55
+ case ComponentAnimationType.player: {
56
+ return { x: 0, y: 0 };
57
+ }
58
+
59
+ case ComponentAnimationType.componentFade: {
60
+ return 1;
61
+ }
62
+
63
+ case ComponentAnimationType.audioPlayerPaddingHorizontal:
64
+ case ComponentAnimationType.moveComponentHorizontal:
65
+ case ComponentAnimationType.componentAppears:
66
+ case ComponentAnimationType.moveUpComponent: {
67
+ return 0;
68
+ }
69
+ }
70
+ };
71
+
72
+ export const calculateAnimationValue = (animationType, dragPosition, data) => {
73
+ const {
74
+ isAudioItem,
75
+ bottomTabBarHeight,
76
+ minimisedHeight,
77
+ minimisedWidth,
78
+ defaultValue,
79
+ moveUpValue,
80
+ moveComponentHorizontalValue,
81
+ isTablet,
82
+ isTabletLandscape,
83
+ isRTL,
84
+ fromMiniPlayer,
85
+ inlineAudioPlayer,
86
+ } = data;
87
+
88
+ switch (animationType) {
89
+ case ComponentAnimationType.bottomBar: {
90
+ if (fromMiniPlayer) {
91
+ return dragPosition < bottomTabBarHeight
92
+ ? dragPosition
93
+ : bottomTabBarHeight;
94
+ }
95
+
96
+ return dragPosition < bottomTabBarHeight
97
+ ? bottomTabBarHeight - dragPosition
98
+ : 0;
99
+ }
100
+
101
+ case ComponentAnimationType.player: {
102
+ const value =
103
+ isAudioItem && !inlineAudioPlayer
104
+ ? isTabletLandscape
105
+ ? fromMiniPlayer
106
+ ? { forWidth: 4, forHeight: 4.5 }
107
+ : { forWidth: 3, forHeight: 3 }
108
+ : { forWidth: 2, forHeight: 2 }
109
+ : isTabletLandscape
110
+ ? { forWidth: 8, forHeight: 6.5 }
111
+ : { forWidth: 3.5, forHeight: 2 };
112
+
113
+ const minWidth =
114
+ isAudioItem && !inlineAudioPlayer ? minimisedHeight : minimisedWidth;
115
+
116
+ if (fromMiniPlayer) {
117
+ const calculationWidth =
118
+ dragPosition * value.forWidth < minWidth
119
+ ? minWidth
120
+ : dragPosition * value.forWidth;
121
+ const calculationHeight =
122
+ dragPosition * value.forHeight < minimisedHeight
123
+ ? minimisedHeight
124
+ : dragPosition * value.forHeight;
125
+
126
+ return {
127
+ x:
128
+ calculationWidth < defaultValue.x
129
+ ? calculationWidth
130
+ : defaultValue.x,
131
+ y:
132
+ calculationHeight < defaultValue.y
133
+ ? calculationHeight
134
+ : defaultValue.y,
135
+ };
136
+ }
137
+
138
+ const calculationWidth = defaultValue.x - dragPosition * value.forWidth;
139
+
140
+ const calculationHeight = defaultValue.y - dragPosition * value.forHeight;
141
+
142
+ return {
143
+ x: calculationWidth > minWidth ? calculationWidth : minWidth,
144
+ y:
145
+ calculationHeight > minimisedHeight
146
+ ? calculationHeight
147
+ : minimisedHeight,
148
+ };
149
+ }
150
+
151
+ case ComponentAnimationType.componentFade: {
152
+ if (fromMiniPlayer) {
153
+ const calculation = dragPosition / (isTablet ? 200 : 150);
154
+
155
+ return calculation < 1 ? calculation : 1;
156
+ }
157
+
158
+ const calculation = 1 - dragPosition / (isTablet ? 200 : 150);
159
+
160
+ return calculation > 0 ? calculation : 0;
161
+ }
162
+
163
+ case ComponentAnimationType.componentAppears: {
164
+ if (fromMiniPlayer) {
165
+ const calculation = 1 - dragPosition / (isTablet ? 200 : 150);
166
+
167
+ return calculation > 0 ? calculation : 0;
168
+ }
169
+
170
+ const calculation = dragPosition / (isTablet ? 200 : 150);
171
+
172
+ return calculation < 1 ? calculation : 1;
173
+ }
174
+
175
+ case ComponentAnimationType.moveUpComponent: {
176
+ if (fromMiniPlayer) {
177
+ const calculation =
178
+ moveUpValue + dragPosition / (isTabletLandscape ? 1 : 4);
179
+
180
+ return calculation < 0 ? calculation : 0;
181
+ }
182
+
183
+ const calculation = 0 - dragPosition / (isTabletLandscape ? 1 : 2);
184
+
185
+ return calculation > moveUpValue ? calculation : moveUpValue;
186
+ }
187
+
188
+ case ComponentAnimationType.moveComponentHorizontal: {
189
+ if (fromMiniPlayer) {
190
+ const calculation = isRTL
191
+ ? moveComponentHorizontalValue - dragPosition * 2
192
+ : moveComponentHorizontalValue + dragPosition * 2;
193
+ const condition = isRTL ? calculation > 0 : calculation < 0;
194
+
195
+ return condition ? calculation : 0;
196
+ }
197
+
198
+ const calculation = isRTL ? dragPosition * 2 : -(dragPosition * 2);
199
+ const condition = isRTL
200
+ ? calculation < moveComponentHorizontalValue
201
+ : calculation > moveComponentHorizontalValue;
202
+
203
+ return condition ? calculation : moveComponentHorizontalValue;
204
+ }
205
+
206
+ case ComponentAnimationType.audioPlayerPaddingHorizontal: {
207
+ const padding = isRTL
208
+ ? AUDIO_PLAYER_HORIZONTAL_PADDING
209
+ : -AUDIO_PLAYER_HORIZONTAL_PADDING;
210
+
211
+ if (fromMiniPlayer) {
212
+ const calculation = isRTL
213
+ ? padding - dragPosition / 5
214
+ : padding + dragPosition / 5;
215
+ const condition = isRTL ? calculation > 0 : calculation < 0;
216
+
217
+ return condition ? calculation : 0;
218
+ }
219
+
220
+ const calculation = isRTL ? dragPosition / 5 : -(dragPosition / 5);
221
+ const condition = isRTL ? calculation < padding : calculation > padding;
222
+
223
+ return condition ? calculation : padding;
224
+ }
225
+ }
226
+ };
227
+
228
+ export const gestureListenerHelper = (data) => {
229
+ const {
230
+ listenerValue,
231
+ preparedValue,
232
+ animationType,
233
+ animatedValue,
234
+ calculationData,
235
+ modalSnapPoint,
236
+ startAnimationDistance,
237
+ startComponentsAnimation,
238
+ setStartComponentsAnimation,
239
+ getAnimationValue,
240
+ } = data;
241
+
242
+ if (calculationData.fromMiniPlayer) {
243
+ if (listenerValue <= 0) {
244
+ if (
245
+ preparedValue >= 0 &&
246
+ preparedValue <= modalSnapPoint - startAnimationDistance
247
+ ) {
248
+ !startComponentsAnimation && setStartComponentsAnimation(true);
249
+
250
+ animatedValue.setValue(
251
+ calculateAnimationValue(animationType, preparedValue, calculationData)
252
+ );
253
+ } else {
254
+ animatedValue.setValue(calculationData.defaultValue);
255
+ startComponentsAnimation && setStartComponentsAnimation(false);
256
+ }
257
+ } else {
258
+ const value = getAnimationValue(
259
+ animationType,
260
+ PlayerAnimationStateEnum.minimize
261
+ ).toValue;
262
+
263
+ animatedValue.setValue(value);
264
+ }
265
+ } else {
266
+ if (preparedValue >= startAnimationDistance) {
267
+ !startComponentsAnimation && setStartComponentsAnimation(true);
268
+ const value = Math.round(preparedValue - startAnimationDistance);
269
+
270
+ animatedValue.setValue(
271
+ calculateAnimationValue(animationType, value, calculationData)
272
+ );
273
+ } else {
274
+ animatedValue.setValue(calculationData.defaultValue);
275
+ startComponentsAnimation && setStartComponentsAnimation(false);
276
+ }
277
+ }
278
+ };
279
+
280
+ export const setScrollModalAnimatedValue = (
281
+ animatedValue,
282
+ value,
283
+ setLastSnap
284
+ ) => {
285
+ setLastSnap(value);
286
+ animatedValue.setValue(value);
287
+ };
288
+
289
+ export const resetScrollAnimatedValues = (
290
+ lastScrollY,
291
+ lastScrollYValue,
292
+ dragScrollY,
293
+ dragVideoPlayerY
294
+ ) => {
295
+ lastScrollY.setValue(0);
296
+ lastScrollYValue.current = 0;
297
+ dragScrollY.setValue(0);
298
+ dragVideoPlayerY.setValue(0);
299
+ };
@@ -15,9 +15,16 @@ import { playerDimesionsHack } from "./utils";
15
15
  import { PathnameContext } from "../../Contexts/PathnameContext";
16
16
  import { ScreenContextProvider } from "../../Contexts/ScreenContext";
17
17
 
18
+ import {
19
+ AnimationComponent,
20
+ ComponentAnimationType,
21
+ AnimatedScrollModal,
22
+ AnimatedVideoPlayerComponent,
23
+ } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
24
+
18
25
  type DimensionsT = {
19
26
  width: number | string;
20
- height: number | string;
27
+ height: number | string | undefined;
21
28
  aspectRatio?: number;
22
29
  };
23
30
 
@@ -44,6 +51,7 @@ type Props = {
44
51
  const defaultStyles = StyleSheet.create({
45
52
  playerContainer: { position: "relative", alignSelf: "center", zIndex: 200 },
46
53
  playerDetails: { flex: 1, paddingTop: 20 },
54
+ flex: { flex: 1 },
47
55
  });
48
56
 
49
57
  const orientationStyles = StyleSheet.create({
@@ -82,18 +90,9 @@ const safeAreaStyles = (
82
90
  };
83
91
  };
84
92
 
85
- const getEdges = (
86
- isTablet: boolean,
87
- docked: boolean,
88
- isInlineModal: boolean
89
- ) => {
93
+ const getEdges = (isTablet: boolean, isInlineModal: boolean) => {
90
94
  if (isTablet) {
91
- return docked ? ["right", "left"] : ["top"];
92
- }
93
-
94
- // mobile
95
- if (isInlineModal && docked) {
96
- return ["bottom"];
95
+ return ["top"];
97
96
  }
98
97
 
99
98
  if (!isInlineModal && Platform.OS === "android") {
@@ -151,9 +150,9 @@ export const PlayerWrapper = (props: Props) => {
151
150
  () => ({
152
151
  width:
153
152
  isInlineModal && !docked && isTabletLandscape ? tabletWidth : "100%",
154
- height: isInlineModal && docked ? style.height : undefined,
153
+ height: undefined,
155
154
  }),
156
- [isInlineModal, tabletWidth, style.height, docked]
155
+ [isInlineModal, tabletWidth, docked]
157
156
  );
158
157
 
159
158
  const playerDimensions: DimensionsT = React.useMemo(
@@ -183,39 +182,63 @@ export const PlayerWrapper = (props: Props) => {
183
182
 
184
183
  return (
185
184
  <WrapperView
186
- edges={getEdges(isTablet, docked, isInlineModal) as readonly Edge[]}
185
+ edges={getEdges(isTablet, isInlineModal) as readonly Edge[]}
187
186
  style={[
188
- directionStyles(isTabletLandscape),
189
187
  safeAreaStyles(configuration, isTablet),
190
188
  style,
191
189
  playerDimesionsHack,
192
190
  ]}
193
191
  >
194
- <ScreenContextProvider pathname={"videoModal"}>
195
- <PathnameContext.Provider value={"videoModal"}>
196
- <View
197
- testID={`${entry?.id}-player-container`}
198
- style={[
199
- defaultStyles.playerContainer,
200
- containerDimensions,
201
- containerStyle,
202
- playerDimesionsHack,
203
- ]}
204
- >
205
- {children(childrenStyles)}
206
- </View>
207
- {isInlineModal && !docked ? (
208
- <PlayerDetails
209
- configuration={configuration}
210
- style={defaultStyles.playerDetails}
211
- entry={entry}
212
- isTabletLandscape={isTabletLandscape}
213
- />
214
- ) : (
215
- <View style={defaultStyles.playerDetails} />
216
- )}
217
- </PathnameContext.Provider>
218
- </ScreenContextProvider>
192
+ <AnimationComponent
193
+ animationType={ComponentAnimationType.moveUpComponent}
194
+ additionalData={{ saveArea: true }}
195
+ style={directionStyles(isTabletLandscape)}
196
+ >
197
+ <ScreenContextProvider pathname={"videoModal"}>
198
+ <PathnameContext.Provider value={"videoModal"}>
199
+ <View
200
+ testID={`${entry?.id}-player-container`}
201
+ style={[
202
+ defaultStyles.playerContainer,
203
+ containerDimensions,
204
+ containerStyle,
205
+ playerDimesionsHack,
206
+ ]}
207
+ >
208
+ <AnimationComponent
209
+ animationType={ComponentAnimationType.moveUpComponent}
210
+ style={isTabletLandscape ? defaultStyles.flex : undefined}
211
+ additionalData={{
212
+ useLayoutMeasure: isTabletLandscape,
213
+ disableAnimatedComponent: !isTabletLandscape,
214
+ resetAnimationValue: isTabletLandscape && docked,
215
+ }}
216
+ >
217
+ <AnimatedVideoPlayerComponent>
218
+ {children(childrenStyles)}
219
+ </AnimatedVideoPlayerComponent>
220
+ </AnimationComponent>
221
+ </View>
222
+ <AnimatedScrollModal>
223
+ {isInlineModal ? (
224
+ <AnimationComponent
225
+ animationType={ComponentAnimationType.componentFade}
226
+ style={defaultStyles.flex}
227
+ >
228
+ <PlayerDetails
229
+ configuration={configuration}
230
+ style={defaultStyles.playerDetails}
231
+ entry={entry}
232
+ isTabletLandscape={isTabletLandscape}
233
+ />
234
+ </AnimationComponent>
235
+ ) : (
236
+ <View style={defaultStyles.playerDetails} />
237
+ )}
238
+ </AnimatedScrollModal>
239
+ </PathnameContext.Provider>
240
+ </ScreenContextProvider>
241
+ </AnimationComponent>
219
242
  </WrapperView>
220
243
  );
221
244
  };