@applicaster/quick-brick-player 13.0.0-rc.98 → 13.0.0

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.
Files changed (39) hide show
  1. package/package.json +6 -7
  2. package/src/Player/AudioLayer/AudioDescription.tsx +109 -68
  3. package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +81 -189
  4. package/src/Player/AudioLayer/Layout/Controls/VerticalGutter.tsx +23 -5
  5. package/src/Player/AudioLayer/Layout/Controls/index.tsx +46 -60
  6. package/src/Player/AudioLayer/Layout/Controls/utils.ts +5 -13
  7. package/src/Player/AudioLayer/Layout/Debug/index.tsx +55 -0
  8. package/src/Player/AudioLayer/Layout/DockedControls/index.tsx +38 -19
  9. package/src/Player/AudioLayer/Layout/MobileLayout.tsx +35 -25
  10. package/src/Player/AudioLayer/Layout/PlayerImage/AnimatedImage.tsx +39 -40
  11. package/src/Player/AudioLayer/Layout/PlayerImage/FlexImage.tsx +6 -22
  12. package/src/Player/AudioLayer/Layout/PlayerImage/hooks/index.ts +1 -0
  13. package/src/Player/AudioLayer/Layout/PlayerImage/hooks/useChangePlayerState.ts +99 -0
  14. package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +37 -20
  15. package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +19 -0
  16. package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +101 -103
  17. package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +5 -14
  18. package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +39 -13
  19. package/src/Player/AudioLayer/Layout/const.ts +6 -0
  20. package/src/Player/AudioLayer/Layout/debug.ts +1 -1
  21. package/src/Player/AudioLayer/Layout/hooks/index.ts +3 -1
  22. package/src/Player/AudioLayer/Layout/hooks/useMobileLayoutImageSize.ts +14 -0
  23. package/src/Player/AudioLayer/Layout/hooks/{useImageSize.ts → useTabletLayoutImageSize.ts} +10 -5
  24. package/src/Player/AudioLayer/Layout/hooks/useTransportInfoHeight.ts +1 -1
  25. package/src/Player/AudioLayer/Layout/utils.ts +7 -0
  26. package/src/Player/AudioLayer/SleepTimerManager.ts +22 -11
  27. package/src/Player/AudioLayer/components/SleepTimerModalHeader/SleepTimerModalHeader.tsx +66 -0
  28. package/src/Player/AudioLayer/components/SleepTimerModalHeader/index.ts +1 -0
  29. package/src/Player/AudioLayer/useSleepTimerModal.ts +109 -0
  30. package/src/Player/Const/sleepTimerOptions.ts +7 -5
  31. package/src/Player/Utils/index.tsx +6 -0
  32. package/src/Player/hooks/useIsCasting.tsx +57 -0
  33. package/src/Player/index.tsx +84 -37
  34. package/src/QuickBrickPlayer.tsx +3 -0
  35. package/src/Player/AudioLayer/LinearGradient/LinearGradientProxy.ts +0 -3
  36. package/src/Player/AudioLayer/LinearGradient/LinearGradientProxy.web.ts +0 -3
  37. package/src/Player/AudioLayer/LinearGradient/index.ts +0 -1
  38. package/src/Player/AudioLayer/MagicBG/index.tsx +0 -155
  39. package/src/utils/utils.ts +0 -25
@@ -2,10 +2,12 @@ import * as React from "react";
2
2
  import { StyleSheet } from "react-native";
3
3
 
4
4
  import { dayjs } from "@applicaster/zapp-react-native-utils/dateUtils";
5
- import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
5
+ import {
6
+ useIsTablet,
7
+ useZStore,
8
+ } from "@applicaster/zapp-react-native-utils/reactHooks";
6
9
  import {
7
10
  Controls as MobileTransportControls,
8
- CountDown,
9
11
  ProgressBar,
10
12
  } from "@applicaster/quick-brick-mobile-transport-controls";
11
13
  import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
@@ -28,6 +30,7 @@ import {
28
30
  sleepButton,
29
31
  speedButton,
30
32
  } from "./utils";
33
+ import { useSleepTimerModal } from "../../useSleepTimerModal";
31
34
 
