@applicaster/zapp-react-native-ui-components 12.0.0-rc.99 → 12.0.2-alpha.5400332623
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/Cell/Cell.tsx +29 -10
- package/Components/Focusable/__tests__/index.android.test.tsx +72 -0
- package/Components/Focusable/index.android.tsx +15 -9
- package/Components/FocusableList/FocusableChild.ts +2 -2
- package/Components/FocusableList/index.tsx +11 -12
- package/Components/FocusableScrollView/index.tsx +1 -1
- package/Components/FreezeWithCallback/Freeze.tsx +31 -0
- package/Components/FreezeWithCallback/LICENSE +21 -0
- package/Components/FreezeWithCallback/Suspender.tsx +17 -0
- package/Components/FreezeWithCallback/__tests__/index.test.tsx +170 -0
- package/Components/FreezeWithCallback/index.tsx +3 -0
- package/Components/Image/Image.android.tsx +1 -1
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +11 -7
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +1 -7
- package/Components/MasterCell/DefaultComponents/CellBadge/index.tsx +6 -1
- package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +12 -0
- package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +6 -5
- package/Components/MasterCell/DefaultComponents/Image/Image.web.tsx +2 -2
- package/Components/MasterCell/DefaultComponents/ImageBorderContainer/index.ts +71 -0
- package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
- package/Components/MasterCell/DefaultComponents/index.ts +2 -0
- package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +7 -1
- package/Components/MasterCell/dataAdapter.ts +21 -7
- package/Components/MasterCell/index.tsx +5 -3
- package/Components/MasterCell/utils/index.ts +3 -4
- package/Components/PlayerContainer/PlayerContainer.tsx +14 -8
- package/Components/Screen/TV/hooks/index.ts +0 -2
- package/Components/Screen/TV/index.web.tsx +32 -19
- package/Components/Screen/__tests__/Screen.test.tsx +0 -49
- package/Components/Screen/index.tsx +2 -20
- package/Components/Screen/navigationHandler.ts +1 -3
- package/Components/Screen/orientationHandler.ts +18 -7
- package/Components/Screen/utils.ts +16 -0
- package/Components/ScreenResolver/index.tsx +6 -11
- package/Components/Transitioner/Scene.tsx +9 -2
- package/Components/Transitioner/Transitioner.tsx +38 -23
- package/Components/Transitioner/__tests__/Scene.test.js +7 -0
- package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +1 -0
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +5 -0
- package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +3 -9
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +87 -41
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +20 -9
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +41 -22
- package/Components/VideoModal/PlayerDetails.tsx +16 -2
- package/Components/VideoModal/PlayerWrapper.tsx +84 -66
- package/Components/VideoModal/VideoModal.tsx +33 -27
- package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +7 -0
- package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -0
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +72 -10
- package/Components/ZappFrameworkComponents/BarView/BarView.tsx +7 -3
- package/Components/ZappFrameworkComponents/BarView/Buttons/BackButton.tsx +7 -2
- package/Components/ZappFrameworkComponents/BarView/Buttons/CloseButton.tsx +7 -2
- package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +87 -0
- package/Components/ZappFrameworkComponents/Buttons/ActionButton.tsx +9 -4
- package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +4 -4
- package/Contexts/CachedDimensionsContext/index.ts +13 -9
- package/Contexts/ConfirmDialogState/index.ts +1 -1
- package/Contexts/ScreenContext/index.tsx +6 -1
- package/const.ts +6 -0
- package/index.js +3 -0
- package/package.json +5 -5
- 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
|
|
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
|
-
?
|
|
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:
|
|
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
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
|
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={
|
|
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={
|
|
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(
|
|
@@ -45,15 +45,9 @@ export const AnimatedPlayerModalWrapper = (props: Props) => {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
React.useEffect(() => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
|
70
|
-
const
|
|
71
|
-
const
|
|
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
|
-
|
|
85
|
-
|
|
86
|
-
[
|
|
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 (
|
|
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,
|
|
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 (
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
|
|
201
|
-
|
|
221
|
+
mode === "MAXIMIZED" &&
|
|
222
|
+
!enableGesture &&
|
|
223
|
+
scrollPosition.current === 0
|
|
202
224
|
) {
|
|
203
|
-
|
|
225
|
+
setIEnableGesture(true);
|
|
204
226
|
}
|
|
205
227
|
|
|
206
|
-
if (
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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
|
|
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
|
-
|
|
241
|
-
minimiseVideoModal();
|
|
278
|
+
minimiseVideoModal();
|
|
242
279
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
280
|
+
setScrollModalAnimatedValue(
|
|
281
|
+
translateYOffset,
|
|
282
|
+
modalSnapPoints[1],
|
|
283
|
+
setLastSnap
|
|
284
|
+
);
|
|
248
285
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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,
|
|
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
|
|
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 {
|
|
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
|
|
44
|
-
|
|
48
|
+
const isNotMinimizeMaximazeAnimation =
|
|
49
|
+
playerAnimationState !== PlayerAnimationStateEnum.minimize &&
|
|
50
|
+
playerAnimationState !== PlayerAnimationStateEnum.maximaze;
|
|
45
51
|
|
|
46
52
|
const isEnablePanGesture =
|
|
47
|
-
!isLanguageOverlayVisible &&
|
|
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 (
|
|
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 (
|
|
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,
|
|
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
|
|
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", {
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
[
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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 (
|
|
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
|
-
}, [
|
|
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
|
-
|
|
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
|
-
(
|
|
393
|
-
|
|
394
|
-
(
|
|
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 {
|
|
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
|
-
|
|
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 && (
|