@applicaster/zapp-react-native-ui-components 14.0.0-rc.57 → 14.0.0-rc.58

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.
@@ -8,7 +8,7 @@ type Props = {
8
8
  typeof import("@applicaster/zapp-react-native-utils/reactHooks/feed").useLoadPipesDataDispatch
9
9
  >;
10
10
  feedUrl: string;
11
- children: (feed: ZappFeed) => React.ComponentType<any>;
11
+ children: (feed: ZappFeed) => React.ReactNode;
12
12
  onFeedLoaded: (feed: ZappFeed) => {};
13
13
  onError: (error: ZappPipesData["error"]) => {};
14
14
  refreshing: boolean;
@@ -20,7 +20,7 @@ type Props = {
20
20
  onPressOut?: () => void;
21
21
  onLongPress?: () => void;
22
22
  handleFocus?: ({ mouse }: { mouse: boolean }) => void;
23
- children: (boolean, string) => React.ComponentType<any>;
23
+ children: (boolean, string) => React.ReactNode;
24
24
  selected?: boolean;
25
25
  style?: ViewStyle[] | ViewStyle;
26
26
  };
@@ -19,7 +19,7 @@ type Props = {
19
19
  onPress?: (nativeEvent: any) => void;
20
20
  onFocus?: (nativeEvent: any) => void;
21
21
  onBlur?: (nativeEvent: any) => void;
22
- children: (focused?: boolean) => React.ReactNode;
22
+ children: ((focused?: boolean) => React.ReactNode) | React.ReactNode;
23
23
  isParallaxDisabled: boolean;
24
24
  preferredFocus?: boolean;
25
25
  selected?: boolean;
@@ -204,7 +204,7 @@ export class Focusable extends BaseFocusable<Props> {
204
204
  {...this.nextFocusableReactTags}
205
205
  {...otherProps}
206
206
  >
207
- {R.is(Function, children) ? children(focused) : children}
207
+ {typeof children === "function" ? children(focused) : children}
208
208
  </FocusableItemNative>
209
209
  );
210
210
  }
@@ -22,7 +22,7 @@ type FocusableGroupNativeEvent = {
22
22
 
23
23
  type Props = {
24
24
  id: string;
25
- children: (arg1: boolean) => React.ComponentType<any>;
25
+ children: React.ReactNode;
26
26
  isFocusDisabled: boolean;
27
27
  isWithMemory: boolean;
28
28
  focusGroupRef: React.Component;
@@ -20,11 +20,11 @@ import { FocusableScrollView } from "../FocusableScrollView";
20
20
  const mapIndexed = R.addIndex(R.map);
21
21
 
22
22
  export type IListRenderItem<ItemT> = (
23
- info: IListRenderItemInfo<ItemT> & {
23
+ info: {
24
24
  focused: boolean;
25
25
  onLoadFinished: () => void;
26
26
  onLoadFailed: () => void;
27
- }
27
+ } & IListRenderItemInfo<ItemT>
28
28
  ) => React.ReactElement | null;
29
29
 
30
30
  export const getFocusableId = (parentId, index) =>
@@ -423,7 +423,10 @@ const PlayerContainerComponent = (props: Props) => {
423
423
  id: playerContainerId,
424
424
  listener: {
425
425
  onVideoEnd,
426
- onError,
426
+ onError: (err: Error) => {
427
+ // Adapt Error to the expected shape for onError
428
+ onError({ error: err });
429
+ },
427
430
  onLoad,
428
431
  onPlayerClose: close,
429
432
  onPlayerDetached: close,
@@ -62,7 +62,7 @@ const TabsComponent = ({
62
62
  );
63
63
 
64
64
  const renderItem = useCallback(
65
- ({ item, index, focused }) => {
65
+ ({ item, index, focused }: { item: any; index: any; focused?: any }) => {
66
66
  const itemId = generateFocusableId(getId(item));
67
67
 
68
68
  const isSelected = R.equals(index, selectedEntryIndex);
@@ -0,0 +1,294 @@
1
+ import React from "react";
2
+ import { Animated, StyleSheet, View } from "react-native";
3
+
4
+ import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
5
+
6
+ import {
7
+ PlayerAnimationStateEnum,
8
+ useModalAnimationContext,
9
+ } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
10
+ import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
11
+ import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
12
+
13
+ import {
14
+ resetScrollAnimatedValues,
15
+ setScrollModalAnimatedValue,
16
+ } from "./utils";
17
+
18
+ import { DURATION_TO_MINIMIZE } from "./const";
19
+
20
+ const getAnimatedConfig = (toValue) => {
21
+ return {
22
+ toValue,
23
+ duration: DURATION_TO_MINIMIZE,
24
+ useNativeDriver: true,
25
+ };
26
+ };
27
+
28
+ const generalStyles = StyleSheet.create({
29
+ container: {
30
+ flex: 1,
31
+ },
32
+ });
33
+
34
+ type Props = {
35
+ children: React.ReactNode;
36
+ };
37
+
38
+ export const AnimatedScrollModalComponent = ({ children }: Props) => {
39
+ const {
40
+ isActiveGesture,
41
+ playerAnimationState,
42
+ setPlayerAnimationState,
43
+ resetPlayerAnimationState,
44
+ animatedValues: {
45
+ lastScrollY,
46
+ dragScrollY,
47
+ dragVideoPlayerY,
48
+ translateYOffset,
49
+ },
50
+ lastScrollYValue,
51
+ scrollPosition,
52
+ modalSnapPoints,
53
+ setLastSnap,
54
+ setStartComponentsAnimation,
55
+ } = useModalAnimationContext();
56
+
57
+ const [enableGesture, setIEnableGesture] = React.useState<boolean>(true);
58
+
59
+ const { maximiseVideoModal, minimiseVideoModal, videoModalState } =
60
+ useNavigation();
61
+
62
+ const {
63
+ mode: videoModalMode,
64
+ previousMode: previousVideoModalMode,
65
+ item: videoModalItem,
66
+ } = videoModalState;
67
+
68
+ const isMaximizedModal: boolean = videoModalMode === "MAXIMIZED";
69
+ const isMinimizedModal: boolean = videoModalMode === "MINIMIZED";
70
+ const previousItemId = usePrevious(videoModalItem?.id);
71
+
72
+ const isNotMinimizeMaximazeAnimation =
73
+ playerAnimationState !== PlayerAnimationStateEnum.minimize &&
74
+ playerAnimationState !== PlayerAnimationStateEnum.maximize;
75
+
76
+ const isAudioItem = React.useMemo(
77
+ () =>
78
+ videoModalItem?.content?.type?.includes?.("audio") ||
79
+ videoModalItem?.type?.value === "audio",
80
+ [videoModalItem]
81
+ );
82
+
83
+ const onRegisterLastScroll = Animated.event(
84
+ [{ nativeEvent: { contentOffset: { y: lastScrollY } } }],
85
+ { useNativeDriver: true }
86
+ );
87
+
88
+ const onScroll = React.useCallback(({ nativeEvent }) => {
89
+ scrollPosition.current = nativeEvent.contentOffset.y;
90
+ }, []);
91
+
92
+ // Workaround for onMomentumScrollEnd issue
93
+ // https://github.com/facebook/react-native/issues/32696#issuecomment-1104217223
94
+ const canMomentum = React.useRef(false);
95
+
96
+ const onMomentumScrollBegin = React.useCallback(() => {
97
+ canMomentum.current = true;
98
+ }, []);
99
+
100
+ const onMomentumScrollEnd = React.useCallback(
101
+ ({ nativeEvent }) => {
102
+ if (canMomentum.current && !isActiveGesture) {
103
+ if (nativeEvent.contentOffset.y === 0) {
104
+ resetScrollAnimatedValues(
105
+ lastScrollY,
106
+ lastScrollYValue,
107
+ dragScrollY,
108
+ dragVideoPlayerY
109
+ );
110
+
111
+ setIEnableGesture(true);
112
+ } else {
113
+ setIEnableGesture(false);
114
+ }
115
+
116
+ canMomentum.current = false;
117
+ }
118
+ },
119
+ [isActiveGesture]
120
+ );
121
+
122
+ React.useEffect(() => {
123
+ return () => {
124
+ scrollPosition.current = 0;
125
+
126
+ resetScrollAnimatedValues(
127
+ lastScrollY,
128
+ lastScrollYValue,
129
+ dragScrollY,
130
+ dragVideoPlayerY
131
+ );
132
+ };
133
+ }, []);
134
+
135
+ React.useEffect(() => {
136
+ if (
137
+ videoModalMode === "MAXIMIZED" &&
138
+ !enableGesture &&
139
+ scrollPosition.current === 0
140
+ ) {
141
+ setIEnableGesture(true);
142
+ }
143
+
144
+ if (
145
+ videoModalMode === "MINIMIZED" &&
146
+ previousVideoModalMode === "MAXIMIZED"
147
+ ) {
148
+ // set animation to the minimize values if moving from the player to another screen
149
+ if (playerAnimationState === null) {
150
+ setScrollModalAnimatedValue(
151
+ translateYOffset,
152
+ modalSnapPoints[1],
153
+ setLastSnap
154
+ );
155
+
156
+ resetScrollAnimatedValues(
157
+ lastScrollY,
158
+ lastScrollYValue,
159
+ dragScrollY,
160
+ dragVideoPlayerY
161
+ );
162
+ }
163
+ } else if (
164
+ playerAnimationState === null &&
165
+ ((previousItemId === videoModalItem?.id &&
166
+ videoModalMode === "MAXIMIZED" &&
167
+ (previousVideoModalMode === "MINIMIZED" ||
168
+ previousVideoModalMode === "MAXIMIZED")) ||
169
+ (previousItemId !== videoModalItem?.id &&
170
+ videoModalMode !== "FULLSCREEN"))
171
+ ) {
172
+ setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
173
+ }
174
+ }, [videoModalMode, previousVideoModalMode, videoModalItem]);
175
+
176
+ React.useEffect(() => {
177
+ if (playerAnimationState === PlayerAnimationStateEnum.minimize) {
178
+ if (
179
+ (scrollPosition.current === 0 &&
180
+ (lastScrollY as any)._value !== 0 &&
181
+ (dragScrollY as any)._value === 0 &&
182
+ (dragVideoPlayerY as any)._value === 0) ||
183
+ (scrollPosition.current !== 0 &&
184
+ ((dragScrollY as any)._value !== 0 ||
185
+ (dragVideoPlayerY as any)._value !== 0))
186
+ ) {
187
+ resetScrollAnimatedValues(
188
+ lastScrollY,
189
+ lastScrollYValue,
190
+ dragScrollY,
191
+ dragVideoPlayerY
192
+ );
193
+ }
194
+
195
+ Animated.timing(
196
+ translateYOffset,
197
+ getAnimatedConfig(modalSnapPoints[1])
198
+ ).start(() => {
199
+ minimiseVideoModal();
200
+
201
+ setScrollModalAnimatedValue(
202
+ translateYOffset,
203
+ modalSnapPoints[1],
204
+ setLastSnap
205
+ );
206
+
207
+ resetScrollAnimatedValues(
208
+ lastScrollY,
209
+ lastScrollYValue,
210
+ dragScrollY,
211
+ dragVideoPlayerY
212
+ );
213
+
214
+ resetPlayerAnimationState();
215
+ });
216
+ } else if (playerAnimationState === PlayerAnimationStateEnum.maximize) {
217
+ Animated.timing(translateYOffset, getAnimatedConfig(0)).start(() => {
218
+ maximiseVideoModal();
219
+ setScrollModalAnimatedValue(translateYOffset, 0, setLastSnap);
220
+
221
+ resetScrollAnimatedValues(
222
+ lastScrollY,
223
+ lastScrollYValue,
224
+ dragScrollY,
225
+ dragVideoPlayerY
226
+ );
227
+
228
+ resetPlayerAnimationState();
229
+ });
230
+ }
231
+ }, [playerAnimationState]);
232
+
233
+ React.useEffect(() => {
234
+ const lastScrollYListenerId = lastScrollY.addListener(({ value }) => {
235
+ lastScrollYValue.current = value;
236
+ });
237
+
238
+ const dragListenerId = dragScrollY.addListener(({ value }) => {
239
+ const preparedValue =
240
+ isMinimizedModal && value >= 0
241
+ ? 0
242
+ : Math.round(isAudioItem ? Math.abs(value) : value);
243
+
244
+ if (
245
+ preparedValue > 0 &&
246
+ scrollPosition.current === 0 &&
247
+ playerAnimationState !== PlayerAnimationStateEnum.drag_player &&
248
+ playerAnimationState !== PlayerAnimationStateEnum.drag_scroll
249
+ ) {
250
+ isMinimizedModal && setStartComponentsAnimation(true);
251
+ setPlayerAnimationState(PlayerAnimationStateEnum.drag_scroll);
252
+ }
253
+ });
254
+
255
+ return () => {
256
+ lastScrollY.removeListener(lastScrollYListenerId);
257
+ dragScrollY.removeListener(dragListenerId);
258
+ };
259
+ }, [playerAnimationState, isAudioItem, isMinimizedModal]);
260
+
261
+ const scrollEnabled = isMaximizedModal && isNotMinimizeMaximazeAnimation;
262
+
263
+ return (
264
+ <View style={generalStyles.container}>
265
+ <View pointerEvents="box-none">
266
+ <Animated.View>
267
+ <Animated.ScrollView
268
+ scrollEnabled={scrollEnabled}
269
+ bounces={false}
270
+ onScrollBeginDrag={onRegisterLastScroll}
271
+ onScroll={onScroll}
272
+ onMomentumScrollBegin={onMomentumScrollBegin}
273
+ onMomentumScrollEnd={onMomentumScrollEnd}
274
+ scrollEventThrottle={1}
275
+ showsVerticalScrollIndicator={false}
276
+ >
277
+ {children}
278
+ </Animated.ScrollView>
279
+ </Animated.View>
280
+ </View>
281
+ </View>
282
+ );
283
+ };
284
+
285
+ export const AnimatedScrollModal = ({ children }: Props) => {
286
+ const {
287
+ videoModalState: { visible },
288
+ } = useNavigation();
289
+
290
+ const Component =
291
+ !isTV() && visible ? AnimatedScrollModalComponent : React.Fragment;
292
+
293
+ return <Component>{children}</Component>;
294
+ };
@@ -0,0 +1,93 @@
1
+ import React from "react";
2
+ import { Animated, StyleSheet } from "react-native";
3
+
4
+ import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
5
+
6
+ import {
7
+ useModalAnimationContext,
8
+ PlayerAnimationStateEnum,
9
+ } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
10
+ import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
11
+
12
+ const generalStyles = StyleSheet.create({
13
+ container: {
14
+ flex: 1,
15
+ width: "100%",
16
+ position: "absolute",
17
+ zIndex: 201,
18
+ },
19
+ });
20
+
21
+ type Props = {
22
+ children: React.ReactNode;
23
+ };
24
+
25
+ export const AnimatedVideoPlayer = ({ children }: Props) => {
26
+ const {
27
+ playerAnimationState,
28
+ setPlayerAnimationState,
29
+ animatedValues: { translateYOffset, dragVideoPlayerY },
30
+ modalSnapPoints,
31
+ setStartComponentsAnimation,
32
+ } = useModalAnimationContext();
33
+
34
+ const {
35
+ videoModalState: { mode: videoModalMode },
36
+ } = useNavigation();
37
+
38
+ const isMaximazedModal = videoModalMode === "MAXIMIZED";
39
+ const isMinimizedModal = videoModalMode === "MINIMIZED";
40
+
41
+ React.useEffect(() => {
42
+ const dragVideoPlayerYListenerId = dragVideoPlayerY.addListener(
43
+ ({ value }) => {
44
+ if (
45
+ (isMinimizedModal && value >= 0) ||
46
+ (isMaximazedModal && value <= 0)
47
+ ) {
48
+ if (playerAnimationState === PlayerAnimationStateEnum.drag_player) {
49
+ translateYOffset.setValue(
50
+ modalSnapPoints[isMinimizedModal ? 1 : 0]
51
+ );
52
+ }
53
+ } else {
54
+ const preparedValue = Math.round(Math.abs(value));
55
+
56
+ if (
57
+ preparedValue > 0 &&
58
+ playerAnimationState !== PlayerAnimationStateEnum.drag_scroll
59
+ ) {
60
+ if (playerAnimationState !== PlayerAnimationStateEnum.drag_player) {
61
+ isMinimizedModal && setStartComponentsAnimation(true);
62
+ setPlayerAnimationState(PlayerAnimationStateEnum.drag_player);
63
+ }
64
+
65
+ translateYOffset.setValue(
66
+ isMaximazedModal
67
+ ? preparedValue
68
+ : modalSnapPoints[1] - preparedValue
69
+ );
70
+ }
71
+ }
72
+ }
73
+ );
74
+
75
+ return () => {
76
+ dragVideoPlayerY.removeListener(dragVideoPlayerYListenerId);
77
+ };
78
+ }, [playerAnimationState, isMinimizedModal, isMaximazedModal]);
79
+
80
+ return (
81
+ <Animated.View style={generalStyles.container}>{children}</Animated.View>
82
+ );
83
+ };
84
+
85
+ export const AnimatedVideoPlayerComponent = ({ children }: Props) => {
86
+ const {
87
+ videoModalState: { visible },
88
+ } = useNavigation();
89
+
90
+ const Component = !isTV() && visible ? AnimatedVideoPlayer : React.Fragment;
91
+
92
+ return <Component>{children}</Component>;
93
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "14.0.0-rc.57",
3
+ "version": "14.0.0-rc.58",
4
4
  "description": "Applicaster Zapp React Native ui components for the Quick Brick App",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -28,10 +28,10 @@
28
28
  },
29
29
  "homepage": "https://github.com/applicaster/quickbrick#readme",
30
30
  "dependencies": {
31
- "@applicaster/applicaster-types": "14.0.0-rc.57",
32
- "@applicaster/zapp-react-native-bridge": "14.0.0-rc.57",
33
- "@applicaster/zapp-react-native-redux": "14.0.0-rc.57",
34
- "@applicaster/zapp-react-native-utils": "14.0.0-rc.57",
31
+ "@applicaster/applicaster-types": "14.0.0-rc.58",
32
+ "@applicaster/zapp-react-native-bridge": "14.0.0-rc.58",
33
+ "@applicaster/zapp-react-native-redux": "14.0.0-rc.58",
34
+ "@applicaster/zapp-react-native-utils": "14.0.0-rc.58",
35
35
  "promise": "^8.3.0",
36
36
  "url": "^0.11.0",
37
37
  "uuid": "^3.3.2"