@applicaster/zapp-react-native-ui-components 13.0.8-alpha.4915596275 → 13.0.8-alpha.8384339831
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/PlayerContainer/PlayerContainer.tsx +6 -15
- package/Components/River/ComponentsMap/ComponentsMap.tsx +55 -43
- package/Components/River/ComponentsMap/ContextProviders/ComponentsMapHeightContext.ts +8 -0
- package/Components/River/ComponentsMap/ContextProviders/ComponentsMapRefContext.ts +8 -0
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +3 -2
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +8 -32
- package/Components/VideoModal/PlayerDetails.tsx +7 -26
- package/Components/VideoModal/PlayerWrapper.tsx +141 -26
- package/Components/VideoModal/VideoModal.tsx +17 -3
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +7 -1
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +240 -44
- package/Components/VideoModal/hooks/index.ts +2 -0
- package/Components/VideoModal/hooks/useBackgroundColor.ts +10 -0
- package/Components/VideoModal/hooks/useModalSize.ts +2 -18
- package/Components/VideoModal/utils.ts +0 -6
- package/package.json +5 -5
|
@@ -88,7 +88,7 @@ export const VideoModalMode = {
|
|
|
88
88
|
MAXIMIZED: "MAXIMIZED",
|
|
89
89
|
MINIMIZED: "MINIMIZED",
|
|
90
90
|
FULLSCREEN: "FULLSCREEN",
|
|
91
|
-
}
|
|
91
|
+
};
|
|
92
92
|
|
|
93
93
|
export type PlayNextData = {
|
|
94
94
|
state: PlayNextState;
|
|
@@ -132,7 +132,7 @@ const webStyles = {
|
|
|
132
132
|
playerScreen: {
|
|
133
133
|
flex: 1,
|
|
134
134
|
height: "100vh",
|
|
135
|
-
|
|
135
|
+
background: "black",
|
|
136
136
|
},
|
|
137
137
|
playerWrapper: {
|
|
138
138
|
height: "100%",
|
|
@@ -150,6 +150,7 @@ const nativeStyles = {
|
|
|
150
150
|
},
|
|
151
151
|
playerScreen: {
|
|
152
152
|
flex: 1,
|
|
153
|
+
backgroundColor: "black",
|
|
153
154
|
overflow: "hidden",
|
|
154
155
|
},
|
|
155
156
|
playerWrapper: {
|
|
@@ -569,9 +570,8 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
569
570
|
const isInlineTV = isInlineTVUtil(screenData);
|
|
570
571
|
|
|
571
572
|
const inline =
|
|
572
|
-
[VideoModalMode.MAXIMIZED, VideoModalMode.MINIMIZED].includes(
|
|
573
|
-
|
|
574
|
-
) || isInlineTV;
|
|
573
|
+
[VideoModalMode.MAXIMIZED, VideoModalMode.MINIMIZED].includes(mode) ||
|
|
574
|
+
isInlineTV;
|
|
575
575
|
|
|
576
576
|
const value = React.useMemo(
|
|
577
577
|
() => ({ playerId: state.playerId }),
|
|
@@ -592,11 +592,7 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
592
592
|
);
|
|
593
593
|
}
|
|
594
594
|
|
|
595
|
-
if (
|
|
596
|
-
screen_background_color &&
|
|
597
|
-
mode !== VideoModalMode.FULLSCREEN &&
|
|
598
|
-
isTV()
|
|
599
|
-
) {
|
|
595
|
+
if (screen_background_color && mode !== VideoModalMode.FULLSCREEN) {
|
|
600
596
|
updatedStyles.playerScreen.backgroundColor = screen_background_color;
|
|
601
597
|
}
|
|
602
598
|
|
|
@@ -626,8 +622,6 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
626
622
|
playNextData,
|
|
627
623
|
};
|
|
628
624
|
|
|
629
|
-
const pointerEventsProp = mode === "MINIMIZED" ? "box-none" : "auto";
|
|
630
|
-
|
|
631
625
|
return (
|
|
632
626
|
<PlayerStateContext.Provider value={value}>
|
|
633
627
|
<PlayerContainerContextProvider
|
|
@@ -648,17 +642,14 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
648
642
|
preferredFocus
|
|
649
643
|
shouldUsePreferredFocus
|
|
650
644
|
groupId={groupId}
|
|
651
|
-
pointerEvents={pointerEventsProp}
|
|
652
645
|
>
|
|
653
646
|
{/* Video player and components */}
|
|
654
647
|
<View
|
|
655
648
|
style={styles.playerScreen}
|
|
656
649
|
testID={"player-screen-container"}
|
|
657
|
-
pointerEvents={pointerEventsProp}
|
|
658
650
|
>
|
|
659
651
|
{/* Player container */}
|
|
660
652
|
<View
|
|
661
|
-
pointerEvents={pointerEventsProp}
|
|
662
653
|
style={[
|
|
663
654
|
styles.playerWrapper,
|
|
664
655
|
// eslint-disable-next-line react-native/no-inline-styles, react-native/no-color-literals
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
|
-
import {
|
|
3
|
+
import { FlatList, StyleSheet, View } from "react-native";
|
|
4
4
|
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
5
5
|
import { RiverItem } from "../RiverItem";
|
|
6
6
|
import { RiverFooter } from "../RiverFooter";
|
|
@@ -9,8 +9,8 @@ import { useScreenConfiguration } from "../useScreenConfiguration";
|
|
|
9
9
|
import { RefreshControl } from "../RefreshControl";
|
|
10
10
|
import { ifEmptyUseFallback } from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
11
11
|
import {
|
|
12
|
-
useProfilerLogging,
|
|
13
12
|
usePipesCacheReset,
|
|
13
|
+
useProfilerLogging,
|
|
14
14
|
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
15
15
|
import { useLoadingState } from "./hooks/useLoadingState";
|
|
16
16
|
import { ViewportTracker } from "../../Viewport";
|
|
@@ -25,6 +25,8 @@ import { useScreenContextV2 } from "@applicaster/zapp-react-native-utils/reactHo
|
|
|
25
25
|
import { useShallow } from "zustand/react/shallow";
|
|
26
26
|
|
|
27
27
|
import { isAndroidPlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
28
|
+
import { ComponentsMapHeightContext } from "./ContextProviders/ComponentsMapHeightContext";
|
|
29
|
+
import { ComponentsMapRefContext } from "./ContextProviders/ComponentsMapRefContext";
|
|
28
30
|
|
|
29
31
|
const isAndroid = isAndroidPlatform();
|
|
30
32
|
|
|
@@ -70,6 +72,7 @@ function ComponentsMapComponent(props: Props) {
|
|
|
70
72
|
} = props;
|
|
71
73
|
|
|
72
74
|
const flatListRef = React.useRef<FlatList | null>(null);
|
|
75
|
+
const flatListWrapperRef = React.useRef<View | null>(null);
|
|
73
76
|
const screenConfig = useScreenConfiguration(riverId);
|
|
74
77
|
const screenData = useScreenData(riverId);
|
|
75
78
|
const pullToRefreshEnabled = screenData?.rules?.pull_to_refresh_enabled;
|
|
@@ -265,48 +268,57 @@ function ComponentsMapComponent(props: Props) {
|
|
|
265
268
|
// The Screen Picker in Mobile is completly different than the TV
|
|
266
269
|
// so the various offsets / margins in TV do not apply here.
|
|
267
270
|
return (
|
|
268
|
-
<View
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
271
|
+
<View
|
|
272
|
+
style={styles.container}
|
|
273
|
+
ref={(ref) => {
|
|
274
|
+
flatListWrapperRef.current = ref;
|
|
275
|
+
}}
|
|
276
|
+
>
|
|
277
|
+
<ComponentsMapHeightContext.Provider value={flatListHeight}>
|
|
278
|
+
<ComponentsMapRefContext.Provider value={flatListWrapperRef}>
|
|
279
|
+
<ScreenLoadingMeasurements
|
|
280
|
+
riverId={riverId}
|
|
281
|
+
numberOfComponents={riverComponents.length}
|
|
282
|
+
>
|
|
283
|
+
<ViewportTracker>
|
|
284
|
+
<FlatList
|
|
285
|
+
ref={(ref) => {
|
|
286
|
+
flatListRef.current = ref;
|
|
287
|
+
}}
|
|
288
|
+
// Fix for WebView rerender crashes on Android API 28+
|
|
289
|
+
// https://github.com/react-native-webview/react-native-webview/issues/1915#issuecomment-964035468
|
|
290
|
+
overScrollMode={isAndroid ? "never" : "auto"}
|
|
291
|
+
scrollIndicatorInsets={scrollIndicatorInsets}
|
|
292
|
+
extraData={feed}
|
|
293
|
+
stickyHeaderIndices={stickyHeaderIndices}
|
|
294
|
+
removeClippedSubviews={isAndroid}
|
|
295
|
+
onLayout={handleOnLayout}
|
|
296
|
+
initialNumToRender={3}
|
|
297
|
+
maxToRenderPerBatch={10}
|
|
298
|
+
windowSize={12}
|
|
299
|
+
listKey={riverId}
|
|
300
|
+
keyExtractor={keyExtractor}
|
|
301
|
+
renderItem={renderRiverItem}
|
|
302
|
+
data={riverComponents}
|
|
303
|
+
contentContainerStyle={contentContainerStyle}
|
|
304
|
+
ListFooterComponent={
|
|
305
|
+
<RiverFooter
|
|
306
|
+
flatListHeight={flatListHeight}
|
|
307
|
+
loadingState={loadingState}
|
|
308
|
+
/>
|
|
309
|
+
}
|
|
310
|
+
refreshControl={refreshControl}
|
|
311
|
+
onScrollBeginDrag={onScrollBeginDrag}
|
|
312
|
+
onScroll={onScroll}
|
|
313
|
+
onMomentumScrollEnd={_onMomentumScrollEnd}
|
|
314
|
+
onScrollEndDrag={_onScrollEndDrag}
|
|
315
|
+
scrollEventThrottle={16}
|
|
316
|
+
{...scrollViewExtraProps}
|
|
298
317
|
/>
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
onMomentumScrollEnd={_onMomentumScrollEnd}
|
|
304
|
-
onScrollEndDrag={_onScrollEndDrag}
|
|
305
|
-
scrollEventThrottle={16}
|
|
306
|
-
{...scrollViewExtraProps}
|
|
307
|
-
/>
|
|
308
|
-
</ViewportTracker>
|
|
309
|
-
</ScreenLoadingMeasurements>
|
|
318
|
+
</ViewportTracker>
|
|
319
|
+
</ScreenLoadingMeasurements>
|
|
320
|
+
</ComponentsMapRefContext.Provider>
|
|
321
|
+
</ComponentsMapHeightContext.Provider>
|
|
310
322
|
</View>
|
|
311
323
|
);
|
|
312
324
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
|
|
4
|
+
export const ComponentsMapRefContext =
|
|
5
|
+
React.createContext<React.RefObject<View | null> | null>(null);
|
|
6
|
+
|
|
7
|
+
export const useComponentsMapRef = () =>
|
|
8
|
+
React.useContext(ComponentsMapRefContext);
|
|
@@ -372,7 +372,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
372
372
|
maxDeltaY={lastSnap - modalSnapPoints[0]}
|
|
373
373
|
numberOfTaps={1}
|
|
374
374
|
>
|
|
375
|
-
<View pointerEvents="box-none">
|
|
375
|
+
<View pointerEvents="box-none" style={generalStyles.container}>
|
|
376
376
|
<PanGestureHandler
|
|
377
377
|
enabled={isEnablePanGesture}
|
|
378
378
|
ref={panHandlerRef}
|
|
@@ -382,7 +382,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
382
382
|
onHandlerStateChange={onHandlerStateChange}
|
|
383
383
|
activeOffsetY={[-5, 5]}
|
|
384
384
|
>
|
|
385
|
-
<Animated.View>
|
|
385
|
+
<Animated.View style={generalStyles.container}>
|
|
386
386
|
<NativeViewGestureHandler
|
|
387
387
|
ref={scrollRef}
|
|
388
388
|
waitFor={tapHandlerRef}
|
|
@@ -397,6 +397,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
397
397
|
onMomentumScrollEnd={onMomentumScrollEnd}
|
|
398
398
|
scrollEventThrottle={1}
|
|
399
399
|
showsVerticalScrollIndicator={false}
|
|
400
|
+
contentContainerStyle={generalStyles.container}
|
|
400
401
|
>
|
|
401
402
|
{children}
|
|
402
403
|
</Animated.ScrollView>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect } from "react";
|
|
2
|
-
import { Animated
|
|
2
|
+
import { Animated } from "react-native";
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
useSafeAreaInsets,
|
|
@@ -11,7 +11,6 @@ import { isLive } from "@applicaster/zapp-react-native-utils/playerUtils";
|
|
|
11
11
|
|
|
12
12
|
import { PROGRESS_BAR_HEIGHT } from "./utils";
|
|
13
13
|
import { useConfiguration } from "../utils";
|
|
14
|
-
import { useIsTabletLandscape } from "@applicaster/zapp-react-native-utils/reactHooks/device/useMemoizedIsTablet";
|
|
15
14
|
|
|
16
15
|
export enum PlayerAnimationStateEnum {
|
|
17
16
|
minimize = "minimize",
|
|
@@ -24,7 +23,6 @@ export enum PlayerAnimationStateEnum {
|
|
|
24
23
|
export type PlayerAnimationStateT = number | PlayerAnimationStateEnum | null;
|
|
25
24
|
|
|
26
25
|
export type ModalAnimationContextT = {
|
|
27
|
-
yTranslate: React.MutableRefObject<Animated.Value | null>;
|
|
28
26
|
isActiveGesture: boolean;
|
|
29
27
|
playerAnimationState: PlayerAnimationStateT;
|
|
30
28
|
setPlayerAnimationState: (value: PlayerAnimationStateT) => void;
|
|
@@ -50,7 +48,6 @@ export type ModalAnimationContextT = {
|
|
|
50
48
|
};
|
|
51
49
|
|
|
52
50
|
export const ReactContext = React.createContext<ModalAnimationContextT>({
|
|
53
|
-
yTranslate: React.createRef<Animated.Value | null>(),
|
|
54
51
|
isActiveGesture: false,
|
|
55
52
|
playerAnimationState: null,
|
|
56
53
|
setPlayerAnimationState: () => null,
|
|
@@ -76,10 +73,6 @@ export const ReactContext = React.createContext<ModalAnimationContextT>({
|
|
|
76
73
|
});
|
|
77
74
|
|
|
78
75
|
const Provider = ({ children }: { children: React.ReactNode }) => {
|
|
79
|
-
const yTranslate = React.useRef(
|
|
80
|
-
new Animated.Value(Dimensions.get("window").height)
|
|
81
|
-
);
|
|
82
|
-
|
|
83
76
|
const [playerAnimationState, setPlayerAnimationState] =
|
|
84
77
|
React.useState<PlayerAnimationStateT>(null);
|
|
85
78
|
|
|
@@ -103,6 +96,13 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
|
|
|
103
96
|
setStartComponentsAnimation(false);
|
|
104
97
|
}, []);
|
|
105
98
|
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
// Reset player animation state when video modal is closed
|
|
101
|
+
if (!visible) {
|
|
102
|
+
resetPlayerAnimationState();
|
|
103
|
+
}
|
|
104
|
+
}, [visible, resetPlayerAnimationState]);
|
|
105
|
+
|
|
106
106
|
// Animated values
|
|
107
107
|
const lastScrollY = React.useRef(new Animated.Value(0)).current;
|
|
108
108
|
const dragScrollY = React.useRef(new Animated.Value(0)).current;
|
|
@@ -115,29 +115,6 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
|
|
|
115
115
|
const { bottom: bottomSafeArea } = useSafeAreaInsets();
|
|
116
116
|
const bottomTabBarHeight = useGetBottomTabBarHeight();
|
|
117
117
|
const startComponentsAnimationDistance = Math.round((height * 60) / 100);
|
|
118
|
-
const isTabletLandscape = useIsTabletLandscape();
|
|
119
|
-
const windowDimensions = Dimensions.get("window");
|
|
120
|
-
|
|
121
|
-
useEffect(() => {
|
|
122
|
-
// Reset player animation state when video modal is closed
|
|
123
|
-
if (!visible) {
|
|
124
|
-
resetPlayerAnimationState();
|
|
125
|
-
|
|
126
|
-
if (!isTabletLandscape) {
|
|
127
|
-
// restore to portrait ( in portrait mode height is bigger)
|
|
128
|
-
if (windowDimensions.height > windowDimensions.width) {
|
|
129
|
-
yTranslate.current?.setValue(windowDimensions.height);
|
|
130
|
-
}
|
|
131
|
-
} else {
|
|
132
|
-
yTranslate.current?.setValue(windowDimensions.height);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}, [
|
|
136
|
-
visible,
|
|
137
|
-
resetPlayerAnimationState,
|
|
138
|
-
windowDimensions.height,
|
|
139
|
-
isTabletLandscape,
|
|
140
|
-
]);
|
|
141
118
|
|
|
142
119
|
React.useEffect(() => {
|
|
143
120
|
if (visible && mode === "MAXIMIZED" && height !== safeAreaFrameHeight) {
|
|
@@ -164,7 +141,6 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
|
|
|
164
141
|
return (
|
|
165
142
|
<ReactContext.Provider
|
|
166
143
|
value={{
|
|
167
|
-
yTranslate,
|
|
168
144
|
startComponentsAnimation,
|
|
169
145
|
setStartComponentsAnimation,
|
|
170
146
|
isActiveGesture: playerAnimationState !== null,
|
|
@@ -4,17 +4,16 @@ import {
|
|
|
4
4
|
Dimensions,
|
|
5
5
|
Easing,
|
|
6
6
|
StyleProp,
|
|
7
|
-
ViewStyle,
|
|
8
7
|
StyleSheet,
|
|
8
|
+
ViewStyle,
|
|
9
9
|
} from "react-native";
|
|
10
10
|
import { useTargetScreenData } from "@applicaster/zapp-react-native-utils/reactHooks/screen";
|
|
11
11
|
import { ComponentsMap } from "@applicaster/zapp-react-native-ui-components/Components/River/ComponentsMap";
|
|
12
12
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
13
13
|
import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
|
|
14
|
-
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
15
|
-
import { useDelayedPlayerDetails } from "./hooks";
|
|
16
14
|
|
|
17
15
|
const { width: SCREEN_WIDTH } = Dimensions.get("screen");
|
|
16
|
+
const flex1 = { flex: 1 };
|
|
18
17
|
|
|
19
18
|
type Configuration = {
|
|
20
19
|
[key: string]: any;
|
|
@@ -28,10 +27,6 @@ type Props = {
|
|
|
28
27
|
isTabletLandscape?: boolean;
|
|
29
28
|
isAudioPlayer?: boolean;
|
|
30
29
|
isTablet?: boolean;
|
|
31
|
-
inline?: any;
|
|
32
|
-
docked?: boolean;
|
|
33
|
-
isModal?: boolean;
|
|
34
|
-
pip?: boolean;
|
|
35
30
|
};
|
|
36
31
|
|
|
37
32
|
const containerStyle = ({
|
|
@@ -48,31 +43,15 @@ export const PlayerDetails = ({
|
|
|
48
43
|
configuration,
|
|
49
44
|
isTabletLandscape = false,
|
|
50
45
|
isAudioPlayer,
|
|
51
|
-
|
|
52
|
-
docked,
|
|
53
|
-
isModal,
|
|
54
|
-
pip,
|
|
46
|
+
isTablet = false,
|
|
55
47
|
}: Props) => {
|
|
56
|
-
const isInlineModal = inline && isModal;
|
|
57
|
-
|
|
58
|
-
// Mounting the PlayerDetails component is a resource-intensive process.
|
|
59
|
-
// Therefore, for performance reasons, we mount it with a delay to make the rotation process as smooth as possible.
|
|
60
|
-
// The flow is as follows: the rotation occurs first, and then, after a short delay, we mount the PlayerDetails component.
|
|
61
|
-
// This helps to avoid blocking the rotation and any animations related to the rotation.
|
|
62
|
-
const isShowPlayerDetails = useDelayedPlayerDetails({
|
|
63
|
-
isInline: isInlineModal,
|
|
64
|
-
isDocked: docked,
|
|
65
|
-
isPip: pip,
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
const isTablet = useIsTablet();
|
|
69
48
|
const screenData = useTargetScreenData(entry);
|
|
70
49
|
const insets = useSafeAreaInsets();
|
|
71
50
|
|
|
72
51
|
const extraTabletStyles = !isAudioPlayer
|
|
73
52
|
? isTabletLandscape
|
|
74
53
|
? { marginTop: -insets.top, paddingTop: insets.top + 20 }
|
|
75
|
-
: {
|
|
54
|
+
: {}
|
|
76
55
|
: {};
|
|
77
56
|
|
|
78
57
|
// Animation setup
|
|
@@ -101,7 +80,7 @@ export const PlayerDetails = ({
|
|
|
101
80
|
}
|
|
102
81
|
}, [isAudioPlayer]);
|
|
103
82
|
|
|
104
|
-
if (isNilOrEmpty(screenData?.ui_components)
|
|
83
|
+
if (isNilOrEmpty(screenData?.ui_components)) {
|
|
105
84
|
return null;
|
|
106
85
|
}
|
|
107
86
|
|
|
@@ -115,6 +94,7 @@ export const PlayerDetails = ({
|
|
|
115
94
|
transform: [{ translateY }],
|
|
116
95
|
opacity,
|
|
117
96
|
},
|
|
97
|
+
flex1,
|
|
118
98
|
{
|
|
119
99
|
// workaround for avoid wrong text-height after going back to portrait rotation
|
|
120
100
|
// we don't see this view in landscape mode, so we are able to use fixed width from portrait mode
|
|
@@ -129,6 +109,7 @@ export const PlayerDetails = ({
|
|
|
129
109
|
riverId={screenData.id}
|
|
130
110
|
feed={screenData?.data?.source}
|
|
131
111
|
riverComponents={screenData.ui_components}
|
|
112
|
+
isScreenWrappedInContainer
|
|
132
113
|
/>
|
|
133
114
|
) : null}
|
|
134
115
|
</Animated.View>
|
|
@@ -9,8 +9,16 @@ import {
|
|
|
9
9
|
import { Edge, SafeAreaView } from "react-native-safe-area-context";
|
|
10
10
|
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
11
11
|
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
12
|
+
import { PlayerDetails } from "./PlayerDetails";
|
|
12
13
|
import { playerDimensionsHack } from "./utils";
|
|
13
|
-
import {
|
|
14
|
+
import { useDelayedPlayerDetails } from "./hooks";
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
AnimatedScrollModal,
|
|
18
|
+
AnimatedVideoPlayerComponent,
|
|
19
|
+
AnimationComponent,
|
|
20
|
+
ComponentAnimationType,
|
|
21
|
+
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
14
22
|
|
|
15
23
|
const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get("screen");
|
|
16
24
|
|
|
@@ -36,15 +44,29 @@ type Props = {
|
|
|
36
44
|
isModal?: boolean;
|
|
37
45
|
fullscreen?: boolean;
|
|
38
46
|
isTabletPortrait?: boolean;
|
|
47
|
+
children: (playerDimensions: DimensionsT) => React.ReactNode;
|
|
39
48
|
configuration: Configuration;
|
|
40
|
-
|
|
41
|
-
playerContent: (styles: ViewStyle) => React.ReactNode;
|
|
42
49
|
};
|
|
43
50
|
|
|
44
51
|
const defaultStyles = StyleSheet.create({
|
|
45
52
|
playerContainer: { position: "relative", alignSelf: "center", zIndex: 200 },
|
|
53
|
+
playerDetails: { flex: 1, paddingTop: 20 },
|
|
54
|
+
flex: { flex: 1 },
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const orientationStyles = StyleSheet.create({
|
|
58
|
+
landscape: { flexDirection: "row" },
|
|
59
|
+
portrait: { flexDirection: "column" },
|
|
46
60
|
});
|
|
47
61
|
|
|
62
|
+
const directionStyles = (isTabletLandscape: boolean): ViewStyle => {
|
|
63
|
+
if (isTabletLandscape) {
|
|
64
|
+
return orientationStyles.landscape;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return orientationStyles.portrait;
|
|
68
|
+
};
|
|
69
|
+
|
|
48
70
|
const getScreenAspectRatio = () => {
|
|
49
71
|
const longEdge = Math.max(SCREEN_WIDTH, SCREEN_HEIGHT);
|
|
50
72
|
const shortEdge = Math.min(SCREEN_WIDTH, SCREEN_HEIGHT);
|
|
@@ -64,6 +86,51 @@ const getEdges = (isTablet: boolean, isInlineModal: boolean) => {
|
|
|
64
86
|
return ["top"];
|
|
65
87
|
};
|
|
66
88
|
|
|
89
|
+
const isPercentage = (value: string | number): boolean => {
|
|
90
|
+
if (typeof value === "string") {
|
|
91
|
+
return value.includes("%");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return false;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const getPercentageOf = (percent: string, value: number) => {
|
|
98
|
+
const percentageValue = parseFloat(percent.replace("%", ""));
|
|
99
|
+
|
|
100
|
+
if (isNaN(percentageValue)) {
|
|
101
|
+
return value;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return (value * percentageValue) / 100;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const getTabletWidth = (
|
|
108
|
+
configuration: Configuration,
|
|
109
|
+
dimensions: DimensionsT
|
|
110
|
+
) => {
|
|
111
|
+
const tablet_landscape_sidebar_width =
|
|
112
|
+
configuration?.tablet_landscape_sidebar_width;
|
|
113
|
+
|
|
114
|
+
const { width } = dimensions;
|
|
115
|
+
let widthValue = Number(width);
|
|
116
|
+
|
|
117
|
+
if (isPercentage(width)) {
|
|
118
|
+
widthValue = getPercentageOf(width.toString(), SCREEN_WIDTH);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const sidebarWidth = Number(tablet_landscape_sidebar_width?.replace("%", ""));
|
|
122
|
+
|
|
123
|
+
if (tablet_landscape_sidebar_width?.includes("%")) {
|
|
124
|
+
return widthValue * (1 - sidebarWidth / 100);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (Number.isNaN(sidebarWidth)) {
|
|
128
|
+
return widthValue * 0.65;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return widthValue - sidebarWidth;
|
|
132
|
+
};
|
|
133
|
+
|
|
67
134
|
const PlayerWrapperComponent = (props: Props) => {
|
|
68
135
|
const {
|
|
69
136
|
entry,
|
|
@@ -72,26 +139,35 @@ const PlayerWrapperComponent = (props: Props) => {
|
|
|
72
139
|
inline,
|
|
73
140
|
docked,
|
|
74
141
|
isModal,
|
|
142
|
+
children,
|
|
75
143
|
isTabletPortrait,
|
|
76
144
|
configuration,
|
|
145
|
+
fullscreen,
|
|
77
146
|
pip,
|
|
78
|
-
playerContent,
|
|
79
147
|
} = props;
|
|
80
148
|
|
|
81
149
|
const isTablet = useIsTablet();
|
|
82
150
|
|
|
83
151
|
const isInlineModal = inline && isModal;
|
|
84
152
|
|
|
153
|
+
// Mounting the PlayerDetails component is a resource-intensive process.
|
|
154
|
+
// Therefore, for performance reasons, we mount it with a delay to make the rotation process as smooth as possible.
|
|
155
|
+
// The flow is as follows: the rotation occurs first, and then, after a short delay, we mount the PlayerDetails component.
|
|
156
|
+
// This helps to avoid blocking the rotation and any animations related to the rotation.
|
|
157
|
+
const isShowPlayerDetails = useDelayedPlayerDetails({
|
|
158
|
+
isInline: isInlineModal,
|
|
159
|
+
isDocked: docked,
|
|
160
|
+
isPip: pip,
|
|
161
|
+
});
|
|
162
|
+
|
|
85
163
|
const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
|
|
86
164
|
|
|
87
|
-
const tabletWidth = getTabletWidth(
|
|
88
|
-
configuration.tablet_landscape_sidebar_width,
|
|
89
|
-
style
|
|
90
|
-
);
|
|
165
|
+
const tabletWidth = getTabletWidth(configuration, style);
|
|
91
166
|
|
|
92
167
|
const baseDimensions: DimensionsT = React.useMemo(
|
|
93
168
|
() => ({
|
|
94
|
-
width:
|
|
169
|
+
width:
|
|
170
|
+
isInlineModal && !docked && isTabletLandscape ? tabletWidth : "100%",
|
|
95
171
|
height: undefined,
|
|
96
172
|
}),
|
|
97
173
|
[isInlineModal, tabletWidth, docked]
|
|
@@ -100,7 +176,7 @@ const PlayerWrapperComponent = (props: Props) => {
|
|
|
100
176
|
const playerDimensions: DimensionsT = React.useMemo(
|
|
101
177
|
() => ({
|
|
102
178
|
...baseDimensions,
|
|
103
|
-
width: baseDimensions.width,
|
|
179
|
+
width: isInlineModal && docked ? undefined : baseDimensions.width,
|
|
104
180
|
aspectRatio: !isInlineModal && !pip ? getScreenAspectRatio() : 16 / 9,
|
|
105
181
|
}),
|
|
106
182
|
[baseDimensions, isInlineModal, pip]
|
|
@@ -109,7 +185,8 @@ const PlayerWrapperComponent = (props: Props) => {
|
|
|
109
185
|
const containerDimensions: DimensionsT = React.useMemo(
|
|
110
186
|
() => ({
|
|
111
187
|
...baseDimensions,
|
|
112
|
-
aspectRatio:
|
|
188
|
+
aspectRatio:
|
|
189
|
+
isInlineModal && docked ? undefined : playerDimensions.aspectRatio,
|
|
113
190
|
}),
|
|
114
191
|
[baseDimensions, isInlineModal, docked, playerDimensions.aspectRatio]
|
|
115
192
|
);
|
|
@@ -117,29 +194,67 @@ const PlayerWrapperComponent = (props: Props) => {
|
|
|
117
194
|
const WrapperView = React.useMemo(() => (isTV() ? View : SafeAreaView), []);
|
|
118
195
|
|
|
119
196
|
const childrenStyles = React.useMemo(
|
|
120
|
-
() => ({
|
|
121
|
-
...playerDimensions,
|
|
122
|
-
...playerDimensionsHack,
|
|
123
|
-
}),
|
|
197
|
+
() => ({ ...playerDimensions, ...playerDimensionsHack }),
|
|
124
198
|
[containerDimensions, playerDimensionsHack]
|
|
125
199
|
);
|
|
126
200
|
|
|
201
|
+
const wrapperViewStyle: ViewStyle = {
|
|
202
|
+
backgroundColor:
|
|
203
|
+
isTablet && !fullscreen
|
|
204
|
+
? configuration?.tablet_landscape_player_container_background_color
|
|
205
|
+
: "transparent",
|
|
206
|
+
};
|
|
207
|
+
|
|
127
208
|
return (
|
|
128
209
|
<WrapperView
|
|
129
210
|
edges={getEdges(isTablet, isInlineModal) as readonly Edge[]}
|
|
130
|
-
style={playerDimensionsHack}
|
|
211
|
+
style={[wrapperViewStyle, style, playerDimensionsHack]}
|
|
131
212
|
>
|
|
132
|
-
<
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
playerDimensionsHack,
|
|
137
|
-
containerDimensions,
|
|
138
|
-
containerStyle,
|
|
139
|
-
]}
|
|
213
|
+
<AnimationComponent
|
|
214
|
+
animationType={ComponentAnimationType.moveUpComponent}
|
|
215
|
+
additionalData={{ saveArea: true }}
|
|
216
|
+
style={[directionStyles(isTabletLandscape), defaultStyles.flex]}
|
|
140
217
|
>
|
|
141
|
-
|
|
142
|
-
|
|
218
|
+
<View
|
|
219
|
+
testID={`${entry?.id}-player-container`}
|
|
220
|
+
style={[
|
|
221
|
+
defaultStyles.playerContainer,
|
|
222
|
+
containerDimensions,
|
|
223
|
+
containerStyle,
|
|
224
|
+
playerDimensionsHack,
|
|
225
|
+
]}
|
|
226
|
+
>
|
|
227
|
+
<AnimationComponent
|
|
228
|
+
animationType={ComponentAnimationType.moveUpComponent}
|
|
229
|
+
style={isTabletLandscape ? defaultStyles.flex : undefined}
|
|
230
|
+
additionalData={{
|
|
231
|
+
useLayoutMeasure: isTabletLandscape,
|
|
232
|
+
disableAnimatedComponent: !isTabletLandscape,
|
|
233
|
+
resetAnimationValue: isTabletLandscape && docked,
|
|
234
|
+
}}
|
|
235
|
+
>
|
|
236
|
+
<AnimatedVideoPlayerComponent>
|
|
237
|
+
{children(childrenStyles)}
|
|
238
|
+
</AnimatedVideoPlayerComponent>
|
|
239
|
+
</AnimationComponent>
|
|
240
|
+
</View>
|
|
241
|
+
<AnimatedScrollModal>
|
|
242
|
+
{isShowPlayerDetails ? (
|
|
243
|
+
<AnimationComponent
|
|
244
|
+
animationType={ComponentAnimationType.componentFade}
|
|
245
|
+
style={defaultStyles.flex}
|
|
246
|
+
>
|
|
247
|
+
<PlayerDetails
|
|
248
|
+
configuration={configuration}
|
|
249
|
+
style={defaultStyles.playerDetails}
|
|
250
|
+
entry={entry}
|
|
251
|
+
isTabletLandscape={isTabletLandscape}
|
|
252
|
+
isTablet={isTablet}
|
|
253
|
+
/>
|
|
254
|
+
</AnimationComponent>
|
|
255
|
+
) : null}
|
|
256
|
+
</AnimatedScrollModal>
|
|
257
|
+
</AnimationComponent>
|
|
143
258
|
</WrapperView>
|
|
144
259
|
);
|
|
145
260
|
};
|
|
@@ -17,7 +17,11 @@ import {
|
|
|
17
17
|
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks/device/useIsTablet";
|
|
18
18
|
|
|
19
19
|
import { withModalNavigationContextProvider } from "../../Contexts/ModalNavigationContext";
|
|
20
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
useModalSize,
|
|
22
|
+
useBackgroundColor,
|
|
23
|
+
useInitialPlayerState,
|
|
24
|
+
} from "./hooks";
|
|
21
25
|
|
|
22
26
|
import { APP_EVENTS } from "@applicaster/zapp-react-native-utils/appUtils/events";
|
|
23
27
|
import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext";
|
|
@@ -29,6 +33,8 @@ import { ScreenContextProvider } from "../../Contexts/ScreenContext";
|
|
|
29
33
|
import { Spinner } from "../Spinner";
|
|
30
34
|
import { OpaqueLayer } from "./OpaqueLayer";
|
|
31
35
|
|
|
36
|
+
import { AnimatedPlayerModalWrapper } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
37
|
+
|
|
32
38
|
const LOADER_BACKGROUND_COLOR = "rgba(64,64,64,0.5)";
|
|
33
39
|
|
|
34
40
|
const styles = StyleSheet.create({
|
|
@@ -59,6 +65,7 @@ const VideoModalComponent = () => {
|
|
|
59
65
|
|
|
60
66
|
const modalSize = useModalSize();
|
|
61
67
|
const isFirstRender = useIsInitialRender();
|
|
68
|
+
const backgroundColor = useBackgroundColor();
|
|
62
69
|
|
|
63
70
|
const {
|
|
64
71
|
closeVideoModal,
|
|
@@ -138,13 +145,20 @@ const VideoModalComponent = () => {
|
|
|
138
145
|
{mode === "FULLSCREEN" && <OpaqueLayer />}
|
|
139
146
|
|
|
140
147
|
{itemIdHooksFinished === item?.id ? (
|
|
141
|
-
<
|
|
148
|
+
<AnimatedPlayerModalWrapper
|
|
149
|
+
style={[
|
|
150
|
+
styles.container,
|
|
151
|
+
{
|
|
152
|
+
backgroundColor,
|
|
153
|
+
},
|
|
154
|
+
]}
|
|
155
|
+
>
|
|
142
156
|
<HandlePlayable
|
|
143
157
|
item={item}
|
|
144
158
|
isModal={mode !== "PIP"}
|
|
145
159
|
mode={mode}
|
|
146
160
|
/>
|
|
147
|
-
</
|
|
161
|
+
</AnimatedPlayerModalWrapper>
|
|
148
162
|
) : (
|
|
149
163
|
<View style={styles.loaderContainer}>
|
|
150
164
|
<Spinner />
|
|
@@ -13,7 +13,6 @@ const props = {
|
|
|
13
13
|
tablet_landscape_sidebar_width: "35%",
|
|
14
14
|
tablet_landscape_player_container_background_color: "red",
|
|
15
15
|
},
|
|
16
|
-
playerContent: jest.fn(() => <></>),
|
|
17
16
|
};
|
|
18
17
|
|
|
19
18
|
const mockUseIsDeviceTablet = jest.fn();
|
|
@@ -123,6 +122,13 @@ describe("PlayerWrapper", () => {
|
|
|
123
122
|
</PlayerWrapper>
|
|
124
123
|
);
|
|
125
124
|
|
|
125
|
+
const expectDimensions = {
|
|
126
|
+
...dimensions,
|
|
127
|
+
width: undefined,
|
|
128
|
+
aspectRatio: 16 / 9,
|
|
129
|
+
};
|
|
130
|
+
|
|
126
131
|
expect(element).toMatchSnapshot();
|
|
132
|
+
expect(children).toHaveBeenCalledWith(expectDimensions);
|
|
127
133
|
});
|
|
128
134
|
});
|
|
@@ -21,27 +21,87 @@ exports[`PlayerWrapper renders inline 1`] = `
|
|
|
21
21
|
"top": "additive",
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
style={
|
|
24
|
+
style={
|
|
25
|
+
[
|
|
26
|
+
{
|
|
27
|
+
"backgroundColor": "transparent",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"height": 800,
|
|
31
|
+
"width": 300,
|
|
32
|
+
},
|
|
33
|
+
{},
|
|
34
|
+
]
|
|
35
|
+
}
|
|
25
36
|
>
|
|
26
37
|
<View
|
|
38
|
+
additionalData={
|
|
39
|
+
{
|
|
40
|
+
"saveArea": true,
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
animationType="moveUpComponent"
|
|
27
44
|
style={
|
|
28
45
|
[
|
|
29
46
|
{
|
|
30
|
-
"
|
|
31
|
-
"position": "relative",
|
|
32
|
-
"zIndex": 200,
|
|
47
|
+
"flexDirection": "column",
|
|
33
48
|
},
|
|
34
|
-
{},
|
|
35
49
|
{
|
|
36
|
-
"
|
|
37
|
-
"height": undefined,
|
|
38
|
-
"width": "100%",
|
|
50
|
+
"flex": 1,
|
|
39
51
|
},
|
|
40
|
-
{},
|
|
41
52
|
]
|
|
42
53
|
}
|
|
43
|
-
|
|
44
|
-
|
|
54
|
+
>
|
|
55
|
+
<View
|
|
56
|
+
style={
|
|
57
|
+
[
|
|
58
|
+
{
|
|
59
|
+
"alignSelf": "center",
|
|
60
|
+
"position": "relative",
|
|
61
|
+
"zIndex": 200,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"aspectRatio": 1.7777777777777777,
|
|
65
|
+
"height": undefined,
|
|
66
|
+
"width": "100%",
|
|
67
|
+
},
|
|
68
|
+
{},
|
|
69
|
+
{},
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
testID="test-player-container"
|
|
73
|
+
/>
|
|
74
|
+
<View
|
|
75
|
+
animationType="componentFade"
|
|
76
|
+
style={
|
|
77
|
+
{
|
|
78
|
+
"flex": 1,
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
>
|
|
82
|
+
<View
|
|
83
|
+
configuration={
|
|
84
|
+
{
|
|
85
|
+
"tablet_landscape_player_container_background_color": "red",
|
|
86
|
+
"tablet_landscape_sidebar_width": "35%",
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
entry={
|
|
90
|
+
{
|
|
91
|
+
"id": "test",
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
isTablet={false}
|
|
95
|
+
isTabletLandscape={false}
|
|
96
|
+
style={
|
|
97
|
+
{
|
|
98
|
+
"flex": 1,
|
|
99
|
+
"paddingTop": 20,
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/>
|
|
103
|
+
</View>
|
|
104
|
+
</View>
|
|
45
105
|
</RNCSafeAreaView>
|
|
46
106
|
</RNCSafeAreaProvider>
|
|
47
107
|
`;
|
|
@@ -67,27 +127,57 @@ exports[`PlayerWrapper renders inline and docked 1`] = `
|
|
|
67
127
|
"top": "additive",
|
|
68
128
|
}
|
|
69
129
|
}
|
|
70
|
-
style={
|
|
130
|
+
style={
|
|
131
|
+
[
|
|
132
|
+
{
|
|
133
|
+
"backgroundColor": "transparent",
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"height": undefined,
|
|
137
|
+
"width": 300,
|
|
138
|
+
},
|
|
139
|
+
{},
|
|
140
|
+
]
|
|
141
|
+
}
|
|
71
142
|
>
|
|
72
143
|
<View
|
|
144
|
+
additionalData={
|
|
145
|
+
{
|
|
146
|
+
"saveArea": true,
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
animationType="moveUpComponent"
|
|
73
150
|
style={
|
|
74
151
|
[
|
|
75
152
|
{
|
|
76
|
-
"
|
|
77
|
-
"position": "relative",
|
|
78
|
-
"zIndex": 200,
|
|
153
|
+
"flexDirection": "column",
|
|
79
154
|
},
|
|
80
|
-
{},
|
|
81
155
|
{
|
|
82
|
-
"
|
|
83
|
-
"height": undefined,
|
|
84
|
-
"width": "100%",
|
|
156
|
+
"flex": 1,
|
|
85
157
|
},
|
|
86
|
-
{},
|
|
87
158
|
]
|
|
88
159
|
}
|
|
89
|
-
|
|
90
|
-
|
|
160
|
+
>
|
|
161
|
+
<View
|
|
162
|
+
style={
|
|
163
|
+
[
|
|
164
|
+
{
|
|
165
|
+
"alignSelf": "center",
|
|
166
|
+
"position": "relative",
|
|
167
|
+
"zIndex": 200,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"aspectRatio": undefined,
|
|
171
|
+
"height": undefined,
|
|
172
|
+
"width": "100%",
|
|
173
|
+
},
|
|
174
|
+
{},
|
|
175
|
+
{},
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
testID="test-player-container"
|
|
179
|
+
/>
|
|
180
|
+
</View>
|
|
91
181
|
</RNCSafeAreaView>
|
|
92
182
|
</RNCSafeAreaProvider>
|
|
93
183
|
`;
|
|
@@ -113,27 +203,103 @@ exports[`PlayerWrapper renders inline on tablet in landscape orientation 1`] = `
|
|
|
113
203
|
"top": "additive",
|
|
114
204
|
}
|
|
115
205
|
}
|
|
116
|
-
style={
|
|
206
|
+
style={
|
|
207
|
+
[
|
|
208
|
+
{
|
|
209
|
+
"backgroundColor": "red",
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"height": 800,
|
|
213
|
+
"width": 300,
|
|
214
|
+
},
|
|
215
|
+
{},
|
|
216
|
+
]
|
|
217
|
+
}
|
|
117
218
|
>
|
|
118
219
|
<View
|
|
220
|
+
additionalData={
|
|
221
|
+
{
|
|
222
|
+
"saveArea": true,
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
animationType="moveUpComponent"
|
|
119
226
|
style={
|
|
120
227
|
[
|
|
121
228
|
{
|
|
122
|
-
"
|
|
123
|
-
"position": "relative",
|
|
124
|
-
"zIndex": 200,
|
|
229
|
+
"flexDirection": "row",
|
|
125
230
|
},
|
|
126
|
-
{},
|
|
127
231
|
{
|
|
128
|
-
"
|
|
129
|
-
"height": undefined,
|
|
130
|
-
"width": 195,
|
|
232
|
+
"flex": 1,
|
|
131
233
|
},
|
|
132
|
-
{},
|
|
133
234
|
]
|
|
134
235
|
}
|
|
135
|
-
|
|
136
|
-
|
|
236
|
+
>
|
|
237
|
+
<View
|
|
238
|
+
style={
|
|
239
|
+
[
|
|
240
|
+
{
|
|
241
|
+
"alignSelf": "center",
|
|
242
|
+
"position": "relative",
|
|
243
|
+
"zIndex": 200,
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
"aspectRatio": 1.7777777777777777,
|
|
247
|
+
"height": undefined,
|
|
248
|
+
"width": 195,
|
|
249
|
+
},
|
|
250
|
+
{},
|
|
251
|
+
{},
|
|
252
|
+
]
|
|
253
|
+
}
|
|
254
|
+
testID="test-player-container"
|
|
255
|
+
>
|
|
256
|
+
<View
|
|
257
|
+
additionalData={
|
|
258
|
+
{
|
|
259
|
+
"disableAnimatedComponent": false,
|
|
260
|
+
"resetAnimationValue": undefined,
|
|
261
|
+
"useLayoutMeasure": true,
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
animationType="moveUpComponent"
|
|
265
|
+
style={
|
|
266
|
+
{
|
|
267
|
+
"flex": 1,
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/>
|
|
271
|
+
</View>
|
|
272
|
+
<View
|
|
273
|
+
animationType="componentFade"
|
|
274
|
+
style={
|
|
275
|
+
{
|
|
276
|
+
"flex": 1,
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
>
|
|
280
|
+
<View
|
|
281
|
+
configuration={
|
|
282
|
+
{
|
|
283
|
+
"tablet_landscape_player_container_background_color": "red",
|
|
284
|
+
"tablet_landscape_sidebar_width": "35%",
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
entry={
|
|
288
|
+
{
|
|
289
|
+
"id": "test",
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
isTablet={true}
|
|
293
|
+
isTabletLandscape={true}
|
|
294
|
+
style={
|
|
295
|
+
{
|
|
296
|
+
"flex": 1,
|
|
297
|
+
"paddingTop": 20,
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/>
|
|
301
|
+
</View>
|
|
302
|
+
</View>
|
|
137
303
|
</RNCSafeAreaView>
|
|
138
304
|
</RNCSafeAreaProvider>
|
|
139
305
|
`;
|
|
@@ -159,27 +325,57 @@ exports[`PlayerWrapper renders properly 1`] = `
|
|
|
159
325
|
"top": "additive",
|
|
160
326
|
}
|
|
161
327
|
}
|
|
162
|
-
style={
|
|
328
|
+
style={
|
|
329
|
+
[
|
|
330
|
+
{
|
|
331
|
+
"backgroundColor": "transparent",
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
"height": 800,
|
|
335
|
+
"width": 300,
|
|
336
|
+
},
|
|
337
|
+
{},
|
|
338
|
+
]
|
|
339
|
+
}
|
|
163
340
|
>
|
|
164
341
|
<View
|
|
342
|
+
additionalData={
|
|
343
|
+
{
|
|
344
|
+
"saveArea": true,
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
animationType="moveUpComponent"
|
|
165
348
|
style={
|
|
166
349
|
[
|
|
167
350
|
{
|
|
168
|
-
"
|
|
169
|
-
"position": "relative",
|
|
170
|
-
"zIndex": 200,
|
|
351
|
+
"flexDirection": "column",
|
|
171
352
|
},
|
|
172
|
-
{},
|
|
173
353
|
{
|
|
174
|
-
"
|
|
175
|
-
"height": undefined,
|
|
176
|
-
"width": "100%",
|
|
354
|
+
"flex": 1,
|
|
177
355
|
},
|
|
178
|
-
{},
|
|
179
356
|
]
|
|
180
357
|
}
|
|
181
|
-
|
|
182
|
-
|
|
358
|
+
>
|
|
359
|
+
<View
|
|
360
|
+
style={
|
|
361
|
+
[
|
|
362
|
+
{
|
|
363
|
+
"alignSelf": "center",
|
|
364
|
+
"position": "relative",
|
|
365
|
+
"zIndex": 200,
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
"aspectRatio": 1.7786666666666666,
|
|
369
|
+
"height": undefined,
|
|
370
|
+
"width": "100%",
|
|
371
|
+
},
|
|
372
|
+
{},
|
|
373
|
+
{},
|
|
374
|
+
]
|
|
375
|
+
}
|
|
376
|
+
testID="test-player-container"
|
|
377
|
+
/>
|
|
378
|
+
</View>
|
|
183
379
|
</RNCSafeAreaView>
|
|
184
380
|
</RNCSafeAreaProvider>
|
|
185
381
|
`;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
2
|
+
import { useConfiguration } from "../utils";
|
|
3
|
+
|
|
4
|
+
export const useBackgroundColor = (): string => {
|
|
5
|
+
const { modal_background_color: modalBackgroundColor } = useConfiguration();
|
|
6
|
+
|
|
7
|
+
const theme = useTheme<BaseThemePropertiesMobile>();
|
|
8
|
+
|
|
9
|
+
return modalBackgroundColor || theme?.status_background_color;
|
|
10
|
+
};
|
|
@@ -9,12 +9,6 @@ import {
|
|
|
9
9
|
|
|
10
10
|
import { getXray } from "@applicaster/zapp-react-native-utils/logger";
|
|
11
11
|
import { useSafeAreaFrame } from "react-native-safe-area-context";
|
|
12
|
-
import {
|
|
13
|
-
isAndroidPlatform,
|
|
14
|
-
isAndroidVersionAtLeast,
|
|
15
|
-
} from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
16
|
-
import { StatusBar } from "react-native";
|
|
17
|
-
import { isAndroidTablet } from "@applicaster/zapp-react-native-utils/reactHooks/layout/isTablet";
|
|
18
12
|
|
|
19
13
|
const { Logger } = getXray();
|
|
20
14
|
|
|
@@ -33,17 +27,12 @@ const MODAL_SIZE_FOR_LANDSCAPE: Size = {
|
|
|
33
27
|
height: "100%",
|
|
34
28
|
};
|
|
35
29
|
|
|
36
|
-
const isOldAndroidDevice =
|
|
37
|
-
isAndroidPlatform() && !isAndroidVersionAtLeast(35) && !isAndroidTablet();
|
|
38
|
-
|
|
39
30
|
export const useModalSize = (): Size => {
|
|
40
31
|
const frame = useSafeAreaFrame();
|
|
41
32
|
|
|
42
33
|
const [modalSize, setModalSize] = React.useState<Size>({
|
|
43
34
|
width: frame.width,
|
|
44
|
-
height:
|
|
45
|
-
? frame.height + StatusBar.currentHeight
|
|
46
|
-
: frame.height,
|
|
35
|
+
height: frame.height,
|
|
47
36
|
});
|
|
48
37
|
|
|
49
38
|
const setNewModalSize = React.useCallback((newSize, log) => {
|
|
@@ -55,12 +44,7 @@ export const useModalSize = (): Size => {
|
|
|
55
44
|
return oldSize;
|
|
56
45
|
}
|
|
57
46
|
|
|
58
|
-
return
|
|
59
|
-
width: newSize.width,
|
|
60
|
-
height: isOldAndroidDevice
|
|
61
|
-
? newSize.height + StatusBar.currentHeight
|
|
62
|
-
: newSize.height,
|
|
63
|
-
};
|
|
47
|
+
return newSize;
|
|
64
48
|
});
|
|
65
49
|
|
|
66
50
|
logger.debug({
|
|
@@ -34,9 +34,6 @@ export const useConfiguration = () => {
|
|
|
34
34
|
minimised_height = 0,
|
|
35
35
|
minimised_height_tablet = 0,
|
|
36
36
|
modal_background_color,
|
|
37
|
-
tablet_landscape_player_container_background_color,
|
|
38
|
-
screen_background_color,
|
|
39
|
-
audio_player_background_color,
|
|
40
37
|
} = config;
|
|
41
38
|
|
|
42
39
|
const minimisedHeight = useIsTablet()
|
|
@@ -46,9 +43,6 @@ export const useConfiguration = () => {
|
|
|
46
43
|
return {
|
|
47
44
|
minimised_height: Number(minimisedHeight),
|
|
48
45
|
modal_background_color,
|
|
49
|
-
tablet_landscape_player_container_background_color,
|
|
50
|
-
audio_player_background_color,
|
|
51
|
-
screen_background_color,
|
|
52
46
|
};
|
|
53
47
|
};
|
|
54
48
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-ui-components",
|
|
3
|
-
"version": "13.0.8-alpha.
|
|
3
|
+
"version": "13.0.8-alpha.8384339831",
|
|
4
4
|
"description": "Applicaster Zapp React Native ui components for the Quick Brick App",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"redux-mock-store": "^1.5.3"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@applicaster/applicaster-types": "13.0.8-alpha.
|
|
35
|
-
"@applicaster/zapp-react-native-bridge": "13.0.8-alpha.
|
|
36
|
-
"@applicaster/zapp-react-native-redux": "13.0.8-alpha.
|
|
37
|
-
"@applicaster/zapp-react-native-utils": "13.0.8-alpha.
|
|
34
|
+
"@applicaster/applicaster-types": "13.0.8-alpha.8384339831",
|
|
35
|
+
"@applicaster/zapp-react-native-bridge": "13.0.8-alpha.8384339831",
|
|
36
|
+
"@applicaster/zapp-react-native-redux": "13.0.8-alpha.8384339831",
|
|
37
|
+
"@applicaster/zapp-react-native-utils": "13.0.8-alpha.8384339831",
|
|
38
38
|
"promise": "^8.3.0",
|
|
39
39
|
"react-router-native": "^5.1.2",
|
|
40
40
|
"url": "^0.11.0",
|