@applicaster/zapp-react-native-ui-components 13.0.0-alpha.1724095599 → 13.0.0-alpha.1731130113
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/AudioPlayer/AudioPlayer.tsx +5 -9
- package/Components/AudioPlayer/AudioPlayerLayout.tsx +8 -9
- package/Components/AudioPlayer/helpers.tsx +1 -2
- package/Components/Cell/Cell.tsx +3 -13
- package/Components/Cell/CellWithFocusable.tsx +21 -15
- package/Components/Cell/CellWrapper.tsx +18 -0
- package/Components/Cell/styles.ts +17 -0
- package/Components/CellRendererResolver/index.ts +2 -1
- package/Components/ErrorScreen/index.tsx +8 -0
- package/Components/FocusableCell/index.tsx +1 -1
- package/Components/FocusableGroup/FocusableTvOS.tsx +34 -86
- package/Components/FocusableGroup/index.tsx +0 -3
- package/Components/GeneralContentScreen/GeneralContentScreen.tsx +3 -0
- package/Components/GeneralContentScreen/utils/useCurationAPI.ts +4 -2
- package/Components/GeneralContentScreen/utils/useEventAlerts.ts +30 -0
- package/Components/HandlePlayable/HandlePlayable.tsx +21 -27
- package/Components/Layout/TV/LayoutBackground.tsx +28 -0
- package/Components/Layout/TV/NavBarContainer.tsx +2 -1
- package/Components/Layout/TV/ScreenContainer.tsx +8 -2
- package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +5 -0
- package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +2 -1
- package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +1 -0
- package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +1 -0
- package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +15 -10
- package/Components/Layout/TV/__tests__/index.test.tsx +8 -2
- package/Components/Layout/TV/index.tsx +6 -20
- package/Components/Layout/TV/index.web.tsx +4 -1
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -3
- package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +4 -3
- package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +11 -7
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/const.ts +3 -0
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +6 -6
- package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +2 -8
- package/Components/MasterCell/utils/behaviorProvider.ts +136 -0
- package/Components/MasterCell/utils/index.ts +8 -134
- package/Components/ModalComponent/BottomSheetModalContent.tsx +66 -54
- package/Components/ModalComponent/Button/Item.tsx +6 -5
- package/Components/ModalComponent/Button/assets.ts +1 -1
- package/Components/ModalComponent/Button/index.tsx +45 -62
- package/Components/ModalComponent/Header/index.tsx +9 -8
- package/Components/ModalComponent/utils.ts +55 -7
- package/Components/OfflineHandler/utils/index.ts +1 -1
- package/Components/PlayerContainer/PlayerContainer.tsx +55 -46
- package/Components/PlayerImageBackground/index.tsx +1 -1
- package/Components/River/ComponentsMap/ComponentsMap.tsx +14 -3
- package/Components/River/ComponentsMap/hooks/useLoadingState.ts +3 -3
- package/Components/River/RiverItem.tsx +8 -3
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +7 -1
- package/Components/RouteManager/TestId.tsx +1 -5
- package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +0 -1
- package/Components/RouteManager/__tests__/testId.test.js +0 -4
- package/Components/Screen/TV/__tests__/index.web.test.tsx +26 -0
- package/Components/Screen/TV/index.web.tsx +5 -6
- package/Components/Screen/__tests__/Screen.test.tsx +22 -14
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +2 -2
- package/Components/Screen/hooks.ts +3 -6
- package/Components/TopMarginApplicator/TopMarginApplicator.tsx +2 -3
- package/Components/TrackedView/index.tsx +1 -0
- package/Components/Transitioner/AnimationManager.js +15 -15
- package/Components/VideoLive/PlayerLiveImageComponent.tsx +4 -0
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +1 -0
- package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +1 -1
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +35 -19
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +3 -3
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +38 -14
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +11 -3
- package/Components/VideoModal/ModalAnimation/__tests__/getMoveUpValue.test.ts +108 -0
- package/Components/VideoModal/ModalAnimation/const.ts +5 -0
- package/Components/VideoModal/ModalAnimation/index.ts +2 -0
- package/Components/VideoModal/ModalAnimation/utils.ts +30 -0
- package/Components/VideoModal/PlayerDetails.tsx +13 -5
- package/Components/VideoModal/PlayerWrapper.tsx +35 -22
- package/Components/VideoModal/VideoModal.tsx +19 -4
- package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -40
- package/Components/VideoModal/utils.ts +3 -4
- package/Components/ZappUIComponent/index.tsx +4 -4
- package/Contexts/FocusableGroupContext/withFocusableContext.tsx +4 -10
- package/Contexts/HeaderOffsetContext/index.tsx +4 -6
- package/Contexts/ScreenContext/index.tsx +3 -10
- package/Contexts/ScreenLayoutContext/index.tsx +5 -3
- package/Decorators/RiverResolver/index.tsx +5 -7
- package/Decorators/ZappPipesDataConnector/index.tsx +4 -30
- package/package.json +5 -9
- package/tsconfig.json +2 -3
- package/.babelrc +0 -8
- package/Components/Cell/CellStyles/FallbackCellStyle/index.js +0 -157
- package/Components/Cell/CellStyles/Hero/index.js +0 -111
- package/Components/Cell/CellStyles/ScreenSelector/index.js +0 -68
- package/Components/Cell/CellStyles/cellStylesResolver.ts +0 -19
- package/Components/Cell/CellStyles/colors.js +0 -40
- package/Components/Cell/CellStyles/index.js +0 -15
- package/Components/Cell/CellWithFocusable.ios.tsx +0 -126
|
@@ -7,15 +7,12 @@ import {
|
|
|
7
7
|
useCurrentScreenData,
|
|
8
8
|
useDimensions,
|
|
9
9
|
useRoute,
|
|
10
|
+
useIsTablet,
|
|
10
11
|
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
11
12
|
import { useMemo, useEffect, useState } from "react";
|
|
12
13
|
|
|
13
14
|
export const useWaitForValidOrientation = () => {
|
|
14
|
-
const {
|
|
15
|
-
width: screenWidth,
|
|
16
|
-
height,
|
|
17
|
-
deviceInfo,
|
|
18
|
-
} = useDimensions("screen", {
|
|
15
|
+
const { width: screenWidth, height } = useDimensions("screen", {
|
|
19
16
|
fullDimensions: true,
|
|
20
17
|
updateForInactiveScreens: false,
|
|
21
18
|
});
|
|
@@ -26,7 +23,7 @@ export const useWaitForValidOrientation = () => {
|
|
|
26
23
|
|
|
27
24
|
const [readyState, setReadyState] = useState(false);
|
|
28
25
|
|
|
29
|
-
const isTablet =
|
|
26
|
+
const isTablet = useIsTablet();
|
|
30
27
|
|
|
31
28
|
const { appData } = usePickFromState(["appData"]);
|
|
32
29
|
const isTabletPortrait = appData?.isTabletPortrait;
|
|
@@ -2,6 +2,7 @@ import React from "react";
|
|
|
2
2
|
import { View, ViewProps, ViewStyle } from "react-native";
|
|
3
3
|
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
4
4
|
import { useCurrentScreenData } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
5
|
+
import { isFirstComponentScreenPicker } from "@applicaster/zapp-react-native-utils/componentsUtils";
|
|
5
6
|
|
|
6
7
|
interface IProps {
|
|
7
8
|
targetScreenId?: string;
|
|
@@ -31,11 +32,9 @@ export const useMarginTop = (targetScreenId: string): number => {
|
|
|
31
32
|
* ScreenPicker is a component but should really be a screen.
|
|
32
33
|
* We need to skip margin top for it as it's already applied to the target screen
|
|
33
34
|
**/
|
|
34
|
-
const isScreenPicker =
|
|
35
|
-
screenData?.ui_components?.[0]?.component_type === "screen-picker-qb-tv";
|
|
36
35
|
|
|
37
36
|
// ignore margin on screenPicker
|
|
38
|
-
if (
|
|
37
|
+
if (isFirstComponentScreenPicker(screenData?.ui_components)) {
|
|
39
38
|
return 0;
|
|
40
39
|
}
|
|
41
40
|
|
|
@@ -12,6 +12,7 @@ type TrackedViewProps = {
|
|
|
12
12
|
onPositionUpdated: (props: { rect?: Record<string, number> }) => void;
|
|
13
13
|
testId?: string | undefined;
|
|
14
14
|
groupId?: string;
|
|
15
|
+
clipThreshold?: number;
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
export const TrackedView = memo(function TrackedView(props: TrackedViewProps) {
|
|
@@ -2,21 +2,21 @@ import { Animated } from "react-native";
|
|
|
2
2
|
|
|
3
3
|
import { NAV_ACTION_PUSH, NAV_ACTION_BACK } from "./Transitioner";
|
|
4
4
|
|
|
5
|
-
type TransitionConfig = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
};
|
|
5
|
+
// type TransitionConfig = {
|
|
6
|
+
// duration: number;
|
|
7
|
+
// easing: any;
|
|
8
|
+
// from: {
|
|
9
|
+
// style: any;
|
|
10
|
+
// };
|
|
11
|
+
// to: {
|
|
12
|
+
// style: any;
|
|
13
|
+
// };
|
|
14
|
+
// };
|
|
15
15
|
|
|
16
|
-
type Props = {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
};
|
|
16
|
+
// type Props = {
|
|
17
|
+
// transitionConfig: TransitionConfig;
|
|
18
|
+
// contentStyle: { [string]: any };
|
|
19
|
+
// };
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Manages animation for the Transitioner,
|
|
@@ -25,7 +25,7 @@ type Props = {
|
|
|
25
25
|
* which must have a proper structure, see types above ^.
|
|
26
26
|
*/
|
|
27
27
|
export class AnimationManager {
|
|
28
|
-
constructor(props
|
|
28
|
+
constructor(props) {
|
|
29
29
|
this.animatedValue = new Animated.Value(0.0);
|
|
30
30
|
|
|
31
31
|
this.config = props.transitionConfig(
|
|
@@ -32,6 +32,9 @@ const { log_error, log_debug } = loggerLiveImageComponent;
|
|
|
32
32
|
const isMeasurement = (item: ZappEntry) =>
|
|
33
33
|
isString(item.id) && item.id.startsWith("pre-measurement-");
|
|
34
34
|
|
|
35
|
+
// Pixels by which the view can slightly extend outside the viewport and still be considered fully visible.
|
|
36
|
+
const CLIP_THRESHOLD = 10;
|
|
37
|
+
|
|
35
38
|
type Props = {
|
|
36
39
|
item: ZappEntry;
|
|
37
40
|
style: Record<string, any>;
|
|
@@ -328,6 +331,7 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
328
331
|
<TrackedView
|
|
329
332
|
testId={`tracked-view-${playerId}-${item.title}`}
|
|
330
333
|
onPositionUpdated={onPositionUpdated}
|
|
334
|
+
clipThreshold={CLIP_THRESHOLD}
|
|
331
335
|
>
|
|
332
336
|
<View ref={trackViewRef}>
|
|
333
337
|
{isVideoMode ? (
|
|
@@ -46,7 +46,7 @@ export const AnimatedPlayerModalWrapper = (props: Props) => {
|
|
|
46
46
|
|
|
47
47
|
React.useEffect(() => {
|
|
48
48
|
(playerAnimationState === PlayerAnimationStateEnum.minimize ||
|
|
49
|
-
playerAnimationState === PlayerAnimationStateEnum.
|
|
49
|
+
playerAnimationState === PlayerAnimationStateEnum.maximize) &&
|
|
50
50
|
setStartComponentsAnimation(true);
|
|
51
51
|
}, [playerAnimationState]);
|
|
52
52
|
|
|
@@ -23,10 +23,12 @@ import {
|
|
|
23
23
|
setScrollModalAnimatedValue,
|
|
24
24
|
} from "./utils";
|
|
25
25
|
|
|
26
|
+
import { DURATION_TO_MINIMIZE } from "./const";
|
|
27
|
+
|
|
26
28
|
const getAnimatedConfig = (toValue) => {
|
|
27
29
|
return {
|
|
28
30
|
toValue,
|
|
29
|
-
duration:
|
|
31
|
+
duration: DURATION_TO_MINIMIZE,
|
|
30
32
|
useNativeDriver: true,
|
|
31
33
|
};
|
|
32
34
|
};
|
|
@@ -70,14 +72,19 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
70
72
|
const { maximiseVideoModal, minimiseVideoModal, videoModalState } =
|
|
71
73
|
useNavigation();
|
|
72
74
|
|
|
73
|
-
const {
|
|
75
|
+
const {
|
|
76
|
+
mode: videoModalMode,
|
|
77
|
+
previousMode: previousVideoModalMode,
|
|
78
|
+
item: videoModalItem,
|
|
79
|
+
} = videoModalState;
|
|
80
|
+
|
|
74
81
|
const isMaximizedModal: boolean = videoModalMode === "MAXIMIZED";
|
|
75
82
|
const isMinimizedModal: boolean = videoModalMode === "MINIMIZED";
|
|
76
83
|
const previousItemId = usePrevious(videoModalItem?.id);
|
|
77
84
|
|
|
78
85
|
const isNotMinimizeMaximazeAnimation =
|
|
79
86
|
playerAnimationState !== PlayerAnimationStateEnum.minimize &&
|
|
80
|
-
playerAnimationState !== PlayerAnimationStateEnum.
|
|
87
|
+
playerAnimationState !== PlayerAnimationStateEnum.maximize;
|
|
81
88
|
|
|
82
89
|
const isEnablePanGesture =
|
|
83
90
|
enableGesture &&
|
|
@@ -121,7 +128,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
121
128
|
const preparedTranslationY =
|
|
122
129
|
Math.abs(translationY) - lastScrollYValue.current;
|
|
123
130
|
|
|
124
|
-
if (
|
|
131
|
+
if (isMaximizedModal) {
|
|
125
132
|
const endOffsetY =
|
|
126
133
|
lastSnap + preparedTranslationY + dragToss * velocityY + 150;
|
|
127
134
|
|
|
@@ -143,8 +150,8 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
143
150
|
translateYOffset.flattenOffset();
|
|
144
151
|
dragScrollY.setValue(0);
|
|
145
152
|
|
|
146
|
-
setPlayerAnimationState(PlayerAnimationStateEnum.
|
|
147
|
-
} else {
|
|
153
|
+
setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
|
|
154
|
+
} else if (destSnapPoint !== modalSnapPoints[0] && isMaximizedModal) {
|
|
148
155
|
setPlayerAnimationState(PlayerAnimationStateEnum.minimize);
|
|
149
156
|
}
|
|
150
157
|
} else {
|
|
@@ -158,7 +165,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
158
165
|
|
|
159
166
|
dragScrollY.setValue(0);
|
|
160
167
|
|
|
161
|
-
setPlayerAnimationState(PlayerAnimationStateEnum.
|
|
168
|
+
setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
|
|
162
169
|
} else {
|
|
163
170
|
resetPlayerAnimationState();
|
|
164
171
|
}
|
|
@@ -168,7 +175,13 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
168
175
|
resetPlayerAnimationState();
|
|
169
176
|
}
|
|
170
177
|
},
|
|
171
|
-
[
|
|
178
|
+
[
|
|
179
|
+
lastSnap,
|
|
180
|
+
modalSnapPoints,
|
|
181
|
+
playerAnimationState,
|
|
182
|
+
isMinimizedModal,
|
|
183
|
+
isMaximizedModal,
|
|
184
|
+
]
|
|
172
185
|
);
|
|
173
186
|
|
|
174
187
|
const onScroll = React.useCallback(({ nativeEvent }) => {
|
|
@@ -219,17 +232,18 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
219
232
|
}, []);
|
|
220
233
|
|
|
221
234
|
React.useEffect(() => {
|
|
222
|
-
const { mode, previousMode, item } = videoModalState;
|
|
223
|
-
|
|
224
235
|
if (
|
|
225
|
-
|
|
236
|
+
videoModalMode === "MAXIMIZED" &&
|
|
226
237
|
!enableGesture &&
|
|
227
238
|
scrollPosition.current === 0
|
|
228
239
|
) {
|
|
229
240
|
setIEnableGesture(true);
|
|
230
241
|
}
|
|
231
242
|
|
|
232
|
-
if (
|
|
243
|
+
if (
|
|
244
|
+
videoModalMode === "MINIMIZED" &&
|
|
245
|
+
previousVideoModalMode === "MAXIMIZED"
|
|
246
|
+
) {
|
|
233
247
|
// set animation to the minimize values if moving from the player to another screen
|
|
234
248
|
if (playerAnimationState === null) {
|
|
235
249
|
setScrollModalAnimatedValue(
|
|
@@ -247,14 +261,16 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
247
261
|
}
|
|
248
262
|
} else if (
|
|
249
263
|
playerAnimationState === null &&
|
|
250
|
-
((previousItemId ===
|
|
251
|
-
|
|
252
|
-
(
|
|
253
|
-
|
|
264
|
+
((previousItemId === videoModalItem?.id &&
|
|
265
|
+
videoModalMode === "MAXIMIZED" &&
|
|
266
|
+
(previousVideoModalMode === "MINIMIZED" ||
|
|
267
|
+
previousVideoModalMode === "MAXIMIZED")) ||
|
|
268
|
+
(previousItemId !== videoModalItem?.id &&
|
|
269
|
+
videoModalMode !== "FULLSCREEN"))
|
|
254
270
|
) {
|
|
255
|
-
setPlayerAnimationState(PlayerAnimationStateEnum.
|
|
271
|
+
setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
|
|
256
272
|
}
|
|
257
|
-
}, [
|
|
273
|
+
}, [videoModalMode, previousVideoModalMode, videoModalItem]);
|
|
258
274
|
|
|
259
275
|
React.useEffect(() => {
|
|
260
276
|
if (playerAnimationState === PlayerAnimationStateEnum.minimize) {
|
|
@@ -296,7 +312,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
296
312
|
|
|
297
313
|
resetPlayerAnimationState();
|
|
298
314
|
});
|
|
299
|
-
} else if (playerAnimationState === PlayerAnimationStateEnum.
|
|
315
|
+
} else if (playerAnimationState === PlayerAnimationStateEnum.maximize) {
|
|
300
316
|
Animated.timing(translateYOffset, getAnimatedConfig(0)).start(() => {
|
|
301
317
|
maximiseVideoModal();
|
|
302
318
|
setScrollModalAnimatedValue(translateYOffset, 0, setLastSnap);
|
|
@@ -50,7 +50,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
|
|
|
50
50
|
|
|
51
51
|
const isNotMinimizeMaximazeAnimation =
|
|
52
52
|
playerAnimationState !== PlayerAnimationStateEnum.minimize &&
|
|
53
|
-
playerAnimationState !== PlayerAnimationStateEnum.
|
|
53
|
+
playerAnimationState !== PlayerAnimationStateEnum.maximize;
|
|
54
54
|
|
|
55
55
|
const isEnablePanGesture =
|
|
56
56
|
!isLanguageOverlayVisible &&
|
|
@@ -89,7 +89,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
|
|
|
89
89
|
setLastSnap(destSnapPoint);
|
|
90
90
|
|
|
91
91
|
if (destSnapPoint === modalSnapPoints[0]) {
|
|
92
|
-
setPlayerAnimationState(PlayerAnimationStateEnum.
|
|
92
|
+
setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
|
|
93
93
|
} else {
|
|
94
94
|
lastScrollY.setValue(0);
|
|
95
95
|
lastScrollYValue.current = 0;
|
|
@@ -105,7 +105,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
|
|
|
105
105
|
modalSnapPoints[1] - preparedTranslationY
|
|
106
106
|
);
|
|
107
107
|
|
|
108
|
-
setPlayerAnimationState(PlayerAnimationStateEnum.
|
|
108
|
+
setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
|
|
109
109
|
} else {
|
|
110
110
|
resetPlayerAnimationState();
|
|
111
111
|
}
|
|
@@ -24,8 +24,11 @@ import {
|
|
|
24
24
|
gestureListenerHelper,
|
|
25
25
|
getAnimationDefaultValue,
|
|
26
26
|
getAnimationStyle,
|
|
27
|
+
getMoveUpValue,
|
|
27
28
|
} from "./utils";
|
|
28
29
|
|
|
30
|
+
import { DURATION_TO_MINIMIZE, DEFAULT_DURATION_FOR_ANIMATION } from "./const";
|
|
31
|
+
|
|
29
32
|
type Props = {
|
|
30
33
|
animationType: string;
|
|
31
34
|
children: React.ReactNode;
|
|
@@ -91,20 +94,21 @@ export const AnimationView = ({
|
|
|
91
94
|
const isAudioItem = React.useMemo(
|
|
92
95
|
() =>
|
|
93
96
|
videoModalItem?.content?.type?.includes?.("audio") ||
|
|
94
|
-
videoModalItem?.type?.value
|
|
97
|
+
videoModalItem?.type?.value?.includes?.("audio"),
|
|
95
98
|
[videoModalItem]
|
|
96
99
|
);
|
|
97
100
|
|
|
98
101
|
const inlineAudioPlayer = additionalData.inlineAudioPlayer;
|
|
99
102
|
|
|
100
|
-
const moveUpValue =
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
const moveUpValue = getMoveUpValue({
|
|
104
|
+
additionalData,
|
|
105
|
+
insets,
|
|
106
|
+
isAudioItem,
|
|
107
|
+
progressBarHeight,
|
|
108
|
+
isTablet,
|
|
109
|
+
isTabletLandscape,
|
|
110
|
+
tabletLandscapePlayerTopPosition,
|
|
111
|
+
});
|
|
108
112
|
|
|
109
113
|
const moveComponentHorizontalValue = additionalData.moveValue
|
|
110
114
|
? isRTL
|
|
@@ -119,7 +123,10 @@ export const AnimationView = ({
|
|
|
119
123
|
(animationType, state) => {
|
|
120
124
|
const defaultConfig = {
|
|
121
125
|
toValue: 0,
|
|
122
|
-
duration:
|
|
126
|
+
duration:
|
|
127
|
+
state === PlayerAnimationStateEnum.minimize
|
|
128
|
+
? DURATION_TO_MINIMIZE
|
|
129
|
+
: DEFAULT_DURATION_FOR_ANIMATION,
|
|
123
130
|
useNativeDriver: true,
|
|
124
131
|
};
|
|
125
132
|
|
|
@@ -228,6 +235,8 @@ export const AnimationView = ({
|
|
|
228
235
|
isAudioItem,
|
|
229
236
|
moveUpValue,
|
|
230
237
|
moveComponentHorizontalValue,
|
|
238
|
+
isRTL,
|
|
239
|
+
inlineAudioPlayer,
|
|
231
240
|
]
|
|
232
241
|
);
|
|
233
242
|
|
|
@@ -246,7 +255,7 @@ export const AnimationView = ({
|
|
|
246
255
|
default:
|
|
247
256
|
return getAnimationValue(
|
|
248
257
|
animationType,
|
|
249
|
-
PlayerAnimationStateEnum.
|
|
258
|
+
PlayerAnimationStateEnum.maximize
|
|
250
259
|
).toValue;
|
|
251
260
|
}
|
|
252
261
|
}, [defaultValue, videoModalState]);
|
|
@@ -278,6 +287,11 @@ export const AnimationView = ({
|
|
|
278
287
|
moveUpValue,
|
|
279
288
|
moveComponentHorizontalValue,
|
|
280
289
|
videoModalMode,
|
|
290
|
+
isAudioItem,
|
|
291
|
+
isTablet,
|
|
292
|
+
isTabletLandscape,
|
|
293
|
+
isRTL,
|
|
294
|
+
inlineAudioPlayer,
|
|
281
295
|
]
|
|
282
296
|
);
|
|
283
297
|
|
|
@@ -306,7 +320,7 @@ export const AnimationView = ({
|
|
|
306
320
|
}
|
|
307
321
|
|
|
308
322
|
if (
|
|
309
|
-
videoModalMode === "MAXIMIZED" &&
|
|
323
|
+
(videoModalMode === "MAXIMIZED" || videoModalMode === "MINIMIZED") &&
|
|
310
324
|
defaultValue.x !== screenWidth &&
|
|
311
325
|
width &&
|
|
312
326
|
height
|
|
@@ -332,7 +346,13 @@ export const AnimationView = ({
|
|
|
332
346
|
animatedValue.setValue(value);
|
|
333
347
|
}
|
|
334
348
|
}
|
|
335
|
-
}, [
|
|
349
|
+
}, [
|
|
350
|
+
animatedValue,
|
|
351
|
+
animationType,
|
|
352
|
+
getAnimationValue,
|
|
353
|
+
playerAnimationState,
|
|
354
|
+
videoModalState,
|
|
355
|
+
]);
|
|
336
356
|
|
|
337
357
|
React.useEffect(() => {
|
|
338
358
|
if (
|
|
@@ -344,7 +364,7 @@ export const AnimationView = ({
|
|
|
344
364
|
animatedValue,
|
|
345
365
|
getAnimationValue(animationType, playerAnimationState)
|
|
346
366
|
).start();
|
|
347
|
-
} else if (playerAnimationState === PlayerAnimationStateEnum.
|
|
367
|
+
} else if (playerAnimationState === PlayerAnimationStateEnum.maximize) {
|
|
348
368
|
animatedValue.setValue(defaultValue);
|
|
349
369
|
}
|
|
350
370
|
}, [playerAnimationState, startComponentsAnimation, defaultValue]);
|
|
@@ -427,6 +447,10 @@ export const AnimationComponent = (props: Props) => {
|
|
|
427
447
|
videoModalState: { visible },
|
|
428
448
|
} = useNavigation();
|
|
429
449
|
|
|
450
|
+
if (additionalData?.disableAnimatedComponent) {
|
|
451
|
+
return <>{props.children}</>;
|
|
452
|
+
}
|
|
453
|
+
|
|
430
454
|
const useAnimation =
|
|
431
455
|
visible && !additionalData.disableAnimatedComponent && !isTV();
|
|
432
456
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
2
|
import { Animated } from "react-native";
|
|
3
3
|
|
|
4
4
|
import {
|
|
@@ -14,12 +14,13 @@ import { useConfiguration } from "../utils";
|
|
|
14
14
|
|
|
15
15
|
export enum PlayerAnimationStateEnum {
|
|
16
16
|
minimize = "minimize",
|
|
17
|
-
|
|
17
|
+
maximize = "maximize",
|
|
18
18
|
drag_player = "drag_player",
|
|
19
19
|
drag_scroll = "drag_scroll",
|
|
20
|
+
appear_as_docked = "appear_as_docked",
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
type PlayerAnimationStateT = number | PlayerAnimationStateEnum | null;
|
|
23
|
+
export type PlayerAnimationStateT = number | PlayerAnimationStateEnum | null;
|
|
23
24
|
|
|
24
25
|
export type ModalAnimationContextT = {
|
|
25
26
|
isActiveGesture: boolean;
|
|
@@ -95,6 +96,13 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
|
|
|
95
96
|
setStartComponentsAnimation(false);
|
|
96
97
|
}, []);
|
|
97
98
|
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
// Reset player animation state when video modal is closed
|
|
101
|
+
if (!visible) {
|
|
102
|
+
resetPlayerAnimationState();
|
|
103
|
+
}
|
|
104
|
+
}, [visible, resetPlayerAnimationState]);
|
|
105
|
+
|
|
98
106
|
// Animated values
|
|
99
107
|
const lastScrollY = React.useRef(new Animated.Value(0)).current;
|
|
100
108
|
const dragScrollY = React.useRef(new Animated.Value(0)).current;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { getMoveUpValue } from "../utils";
|
|
2
|
+
|
|
3
|
+
describe("getMoveUpValue", () => {
|
|
4
|
+
it("returns correct value when additionalData.saveArea is true and isAudioItem is false", () => {
|
|
5
|
+
const result = getMoveUpValue({
|
|
6
|
+
additionalData: { saveArea: true },
|
|
7
|
+
insets: { top: 20 },
|
|
8
|
+
isAudioItem: false,
|
|
9
|
+
progressBarHeight: 10,
|
|
10
|
+
isTablet: false,
|
|
11
|
+
isTabletLandscape: false,
|
|
12
|
+
inlineAudioPlayer: false,
|
|
13
|
+
tabletLandscapePlayerTopPosition: 100,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
expect(result).toBe(-20 + 10);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("returns correct value when additionalData.saveArea is true and isAudioItem is true", () => {
|
|
20
|
+
const result = getMoveUpValue({
|
|
21
|
+
additionalData: { saveArea: true },
|
|
22
|
+
insets: { top: 15 },
|
|
23
|
+
isAudioItem: true,
|
|
24
|
+
progressBarHeight: 5,
|
|
25
|
+
isTablet: false,
|
|
26
|
+
isTabletLandscape: false,
|
|
27
|
+
inlineAudioPlayer: false,
|
|
28
|
+
tabletLandscapePlayerTopPosition: 100,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
expect(result).toBe(-15 + 0);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("returns correct value for audio item (tablet or not)", () => {
|
|
35
|
+
const result = getMoveUpValue({
|
|
36
|
+
additionalData: { marginTop: 30 },
|
|
37
|
+
insets: { top: 0 },
|
|
38
|
+
isAudioItem: true,
|
|
39
|
+
progressBarHeight: 0,
|
|
40
|
+
isTablet: false,
|
|
41
|
+
isTabletLandscape: false,
|
|
42
|
+
inlineAudioPlayer: false,
|
|
43
|
+
tabletLandscapePlayerTopPosition: 0,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
expect(result).toBe(-30);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("returns correct value for tablet landscape with inline audio player", () => {
|
|
50
|
+
const result = getMoveUpValue({
|
|
51
|
+
additionalData: {},
|
|
52
|
+
insets: { top: 0 },
|
|
53
|
+
isAudioItem: true,
|
|
54
|
+
progressBarHeight: 8,
|
|
55
|
+
isTablet: true,
|
|
56
|
+
isTabletLandscape: true,
|
|
57
|
+
inlineAudioPlayer: true,
|
|
58
|
+
tabletLandscapePlayerTopPosition: 50,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
expect(result).toBe(-0);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("returns correct value for tablet landscape without audio item", () => {
|
|
65
|
+
const result = getMoveUpValue({
|
|
66
|
+
additionalData: {},
|
|
67
|
+
insets: { top: 0 },
|
|
68
|
+
isAudioItem: false,
|
|
69
|
+
progressBarHeight: 12,
|
|
70
|
+
isTablet: true,
|
|
71
|
+
isTabletLandscape: true,
|
|
72
|
+
inlineAudioPlayer: false,
|
|
73
|
+
tabletLandscapePlayerTopPosition: 60,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
expect(result).toBe(-60 + 12);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("returns -130 for tablet portrait (not landscape)", () => {
|
|
80
|
+
const result = getMoveUpValue({
|
|
81
|
+
additionalData: {},
|
|
82
|
+
insets: { top: 0 },
|
|
83
|
+
isAudioItem: false,
|
|
84
|
+
progressBarHeight: 0,
|
|
85
|
+
isTablet: true,
|
|
86
|
+
isTabletLandscape: false,
|
|
87
|
+
inlineAudioPlayer: false,
|
|
88
|
+
tabletLandscapePlayerTopPosition: 0,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
expect(result).toBe(-130);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("returns -50 + progressBarHeight for mobile audio player in docked mode", () => {
|
|
95
|
+
const result = getMoveUpValue({
|
|
96
|
+
additionalData: {},
|
|
97
|
+
insets: { top: 0 },
|
|
98
|
+
isAudioItem: false,
|
|
99
|
+
progressBarHeight: 7,
|
|
100
|
+
isTablet: false,
|
|
101
|
+
isTabletLandscape: false,
|
|
102
|
+
inlineAudioPlayer: false,
|
|
103
|
+
tabletLandscapePlayerTopPosition: 0,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
expect(result).toBe(-50 + 7);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
@@ -14,3 +14,5 @@ export { useModalAnimationContext } from "./useModalAnimationContext";
|
|
|
14
14
|
export { AnimationComponent } from "./AnimationComponent";
|
|
15
15
|
|
|
16
16
|
export { ComponentAnimationType, defaultAspectRatioWidth } from "./utils";
|
|
17
|
+
|
|
18
|
+
export { DURATION_TO_MINIMIZE, DURATION_TO_MAXIMIZE } from "./const";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* eslint-disable padding-line-between-statements */
|
|
2
2
|
|
|
3
3
|
import { PlayerAnimationStateEnum } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
4
|
+
import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
4
5
|
|
|
5
6
|
export enum ComponentAnimationType {
|
|
6
7
|
bottomBar = "bottomBar",
|
|
@@ -300,3 +301,32 @@ export const resetScrollAnimatedValues = (
|
|
|
300
301
|
dragScrollY.setValue(0);
|
|
301
302
|
dragVideoPlayerY.setValue(0);
|
|
302
303
|
};
|
|
304
|
+
|
|
305
|
+
export const getMoveUpValue = ({
|
|
306
|
+
additionalData,
|
|
307
|
+
insets,
|
|
308
|
+
isAudioItem,
|
|
309
|
+
progressBarHeight,
|
|
310
|
+
isTablet,
|
|
311
|
+
isTabletLandscape,
|
|
312
|
+
tabletLandscapePlayerTopPosition,
|
|
313
|
+
}) => {
|
|
314
|
+
if (additionalData.saveArea) {
|
|
315
|
+
return -insets.top + (isAudioItem ? 0 : progressBarHeight);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (isAudioItem) {
|
|
319
|
+
// for any layouts in audioPlayer
|
|
320
|
+
return -1 * toNumberWithDefaultZero(additionalData?.marginTop);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (isTablet) {
|
|
324
|
+
if (isTabletLandscape) {
|
|
325
|
+
return -tabletLandscapePlayerTopPosition + progressBarHeight;
|
|
326
|
+
} else {
|
|
327
|
+
return -130;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return -50 + progressBarHeight;
|
|
332
|
+
};
|
|
@@ -5,10 +5,12 @@ import {
|
|
|
5
5
|
Easing,
|
|
6
6
|
StyleProp,
|
|
7
7
|
ViewStyle,
|
|
8
|
+
StyleSheet,
|
|
8
9
|
} from "react-native";
|
|
9
10
|
import { useTargetScreenData } from "@applicaster/zapp-react-native-utils/reactHooks/screen";
|
|
10
11
|
import { ComponentsMap } from "@applicaster/zapp-react-native-ui-components/Components/River/ComponentsMap";
|
|
11
12
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
13
|
+
import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
|
|
12
14
|
|
|
13
15
|
const { width: SCREEN_WIDTH } = Dimensions.get("screen");
|
|
14
16
|
|
|
@@ -21,9 +23,9 @@ type Props = {
|
|
|
21
23
|
entry: ZappEntry;
|
|
22
24
|
style: StyleProp<ViewStyle>;
|
|
23
25
|
configuration: Configuration;
|
|
24
|
-
isTabletLandscape
|
|
26
|
+
isTabletLandscape?: boolean;
|
|
25
27
|
isAudioPlayer?: boolean;
|
|
26
|
-
isTablet
|
|
28
|
+
isTablet?: boolean;
|
|
27
29
|
};
|
|
28
30
|
|
|
29
31
|
const containerStyle = ({
|
|
@@ -38,9 +40,9 @@ export const PlayerDetails = ({
|
|
|
38
40
|
entry,
|
|
39
41
|
style,
|
|
40
42
|
configuration,
|
|
41
|
-
isTabletLandscape,
|
|
43
|
+
isTabletLandscape = false,
|
|
42
44
|
isAudioPlayer,
|
|
43
|
-
isTablet,
|
|
45
|
+
isTablet = false,
|
|
44
46
|
}: Props) => {
|
|
45
47
|
const screenData = useTargetScreenData(entry);
|
|
46
48
|
const insets = useSafeAreaInsets();
|
|
@@ -77,6 +79,10 @@ export const PlayerDetails = ({
|
|
|
77
79
|
}
|
|
78
80
|
}, [isAudioPlayer]);
|
|
79
81
|
|
|
82
|
+
if (isNilOrEmpty(screenData?.ui_components)) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
80
86
|
return (
|
|
81
87
|
<Animated.View
|
|
82
88
|
style={[
|
|
@@ -90,7 +96,9 @@ export const PlayerDetails = ({
|
|
|
90
96
|
{
|
|
91
97
|
// workaround for avoid wrong text-height after going back to portrait rotation
|
|
92
98
|
// we don't see this view in landscape mode, so we are able to use fixed width from portrait mode
|
|
93
|
-
width: isTablet
|
|
99
|
+
width: isTablet
|
|
100
|
+
? undefined
|
|
101
|
+
: (StyleSheet.flatten(style)?.width ?? SCREEN_WIDTH),
|
|
94
102
|
},
|
|
95
103
|
]}
|
|
96
104
|
>
|