@applicaster/zapp-react-native-ui-components 12.0.0-alpha.4462655310 → 12.0.0-alpha.4484269996
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/BaseFocusable/index.tsx +2 -2
- package/Components/Cell/Cell.tsx +26 -5
- package/Components/Cell/CellWithFocusable.tsx +6 -4
- package/Components/Cell/TvOSCellComponent.tsx +3 -7
- package/Components/Focusable/Focusable.tsx +6 -1
- package/Components/FocusableGroup/index.tsx +10 -2
- 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/Layout/TV/ScreenContainer.tsx +79 -5
- package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +38 -28
- package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +25 -13
- package/Components/Layout/TV/__tests__/index.test.tsx +2 -1
- package/Components/Layout/TV/index.tsx +11 -65
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -1
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +1 -7
- package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -1
- package/Components/MasterCell/DefaultComponents/ImageBorderContainer/index.ts +71 -0
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +20 -0
- package/Components/MasterCell/DefaultComponents/index.ts +2 -0
- package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.tsx +6 -1
- 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/__tests__/insertBetween.test.js +9 -0
- package/Components/Navigator/StackNavigator.tsx +14 -5
- package/Components/PlayerContainer/PlayerContainer.tsx +2 -5
- package/Components/Screen/TV/hooks/index.ts +0 -2
- package/Components/Screen/TV/index.web.tsx +40 -41
- package/Components/Screen/__tests__/Screen.test.tsx +0 -49
- package/Components/Screen/index.tsx +28 -77
- package/Components/Screen/navigationHandler.ts +6 -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 +20 -12
- package/Components/Transitioner/Transitioner.tsx +26 -21
- package/Components/Transitioner/__tests__/Scene.test.js +7 -0
- package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +8 -4
- package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +1 -0
- package/Components/VideoLive/LiveImageManager.ts +10 -0
- package/Components/VideoLive/PlayerLiveImageComponent.tsx +52 -24
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +26 -24
- package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +2 -14
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +31 -7
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +9 -2
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +27 -15
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +32 -4
- package/Components/VideoModal/ModalAnimation/utils.ts +7 -4
- package/Components/VideoModal/PlayerWrapper.tsx +2 -2
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +80 -14
- package/Components/VideoModal/hooks/useModalSize.ts +10 -12
- package/Components/ZappFrameworkComponents/BarView/BarView.tsx +4 -3
- package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +4 -4
- package/Contexts/FocusableGroupContext/FocusableGroupContext.ts +3 -0
- package/Contexts/FocusableGroupContext/FocusableGroupContextProvider.tsx +16 -0
- package/Contexts/FocusableGroupContext/__tests__/FocusableGroupContextProvider.test.tsx +22 -0
- package/Contexts/FocusableGroupContext/__tests__/withFocusableContext.test.tsx +26 -0
- package/Contexts/FocusableGroupContext/index.ts +7 -0
- package/Contexts/FocusableGroupContext/withFocusableContext.tsx +17 -0
- package/package.json +5 -5
- package/Components/Screen/TV/hooks/useRestoreFocus.ts +0 -22
- /package/Components/FocusableGroup/{index.android.js → index.android.ts} +0 -0
- /package/Components/FocusableGroup/{index.ios.js → index.ios.ts} +0 -0
|
@@ -22,7 +22,9 @@ exports[`<Scene /> renders correctly 1`] = `
|
|
|
22
22
|
}
|
|
23
23
|
>
|
|
24
24
|
<ContextProvider>
|
|
25
|
-
<ContextProvider
|
|
25
|
+
<ContextProvider>
|
|
26
|
+
<ScreenContextProvider />
|
|
27
|
+
</ContextProvider>
|
|
26
28
|
</ContextProvider>
|
|
27
29
|
</ForwardRef(AnimatedComponentWrapper)>
|
|
28
30
|
`;
|
|
@@ -39,14 +41,16 @@ exports[`<Scene /> renders the overlay while animating 1`] = `
|
|
|
39
41
|
"paddingBottom": 49,
|
|
40
42
|
},
|
|
41
43
|
Object {
|
|
42
|
-
"height":
|
|
43
|
-
"width":
|
|
44
|
+
"height": "100%",
|
|
45
|
+
"width": "100%",
|
|
44
46
|
},
|
|
45
47
|
]
|
|
46
48
|
}
|
|
47
49
|
>
|
|
48
50
|
<ContextProvider>
|
|
49
|
-
<ContextProvider
|
|
51
|
+
<ContextProvider>
|
|
52
|
+
<ScreenContextProvider />
|
|
53
|
+
</ContextProvider>
|
|
50
54
|
</ContextProvider>
|
|
51
55
|
<ForwardRef(AnimatedComponentWrapper)
|
|
52
56
|
style={
|
|
@@ -525,6 +525,16 @@ export class LiveImage implements QuickBrickPlayer.SharedPlayerCallBacks {
|
|
|
525
525
|
LiveImageManager.instance.onLiveImageError(this, error);
|
|
526
526
|
};
|
|
527
527
|
|
|
528
|
+
onVideoError = (error: Error) => {
|
|
529
|
+
log_error(
|
|
530
|
+
`onVideoError: live-image, fail to play, switching back to image. error: ${
|
|
531
|
+
error?.message
|
|
532
|
+
}, ${playerInfo(this.player)}`
|
|
533
|
+
);
|
|
534
|
+
|
|
535
|
+
LiveImageManager.instance.onLiveImageError(this, error);
|
|
536
|
+
};
|
|
537
|
+
|
|
528
538
|
onVideoEnd = (_event) => {
|
|
529
539
|
log_info(
|
|
530
540
|
`onVideoEnd: live-image, video completed, switching back to image, ${playerInfo(
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
//
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
|
|
5
|
-
import { AppState, AppStateStatus } from "react-native";
|
|
5
|
+
import { AppState, AppStateStatus, View } from "react-native";
|
|
6
6
|
import { TrackedView } from "../TrackedView";
|
|
7
7
|
import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks/layout";
|
|
8
8
|
|
|
@@ -25,8 +25,9 @@ import { PlayerRole } from "@applicaster/zapp-react-native-utils/appUtils/player
|
|
|
25
25
|
import { getAutoplaySettings } from "./utils";
|
|
26
26
|
import { isString } from "@applicaster/zapp-react-native-utils/stringUtils";
|
|
27
27
|
import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
|
|
28
|
+
import { useEffect } from "react";
|
|
28
29
|
|
|
29
|
-
const { log_error } = loggerLiveImageComponent;
|
|
30
|
+
const { log_error, log_debug } = loggerLiveImageComponent;
|
|
30
31
|
|
|
31
32
|
const isMeasurement = (item: ZappEntry) =>
|
|
32
33
|
isString(item.id) && item.id.startsWith("pre-measurement-");
|
|
@@ -56,6 +57,7 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
56
57
|
);
|
|
57
58
|
|
|
58
59
|
const ref = React.useRef(null);
|
|
60
|
+
const trackViewRef = React.useRef(null);
|
|
59
61
|
|
|
60
62
|
/**
|
|
61
63
|
* Debounced setMode function.
|
|
@@ -86,6 +88,30 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
86
88
|
[mode]
|
|
87
89
|
);
|
|
88
90
|
|
|
91
|
+
const entryToViewIdMapping = React.useRef({});
|
|
92
|
+
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
const nativeTag = trackViewRef.current?._nativeTag?.toString();
|
|
95
|
+
|
|
96
|
+
if (!nativeTag) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const prevValue = entryToViewIdMapping.current[nativeTag];
|
|
101
|
+
|
|
102
|
+
if (prevValue && prevValue.itemId !== item.id) {
|
|
103
|
+
if (mode === LiveImageType.Video) {
|
|
104
|
+
log_debug(
|
|
105
|
+
"Entry to view association changed, stopping current live image"
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
setMode(LiveImageType.Image);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
entryToViewIdMapping.current[nativeTag] = { itemId: item.id };
|
|
113
|
+
}, [trackViewRef.current, item.id, mode]);
|
|
114
|
+
|
|
89
115
|
const { screenConfig, playerPluginId } = props;
|
|
90
116
|
|
|
91
117
|
const liveImageItem: LiveImage = React.useMemo(() => {
|
|
@@ -295,28 +321,30 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
295
321
|
testId={`tracked-view-${playerId}-${item.title}`}
|
|
296
322
|
onPositionUpdated={onPositionUpdated}
|
|
297
323
|
>
|
|
298
|
-
{
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
324
|
+
<View ref={trackViewRef}>
|
|
325
|
+
{isVideoMode && (
|
|
326
|
+
<Player
|
|
327
|
+
autoplay={false}
|
|
328
|
+
ref={_assignRoot}
|
|
329
|
+
entry={item} // Must be passed first in list
|
|
330
|
+
style={videoStyles}
|
|
331
|
+
playerId={playerId}
|
|
332
|
+
muted={muted}
|
|
333
|
+
listener={controller?.getListener()}
|
|
334
|
+
resizeMode={"cover"}
|
|
335
|
+
{...platformSpecificProps}
|
|
336
|
+
/>
|
|
337
|
+
)}
|
|
338
|
+
{
|
|
339
|
+
<AnimatedInOut
|
|
340
|
+
visible={isBackgroundImageVisible}
|
|
341
|
+
animationConfig={overlayFadeIn}
|
|
342
|
+
staticStyles={style}
|
|
343
|
+
>
|
|
344
|
+
<Image {...props} resizeMode="cover" style={style} applyMaxSize />
|
|
345
|
+
</AnimatedInOut>
|
|
346
|
+
}
|
|
347
|
+
</View>
|
|
320
348
|
</TrackedView>
|
|
321
349
|
);
|
|
322
350
|
};
|
|
@@ -5,33 +5,35 @@ exports[`PlayerLiveImageComponent should render correctly with default props 1`]
|
|
|
5
5
|
onPositionUpdated={[Function]}
|
|
6
6
|
testId="tracked-view-player1-Test"
|
|
7
7
|
>
|
|
8
|
-
<View
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"opacity": 1,
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
>
|
|
16
|
-
<Image
|
|
17
|
-
applyMaxSize={true}
|
|
18
|
-
audioMutedByDefault={false}
|
|
19
|
-
imageKey="image1"
|
|
20
|
-
item={
|
|
8
|
+
<View>
|
|
9
|
+
<View
|
|
10
|
+
collapsable={false}
|
|
11
|
+
style={
|
|
21
12
|
Object {
|
|
22
|
-
"
|
|
23
|
-
"title": "Test",
|
|
24
|
-
"type": Object {
|
|
25
|
-
"value": "",
|
|
26
|
-
},
|
|
13
|
+
"opacity": 1,
|
|
27
14
|
}
|
|
28
15
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
16
|
+
>
|
|
17
|
+
<Image
|
|
18
|
+
applyMaxSize={true}
|
|
19
|
+
audioMutedByDefault={false}
|
|
20
|
+
imageKey="image1"
|
|
21
|
+
item={
|
|
22
|
+
Object {
|
|
23
|
+
"id": "1",
|
|
24
|
+
"title": "Test",
|
|
25
|
+
"type": Object {
|
|
26
|
+
"value": "",
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
onError={[Function]}
|
|
31
|
+
playerId="player1"
|
|
32
|
+
resizeMode="cover"
|
|
33
|
+
screenConfig={Object {}}
|
|
34
|
+
style={Object {}}
|
|
35
|
+
/>
|
|
36
|
+
</View>
|
|
35
37
|
</View>
|
|
36
38
|
</TrackedView>
|
|
37
39
|
`;
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
useModalAnimationContext,
|
|
6
6
|
PlayerAnimationStateEnum,
|
|
7
7
|
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
8
|
-
import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
9
8
|
|
|
10
9
|
type Props = {
|
|
11
10
|
style: ViewStyle[];
|
|
@@ -18,13 +17,8 @@ export const AnimatedPlayerModalWrapper = (props: Props) => {
|
|
|
18
17
|
animatedValues: { lastScrollY, dragScrollY, translateYOffset },
|
|
19
18
|
modalSnapPoints,
|
|
20
19
|
setStartComponentsAnimation,
|
|
21
|
-
lastScrollYValue,
|
|
22
20
|
} = useModalAnimationContext();
|
|
23
21
|
|
|
24
|
-
const { height: screenHeight } = useDimensions("screen", {
|
|
25
|
-
deviceInfo: true,
|
|
26
|
-
});
|
|
27
|
-
|
|
28
22
|
const interpolateConfig: Animated.InterpolationConfigType = React.useMemo(
|
|
29
23
|
() => ({
|
|
30
24
|
inputRange: modalSnapPoints,
|
|
@@ -51,16 +45,10 @@ export const AnimatedPlayerModalWrapper = (props: Props) => {
|
|
|
51
45
|
}
|
|
52
46
|
|
|
53
47
|
React.useEffect(() => {
|
|
54
|
-
const translateYListener = translateY.addListener((
|
|
55
|
-
const preparedValue = Math.round(
|
|
56
|
-
Math.abs(value) - lastScrollYValue.current
|
|
57
|
-
);
|
|
58
|
-
|
|
48
|
+
const translateYListener = translateY.addListener(() => {
|
|
59
49
|
(playerAnimationState === PlayerAnimationStateEnum.minimize ||
|
|
60
50
|
playerAnimationState === PlayerAnimationStateEnum.maximaze) &&
|
|
61
|
-
setStartComponentsAnimation(
|
|
62
|
-
preparedValue >= Math.round((screenHeight * 10) / 100)
|
|
63
|
-
);
|
|
51
|
+
setStartComponentsAnimation(true);
|
|
64
52
|
});
|
|
65
53
|
|
|
66
54
|
return () => {
|
|
@@ -58,6 +58,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
58
58
|
modalSnapPoints,
|
|
59
59
|
lastSnap,
|
|
60
60
|
setLastSnap,
|
|
61
|
+
setStartComponentsAnimation,
|
|
61
62
|
} = useModalAnimationContext();
|
|
62
63
|
|
|
63
64
|
const { isLanguageOverlayVisible } = React.useContext(PlayerContainerContext);
|
|
@@ -199,12 +200,29 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
199
200
|
videoModalState.mode === "MINIMIZED" &&
|
|
200
201
|
videoModalState.previousMode === "MAXIMIZED"
|
|
201
202
|
) {
|
|
202
|
-
|
|
203
|
+
// set animation to the minimize values if moving from the player to another screen
|
|
204
|
+
if (playerAnimationState === null) {
|
|
205
|
+
setScrollModalAnimatedValue(
|
|
206
|
+
translateYOffset,
|
|
207
|
+
modalSnapPoints[1],
|
|
208
|
+
setLastSnap
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
resetScrollAnimatedValues(
|
|
212
|
+
lastScrollY,
|
|
213
|
+
lastScrollYValue,
|
|
214
|
+
dragScrollY,
|
|
215
|
+
dragVideoPlayerY
|
|
216
|
+
);
|
|
217
|
+
} else {
|
|
218
|
+
resetPlayerAnimationState();
|
|
219
|
+
}
|
|
203
220
|
}
|
|
204
221
|
|
|
205
222
|
if (
|
|
206
223
|
(videoModalState.mode === "MAXIMIZED" &&
|
|
207
|
-
videoModalState.previousMode === "
|
|
224
|
+
videoModalState.previousMode === "MINIMIZED" &&
|
|
225
|
+
previousItemId === videoModalState.item?.id) ||
|
|
208
226
|
previousItemId !== videoModalState.item?.id
|
|
209
227
|
) {
|
|
210
228
|
setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
|
|
@@ -281,10 +299,11 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
281
299
|
if (
|
|
282
300
|
preparedValue > 0 &&
|
|
283
301
|
scrollPosition.current === 0 &&
|
|
284
|
-
playerAnimationState !== PlayerAnimationStateEnum.drag_player
|
|
302
|
+
playerAnimationState !== PlayerAnimationStateEnum.drag_player &&
|
|
303
|
+
playerAnimationState !== PlayerAnimationStateEnum.drag_scroll
|
|
285
304
|
) {
|
|
286
|
-
|
|
287
|
-
|
|
305
|
+
isMinimizedModal && setStartComponentsAnimation(true);
|
|
306
|
+
setPlayerAnimationState(PlayerAnimationStateEnum.drag_scroll);
|
|
288
307
|
}
|
|
289
308
|
});
|
|
290
309
|
|
|
@@ -292,7 +311,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
292
311
|
lastScrollY.removeListener(lastScrollYListenerId);
|
|
293
312
|
dragScrollY.removeListener(dragListenerId);
|
|
294
313
|
};
|
|
295
|
-
}, [playerAnimationState, isAudioItem, modalSnapPoints]);
|
|
314
|
+
}, [playerAnimationState, isAudioItem, modalSnapPoints, isMinimizedModal]);
|
|
296
315
|
|
|
297
316
|
const Wrapper = React.useMemo(
|
|
298
317
|
() => (Platform.OS === "android" ? GestureHandlerRootView : View),
|
|
@@ -346,7 +365,12 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
346
365
|
};
|
|
347
366
|
|
|
348
367
|
export const AnimatedScrollModal = ({ children }: Props) => {
|
|
349
|
-
const
|
|
368
|
+
const {
|
|
369
|
+
videoModalState: { visible },
|
|
370
|
+
} = useNavigation();
|
|
371
|
+
|
|
372
|
+
const Component =
|
|
373
|
+
!isTV() && visible ? AnimatedScrollModalComponent : React.Fragment;
|
|
350
374
|
|
|
351
375
|
return <Component>{children}</Component>;
|
|
352
376
|
};
|
|
@@ -34,6 +34,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
|
|
|
34
34
|
lastSnap,
|
|
35
35
|
setLastSnap,
|
|
36
36
|
resetPlayerAnimationState,
|
|
37
|
+
setStartComponentsAnimation,
|
|
37
38
|
} = useModalAnimationContext();
|
|
38
39
|
|
|
39
40
|
const { videoModalState } = useNavigation();
|
|
@@ -121,8 +122,10 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
|
|
|
121
122
|
preparedValue > 0 &&
|
|
122
123
|
playerAnimationState !== PlayerAnimationStateEnum.drag_scroll
|
|
123
124
|
) {
|
|
124
|
-
playerAnimationState !== PlayerAnimationStateEnum.drag_player
|
|
125
|
+
if (playerAnimationState !== PlayerAnimationStateEnum.drag_player) {
|
|
126
|
+
isMinimizedModal && setStartComponentsAnimation(true);
|
|
125
127
|
setPlayerAnimationState(PlayerAnimationStateEnum.drag_player);
|
|
128
|
+
}
|
|
126
129
|
|
|
127
130
|
translateYOffset.setValue(
|
|
128
131
|
isMaximazedModal
|
|
@@ -152,7 +155,11 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
|
|
|
152
155
|
};
|
|
153
156
|
|
|
154
157
|
export const AnimatedVideoPlayerComponent = ({ children }: Props) => {
|
|
155
|
-
const
|
|
158
|
+
const {
|
|
159
|
+
videoModalState: { visible },
|
|
160
|
+
} = useNavigation();
|
|
161
|
+
|
|
162
|
+
const Component = !isTV() && visible ? AnimatedVideoPlayer : React.Fragment;
|
|
156
163
|
|
|
157
164
|
return <Component>{children}</Component>;
|
|
158
165
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useRef, useState } from "react";
|
|
2
|
-
import { Animated, View
|
|
2
|
+
import { Animated, View } from "react-native";
|
|
3
3
|
|
|
4
4
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
5
5
|
|
|
@@ -33,10 +33,6 @@ type Props = {
|
|
|
33
33
|
additionalData?: { [key: string]: any };
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
-
const styles = StyleSheet.create({
|
|
37
|
-
flex: { flex: 1 },
|
|
38
|
-
});
|
|
39
|
-
|
|
40
36
|
export const AnimationView = ({
|
|
41
37
|
animationType,
|
|
42
38
|
style,
|
|
@@ -54,22 +50,22 @@ export const AnimationView = ({
|
|
|
54
50
|
tabletLandscapePlayerTopPosition,
|
|
55
51
|
setTabletLandscapePlayerTopPosition,
|
|
56
52
|
modalSnapPoints,
|
|
53
|
+
startComponentsAnimationDistance,
|
|
54
|
+
progressBarHeight,
|
|
57
55
|
} = useModalAnimationContext();
|
|
58
56
|
|
|
59
57
|
const isRTL = useIsRTL();
|
|
60
58
|
const isAppActive = useAppState(true);
|
|
61
59
|
|
|
62
60
|
const {
|
|
63
|
-
height: screenHeight,
|
|
64
61
|
width: screenWidth,
|
|
65
62
|
deviceInfo: { isTablet, isTabletLandscape },
|
|
66
63
|
} = useDimensions("window", { deviceInfo: true });
|
|
67
64
|
|
|
68
|
-
const startAnimationDistance = Math.round((screenHeight * 60) / 100);
|
|
69
65
|
const { videoModalState } = useNavigation();
|
|
70
|
-
const bottomTabBarHeight = useGetBottomTabBarHeight();
|
|
71
|
-
const minimisedWidth = defaultAspectRatioWidth(minimisedHeight);
|
|
72
66
|
const insets = useSafeAreaInsets();
|
|
67
|
+
const bottomTabBarHeight = useGetBottomTabBarHeight() + (insets.bottom || 0);
|
|
68
|
+
const minimisedWidth = defaultAspectRatioWidth(minimisedHeight);
|
|
73
69
|
const animationComponentRef = useRef(null);
|
|
74
70
|
|
|
75
71
|
// retrieving top position of the player for tablet landscape mode
|
|
@@ -97,12 +93,12 @@ export const AnimationView = ({
|
|
|
97
93
|
const inlineAudioPlayer = additionalData.inlineAudioPlayer;
|
|
98
94
|
|
|
99
95
|
const moveUpValue = additionalData.saveArea
|
|
100
|
-
? -insets.top
|
|
96
|
+
? -insets.top + (isAudioItem ? 0 : progressBarHeight)
|
|
101
97
|
: isTablet
|
|
102
98
|
? isTabletLandscape && (!isAudioItem || (isAudioItem && inlineAudioPlayer))
|
|
103
|
-
? -tabletLandscapePlayerTopPosition
|
|
99
|
+
? -tabletLandscapePlayerTopPosition + progressBarHeight
|
|
104
100
|
: -130
|
|
105
|
-
: -50;
|
|
101
|
+
: -50 + progressBarHeight;
|
|
106
102
|
|
|
107
103
|
const moveComponentHorizontalValue = additionalData.moveValue
|
|
108
104
|
? isRTL
|
|
@@ -313,6 +309,23 @@ export const AnimationView = ({
|
|
|
313
309
|
}
|
|
314
310
|
}, [additionalData, screenWidth]);
|
|
315
311
|
|
|
312
|
+
React.useEffect(() => {
|
|
313
|
+
if (
|
|
314
|
+
videoModalState.mode === "MINIMIZED" &&
|
|
315
|
+
videoModalState.previousMode === "MAXIMIZED"
|
|
316
|
+
) {
|
|
317
|
+
// set animation to the minimize values if moving from the player to another screen
|
|
318
|
+
if (playerAnimationState === null) {
|
|
319
|
+
const value = getAnimationValue(
|
|
320
|
+
animationType,
|
|
321
|
+
PlayerAnimationStateEnum.minimize
|
|
322
|
+
).toValue;
|
|
323
|
+
|
|
324
|
+
animatedValue.setValue(value);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}, [videoModalState]);
|
|
328
|
+
|
|
316
329
|
React.useEffect(() => {
|
|
317
330
|
if (
|
|
318
331
|
playerAnimationState === PlayerAnimationStateEnum.minimize &&
|
|
@@ -346,7 +359,7 @@ export const AnimationView = ({
|
|
|
346
359
|
animatedValue,
|
|
347
360
|
calculationData,
|
|
348
361
|
modalSnapPoint: modalSnapPoints[1],
|
|
349
|
-
|
|
362
|
+
startComponentsAnimationDistance,
|
|
350
363
|
startComponentsAnimation,
|
|
351
364
|
setStartComponentsAnimation,
|
|
352
365
|
getAnimationValue,
|
|
@@ -371,7 +384,7 @@ export const AnimationView = ({
|
|
|
371
384
|
animatedValue,
|
|
372
385
|
calculationData,
|
|
373
386
|
modalSnapPoint: modalSnapPoints[1],
|
|
374
|
-
|
|
387
|
+
startComponentsAnimationDistance,
|
|
375
388
|
startComponentsAnimation,
|
|
376
389
|
setStartComponentsAnimation,
|
|
377
390
|
getAnimationValue,
|
|
@@ -393,7 +406,6 @@ export const AnimationView = ({
|
|
|
393
406
|
ref={animationComponentRef}
|
|
394
407
|
style={[
|
|
395
408
|
...preparedStyles,
|
|
396
|
-
additionalData.saveArea ? styles.flex : null,
|
|
397
409
|
(videoModalState.mode === "MAXIMIZED" ||
|
|
398
410
|
videoModalState.mode === "MINIMIZED" ||
|
|
399
411
|
(videoModalState.mode === "PIP" && isAppActive)) &&
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import React, { useContext } from "react";
|
|
2
2
|
import { Animated } from "react-native";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
useSafeAreaInsets,
|
|
6
|
+
useSafeAreaFrame,
|
|
7
|
+
} from "react-native-safe-area-context";
|
|
5
8
|
import {
|
|
6
9
|
useGetBottomTabBarHeight,
|
|
7
|
-
|
|
10
|
+
useNavigation,
|
|
8
11
|
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
12
|
+
import { isLive } from "@applicaster/zapp-react-native-utils/playerUtils";
|
|
9
13
|
|
|
14
|
+
import { PROGRESS_BAR_HEIGHT } from "./utils";
|
|
10
15
|
import { useConfiguration } from "../utils";
|
|
11
16
|
|
|
12
17
|
export enum PlayerAnimationStateEnum {
|
|
@@ -39,6 +44,8 @@ export type ModalAnimationContextT = {
|
|
|
39
44
|
setLastSnap: (value: number) => void;
|
|
40
45
|
tabletLandscapePlayerTopPosition: number;
|
|
41
46
|
setTabletLandscapePlayerTopPosition: (value: number) => void;
|
|
47
|
+
startComponentsAnimationDistance: number;
|
|
48
|
+
progressBarHeight: number;
|
|
42
49
|
};
|
|
43
50
|
|
|
44
51
|
const ReactContext = React.createContext<ModalAnimationContextT>({
|
|
@@ -62,6 +69,8 @@ const ReactContext = React.createContext<ModalAnimationContextT>({
|
|
|
62
69
|
setLastSnap: () => null,
|
|
63
70
|
tabletLandscapePlayerTopPosition: 0,
|
|
64
71
|
setTabletLandscapePlayerTopPosition: () => null,
|
|
72
|
+
startComponentsAnimationDistance: 0,
|
|
73
|
+
progressBarHeight: 0,
|
|
65
74
|
});
|
|
66
75
|
|
|
67
76
|
export function useModalAnimationContext() {
|
|
@@ -80,6 +89,11 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
|
|
|
80
89
|
const [startComponentsAnimation, setStartComponentsAnimation] =
|
|
81
90
|
React.useState<boolean>(false);
|
|
82
91
|
|
|
92
|
+
const {
|
|
93
|
+
videoModalState: { mode, visible, item },
|
|
94
|
+
} = useNavigation();
|
|
95
|
+
|
|
96
|
+
const isLiveItem = isLive(item);
|
|
83
97
|
const { minimised_height: minimisedHeight } = useConfiguration();
|
|
84
98
|
|
|
85
99
|
const resetPlayerAnimationState = React.useCallback(() => {
|
|
@@ -93,16 +107,28 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
|
|
|
93
107
|
const translateYOffset = React.useRef(new Animated.Value(0)).current;
|
|
94
108
|
const dragVideoPlayerY = React.useRef(new Animated.Value(0)).current;
|
|
95
109
|
|
|
96
|
-
const { height } =
|
|
110
|
+
const { height: safeAreaFrameHeight } = useSafeAreaFrame();
|
|
111
|
+
const [height, setHeight] = React.useState<number>(safeAreaFrameHeight);
|
|
112
|
+
const progressBarHeight = isLiveItem ? 0 : PROGRESS_BAR_HEIGHT;
|
|
97
113
|
const { bottom: bottomSafeArea } = useSafeAreaInsets();
|
|
98
114
|
const bottomTabBarHeight = useGetBottomTabBarHeight();
|
|
115
|
+
const startComponentsAnimationDistance = Math.round((height * 60) / 100);
|
|
116
|
+
|
|
117
|
+
React.useEffect(() => {
|
|
118
|
+
if (visible && mode === "MAXIMIZED" && height !== safeAreaFrameHeight) {
|
|
119
|
+
setHeight(safeAreaFrameHeight);
|
|
120
|
+
}
|
|
121
|
+
}, [height, safeAreaFrameHeight, mode, visible]);
|
|
99
122
|
|
|
100
123
|
/*
|
|
101
124
|
If bottomTabBarHeight is equal 0 it means an app does not use bottomTabBar.
|
|
102
125
|
Because of this we need to minus bottom SafeArea offset.
|
|
103
126
|
*/
|
|
104
127
|
const minValue =
|
|
105
|
-
height -
|
|
128
|
+
height -
|
|
129
|
+
minimisedHeight -
|
|
130
|
+
(bottomTabBarHeight || bottomSafeArea) -
|
|
131
|
+
progressBarHeight;
|
|
106
132
|
|
|
107
133
|
const modalSnapPoints = React.useMemo(() => [0, minValue], [minValue]);
|
|
108
134
|
// Last snap state which will helps us to make smooth responder to scrollview animation
|
|
@@ -134,6 +160,8 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
|
|
|
134
160
|
setLastSnap,
|
|
135
161
|
tabletLandscapePlayerTopPosition,
|
|
136
162
|
setTabletLandscapePlayerTopPosition,
|
|
163
|
+
startComponentsAnimationDistance,
|
|
164
|
+
progressBarHeight,
|
|
137
165
|
}}
|
|
138
166
|
>
|
|
139
167
|
{children}
|
|
@@ -13,6 +13,7 @@ export enum ComponentAnimationType {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export const AUDIO_PLAYER_HORIZONTAL_PADDING = 15;
|
|
16
|
+
export const PROGRESS_BAR_HEIGHT = 3;
|
|
16
17
|
|
|
17
18
|
export const defaultAspectRatioWidth = (height: number): number =>
|
|
18
19
|
(height / 9) * 16;
|
|
@@ -233,7 +234,7 @@ export const gestureListenerHelper = (data) => {
|
|
|
233
234
|
animatedValue,
|
|
234
235
|
calculationData,
|
|
235
236
|
modalSnapPoint,
|
|
236
|
-
|
|
237
|
+
startComponentsAnimationDistance,
|
|
237
238
|
startComponentsAnimation,
|
|
238
239
|
setStartComponentsAnimation,
|
|
239
240
|
getAnimationValue,
|
|
@@ -243,7 +244,7 @@ export const gestureListenerHelper = (data) => {
|
|
|
243
244
|
if (listenerValue <= 0) {
|
|
244
245
|
if (
|
|
245
246
|
preparedValue >= 0 &&
|
|
246
|
-
preparedValue <= modalSnapPoint -
|
|
247
|
+
preparedValue <= modalSnapPoint - startComponentsAnimationDistance
|
|
247
248
|
) {
|
|
248
249
|
!startComponentsAnimation && setStartComponentsAnimation(true);
|
|
249
250
|
|
|
@@ -263,9 +264,11 @@ export const gestureListenerHelper = (data) => {
|
|
|
263
264
|
animatedValue.setValue(value);
|
|
264
265
|
}
|
|
265
266
|
} else {
|
|
266
|
-
if (preparedValue >=
|
|
267
|
+
if (preparedValue >= startComponentsAnimationDistance) {
|
|
267
268
|
!startComponentsAnimation && setStartComponentsAnimation(true);
|
|
268
|
-
const value = Math.round(
|
|
269
|
+
const value = Math.round(
|
|
270
|
+
preparedValue - startComponentsAnimationDistance
|
|
271
|
+
);
|
|
269
272
|
|
|
270
273
|
animatedValue.setValue(
|
|
271
274
|
calculateAnimationValue(animationType, value, calculationData)
|
|
@@ -197,7 +197,7 @@ export const PlayerWrapper = (props: Props) => {
|
|
|
197
197
|
<AnimationComponent
|
|
198
198
|
animationType={ComponentAnimationType.moveUpComponent}
|
|
199
199
|
additionalData={{ saveArea: true }}
|
|
200
|
-
style={directionStyles(isTabletLandscape)}
|
|
200
|
+
style={[directionStyles(isTabletLandscape), defaultStyles.flex]}
|
|
201
201
|
>
|
|
202
202
|
<PathnameContext.Provider value={pathname}>
|
|
203
203
|
<ScreenContextProvider pathname={pathname}>
|
|
@@ -225,7 +225,7 @@ export const PlayerWrapper = (props: Props) => {
|
|
|
225
225
|
</AnimationComponent>
|
|
226
226
|
</View>
|
|
227
227
|
<AnimatedScrollModal>
|
|
228
|
-
{isInlineModal ? (
|
|
228
|
+
{isInlineModal && !docked ? (
|
|
229
229
|
<AnimationComponent
|
|
230
230
|
animationType={ComponentAnimationType.componentFade}
|
|
231
231
|
style={defaultStyles.flex}
|