32
35
  const styles = StyleSheet.create({
33
36
  flex: {
@@ -39,19 +42,24 @@ const styles = StyleSheet.create({
39
42
  progressBar: {
40
43
  flex: 0,
41
44
  },
45
+ progressBarTrackStyles: {
46
+ borderRadius: 3,
47
+ height: 6,
48
+ },
49
+ progressBarThumbStyles: {
50
+ width: 14,
51
+ height: 14,
52
+ borderRadius: 7,
53
+ },
54
+ progressBarThumbStyles_pressed: {
55
+ width: 20,
56
+ height: 20,
57
+ borderRadius: 10,
58
+ },
42
59
  });
43
60
 
44
- const controlsStyles = ({
45
- isTablet,
46
- isLiveShowFullControls,
47
- }: {
48
- isTablet: boolean;
49
- isLiveShowFullControls: boolean;
50
- }) => ({
51
- height: isTablet ? undefined : 50,
52
- marginHorizontal: isTablet ? undefined : 10,
53
- justifyContent: isLiveShowFullControls ? "space-between" : "space-evenly",
54
- });
61
+ const getControlJustifyContent = (countOfButtons: number) =>
62
+ countOfButtons <= 1 ? "center" : "space-between";
55
63
 
56
64
  type Props = {
57
65
  entry: ZappEntry;
@@ -60,11 +68,8 @@ type Props = {
60
68
  value: GetValue;
61
69
  title: string | number;
62
70
  summary: string | number;
63
- sleepTimerDate: number;
64
- cancelSleepTimer: Callback;
65
71
 
66
72
  playbackSpeedName: string;
67
- playbackSleepName: string;
68
73
 
69
74
  onPlaybackButtonPress: Callback;
70
75
  onRewindButtonPress: Callback;
@@ -73,7 +78,8 @@ type Props = {
73
78
  onSkipStart: Callback;
74
79
  onSkipLive: Callback;
75
80
  onSpeedButtonPress: Callback;
76
- onSleepButtonPress: Callback;
81
+
82
+ maxWidth?: number;
77
83
 
78
84
  docked: boolean;
79
85
  };
@@ -86,11 +92,8 @@ export const Controls = (props: Props) => {
86
92
  value,
87
93
  title,
88
94
  summary,
89
- sleepTimerDate,
90
- cancelSleepTimer,
91
95
 
92
96
  playbackSpeedName,
93
- playbackSleepName,
94
97
 
95
98
  onPlaybackButtonPress,
96
99
  onRewindButtonPress,
@@ -99,11 +102,26 @@ export const Controls = (props: Props) => {
99
102
  onSkipStart,
100
103
  onSkipLive,
101
104
  onSpeedButtonPress,
102
- onSleepButtonPress,
105
+ maxWidth = 320,
103
106
 
104
107
  docked,
105
108
  } = props;
106
109
 
110
+ const configuration = useZStore("playerConfiguration");
111
+
112
+ const { sleepTimerState, onSleepButtonPress } = useSleepTimerModal(
113
+ playerManager.getActivePlayer(),
114
+ configuration
115
+ );
116
+
117
+ const timerRemaining =
118
+ sleepTimerState.timerDate !== 0 && +sleepTimerState.timerDate > Date.now()
119
+ ? sleepTimerState.timerDate
120
+ : null;
121
+
122
+ const playbackSleepName =
123
+ timerRemaining === null ? "sleep_timer" : "sleep_timer_active";
124
+
107
125
  const isTablet = useIsTablet();
108
126
  const controller = playerManager.getActivePlayer();
109
127
  let showFullControls = !controller?.isAd();
@@ -117,40 +135,6 @@ export const Controls = (props: Props) => {
117
135
  showFullControls = !!(controller?.hasSeekableDuration?.() && seekEnabled);
118
136
  }
119
137
 
120
- const sleepTitle = value("playback_sleep_countdown_label");
121
-
122
- const [timeLeft, setTimeLeft] = React.useState(
123
- sleepTimerDate !== 0 ? sleepTimerDate - Date.now() : 0
124
- );
125
-
126
- const showCounter = React.useMemo(() => sleepTimerDate > 0, [sleepTimerDate]);
127
-
128
- React.useEffect(() => {
129
- if (showCounter && sleepTimerDate !== 0) {
130
- setTimeLeft(sleepTimerDate - Date.now());
131
-
132
- const intervalId = setInterval(() => {
133
- setTimeLeft(() => {
134
- const newTimeLeft = sleepTimerDate - Date.now();
135
-
136
- if (newTimeLeft <= 0) {
137
- clearInterval(intervalId);
138
-
139
- cancelSleepTimer();
140
-
141
- return 0;
142
- } else {
143
- return newTimeLeft;
144
- }
145
- });
146
- }, 1000);
147
-
148
- return () => clearInterval(intervalId);
149
- } else {
150
- setTimeLeft(0);
151
- }
152
- }, [sleepTimerDate, showCounter, cancelSleepTimer]);
153
-
154
138
  const startTime = entry.extensions?.live?.start_time;
155
139
  const endTime = entry.extensions?.live?.end_time;
156
140
 
@@ -261,6 +245,7 @@ export const Controls = (props: Props) => {
261
245
  summary={summary}
262
246
  value={value}
263
247
  layoutState={layoutState}
248
+ maxWidth={maxWidth}
264
249
  />
265
250
 
266
251
  <VerticalGutter />
@@ -282,12 +267,11 @@ export const Controls = (props: Props) => {
282
267
  isDateBasedLiveContent={isDateBasedLiveContent}
283
268
  onSkipLive={onSkipLive}
284
269
  progressBarStyles={styles.progressBar}
270
+ thumbStyles={styles.progressBarThumbStyles}
271
+ thumbStylesPressed={styles.progressBarThumbStyles_pressed}
272
+ trackStyles={styles.progressBarTrackStyles}
285
273
  />
286
274
 
287
- {showCounter && timeLeft >= 0 ? (
288
- <CountDown timeLeft={timeLeft} value={value} title={sleepTitle} />
289
- ) : null}
290
-
291
275
  <VerticalGutter />
292
276
  </>
293
277
  ) : null}
@@ -297,7 +281,9 @@ export const Controls = (props: Props) => {
297
281
  visible={true}
298
282
  keepAlive={null}
299
283
  buttons={controlButtons}
300
- style={controlsStyles({ isTablet, isLiveShowFullControls })}
284
+ style={{
285
+ justifyContent: getControlJustifyContent(controlButtons().length),
286
+ }}
301
287
  playerState={playerState}
302
288
  />
303
289
  </AnimationComponent>
@@ -1,14 +1,7 @@
1
- const rewindButtonSize = (isTablet: boolean): keyof ButtonSizeStyles =>
2
- isTablet ? "big" : "smallMargins";
3
-
4
- const playbackButtonSize = (isTablet: boolean): keyof ButtonSizeStyles =>
5
- isTablet ? "bigExtended" : "mediumExtended";
6
-
7
1
  const playbackButtonMargins = (
8
2
  isTablet: boolean,
9
3
  isLiveShowFullControls: boolean
10
- ): number =>
11
- isLiveShowFullControls ? (isTablet ? 65 : 10) : isTablet ? undefined : 40;
4
+ ): number => (isLiveShowFullControls ? (isTablet ? 65 : 10) : undefined);
12
5
 
13
6
  export const playbackButton = ({
14
7
  playerState,
@@ -30,7 +23,7 @@ export const playbackButton = ({
30
23
  : "pause";
31
24
 
32
25
  return {
33
- size: playbackButtonSize(isTablet),
26
+ size: "bigExtended",
34
27
  icon: playerState.isBuffering ? "buffering" : icon,
35
28
  preferredFocus: true,
36
29
  onPress,
@@ -52,10 +45,9 @@ type ButtonsByNameProps = ButtonsProps & { name?: string };
52
45
  const rewindButtonByName = ({
53
46
  name,
54
47
  onPress,
55
- isTablet,
56
48
  style,
57
49
  }: ButtonsByNameProps): ControlsButton => ({
58
- size: rewindButtonSize(isTablet),
50
+ size: "big",
59
51
  icon: name,
60
52
  onPress,
61
53
  style,
@@ -107,7 +99,7 @@ export const skipToLiveButton = (props: ButtonsProps): ControlsButton =>
107
99
  skipButtonByName({ ...props, name: "skip_live" });
108
100
 
109
101
  export const speedButton = (props: ButtonsProps): ControlsButton =>
110
- speedButtonByName({ ...props });
102
+ speedButtonByName(props);
111
103
 
112
104
  export const sleepButton = (props: ButtonsProps): ControlsButton =>
113
- sleepButtonByName({ ...props });
105
+ sleepButtonByName(props);
@@ -0,0 +1,55 @@
1
+ /* eslint react-native/no-color-literals: off */
2
+ /* eslint react-native/no-inline-styles: off */
3
+
4
+ import * as React from "react";
5
+ import { View } from "react-native";
6
+
7
+ import { MOBILE } from "../const";
8
+
9
+ export const LeftDebugSquare = () => (
10
+ <View
11
+ style={{
12
+ position: "absolute",
13
+ top: 200,
14
+ left: 0,
15
+ width: MOBILE.MARGIN_HORIZONTAL,
16
+ height: MOBILE.MARGIN_HORIZONTAL,
17
+ backgroundColor: "blue",
18
+
19
+ borderWidth: 1,
20
+ borderColor: "yellow",
21
+ }}
22
+ />
23
+ );
24
+
25
+ export const RightDebugSquare = () => (
26
+ <View
27
+ style={{
28
+ position: "absolute",
29
+ top: 200,
30
+ right: 0,
31
+ width: MOBILE.MARGIN_HORIZONTAL,
32
+ height: MOBILE.MARGIN_HORIZONTAL,
33
+ backgroundColor: "blue",
34
+
35
+ borderWidth: 1,
36
+ borderColor: "yellow",
37
+ }}
38
+ />
39
+ );
40
+
41
+ export const BottomDebugSquare = () => (
42
+ <View
43
+ style={{
44
+ position: "absolute",
45
+ left: 170,
46
+ bottom: 0,
47
+ width: MOBILE.MARGIN_BOTTOM,
48
+ height: MOBILE.MARGIN_BOTTOM,
49
+ backgroundColor: "blue",
50
+
51
+ borderWidth: 1,
52
+ borderColor: "yellow",
53
+ }}
54
+ />
55
+ );
@@ -24,19 +24,23 @@ import {
24
24
  useModalAnimationContext,
25
25
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
26
26
  import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
27
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
28
+ import { getTabBarHeight } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/getTabBarHeight";
29
+
30
+ const bottomTabBarHeight = getTabBarHeight();
27
31
 
28
32
  type Props = {
29
33
  entry: ZappEntry;
30
34
  layoutState: QuickBrickPlayer.LayoutState;
31
35
  playerState: QuickBrickPlayer.PlayerState;
32
36
  value: GetValue;
33
- configuration: QuickBrickPlayer.AudioPlayerProps["configuration"];
34
37
  dimensions: QuickBrickPlayer.AudioPlayerProps["dimensions"];
35
38
  onCloseVideoModal: () => void;
36
39
  onPlayerSeek: (targetTime: number) => void;
37
40
  playNextData: PlayNextData;
38
41
  title: string | number;
39
42
  summary: string | number;
43
+ ImageComponent?: React.ReactNode;
40
44
  };
41
45
 
42
46
  const styles = StyleSheet.create({
@@ -53,6 +57,7 @@ const styles = StyleSheet.create({
53
57
  touchableArea: {
54
58
  flexShrink: 1,
55
59
  flex: 1,
60
+ flexDirection: "row",
56
61
  alignSelf: "stretch",
57
62
  },
58
63
  contentInfo: {
@@ -87,15 +92,11 @@ const styles = StyleSheet.create({
87
92
  },
88
93
  });
89
94
 
90
- const backgroundColorStyle = (value: GetValue): ViewStyle => ({
91
- backgroundColor: value("docked_player_background_color"),
92
- });
93
-
94
95
  const playerDimensionsStyle = (
95
96
  minimisedHeight: number,
96
97
  addPadding: boolean
97
98
  ): ViewStyle => ({
98
- paddingLeft: addPadding ? toNumberWithDefault(100, minimisedHeight) : 0,
99
+ width: addPadding ? toNumberWithDefault(100, minimisedHeight) : 0,
99
100
  });
100
101
 
101
102
  const animatedContainerStyle = (
@@ -181,13 +182,13 @@ export const DockedControls = (props: Props) => {
181
182
  layoutState,
182
183
  playerState,
183
184
  value,
184
- configuration,
185
185
  dimensions,
186
186
  onCloseVideoModal,
187
187
  onPlayerSeek,
188
188
  playNextData,
189
189
  title,
190
190
  summary,
191
+ ImageComponent,
191
192
  } = props;
192
193
 
193
194
  const isTablet = useIsTablet();
@@ -207,6 +208,10 @@ export const DockedControls = (props: Props) => {
207
208
  []
208
209
  );
209
210
 
211
+ const dockedBackgroundColor = value("docked_player_background_color");
212
+
213
+ const insets = useSafeAreaInsets();
214
+
210
215
  if (!layoutState.docked && !startComponentsAnimation) return null;
211
216
 
212
217
  return (
@@ -218,7 +223,9 @@ export const DockedControls = (props: Props) => {
218
223
  isActiveGesture || layoutState.docked,
219
224
  progressBarHeight
220
225
  ),
221
- { height: minimisedHeight },
226
+ {
227
+ height: minimisedHeight + bottomTabBarHeight + insets.bottom,
228
+ },
222
229
  ]}
223
230
  >
224
231
  {!playerState.isLive &&
@@ -245,19 +252,25 @@ export const DockedControls = (props: Props) => {
245
252
  )}
246
253
  />
247
254
  <TouchableWithoutFeedback onPress={maximazeVideoModal}>
248
- <View
249
- style={[
250
- styles.touchableArea,
251
- playerDimensionsStyle(
252
- minimisedHeight,
253
- isActiveGesture || layoutState.docked
254
- ),
255
- ]}
256
- >
255
+ <View style={styles.touchableArea}>
256
+ {isActiveGesture || layoutState.docked ? (
257
+ <View
258
+ style={{ width: toNumberWithDefault(100, minimisedHeight) }}
259
+ >
260
+ {ImageComponent || null}
261
+ </View>
262
+ ) : (
263
+ <View
264
+ style={playerDimensionsStyle(
265
+ minimisedHeight,
266
+ isActiveGesture || layoutState.docked
267
+ )}
268
+ />
269
+ )}
257
270
  <View
258
271
  style={[
259
272
  styles.contentInfo,
260
- !configuration.magic_background && backgroundColorStyle(value),
273
+ { backgroundColor: dockedBackgroundColor },
261
274
  ]}
262
275
  >
263
276
  <ContentInfo
@@ -273,7 +286,7 @@ export const DockedControls = (props: Props) => {
273
286
  isTablet
274
287
  ? styles.controlsContainerForTablet
275
288
  : styles.controlsContainerForMobile,
276
- !configuration.magic_background && backgroundColorStyle(value),
289
+ { backgroundColor: dockedBackgroundColor },
277
290
  ]}
278
291
  >
279
292
  <Controls
@@ -295,6 +308,12 @@ export const DockedControls = (props: Props) => {
295
308
  />
296
309
  </View>
297
310
  </View>
311
+ <View
312
+ style={{
313
+ height: insets.bottom + bottomTabBarHeight,
314
+ backgroundColor: dockedBackgroundColor,
315
+ }}
316
+ />
298
317
  </AnimationComponent>
299
318
  );
300
319
  };
@@ -1,19 +1,24 @@
1
1
  import * as React from "react";
2
- import { View, ViewStyle, StyleSheet } from "react-native";
2
+ import { StyleSheet, View, ViewStyle } from "react-native";
3
3
  import {
4
- useSafeAreaInsets,
5
4
  useSafeAreaFrame,
5
+ useSafeAreaInsets,
6
6
  } from "react-native-safe-area-context";
7
7
  import { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
8
8
 
9
- import { MOBILE } from "./const";
9
+ import { MOBILE, NAVBAR_HEIGHT } from "./const";
10
10
  import { TransportInfo } from "./TransportInfo";
11
11
  import { PlayerImage } from "./PlayerImage";
12
12
  import { Controls } from "./Controls";
13
13
 
14
- import { useImageSize, useTransportInfoHeight } from "./hooks";
14
+ import { useMobileLayoutImageSize, useTransportInfoHeight } from "./hooks";
15
15
  import { DockedControls } from "./DockedControls";
16
- import { withDebug } from "./debug";
16
+ import { DEBUG, withDebug } from "./debug";
17
+ import {
18
+ BottomDebugSquare,
19
+ LeftDebugSquare,
20
+ RightDebugSquare,
21
+ } from "./Debug/index";
17
22
 
18
23
  import { Props } from "./types";
19
24
 
@@ -72,15 +77,11 @@ export function MobileLayout({
72
77
  onSkipStart,
73
78
  onSkipLive,
74
79
  onSpeedButtonPress,
75
- onSleepButtonPress,
76
80
  onCloseVideoModal,
77
81
  playbackSpeedName,
78
- playbackSleepName,
79
82
  configuration,
80
83
  dimensions,
81
84
  playNextData,
82
- cancelSleepTimer,
83
- sleepTimerDate,
84
85
  title,
85
86
  summary,
86
87
  }: Props) {
@@ -90,11 +91,27 @@ export function MobileLayout({
90
91
  const { height: screenHeight } = useSafeAreaFrame();
91
92
  const { progressBarHeight } = useModalAnimationContext();
92
93
 
93
- const { imageSize, onLayout } = useImageSize({ isPortraitMode: true });
94
+ const { imageSize } = useMobileLayoutImageSize();
94
95
 
95
96
  const { height: transportInfoHeight, onLayout: onTransportInfoLayout } =
96
97
  useTransportInfoHeight();
97
98
 
99
+ const controlsContainerHeight = React.useMemo(() => {
100
+ return (
101
+ screenHeight -
102
+ topInset -
103
+ imageSize -
104
+ NAVBAR_HEIGHT -
105
+ MOBILE.MARGIN_BOTTOM -
106
+ MOBILE.MARGIN_TOP -
107
+ bottomInset
108
+ );
109
+ }, [screenHeight, topInset, imageSize, bottomInset]);
110
+
111
+ const verticalOffsetForImage = React.useMemo(() => {
112
+ return transportInfoHeight + MOBILE.MARGIN_TOP - progressBarHeight;
113
+ }, [transportInfoHeight, progressBarHeight]);
114
+
98
115
  return (
99
116
  <View
100
117
  style={[
@@ -107,6 +124,10 @@ export function MobileLayout({
107
124
  }),
108
125
  ]}
109
126
  >
127
+ {DEBUG ? <LeftDebugSquare /> : null}
128
+ {DEBUG ? <RightDebugSquare /> : null}
129
+ {DEBUG ? <BottomDebugSquare /> : null}
130
+
110
131
  {/* TransportInfo */}
111
132
  <TransportInfo
112
133
  entry={entry}
@@ -139,7 +160,6 @@ export function MobileLayout({
139
160
  }),
140
161
  },
141
162
  ]}
142
- onLayout={onLayout}
143
163
  >
144
164
  <PlayerImage
145
165
  entry={entry}
@@ -155,20 +175,15 @@ export function MobileLayout({
155
175
  summary={summary}
156
176
  docked={docked}
157
177
  imageWidth={imageSize}
158
- verticalOffset={
159
- transportInfoHeight + MOBILE.MARGIN_TOP - progressBarHeight
160
- }
178
+ verticalOffset={verticalOffsetForImage}
161
179
  />
162
180
  </View>
163
181
  {/* PlayerImage */}
164
182
 
165
183
  <View
166
- style={[
167
- styles.flex,
168
- {
169
- marginBottom: MOBILE.MARGIN_BOTTOM,
170
- },
171
- ]}
184
+ style={{
185
+ height: controlsContainerHeight,
186
+ }}
172
187
  >
173
188
  <Controls
174
189
  entry={entry}
@@ -177,10 +192,7 @@ export function MobileLayout({
177
192
  value={value}
178
193
  title={title}
179
194
  summary={summary}
180
- sleepTimerDate={sleepTimerDate}
181
- cancelSleepTimer={cancelSleepTimer}
182
195
  playbackSpeedName={playbackSpeedName}
183
- playbackSleepName={playbackSleepName}
184
196
  onPlaybackButtonPress={onPlaybackButtonPress}
185
197
  onRewindButtonPress={onRewindButtonPress}
186
198
  onForwardButtonPress={onForwardButtonPress}
@@ -188,7 +200,6 @@ export function MobileLayout({
188
200
  onSkipStart={onSkipStart}
189
201
  onSkipLive={onSkipLive}
190
202
  onSpeedButtonPress={onSpeedButtonPress}
191
- onSleepButtonPress={onSleepButtonPress}
192
203
  docked={docked}
193
204
  />
194
205
  </View>
@@ -199,7 +210,6 @@ export function MobileLayout({
199
210
  layoutState={layoutState}
200
211
  playerState={playerState}
201
212
  value={value}
202
- configuration={configuration}
203
213
  dimensions={dimensions}
204
214
  onCloseVideoModal={onCloseVideoModal}
205
215
  onPlayerSeek={onPlayerSeek}
@@ -1,13 +1,16 @@
1
1
  import React, { PropsWithChildren } from "react";
2
- import { ImageBackground, Animated, StyleSheet } from "react-native";
2
+ import { Image, Animated, StyleSheet, ImageStyle } from "react-native";
3
3
 
4
- import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
5
4
  import {
6
5
  useModalAnimationContext,
7
6
  PlayerAnimationStateEnum,
8
7
  DURATION_TO_MINIMIZE,
9
8
  DURATION_TO_MAXIMIZE,
10
9
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
10
+ import { PlayerAnimationStateT } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/ModalAnimationContext";
11
+ import { useBackgroundImage } from "@applicaster/zapp-react-native-utils/audioPlayerUtils";
12
+
13
+ import { useChangePlayerState } from "./hooks";
11
14
 
12
15
  const styles = StyleSheet.create({
13
16
  container: {
@@ -19,47 +22,50 @@ const styles = StyleSheet.create({
19
22
 
20
23
  type Props = PropsWithChildren<{
21
24
  entry: ZappEntry;
22
- style?: { [K: string]: any };
23
- imageStyle?: { [K: string]: any };
25
+ style?: ImageStyle | ImageStyle[];
24
26
  imageWidth: number;
27
+ docked: boolean;
25
28
  }>;
26
29
 
27
- export const AnimatedImage = ({
28
- entry,
29
- style,
30
- imageStyle,
31
- imageWidth,
32
- }: Props) => {
30
+ export const AnimatedImage = ({ entry, style, imageWidth, docked }: Props) => {
33
31
  const heightAnim = React.useRef(new Animated.Value(imageWidth)).current;
34
32
 
35
- const source = React.useMemo(
36
- () => ({ uri: imageSrcFromMediaItem(entry, undefined) }),
37
- [entry]
38
- );
33
+ const backgroundImageSource = useBackgroundImage(entry);
34
+
35
+ const { minimisedHeight } = useModalAnimationContext();
39
36
 
40
- const { playerAnimationState, minimisedHeight } = useModalAnimationContext();
37
+ const changePlayerState$ = useChangePlayerState({ docked });
41
38
 
42
39
  React.useEffect(() => {
43
- if (playerAnimationState === PlayerAnimationStateEnum.minimize) {
44
- Animated.timing(heightAnim, {
45
- toValue: minimisedHeight,
46
- duration: DURATION_TO_MINIMIZE,
47
- useNativeDriver: false, // width/height can't use native driver
48
- }).start();
40
+ const subscription = changePlayerState$.subscribe({
41
+ next: (nextPlayerState: PlayerAnimationStateT) => {
42
+ if (nextPlayerState === PlayerAnimationStateEnum.minimize) {
43
+ Animated.timing(heightAnim, {
44
+ toValue: minimisedHeight,
45
+ duration: DURATION_TO_MINIMIZE,
46
+ useNativeDriver: false, // width/height can't use native driver
47
+ }).start();
48
+ }
49
49
 
50
- return;
51
- }
50
+ if (nextPlayerState === PlayerAnimationStateEnum.maximize) {
51
+ Animated.timing(heightAnim, {
52
+ toValue: imageWidth,
53
+ duration: DURATION_TO_MAXIMIZE,
54
+ useNativeDriver: false, // width/height can't use native driver
55
+ }).start();
56
+ }
52
57
 
53
- if (playerAnimationState === PlayerAnimationStateEnum.maximize) {
54
- Animated.timing(heightAnim, {
55
- toValue: imageWidth,
56
- duration: DURATION_TO_MAXIMIZE,
57
- useNativeDriver: false, // width/height can't use native driver
58
- }).start();
59
- }
60
- }, [playerAnimationState, imageWidth]);
58
+ if (nextPlayerState === PlayerAnimationStateEnum.appear_as_docked) {
59
+ // minimize image immediatly
60
+ heightAnim.setValue(minimisedHeight);
61
+ }
62
+ },
63
+ });
61
64
 
62
- if (!source) return null;
65
+ return () => {
66
+ subscription.unsubscribe();
67
+ };
68
+ }, [changePlayerState$, minimisedHeight, imageWidth]);
63
69
 
64
70
  return (
65
71
  <Animated.View
@@ -70,14 +76,7 @@ export const AnimatedImage = ({
70
76
  },
71
77
  ]}
72
78
  >
73
- <ImageBackground
74
- resizeMode="cover"
75
- style={style}
76
- imageStyle={imageStyle}
77
- source={source}
78
- >
79
- {null}
80
- </ImageBackground>
79
+ <Image resizeMode="cover" style={style} source={backgroundImageSource} />
81
80
  </Animated.View>
82
81
  );
83
82
  };