@applicaster/quick-brick-player 14.0.0-alpha.2482261241 → 14.0.0-alpha.2802628909
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/package.json +6 -6
- package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +20 -8
- package/src/Player/AudioLayer/Layout/DockedControls/index.tsx +112 -98
- package/src/Player/AudioLayer/Layout/MobileLayout.tsx +1 -6
- package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +5 -23
- package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +5 -8
- package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +1 -6
- package/src/Player/AudioLayer/utils.ts +1 -27
- package/src/Player/PlayerModal/PlayerModal.tsx +16 -15
- package/src/Player/PlayerModal/VideoPlayerModal.tsx +136 -124
- package/src/Player/PlayerModal/consts/index.ts +2 -19
- package/src/Player/PlayerModal/context/index.ts +6 -0
- package/src/Player/PlayerModal/hooks/index.ts +66 -128
- package/src/Player/PlayerModal/index.web.ts +5 -0
- package/src/Player/PlayerModal/styles.ts +6 -0
- package/src/Player/PlayerModal/utils/index.ts +89 -0
- package/src/Player/PlayerView/types.ts +1 -2
- package/src/Player/index.tsx +559 -366
- package/src/QuickBrickPlayer.tsx +16 -10
- package/src/utils/dimensions.ts +29 -0
- package/src/utils/index.ts +12 -0
- package/src/utils/logger.ts +6 -0
- package/src/utils/playerHelpers.ts +11 -0
- package/src/utils/playerStyles.ts +50 -0
- package/src/Player/AudioLayer/Layout/PlayerImage/AnimatedImage.tsx +0 -82
- package/src/Player/AudioLayer/Layout/PlayerImage/hooks/index.ts +0 -1
- package/src/Player/AudioLayer/Layout/PlayerImage/hooks/useChangePlayerState.ts +0 -99
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/quick-brick-player",
|
|
3
|
-
"version": "14.0.0-alpha.
|
|
3
|
+
"version": "14.0.0-alpha.2802628909",
|
|
4
4
|
"description": "Quick Brick Player",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
},
|
|
36
36
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@applicaster/quick-brick-mobile-transport-controls": "14.0.0-
|
|
39
|
-
"@applicaster/quick-brick-tv-transport-controls": "14.0.0-rc.
|
|
40
|
-
"@applicaster/zapp-react-native-tvos-app": "14.0.0-alpha.
|
|
41
|
-
"@applicaster/zapp-react-native-ui-components": "14.0.0-alpha.
|
|
42
|
-
"@applicaster/zapp-react-native-utils": "14.0.0-alpha.
|
|
38
|
+
"@applicaster/quick-brick-mobile-transport-controls": "14.0.0-rc.83",
|
|
39
|
+
"@applicaster/quick-brick-tv-transport-controls": "14.0.0-rc.71",
|
|
40
|
+
"@applicaster/zapp-react-native-tvos-app": "14.0.0-alpha.2802628909",
|
|
41
|
+
"@applicaster/zapp-react-native-ui-components": "14.0.0-alpha.2802628909",
|
|
42
|
+
"@applicaster/zapp-react-native-utils": "14.0.0-alpha.2802628909",
|
|
43
43
|
"query-string": "7.1.3",
|
|
44
44
|
"shaka-player": "4.3.5",
|
|
45
45
|
"typeface-montserrat": "^0.0.54",
|
|
@@ -61,6 +61,7 @@ type Props = {
|
|
|
61
61
|
inline: boolean;
|
|
62
62
|
docked: boolean;
|
|
63
63
|
isModal: boolean;
|
|
64
|
+
pip: boolean;
|
|
64
65
|
};
|
|
65
66
|
playNextData: PlayNextData;
|
|
66
67
|
isTabletPortrait?: boolean;
|
|
@@ -99,11 +100,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
99
100
|
);
|
|
100
101
|
|
|
101
102
|
useEffect(() => {
|
|
102
|
-
|
|
103
|
-
setSpeedManager(new SpeedController(player));
|
|
104
|
-
} else {
|
|
105
|
-
setSpeedManager(null);
|
|
106
|
-
}
|
|
103
|
+
setSpeedManager(player ? new SpeedController(player) : null);
|
|
107
104
|
}, [player]);
|
|
108
105
|
|
|
109
106
|
useEffect(() => {
|
|
@@ -217,7 +214,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
217
214
|
items: speedOptions,
|
|
218
215
|
current_selection: playbackSpeed,
|
|
219
216
|
onPress: onSpeedSelect,
|
|
220
|
-
title: configuration
|
|
217
|
+
title: configuration.playback_speed_title,
|
|
221
218
|
itemProps: getBottomSheetModalItemProps,
|
|
222
219
|
iconProps: getBottomSheetModalIconProps,
|
|
223
220
|
labelProps: getBottomSheetModalLabelProps,
|
|
@@ -233,7 +230,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
233
230
|
],
|
|
234
231
|
},
|
|
235
232
|
});
|
|
236
|
-
}, [playbackSpeed, onSpeedSelect, configuration
|
|
233
|
+
}, [playbackSpeed, onSpeedSelect, configuration.playback_speed_title]);
|
|
237
234
|
|
|
238
235
|
const onPlayerSeek = React.useCallback(
|
|
239
236
|
(targetTime: number) => {
|
|
@@ -250,13 +247,28 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
250
247
|
player?.seekTo(0);
|
|
251
248
|
}, [player]);
|
|
252
249
|
|
|
250
|
+
const layoutStateMemo = React.useMemo(
|
|
251
|
+
() => ({
|
|
252
|
+
inline: layoutState.inline,
|
|
253
|
+
docked: layoutState.docked,
|
|
254
|
+
isModal: layoutState.isModal,
|
|
255
|
+
pip: layoutState.pip,
|
|
256
|
+
}),
|
|
257
|
+
[
|
|
258
|
+
layoutState.inline,
|
|
259
|
+
layoutState.docked,
|
|
260
|
+
layoutState.isModal,
|
|
261
|
+
layoutState.pip,
|
|
262
|
+
]
|
|
263
|
+
);
|
|
264
|
+
|
|
253
265
|
return (
|
|
254
266
|
<SafeAreaView style={[style, Styles.playerContainer]} edges={edges}>
|
|
255
267
|
<View style={Styles.playerContainer} onLayout={onLayout}>
|
|
256
268
|
<Layout
|
|
257
269
|
entry={entry}
|
|
258
270
|
playerState={playerState}
|
|
259
|
-
layoutState={
|
|
271
|
+
layoutState={layoutStateMemo}
|
|
260
272
|
value={value}
|
|
261
273
|
onPlaybackButtonPress={onPlaybackButtonPress}
|
|
262
274
|
onRewindButtonPress={onRewindButtonPress}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { StyleSheet, View
|
|
3
|
-
import * as R from "ramda";
|
|
2
|
+
import { StyleSheet, View } from "react-native";
|
|
4
3
|
import {
|
|
5
4
|
useIsTablet,
|
|
6
5
|
useZStore,
|
|
@@ -16,7 +15,6 @@ import {
|
|
|
16
15
|
|
|
17
16
|
import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
|
|
18
17
|
|
|
19
|
-
import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
20
18
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
21
19
|
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation";
|
|
22
20
|
import { getTabBarHeight } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/getTabBarHeight";
|
|
@@ -26,22 +24,18 @@ import { useConfiguration } from "@applicaster/zapp-react-native-ui-components/C
|
|
|
26
24
|
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
27
25
|
import { PROGRESS_BAR_HEIGHT } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/utils";
|
|
28
26
|
import { isMenuVisible } from "@applicaster/zapp-react-native-ui-components/Components/Screen/navigationHandler";
|
|
27
|
+
import { usePlugins } from "@applicaster/zapp-react-native-redux";
|
|
28
|
+
import { partial } from "@applicaster/zapp-react-native-utils/utils";
|
|
29
29
|
|
|
30
30
|
const bottomTabBarHeight = getTabBarHeight();
|
|
31
31
|
|
|
32
32
|
type Props = {
|
|
33
33
|
entry: ZappEntry;
|
|
34
34
|
layoutState: QuickBrickPlayer.LayoutState;
|
|
35
|
-
|
|
36
|
-
value: GetValue;
|
|
37
|
-
onCloseVideoModal: () => void;
|
|
38
|
-
onPlayerSeek: (targetTime: number) => void;
|
|
35
|
+
onPlayerSeek?: (targetTime: number) => void;
|
|
39
36
|
playNextData: PlayNextData;
|
|
40
|
-
title: string | number;
|
|
41
|
-
summary: string | number;
|
|
42
37
|
ImageComponent?: React.ReactNode;
|
|
43
38
|
isActiveGesture?: boolean;
|
|
44
|
-
minimisedHeight: number;
|
|
45
39
|
aspectRatio?: number;
|
|
46
40
|
};
|
|
47
41
|
|
|
@@ -50,7 +44,6 @@ const styles = StyleSheet.create({
|
|
|
50
44
|
flex: 1,
|
|
51
45
|
flexDirection: "column",
|
|
52
46
|
alignItems: "stretch",
|
|
53
|
-
marginTop: PROGRESS_BAR_HEIGHT,
|
|
54
47
|
},
|
|
55
48
|
content: {
|
|
56
49
|
flex: 1,
|
|
@@ -93,14 +86,12 @@ const styles = StyleSheet.create({
|
|
|
93
86
|
buttons: {
|
|
94
87
|
marginVertical: 10,
|
|
95
88
|
},
|
|
89
|
+
liveMarginTop: { marginTop: 0 },
|
|
90
|
+
marginTop: { marginTop: PROGRESS_BAR_HEIGHT },
|
|
96
91
|
});
|
|
97
92
|
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
addPadding: boolean
|
|
101
|
-
): ViewStyle => ({
|
|
102
|
-
width: addPadding ? toNumberWithDefault(100, minimisedHeight) : 0,
|
|
103
|
-
});
|
|
93
|
+
const getValue = (key: string, stylesObj: Record<string, any>) =>
|
|
94
|
+
stylesObj?.[key] ?? null;
|
|
104
95
|
|
|
105
96
|
const controlButtons = (
|
|
106
97
|
live: boolean,
|
|
@@ -166,7 +157,6 @@ export const DockedControls = (props: Props) => {
|
|
|
166
157
|
onPlayerSeek = noop,
|
|
167
158
|
playNextData,
|
|
168
159
|
ImageComponent,
|
|
169
|
-
isActiveGesture = true,
|
|
170
160
|
aspectRatio,
|
|
171
161
|
} = props;
|
|
172
162
|
|
|
@@ -176,16 +166,14 @@ export const DockedControls = (props: Props) => {
|
|
|
176
166
|
|
|
177
167
|
const { currentRoute, screenData } = useNavigation();
|
|
178
168
|
|
|
179
|
-
const
|
|
169
|
+
const plugins = usePlugins();
|
|
170
|
+
const menuVisible = isMenuVisible(currentRoute, screenData, plugins);
|
|
180
171
|
|
|
181
172
|
const { minimised_height: minimisedHeight } = useConfiguration();
|
|
182
173
|
|
|
183
174
|
const configuration = useZStore("playerConfiguration")();
|
|
184
175
|
const playerState = usePlayerState("shared-player-wrapper-docked");
|
|
185
176
|
|
|
186
|
-
const getValue = (key: string, stylesObj: {}) =>
|
|
187
|
-
R.propOr(null, key, stylesObj);
|
|
188
|
-
|
|
189
177
|
const value = React.useCallback(
|
|
190
178
|
(key: string) => {
|
|
191
179
|
const retVal = getValue(key, configuration);
|
|
@@ -204,7 +192,7 @@ export const DockedControls = (props: Props) => {
|
|
|
204
192
|
|
|
205
193
|
return retVal;
|
|
206
194
|
},
|
|
207
|
-
[...Object.values(configuration), playerState]
|
|
195
|
+
[...Object.values(configuration), playerState.seekableDuration]
|
|
208
196
|
);
|
|
209
197
|
|
|
210
198
|
const { title, summary } = useTitleSummaryOverlay(
|
|
@@ -221,93 +209,119 @@ export const DockedControls = (props: Props) => {
|
|
|
221
209
|
|
|
222
210
|
const insets = useSafeAreaInsets();
|
|
223
211
|
|
|
212
|
+
const progressBarLayoutState = React.useMemo(
|
|
213
|
+
() => ({
|
|
214
|
+
inline: layoutState.inline,
|
|
215
|
+
docked: true,
|
|
216
|
+
isModal: layoutState.isModal,
|
|
217
|
+
pip: layoutState.pip,
|
|
218
|
+
}),
|
|
219
|
+
[layoutState.inline, layoutState.isModal, layoutState.pip]
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
const _controlButtons = React.useMemo(
|
|
223
|
+
() => partial(controlButtons, playerState.isLive && liveButton),
|
|
224
|
+
[playerState.isLive, liveButton]
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
const containerStyles = React.useMemo(
|
|
228
|
+
() => ({
|
|
229
|
+
height: minimisedHeight,
|
|
230
|
+
maxHeight: minimisedHeight,
|
|
231
|
+
}),
|
|
232
|
+
[minimisedHeight]
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
const imageComponentWrapperStyles = React.useMemo(
|
|
236
|
+
() => ({
|
|
237
|
+
aspectRatio: aspectRatio,
|
|
238
|
+
height: minimisedHeight,
|
|
239
|
+
}),
|
|
240
|
+
[aspectRatio, minimisedHeight]
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
const backgroundColorStyle = React.useMemo(
|
|
244
|
+
() => ({
|
|
245
|
+
backgroundColor: dockedBackgroundColor,
|
|
246
|
+
}),
|
|
247
|
+
[dockedBackgroundColor]
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
const bottomSpacerStyle = React.useMemo(() => {
|
|
251
|
+
const tabBarHeight = menuVisible ? bottomTabBarHeight : 0;
|
|
252
|
+
const safeAreaBottomInset = insets.bottom || 0;
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
height: safeAreaBottomInset + tabBarHeight,
|
|
256
|
+
};
|
|
257
|
+
}, [menuVisible, insets.bottom]);
|
|
258
|
+
|
|
259
|
+
const contentInfoContent = React.useMemo(
|
|
260
|
+
() => ({ ...entry, title, summary }),
|
|
261
|
+
[title, summary, entry]
|
|
262
|
+
);
|
|
263
|
+
|
|
224
264
|
return (
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
<View style={styles.content}>
|
|
251
|
-
<View style={styles.touchableArea}>
|
|
252
|
-
{isActiveGesture || layoutState.docked ? (
|
|
253
|
-
<View style={{ aspectRatio: aspectRatio, height: minimisedHeight }}>
|
|
265
|
+
<>
|
|
266
|
+
<View
|
|
267
|
+
style={[
|
|
268
|
+
styles.container,
|
|
269
|
+
containerStyles,
|
|
270
|
+
playerState.isLive ? styles.liveMarginTop : styles.marginTop,
|
|
271
|
+
]}
|
|
272
|
+
>
|
|
273
|
+
{!playerState.isLive ? (
|
|
274
|
+
<ProgressBar
|
|
275
|
+
name={"shared-docked-layout"}
|
|
276
|
+
content={entry}
|
|
277
|
+
value={value}
|
|
278
|
+
visible
|
|
279
|
+
layoutState={progressBarLayoutState}
|
|
280
|
+
onPlayerSeek={onPlayerSeek}
|
|
281
|
+
playerState={playerState}
|
|
282
|
+
docked
|
|
283
|
+
/>
|
|
284
|
+
) : null}
|
|
285
|
+
|
|
286
|
+
<View style={styles.content}>
|
|
287
|
+
<View style={styles.touchableArea}>
|
|
288
|
+
<View style={imageComponentWrapperStyles}>
|
|
254
289
|
{ImageComponent || null}
|
|
255
290
|
</View>
|
|
256
|
-
) : (
|
|
257
291
|
<View
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
292
|
+
testID="content-info"
|
|
293
|
+
style={[styles.contentInfo, backgroundColorStyle]}
|
|
294
|
+
>
|
|
295
|
+
<ContentInfo content={contentInfoContent} value={value} docked />
|
|
296
|
+
</View>
|
|
297
|
+
</View>
|
|
264
298
|
<View
|
|
265
|
-
testID="content-info"
|
|
266
299
|
style={[
|
|
267
|
-
|
|
268
|
-
|
|
300
|
+
isTablet
|
|
301
|
+
? styles.controlsContainerForTablet
|
|
302
|
+
: styles.controlsContainerForMobile,
|
|
303
|
+
backgroundColorStyle,
|
|
269
304
|
]}
|
|
270
305
|
>
|
|
271
|
-
<
|
|
272
|
-
|
|
306
|
+
<Controls
|
|
307
|
+
value={value}
|
|
308
|
+
visible
|
|
309
|
+
buttons={_controlButtons}
|
|
310
|
+
style={styles.playPauseButton}
|
|
311
|
+
playNextData={playNextData}
|
|
312
|
+
playerState={playerState}
|
|
313
|
+
/>
|
|
314
|
+
<Button
|
|
315
|
+
icon={"close_mini"}
|
|
316
|
+
size={"medium"}
|
|
273
317
|
value={value}
|
|
274
|
-
|
|
318
|
+
onPress={onCloseVideoModal}
|
|
319
|
+
style={styles.buttons}
|
|
275
320
|
/>
|
|
276
321
|
</View>
|
|
277
322
|
</View>
|
|
278
|
-
<View
|
|
279
|
-
style={[
|
|
280
|
-
isTablet
|
|
281
|
-
? styles.controlsContainerForTablet
|
|
282
|
-
: styles.controlsContainerForMobile,
|
|
283
|
-
{ backgroundColor: dockedBackgroundColor },
|
|
284
|
-
]}
|
|
285
|
-
>
|
|
286
|
-
<Controls
|
|
287
|
-
value={value}
|
|
288
|
-
visible
|
|
289
|
-
buttons={R.partial(controlButtons, [
|
|
290
|
-
playerState.isLive && liveButton,
|
|
291
|
-
])}
|
|
292
|
-
style={styles.playPauseButton}
|
|
293
|
-
playNextData={playNextData}
|
|
294
|
-
playerState={playerState}
|
|
295
|
-
/>
|
|
296
|
-
<Button
|
|
297
|
-
icon={"close_mini"}
|
|
298
|
-
size={"medium"}
|
|
299
|
-
value={value}
|
|
300
|
-
onPress={onCloseVideoModal}
|
|
301
|
-
style={styles.buttons}
|
|
302
|
-
/>
|
|
303
|
-
</View>
|
|
304
323
|
</View>
|
|
305
|
-
<View
|
|
306
|
-
|
|
307
|
-
height: insets.bottom + (menuVisible ? bottomTabBarHeight : 0),
|
|
308
|
-
backgroundColor: dockedBackgroundColor,
|
|
309
|
-
}}
|
|
310
|
-
/>
|
|
311
|
-
</View>
|
|
324
|
+
<View style={[bottomSpacerStyle, backgroundColorStyle]} />
|
|
325
|
+
</>
|
|
312
326
|
);
|
|
313
327
|
};
|
|
@@ -151,12 +151,7 @@ export function MobileLayout({
|
|
|
151
151
|
},
|
|
152
152
|
]}
|
|
153
153
|
>
|
|
154
|
-
<PlayerImage
|
|
155
|
-
entry={entry}
|
|
156
|
-
docked={false}
|
|
157
|
-
imageWidth={imageSize}
|
|
158
|
-
configuration={configuration}
|
|
159
|
-
/>
|
|
154
|
+
<PlayerImage entry={entry} configuration={configuration} />
|
|
160
155
|
</View>
|
|
161
156
|
{/* PlayerImage */}
|
|
162
157
|
|
|
@@ -4,7 +4,6 @@ import { LayoutChangeEvent, View } from "react-native";
|
|
|
4
4
|
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
5
5
|
import { toBooleanWithDefaultTrue } from "@applicaster/zapp-react-native-utils/booleanUtils";
|
|
6
6
|
|
|
7
|
-
import { AnimatedImage } from "./AnimatedImage";
|
|
8
7
|
import { FlexImage } from "./FlexImage";
|
|
9
8
|
|
|
10
9
|
import { styles } from "./styles";
|
|
@@ -13,19 +12,12 @@ import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/nu
|
|
|
13
12
|
type Props = {
|
|
14
13
|
entry: ZappEntry;
|
|
15
14
|
configuration: QuickBrickPlayer.AudioPlayerProps["configuration"];
|
|
16
|
-
docked
|
|
17
|
-
imageWidth?: Option<number>;
|
|
15
|
+
docked?: boolean;
|
|
18
16
|
onLayoutImage?: (event: LayoutChangeEvent) => void;
|
|
19
17
|
};
|
|
20
18
|
|
|
21
19
|
export const PlayerImage = (props: Props) => {
|
|
22
|
-
const {
|
|
23
|
-
entry,
|
|
24
|
-
docked,
|
|
25
|
-
imageWidth,
|
|
26
|
-
configuration,
|
|
27
|
-
onLayoutImage = noop,
|
|
28
|
-
} = props;
|
|
20
|
+
const { entry, docked = false, configuration, onLayoutImage = noop } = props;
|
|
29
21
|
|
|
30
22
|
const isShadowEnabled = toBooleanWithDefaultTrue(
|
|
31
23
|
configuration?.audio_player_artwork_shadow_enabled
|
|
@@ -43,19 +35,9 @@ export const PlayerImage = (props: Props) => {
|
|
|
43
35
|
onLayout={onLayoutImage}
|
|
44
36
|
style={[shouldShowShadow ? styles.shadow : undefined, { borderRadius }]}
|
|
45
37
|
>
|
|
46
|
-
{
|
|
47
|
-
<
|
|
48
|
-
|
|
49
|
-
</View>
|
|
50
|
-
) : (
|
|
51
|
-
// we have imageSize here and now we could animate resizing of this image
|
|
52
|
-
<AnimatedImage
|
|
53
|
-
entry={entry}
|
|
54
|
-
style={[styles.backgroundImageContainer, { borderRadius }]}
|
|
55
|
-
imageWidth={imageWidth}
|
|
56
|
-
docked={docked}
|
|
57
|
-
/>
|
|
58
|
-
)}
|
|
38
|
+
<View style={[styles.defaultImageWrapperView, { borderRadius }]}>
|
|
39
|
+
<FlexImage entry={entry} style={styles.backgroundImageContainer} />
|
|
40
|
+
</View>
|
|
59
41
|
</View>
|
|
60
42
|
</View>
|
|
61
43
|
);
|
|
@@ -117,14 +117,11 @@ export function TabletLandscapeLayout({
|
|
|
117
117
|
<View style={[styles.flex, styles.audioPlayerContainerHeightLimit]}>
|
|
118
118
|
{/* PlayerImage non-docked */}
|
|
119
119
|
<View style={[styles.flex, withDebug(styles.debugYellow)]}>
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
onLayoutImage={onLayoutImage}
|
|
126
|
-
/>
|
|
127
|
-
) : null}
|
|
120
|
+
<PlayerImage
|
|
121
|
+
entry={entry}
|
|
122
|
+
configuration={configuration}
|
|
123
|
+
onLayoutImage={onLayoutImage}
|
|
124
|
+
/>
|
|
128
125
|
</View>
|
|
129
126
|
{/* PlayerImage */}
|
|
130
127
|
|
|
@@ -144,12 +144,7 @@ export function TabletPortraitLayout({
|
|
|
144
144
|
]}
|
|
145
145
|
onLayout={onLayout}
|
|
146
146
|
>
|
|
147
|
-
<PlayerImage
|
|
148
|
-
entry={entry}
|
|
149
|
-
configuration={configuration}
|
|
150
|
-
docked={docked}
|
|
151
|
-
imageWidth={imageSize}
|
|
152
|
-
/>
|
|
147
|
+
<PlayerImage entry={entry} configuration={configuration} />
|
|
153
148
|
</View>
|
|
154
149
|
|
|
155
150
|
<View
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
|
|
2
|
-
|
|
3
|
-
PlayerAnimationStateEnum,
|
|
4
|
-
PlayerAnimationStateT,
|
|
5
|
-
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/ModalAnimationContext";
|
|
2
|
+
|
|
6
3
|
import { parseJsonIfNeeded } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
7
|
-
import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
8
4
|
|
|
9
5
|
export const NAMESPACE = "audio-player";
|
|
10
6
|
|
|
@@ -36,25 +32,3 @@ export const formatSpeed = (value: number) => {
|
|
|
36
32
|
// Return the formatted string with "speed_" prefix
|
|
37
33
|
return `speed_${formattedValue}`;
|
|
38
34
|
};
|
|
39
|
-
|
|
40
|
-
export const calculateBorderRadius = (
|
|
41
|
-
docked: boolean,
|
|
42
|
-
startComponentsAnimation: boolean,
|
|
43
|
-
isActiveGesture: boolean,
|
|
44
|
-
playerAnimationState: PlayerAnimationStateT,
|
|
45
|
-
configuration: Record<string, any>
|
|
46
|
-
): number => {
|
|
47
|
-
const shouldRemoveBorderRadius =
|
|
48
|
-
(startComponentsAnimation &&
|
|
49
|
-
isActiveGesture &&
|
|
50
|
-
playerAnimationState !== PlayerAnimationStateEnum.maximize) ||
|
|
51
|
-
docked;
|
|
52
|
-
|
|
53
|
-
if (shouldRemoveBorderRadius) {
|
|
54
|
-
return 0;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return toNumberWithDefaultZero(
|
|
58
|
-
configuration.audio_player_artwork_border_radius
|
|
59
|
-
);
|
|
60
|
-
};
|
|
@@ -4,8 +4,9 @@ import { Animated, Pressable } from "react-native";
|
|
|
4
4
|
import { PanGestureHandler } from "react-native-gesture-handler";
|
|
5
5
|
import { useStyles } from "./styles";
|
|
6
6
|
import { useVideoModalState } from "./hooks";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { MODAL_COLLAPSE_RATIO, MODAL_RADIUS } from "./consts";
|
|
8
|
+
import { getWindowHeight } from "./utils";
|
|
9
|
+
import { useSafeAreaFrame } from "react-native-safe-area-context";
|
|
9
10
|
|
|
10
11
|
type AnimatedModalProps = {
|
|
11
12
|
content?: ReactElement;
|
|
@@ -16,33 +17,34 @@ export function AnimatedModal({
|
|
|
16
17
|
content,
|
|
17
18
|
collapsedContent,
|
|
18
19
|
}: AnimatedModalProps) {
|
|
19
|
-
const
|
|
20
|
+
const { translateY, collapsed, gestureHandlerProps, expand, offset } =
|
|
21
|
+
useVideoModalState();
|
|
20
22
|
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
expand,
|
|
27
|
-
} = useVideoModalState(translateYRef);
|
|
23
|
+
const frame = useSafeAreaFrame();
|
|
24
|
+
const collapsedHeight = frame.height - offset.current;
|
|
25
|
+
|
|
26
|
+
const height = getWindowHeight();
|
|
27
|
+
const heightAboveMinimised = height - collapsedHeight;
|
|
28
28
|
|
|
29
29
|
const styles = useStyles({ height: collapsedHeight, type: "audio" });
|
|
30
30
|
|
|
31
|
+
const MODAL_COLLAPSE_START = height * MODAL_COLLAPSE_RATIO;
|
|
32
|
+
|
|
31
33
|
// Interpolated opacities for smooth cross-fade
|
|
32
34
|
const collapsedOpacity = translateY.interpolate({
|
|
33
|
-
inputRange: [MODAL_COLLAPSE_START,
|
|
35
|
+
inputRange: [MODAL_COLLAPSE_START, heightAboveMinimised],
|
|
34
36
|
outputRange: [0, 1],
|
|
35
37
|
extrapolate: "clamp",
|
|
36
38
|
});
|
|
37
39
|
|
|
38
40
|
const expandedOpacity = translateY.interpolate({
|
|
39
|
-
inputRange: [0,
|
|
41
|
+
inputRange: [0, heightAboveMinimised],
|
|
40
42
|
outputRange: [1, 0],
|
|
41
43
|
extrapolate: "clamp",
|
|
42
44
|
});
|
|
43
45
|
|
|
44
46
|
const borderTopRadiusAnimated = translateY.interpolate({
|
|
45
|
-
inputRange: [0,
|
|
47
|
+
inputRange: [0, heightAboveMinimised],
|
|
46
48
|
outputRange: [MODAL_RADIUS, 0],
|
|
47
49
|
extrapolate: "clamp",
|
|
48
50
|
});
|
|
@@ -57,7 +59,7 @@ export function AnimatedModal({
|
|
|
57
59
|
borderTopLeftRadius: borderTopRadiusAnimated,
|
|
58
60
|
borderTopRightRadius: borderTopRadiusAnimated,
|
|
59
61
|
transform: [{ translateY }],
|
|
60
|
-
height:
|
|
62
|
+
height: height,
|
|
61
63
|
},
|
|
62
64
|
]}
|
|
63
65
|
>
|
|
@@ -67,7 +69,6 @@ export function AnimatedModal({
|
|
|
67
69
|
{
|
|
68
70
|
borderTopLeftRadius: borderTopRadiusAnimated,
|
|
69
71
|
borderTopRightRadius: borderTopRadiusAnimated,
|
|
70
|
-
height: SCREEN_HEIGHT,
|
|
71
72
|
},
|
|
72
73
|
]}
|
|
73
74
|
>
|