@applicaster/zapp-react-native-ui-components 12.0.0-alpha.5040434238 → 12.0.0-alpha.5061452310
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.
- package/Components/Image/utils/index.ts +21 -11
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +14 -1
- package/Components/MasterCell/utils/index.ts +16 -5
- package/Components/PlayerContainer/PlayerContainer.tsx +8 -9
- package/Components/PlayerImageBackground/index.tsx +13 -3
- package/Components/Screen/index.tsx +1 -1
- package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +16 -6
- package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +17 -15
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +138 -85
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +36 -25
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +133 -74
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +10 -9
- package/Components/VideoModal/ModalAnimation/utils.ts +69 -37
- package/Components/VideoModal/PlayerWrapper.tsx +1 -4
- package/Components/VideoModal/VideoModal.tsx +0 -19
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +28 -0
- package/package.json +5 -5
- package/Components/VideoModal/hooks/usePosition.ts +0 -52
|
@@ -1,19 +1,29 @@
|
|
|
1
|
+
import FastImage, { Source } from "@applicaster/react-native-fast-image";
|
|
1
2
|
import { useMemo } from "react";
|
|
3
|
+
import { ImageRequireSource } from "react-native";
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
function getSourceCache(cache: Source["cache"]) {
|
|
6
|
+
return cache || FastImage.cacheControl.web;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const useImageSource = (source?: Source | ImageRequireSource) => {
|
|
4
10
|
return useMemo(() => {
|
|
5
|
-
if (
|
|
6
|
-
|
|
11
|
+
if (source) {
|
|
12
|
+
if (typeof source === "number") {
|
|
13
|
+
return source;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
uri: source.uri,
|
|
18
|
+
headers: source.headers,
|
|
19
|
+
priority: source.priority,
|
|
20
|
+
cache: getSourceCache(source?.cache),
|
|
21
|
+
maxWidth: source.maxWidth,
|
|
22
|
+
maxHeight: source.maxHeight,
|
|
23
|
+
};
|
|
7
24
|
}
|
|
8
25
|
|
|
9
|
-
return
|
|
10
|
-
uri: source.uri,
|
|
11
|
-
headers: source.headers,
|
|
12
|
-
priority: source.priority,
|
|
13
|
-
cache: source.cache,
|
|
14
|
-
maxWidth: source.maxWidth,
|
|
15
|
-
maxHeight: source.maxHeight,
|
|
16
|
-
};
|
|
26
|
+
return undefined;
|
|
17
27
|
}, [
|
|
18
28
|
...(typeof source === "object"
|
|
19
29
|
? [
|
|
@@ -177,10 +177,23 @@ const getPlayerConfig = (player_screen_id, actionIdentifier) => {
|
|
|
177
177
|
const positionAbsolute: ViewStyle = { position: "absolute" };
|
|
178
178
|
|
|
179
179
|
const LiveImageComponent = (props: LiveImageProps) => {
|
|
180
|
-
const {
|
|
180
|
+
const {
|
|
181
|
+
item,
|
|
182
|
+
style: componentStyle,
|
|
183
|
+
cellUUID,
|
|
184
|
+
imageKey,
|
|
185
|
+
actionIdentifier,
|
|
186
|
+
state,
|
|
187
|
+
} = props;
|
|
181
188
|
|
|
182
189
|
const component = useUIComponentContext();
|
|
183
190
|
|
|
191
|
+
// Fix for blinking on state change
|
|
192
|
+
const style = React.useMemo(
|
|
193
|
+
() => ({ ...componentStyle, backgroundColor: "transparent" }),
|
|
194
|
+
[componentStyle]
|
|
195
|
+
);
|
|
196
|
+
|
|
184
197
|
const componentType = React.useMemo(
|
|
185
198
|
() => getPropComponentType(component),
|
|
186
199
|
[component?.id]
|
|
@@ -125,13 +125,24 @@ export const useFilterChildren = <
|
|
|
125
125
|
|
|
126
126
|
const filteredChildren = children.filter((child) => {
|
|
127
127
|
const item = child.props.item;
|
|
128
|
-
const
|
|
128
|
+
const actionIdentifier = child.props.pluginIdentifier;
|
|
129
|
+
const action = actions.actions[actionIdentifier];
|
|
130
|
+
|
|
129
131
|
// context value of specific plugin
|
|
130
|
-
|
|
132
|
+
if (action?.module && action.module.context) {
|
|
133
|
+
const currentValue = action.module.context._currentValue;
|
|
134
|
+
|
|
135
|
+
return currentValue?.isActionAvailable
|
|
136
|
+
? currentValue.isActionAvailable(item)
|
|
137
|
+
: true;
|
|
138
|
+
}
|
|
131
139
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
:
|
|
140
|
+
masterCellLogger.error({
|
|
141
|
+
message: `Action plugin for ${actionIdentifier} could not be found, check the configuration of your action button`,
|
|
142
|
+
data: { item, action: child.props.pluginIdentifier },
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
return false;
|
|
135
146
|
});
|
|
136
147
|
|
|
137
148
|
return filteredChildren;
|
|
@@ -147,13 +147,7 @@ const renderApplePlayer = ({
|
|
|
147
147
|
}) => {
|
|
148
148
|
const { title, summary } = item || {};
|
|
149
149
|
|
|
150
|
-
if (!
|
|
151
|
-
return null;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// TODO: Check if it is not breaking default player logic on tvos
|
|
155
|
-
// Also if needs to add on tvos brightcove player for QB player
|
|
156
|
-
if (player.supportsNativeControls()) {
|
|
150
|
+
if (!isAppleTV() || !player) {
|
|
157
151
|
return null;
|
|
158
152
|
}
|
|
159
153
|
|
|
@@ -606,7 +600,8 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
606
600
|
pluginConfiguration,
|
|
607
601
|
};
|
|
608
602
|
|
|
609
|
-
const { isActiveGesture, startComponentsAnimation } =
|
|
603
|
+
const { isActiveGesture, startComponentsAnimation } =
|
|
604
|
+
useModalAnimationContext();
|
|
610
605
|
|
|
611
606
|
return (
|
|
612
607
|
<PlayerStateContext.Provider value={value}>
|
|
@@ -651,7 +646,11 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
651
646
|
autoplay={true}
|
|
652
647
|
controls={false}
|
|
653
648
|
disableCastAction={disableCastAction}
|
|
654
|
-
docked={
|
|
649
|
+
docked={
|
|
650
|
+
navigator.isVideoModalDocked() &&
|
|
651
|
+
!startComponentsAnimation &&
|
|
652
|
+
!isActiveGesture
|
|
653
|
+
}
|
|
655
654
|
entry={item}
|
|
656
655
|
fullscreen={mode === VideoModalMode.FULLSCREEN}
|
|
657
656
|
inline={inline}
|
|
@@ -33,12 +33,22 @@ const PlayerImageBackgroundComponent = ({
|
|
|
33
33
|
);
|
|
34
34
|
|
|
35
35
|
const { playerAnimationState } = useModalAnimationContext();
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
if (!source) return <>{children}</>;
|
|
38
38
|
|
|
39
39
|
return (
|
|
40
|
-
<View
|
|
41
|
-
|
|
40
|
+
<View
|
|
41
|
+
style={
|
|
42
|
+
playerAnimationState === PlayerAnimationStateEnum.maximaze
|
|
43
|
+
? defaultImageDimensions
|
|
44
|
+
: style
|
|
45
|
+
}
|
|
46
|
+
>
|
|
47
|
+
<AnimationComponent
|
|
48
|
+
style={style}
|
|
49
|
+
animationType={ComponentAnimationType.player}
|
|
50
|
+
additionalData={defaultImageDimensions}
|
|
51
|
+
>
|
|
42
52
|
<ImageBackground
|
|
43
53
|
resizeMode="cover"
|
|
44
54
|
style={imageSize}
|
|
@@ -137,7 +137,7 @@ export function Screen({ setToggleMenu, setCloseMenu }: Props) {
|
|
|
137
137
|
{...{ ...(navBarProps as MobileNavBarPluginProps), id: pathname }}
|
|
138
138
|
/>
|
|
139
139
|
|
|
140
|
-
<OfflineFallbackScreen screenData={
|
|
140
|
+
<OfflineFallbackScreen screenData={targetScreenData}>
|
|
141
141
|
{/* @TODO RouteManager doesn't use props, can they be removed ? */}
|
|
142
142
|
<RouteManager pathname={pathname} screenData={screenData} />
|
|
143
143
|
</OfflineFallbackScreen>
|
|
@@ -9,6 +9,9 @@ import * as navigationHooks from "@applicaster/zapp-react-native-utils/reactHook
|
|
|
9
9
|
import { PlayerLiveImage } from "../PlayerLiveImageComponent";
|
|
10
10
|
import * as useNavigationHooks from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation";
|
|
11
11
|
|
|
12
|
+
import { Provider } from "react-redux";
|
|
13
|
+
import configureStore from "redux-mock-store";
|
|
14
|
+
|
|
12
15
|
const seekTo = jest.fn();
|
|
13
16
|
|
|
14
17
|
jest.mock(
|
|
@@ -22,16 +25,23 @@ jest.mock(
|
|
|
22
25
|
|
|
23
26
|
jest
|
|
24
27
|
.spyOn(useNavigationHooks, "useNavigation")
|
|
25
|
-
.mockImplementation(() => ({videoModalState: { visible: false }}));
|
|
28
|
+
.mockImplementation(() => ({ videoModalState: { visible: false } }));
|
|
26
29
|
|
|
27
30
|
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation");
|
|
28
31
|
|
|
32
|
+
const mockStore = configureStore();
|
|
33
|
+
|
|
34
|
+
const store = mockStore({ appData: {} });
|
|
35
|
+
|
|
29
36
|
const Wrapper = ({ children }: { children: React.ReactChildren }) => (
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
/* @ts-ignore */
|
|
38
|
+
<Provider store={store}>
|
|
39
|
+
<ThemeContext.Provider
|
|
40
|
+
value={{ themes: { myTheme: {} }, selectedThemeId: "myTheme" }}
|
|
41
|
+
>
|
|
42
|
+
{children}
|
|
43
|
+
</ThemeContext.Provider>
|
|
44
|
+
</Provider>
|
|
35
45
|
);
|
|
36
46
|
|
|
37
47
|
describe("PlayerLiveImageComponent", () => {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Animated, ViewStyle } from "react-native";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
useModalAnimationContext,
|
|
6
|
+
PlayerAnimationStateEnum,
|
|
7
|
+
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
5
8
|
import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
6
9
|
|
|
7
10
|
type Props = {
|
|
@@ -12,17 +15,15 @@ type Props = {
|
|
|
12
15
|
export const AnimatedPlayerModalWrapper = (props: Props) => {
|
|
13
16
|
const {
|
|
14
17
|
playerAnimationState,
|
|
15
|
-
animatedValues: {
|
|
16
|
-
lastScrollY,
|
|
17
|
-
dragScrollY,
|
|
18
|
-
translateYOffset,
|
|
19
|
-
},
|
|
18
|
+
animatedValues: { lastScrollY, dragScrollY, translateYOffset },
|
|
20
19
|
modalSnapPoints,
|
|
21
20
|
setStartComponentsAnimation,
|
|
22
21
|
lastScrollYValue,
|
|
23
22
|
} = useModalAnimationContext();
|
|
24
23
|
|
|
25
|
-
const { height: screenHeight } = useDimensions("screen", {
|
|
24
|
+
const { height: screenHeight } = useDimensions("screen", {
|
|
25
|
+
deviceInfo: true,
|
|
26
|
+
});
|
|
26
27
|
|
|
27
28
|
const interpolateConfig: Animated.InterpolationConfigType = React.useMemo(
|
|
28
29
|
() => ({
|
|
@@ -51,13 +52,17 @@ export const AnimatedPlayerModalWrapper = (props: Props) => {
|
|
|
51
52
|
|
|
52
53
|
React.useEffect(() => {
|
|
53
54
|
const translateYListener = translateY.addListener(({ value }) => {
|
|
54
|
-
const preparedValue = Math.round(
|
|
55
|
+
const preparedValue = Math.round(
|
|
56
|
+
Math.abs(value) - lastScrollYValue.current
|
|
57
|
+
);
|
|
55
58
|
|
|
56
59
|
(playerAnimationState === PlayerAnimationStateEnum.minimize ||
|
|
57
|
-
|
|
58
|
-
setStartComponentsAnimation(
|
|
60
|
+
playerAnimationState === PlayerAnimationStateEnum.maximaze) &&
|
|
61
|
+
setStartComponentsAnimation(
|
|
62
|
+
preparedValue >= Math.round((screenHeight * 10) / 100)
|
|
63
|
+
);
|
|
59
64
|
});
|
|
60
|
-
|
|
65
|
+
|
|
61
66
|
return () => {
|
|
62
67
|
translateYListener && translateY.removeListener(translateYListener);
|
|
63
68
|
};
|
|
@@ -65,10 +70,7 @@ export const AnimatedPlayerModalWrapper = (props: Props) => {
|
|
|
65
70
|
|
|
66
71
|
return (
|
|
67
72
|
<Animated.View
|
|
68
|
-
style={[
|
|
69
|
-
props.style,
|
|
70
|
-
{ transform: [{ translateY: translateY }] },
|
|
71
|
-
]}
|
|
73
|
+
style={[props.style, { transform: [{ translateY: translateY }] }]}
|
|
72
74
|
>
|
|
73
75
|
{props.children}
|
|
74
76
|
</Animated.View>
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
PanGestureHandler,
|
|
8
8
|
State,
|
|
9
9
|
TapGestureHandler,
|
|
10
|
+
GestureHandlerRootView,
|
|
10
11
|
} from "react-native-gesture-handler";
|
|
11
12
|
import {
|
|
12
13
|
useModalAnimationContext,
|
|
@@ -15,7 +16,10 @@ import {
|
|
|
15
16
|
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
16
17
|
import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
|
|
17
18
|
|
|
18
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
setScrollModalAnimatedValue,
|
|
21
|
+
resetScrollAnimatedValues,
|
|
22
|
+
} from "./utils";
|
|
19
23
|
|
|
20
24
|
const getAnimatedConfig = (toValue) => {
|
|
21
25
|
return {
|
|
@@ -54,11 +58,17 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
54
58
|
setLastSnap,
|
|
55
59
|
} = useModalAnimationContext();
|
|
56
60
|
|
|
57
|
-
const { maximiseVideoModal, minimiseVideoModal, videoModalState } =
|
|
61
|
+
const { maximiseVideoModal, minimiseVideoModal, videoModalState } =
|
|
62
|
+
useNavigation();
|
|
63
|
+
|
|
58
64
|
const isMaximazedModal = videoModalState.mode === "MAXIMIZED";
|
|
59
65
|
const isMinimizedModal = videoModalState.mode === "MINIMIZED";
|
|
60
66
|
const previousItemId = usePrevious(videoModalState.item?.id);
|
|
61
67
|
|
|
68
|
+
const isNotMinimizeMaximazeAnimation =
|
|
69
|
+
playerAnimationState !== PlayerAnimationStateEnum.minimize &&
|
|
70
|
+
playerAnimationState !== PlayerAnimationStateEnum.maximaze;
|
|
71
|
+
|
|
62
72
|
const isAudioItem = React.useMemo(
|
|
63
73
|
() =>
|
|
64
74
|
videoModalState.item?.content?.type?.includes?.("audio") ||
|
|
@@ -85,30 +95,33 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
85
95
|
if (nativeEvent.oldState === State.ACTIVE && scrollPosition.current === 0) {
|
|
86
96
|
// eslint-disable-next-line prefer-const
|
|
87
97
|
const { velocityY, translationY } = nativeEvent;
|
|
88
|
-
const preparedTranslationY = Math.abs(translationY) - lastScrollYValue.current;
|
|
89
98
|
const dragToss = 0.05;
|
|
90
99
|
|
|
100
|
+
const preparedTranslationY =
|
|
101
|
+
Math.abs(translationY) - lastScrollYValue.current;
|
|
102
|
+
|
|
91
103
|
if (videoModalState.mode === "MAXIMIZED") {
|
|
92
|
-
const endOffsetY =
|
|
93
|
-
|
|
104
|
+
const endOffsetY =
|
|
105
|
+
lastSnap + preparedTranslationY + dragToss * velocityY + 150;
|
|
106
|
+
|
|
94
107
|
let destSnapPoint = modalSnapPoints[0];
|
|
95
|
-
|
|
108
|
+
|
|
96
109
|
for (const snapPoint of modalSnapPoints) {
|
|
97
110
|
const distFromSnap = Math.abs(snapPoint - endOffsetY);
|
|
98
|
-
|
|
111
|
+
|
|
99
112
|
if (distFromSnap < Math.abs(destSnapPoint - endOffsetY)) {
|
|
100
113
|
destSnapPoint = snapPoint;
|
|
101
114
|
}
|
|
102
115
|
}
|
|
103
|
-
|
|
116
|
+
|
|
104
117
|
setLastSnap(destSnapPoint);
|
|
105
|
-
|
|
118
|
+
|
|
106
119
|
if (destSnapPoint === modalSnapPoints[0]) {
|
|
107
120
|
translateYOffset.extractOffset();
|
|
108
121
|
translateYOffset.setValue(preparedTranslationY);
|
|
109
122
|
translateYOffset.flattenOffset();
|
|
110
123
|
dragScrollY.setValue(0);
|
|
111
|
-
|
|
124
|
+
|
|
112
125
|
setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
|
|
113
126
|
} else {
|
|
114
127
|
setPlayerAnimationState(PlayerAnimationStateEnum.minimize);
|
|
@@ -125,6 +138,9 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
125
138
|
resetPlayerAnimationState();
|
|
126
139
|
}
|
|
127
140
|
}
|
|
141
|
+
} else {
|
|
142
|
+
playerAnimationState === PlayerAnimationStateEnum.drag_scroll &&
|
|
143
|
+
resetPlayerAnimationState();
|
|
128
144
|
}
|
|
129
145
|
};
|
|
130
146
|
|
|
@@ -132,50 +148,46 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
132
148
|
scrollPosition.current = nativeEvent.contentOffset.y;
|
|
133
149
|
}, []);
|
|
134
150
|
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const onMomentumScrollBegin = React.useCallback(() => {
|
|
139
|
-
canMomentum.current = true;
|
|
140
|
-
}, []);
|
|
141
|
-
|
|
142
|
-
const onMomentumScrollEnd = React.useCallback(({ nativeEvent }) => {
|
|
143
|
-
if (Platform.OS === "android") {
|
|
144
|
-
// onMomentumScrollEnd doesn't work correct on android(https://github.com/facebook/react-native/issues/32696)
|
|
145
|
-
if (canMomentum.current) {
|
|
146
|
-
if (nativeEvent.contentOffset.y === 0 && momentumScrollEnd.current !== 0 && !isActiveGesture) {
|
|
147
|
-
resetScrollAnimatedValues(lastScrollY, lastScrollYValue, dragScrollY, dragVideoPlayerY);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
momentumScrollEnd.current = nativeEvent.contentOffset.y;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
canMomentum.current = false;
|
|
154
|
-
} else {
|
|
151
|
+
const onMomentumScrollEnd = React.useCallback(
|
|
152
|
+
({ nativeEvent }) => {
|
|
155
153
|
if (nativeEvent.contentOffset.y === 0 && !isActiveGesture) {
|
|
156
|
-
resetScrollAnimatedValues(
|
|
154
|
+
resetScrollAnimatedValues(
|
|
155
|
+
lastScrollY,
|
|
156
|
+
lastScrollYValue,
|
|
157
|
+
dragScrollY,
|
|
158
|
+
dragVideoPlayerY
|
|
159
|
+
);
|
|
157
160
|
}
|
|
158
|
-
}
|
|
159
|
-
|
|
161
|
+
},
|
|
162
|
+
[isActiveGesture]
|
|
163
|
+
);
|
|
160
164
|
|
|
161
165
|
React.useEffect(() => {
|
|
162
166
|
return () => {
|
|
163
167
|
scrollPosition.current = 0;
|
|
164
|
-
|
|
168
|
+
|
|
169
|
+
resetScrollAnimatedValues(
|
|
170
|
+
lastScrollY,
|
|
171
|
+
lastScrollYValue,
|
|
172
|
+
dragScrollY,
|
|
173
|
+
dragVideoPlayerY
|
|
174
|
+
);
|
|
165
175
|
};
|
|
166
176
|
}, []);
|
|
167
177
|
|
|
168
178
|
React.useEffect(() => {
|
|
169
179
|
if (
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
videoModalState.previousMode === "MINIMIZED")
|
|
180
|
+
videoModalState.mode === "MINIMIZED" &&
|
|
181
|
+
videoModalState.previousMode === "MAXIMIZED"
|
|
173
182
|
) {
|
|
174
183
|
resetPlayerAnimationState();
|
|
175
184
|
}
|
|
176
185
|
|
|
177
|
-
if (
|
|
178
|
-
(
|
|
186
|
+
if (
|
|
187
|
+
(videoModalState.mode === "MAXIMIZED" &&
|
|
188
|
+
videoModalState.previousMode === "MAXIMIZED") ||
|
|
189
|
+
previousItemId !== videoModalState.item?.id
|
|
190
|
+
) {
|
|
179
191
|
setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
|
|
180
192
|
setTimeout(() => resetPlayerAnimationState());
|
|
181
193
|
}
|
|
@@ -192,7 +204,12 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
192
204
|
((dragScrollY as any)._value !== 0 ||
|
|
193
205
|
(dragVideoPlayerY as any)._value !== 0))
|
|
194
206
|
) {
|
|
195
|
-
resetScrollAnimatedValues(
|
|
207
|
+
resetScrollAnimatedValues(
|
|
208
|
+
lastScrollY,
|
|
209
|
+
lastScrollYValue,
|
|
210
|
+
dragScrollY,
|
|
211
|
+
dragVideoPlayerY
|
|
212
|
+
);
|
|
196
213
|
}
|
|
197
214
|
|
|
198
215
|
Animated.timing(
|
|
@@ -200,16 +217,35 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
200
217
|
getAnimatedConfig(modalSnapPoints[1])
|
|
201
218
|
).start(() => {
|
|
202
219
|
setTimeout(() => {
|
|
203
|
-
setScrollModalAnimatedValue(translateYOffset, modalSnapPoints[1], setLastSnap);
|
|
204
|
-
resetScrollAnimatedValues(lastScrollY, lastScrollYValue, dragScrollY, dragVideoPlayerY);
|
|
205
220
|
minimiseVideoModal();
|
|
221
|
+
|
|
222
|
+
setScrollModalAnimatedValue(
|
|
223
|
+
translateYOffset,
|
|
224
|
+
modalSnapPoints[1],
|
|
225
|
+
setLastSnap
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
resetScrollAnimatedValues(
|
|
229
|
+
lastScrollY,
|
|
230
|
+
lastScrollYValue,
|
|
231
|
+
dragScrollY,
|
|
232
|
+
dragVideoPlayerY
|
|
233
|
+
);
|
|
206
234
|
}, 150);
|
|
207
235
|
});
|
|
208
236
|
} else if (playerAnimationState === PlayerAnimationStateEnum.maximaze) {
|
|
209
237
|
Animated.timing(translateYOffset, getAnimatedConfig(0)).start(() => {
|
|
210
|
-
setScrollModalAnimatedValue(translateYOffset, 0, setLastSnap);
|
|
211
|
-
resetScrollAnimatedValues(lastScrollY, lastScrollYValue, dragScrollY, dragVideoPlayerY);
|
|
212
238
|
maximiseVideoModal();
|
|
239
|
+
setScrollModalAnimatedValue(translateYOffset, 0, setLastSnap);
|
|
240
|
+
|
|
241
|
+
resetScrollAnimatedValues(
|
|
242
|
+
lastScrollY,
|
|
243
|
+
lastScrollYValue,
|
|
244
|
+
dragScrollY,
|
|
245
|
+
dragVideoPlayerY
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
resetPlayerAnimationState();
|
|
213
249
|
});
|
|
214
250
|
}
|
|
215
251
|
|
|
@@ -218,9 +254,16 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
218
254
|
});
|
|
219
255
|
|
|
220
256
|
const dragListenerId = dragScrollY.addListener(({ value }) => {
|
|
221
|
-
const preparedValue =
|
|
257
|
+
const preparedValue =
|
|
258
|
+
isMinimizedModal && value >= 0
|
|
259
|
+
? 0
|
|
260
|
+
: Math.round(isAudioItem ? Math.abs(value) : value);
|
|
222
261
|
|
|
223
|
-
if (
|
|
262
|
+
if (
|
|
263
|
+
preparedValue > 0 &&
|
|
264
|
+
scrollPosition.current === 0 &&
|
|
265
|
+
playerAnimationState !== PlayerAnimationStateEnum.drag_player
|
|
266
|
+
) {
|
|
224
267
|
playerAnimationState !== PlayerAnimationStateEnum.drag_scroll &&
|
|
225
268
|
setPlayerAnimationState(PlayerAnimationStateEnum.drag_scroll);
|
|
226
269
|
}
|
|
@@ -232,51 +275,61 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
232
275
|
};
|
|
233
276
|
}, [playerAnimationState, isAudioItem, modalSnapPoints]);
|
|
234
277
|
|
|
278
|
+
const Wrapper = React.useMemo(
|
|
279
|
+
() => (Platform.OS === "android" ? GestureHandlerRootView : View),
|
|
280
|
+
[]
|
|
281
|
+
);
|
|
282
|
+
|
|
235
283
|
return (
|
|
236
|
-
<
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
>
|
|
256
|
-
<
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
onScroll={onScroll}
|
|
261
|
-
onMomentumScrollBegin={onMomentumScrollBegin}
|
|
262
|
-
onMomentumScrollEnd={onMomentumScrollEnd}
|
|
263
|
-
scrollEventThrottle={1}
|
|
264
|
-
showsVerticalScrollIndicator={false}
|
|
284
|
+
<Wrapper style={generalStyles.container}>
|
|
285
|
+
<TapGestureHandler
|
|
286
|
+
maxDurationMs={100000}
|
|
287
|
+
ref={tapHandlerRef}
|
|
288
|
+
maxDeltaY={lastSnap - modalSnapPoints[0]}
|
|
289
|
+
numberOfTaps={1}
|
|
290
|
+
>
|
|
291
|
+
<View pointerEvents="box-none">
|
|
292
|
+
<PanGestureHandler
|
|
293
|
+
enabled={
|
|
294
|
+
(isMaximazedModal || isMinimizedModal) &&
|
|
295
|
+
isNotMinimizeMaximazeAnimation
|
|
296
|
+
}
|
|
297
|
+
ref={panHandlerRef}
|
|
298
|
+
simultaneousHandlers={[scrollRef, tapHandlerRef]}
|
|
299
|
+
shouldCancelWhenOutside={isMaximazedModal}
|
|
300
|
+
onGestureEvent={onGestureEvent}
|
|
301
|
+
onHandlerStateChange={onHandlerStateChange}
|
|
302
|
+
>
|
|
303
|
+
<Animated.View>
|
|
304
|
+
<NativeViewGestureHandler
|
|
305
|
+
ref={scrollRef}
|
|
306
|
+
waitFor={tapHandlerRef}
|
|
307
|
+
simultaneousHandlers={panHandlerRef}
|
|
265
308
|
>
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
309
|
+
<Animated.ScrollView
|
|
310
|
+
scrollEnabled={
|
|
311
|
+
isMaximazedModal && isNotMinimizeMaximazeAnimation
|
|
312
|
+
}
|
|
313
|
+
bounces={false}
|
|
314
|
+
onScrollBeginDrag={onRegisterLastScroll}
|
|
315
|
+
onScroll={onScroll}
|
|
316
|
+
onMomentumScrollEnd={onMomentumScrollEnd}
|
|
317
|
+
scrollEventThrottle={1}
|
|
318
|
+
showsVerticalScrollIndicator={false}
|
|
319
|
+
>
|
|
320
|
+
{children}
|
|
321
|
+
</Animated.ScrollView>
|
|
322
|
+
</NativeViewGestureHandler>
|
|
323
|
+
</Animated.View>
|
|
324
|
+
</PanGestureHandler>
|
|
325
|
+
</View>
|
|
326
|
+
</TapGestureHandler>
|
|
327
|
+
</Wrapper>
|
|
273
328
|
);
|
|
274
329
|
};
|
|
275
330
|
|
|
276
331
|
export const AnimatedScrollModal = ({ children }: Props) => {
|
|
277
|
-
const Component = !isTV()
|
|
278
|
-
? AnimatedScrollModalComponent
|
|
279
|
-
: React.Fragment;
|
|
332
|
+
const Component = !isTV() ? AnimatedScrollModalComponent : React.Fragment;
|
|
280
333
|
|
|
281
334
|
return <Component>{children}</Component>;
|
|
282
335
|
};
|