@applicaster/quick-brick-player 13.0.0-alpha.6234681660 → 13.0.0-alpha.6372000108

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 (29) hide show
  1. package/package.json +5 -6
  2. package/src/Player/AudioLayer/AudioDescription.tsx +1 -1
  3. package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +47 -81
  4. package/src/Player/AudioLayer/Layout/Controls/index.tsx +32 -23
  5. package/src/Player/AudioLayer/Layout/Controls/utils.ts +4 -14
  6. package/src/Player/AudioLayer/Layout/Debug/index.tsx +55 -0
  7. package/src/Player/AudioLayer/Layout/DockedControls/index.tsx +7 -7
  8. package/src/Player/AudioLayer/Layout/MobileLayout.tsx +37 -15
  9. package/src/Player/AudioLayer/Layout/PlayerImage/{ScaledImage.tsx → AnimatedImage.tsx} +10 -10
  10. package/src/Player/AudioLayer/Layout/PlayerImage/{StaticImage.tsx → FlexImage.tsx} +4 -11
  11. package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +28 -19
  12. package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +9 -0
  13. package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +17 -7
  14. package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +10 -4
  15. package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +23 -12
  16. package/src/Player/AudioLayer/Layout/const.ts +3 -0
  17. package/src/Player/AudioLayer/Layout/debug.ts +2 -1
  18. package/src/Player/AudioLayer/Layout/hooks/index.ts +3 -1
  19. package/src/Player/AudioLayer/Layout/hooks/useMobileLayoutImageSize.ts +14 -0
  20. package/src/Player/AudioLayer/Layout/hooks/{useImageSize.ts → useTabletLayoutImageSize.ts} +23 -11
  21. package/src/Player/AudioLayer/Layout/index.tsx +6 -37
  22. package/src/Player/AudioLayer/Layout/types.ts +3 -45
  23. package/src/Player/AudioLayer/utils.ts +6 -3
  24. package/src/Player/Const/sleepTimerOptions.ts +39 -0
  25. package/src/Player/Const/speedOptions.ts +4 -0
  26. package/src/Player/Utils/Utils.ts +0 -5
  27. package/src/Player/Utils/index.tsx +117 -0
  28. package/src/Player/index.tsx +4 -1
  29. package/src/Player/Helpers/VideoResizeMode.ts +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/quick-brick-player",
3
- "version": "13.0.0-alpha.6234681660",
3
+ "version": "13.0.0-alpha.6372000108",
4
4
  "description": "Quick Brick Player",
5
5
  "main": "./src/index.ts",
6
6
  "types": "index.d.ts",
@@ -35,12 +35,11 @@
35
35
  },
36
36
  "homepage": "https://github.com/applicaster/quickbrick#readme",
37
37
  "dependencies": {
38
- "@applicaster/quick-brick-mobile-transport-controls": "13.0.0-alpha.6234681660",
38
+ "@applicaster/quick-brick-mobile-transport-controls": "13.0.0-alpha.6372000108",
39
39
  "@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.56",
40
- "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.6234681660",
41
- "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.6234681660",
42
- "@applicaster/zapp-react-native-utils": "13.0.0-alpha.6234681660",
43
- "keymirror": "^0.1.1",
40
+ "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.6372000108",
41
+ "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.6372000108",
42
+ "@applicaster/zapp-react-native-utils": "13.0.0-alpha.6372000108",
44
43
  "query-string": "7.1.3",
45
44
  "react-native-web-linear-gradient": "1.1.2",
46
45
  "shaka-player": "4.3.5",
@@ -82,7 +82,7 @@ export const AudioDescription = (props: AudioDescriptionProps) => {
82
82
 
83
83
  return (
84
84
  <>
85
- <Text style={titleStyles(value, prefix)} numberOfLines={1}>
85
+ <Text style={titleStyles(value, prefix)} numberOfLines={2}>
86
86
  {title}
87
87
  </Text>
88
88
  <Text style={summaryStyles(value, prefix)} numberOfLines={1}>
@@ -1,5 +1,10 @@
1
1
  import * as React from "react";
2
- import { ViewStyle, View, Dimensions as ScreenDimensions } from "react-native";
2
+ import {
3
+ StyleSheet,
4
+ ViewStyle,
5
+ View,
6
+ Dimensions as ScreenDimensions,
7
+ } from "react-native";
3
8
 
4
9
  import { SafeAreaView, Edge } from "react-native-safe-area-context";
5
10
  import { usePlayerState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerState";
@@ -18,7 +23,14 @@ import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
18
23
  import { useEffect, useState } from "react";
19
24
  import { MagicBG } from "./MagicBG";
20
25
  import { formatSpeed } from "./utils";
21
- import { addQueryParam, getLiveUrl } from "../Utils";
26
+ import {
27
+ addQueryParam,
28
+ getBottomSheetModalDefaultItemIcon,
29
+ getBottomSheetModalIconProps,
30
+ getBottomSheetModalItemProps,
31
+ getBottomSheetModalLabelProps,
32
+ getBottomSheetModalSelectedItemIcon,
33
+ } from "../Utils";
22
34
  import { useTitleSummaryOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerTitleSummaryOverlay";
23
35
  import {
24
36
  AnimationComponent,
@@ -27,13 +39,6 @@ import {
27
39
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
28
40
  import { PADDING_HORIZONTAL } from "./Layout/const";
29
41
  import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
30
- import {
31
- speed_0_8,
32
- speed_1,
33
- speed_1_2,
34
- speed_1_5,
35
- speed_2,
36
- } from "@applicaster/quick-brick-mobile-transport-controls";
37
42
  import {
38
43
  SleepTimerController,
39
44
  SleepTimerState,
@@ -42,6 +47,9 @@ import {
42
47
  import { SpeedController, PlaybackSpeed, DEFAULT_SPEED } from "./SpeedManager";
43
48
  import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
44
49
  import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
50
+ import { openBottomSheetModal } from "@applicaster/zapp-react-native-utils/modalState";
51
+ import { getSleepTimerOptions } from "../Const/sleepTimerOptions";
52
+ import { speedOptions } from "../Const/speedOptions";
45
53
 
46
54
  const { log_debug } = createLogger({
47
55
  subsystem: "UIComponent",
@@ -83,51 +91,17 @@ type Props = {
83
91
 
84
92
  const { width: SCREEN_WIDTH } = ScreenDimensions.get("screen");
85
93
 
86
- const Styles = {
87
- mainContainer: (style: ViewStyle) => {
88
- const combinedStyle: ViewStyle = {
89
- flex: 1,
90
- };
91
-
92
- return {
93
- ...combinedStyle,
94
- ...style,
95
- };
96
- },
94
+ const Styles = StyleSheet.create({
97
95
  playerContainer: {
98
96
  flex: 1,
99
97
  },
100
98
  paddingHorizontal: { paddingTop: 0, paddingHorizontal: PADDING_HORIZONTAL },
101
-
102
- controlsMobile: {
103
- height: 50,
104
- marginHorizontal: 24,
105
- },
106
- controlsTablet: {
107
- height: 96,
108
- marginHorizontal: 24,
109
- },
110
99
  playerDetails: {
111
100
  marginTop: 60,
112
101
  alignSelf: "center",
113
102
  width: SCREEN_WIDTH - PADDING_HORIZONTAL * 2,
114
103
  },
115
-
116
- linearGradient: {
117
- flex: 1,
118
- },
119
- };
120
-
121
- const sleeps = [
122
- // { label: "End of episode", value: "episode" },
123
- { label: "5 minutes", value: 5 },
124
- { label: "10 minutes", value: 10 },
125
- { label: "15 minutes", value: 15 },
126
- { label: "30 minutes", value: 30 },
127
- { label: "45 minutes", value: 45 },
128
- { label: "1 hour", value: 60 },
129
- { label: "2 hours", value: 120 },
130
- ];
104
+ });
131
105
 
132
106
  const edges: Edge[] = ["right", "left", "top"];
133
107
 
@@ -147,24 +121,11 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
147
121
  isTabletPortrait,
148
122
  } = props;
149
123
 
150
- const speeds = [
151
- { asset: configuration["speed_0_8"] || speed_0_8, value: 0.8 },
152
- { asset: configuration["speed_1"] || speed_1, value: 1.0 },
153
- { asset: configuration["speed_1_2"] || speed_1_2, value: 1.2 },
154
- { asset: configuration["speed_1_5"] || speed_1_5, value: 1.5 },
155
- { asset: configuration["speed_2"] || speed_2, value: 2.0 },
156
- ];
157
-
158
124
  const isTablet = useIsTablet();
159
125
 
160
126
  const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
161
127
 
162
- // TODO: Have generic place for live url from configuration. Currently its hardcoded for client.
163
-
164
- const feedUrl = getLiveUrl(entry?.extensions?.live?.channel_src ?? "");
165
-
166
128
  const { title, summary } = useTitleSummaryOverlay(
167
- feedUrl,
168
129
  entry,
169
130
  playerState?.isLive,
170
131
  configuration?.audio_live_player_update_interval
@@ -202,8 +163,6 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
202
163
  height: 0,
203
164
  });
204
165
 
205
- const navigator = useNavigation();
206
-
207
166
  const { maximiseVideoModal } = useNavigation();
208
167
 
209
168
  const onLayout = (event: any) => {
@@ -293,44 +252,51 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
293
252
  );
294
253
 
295
254
  const onSpeedButtonPress = React.useCallback(() => {
296
- navigator.openModalBottomSheet({
255
+ openBottomSheetModal({
297
256
  modalBottomSheetContentProps: {
298
- items: speeds,
257
+ items: speedOptions,
299
258
  current_selection: playbackSpeed,
300
259
  onPress: onSpeedSelect,
301
260
  title: configuration["playback_speed_title"],
261
+ itemProps: getBottomSheetModalItemProps,
262
+ iconProps: getBottomSheetModalIconProps,
263
+ labelProps: getBottomSheetModalLabelProps,
264
+ getSelectedItemIcon: getBottomSheetModalSelectedItemIcon,
265
+ getDefaultItemIcon: getBottomSheetModalDefaultItemIcon,
266
+ iconPlacement: "right",
302
267
  },
303
268
  options: {
304
- supportedOrientations: ["portrait"],
269
+ supportedOrientations: [
270
+ "portrait",
271
+ "landscape",
272
+ "portrait-upside-down",
273
+ ],
305
274
  },
306
275
  });
307
- }, [
308
- playbackSpeed,
309
- setPlaybackSpeed,
310
- navigator,
311
- onSpeedSelect,
312
- configuration["playback_speed_title"],
313
- ]);
276
+ }, [playbackSpeed, onSpeedSelect, configuration["playback_speed_title"]]);
314
277
 
315
278
  const onSleepButtonPress = React.useCallback(() => {
316
- navigator.openModalBottomSheet({
279
+ openBottomSheetModal({
317
280
  modalBottomSheetContentProps: {
318
- items: [
319
- {
320
- label: configuration["playback_sleep_off_label"],
321
- value: 0,
322
- },
323
- ].concat(sleeps),
281
+ items: getSleepTimerOptions(configuration),
324
282
  current_selection: sleepTimerState.timer,
325
283
  onPress: onSleepSelect,
326
284
  title: configuration["playback_sleep_title"],
285
+ itemProps: getBottomSheetModalItemProps,
286
+ iconProps: getBottomSheetModalIconProps,
287
+ labelProps: getBottomSheetModalLabelProps,
288
+ getSelectedItemIcon: getBottomSheetModalSelectedItemIcon,
289
+ iconPlacement: "right",
327
290
  },
328
291
  options: {
329
- supportedOrientations: ["portrait"],
292
+ supportedOrientations: [
293
+ "portrait",
294
+ "landscape",
295
+ "portrait-upside-down",
296
+ ],
330
297
  },
331
298
  });
332
299
  }, [
333
- navigator,
334
300
  sleepTimerState.timer,
335
301
  configuration["playback_sleep_title"],
336
302
  configuration["playback_sleep_off_label"],
@@ -366,7 +332,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
366
332
 
367
333
  const MainContent = React.useMemo(() => {
368
334
  return (
369
- <SafeAreaView style={Styles.mainContainer(style)} edges={edges}>
335
+ <SafeAreaView style={[style, Styles.playerContainer]} edges={edges}>
370
336
  <AnimationComponent
371
337
  animationType={ComponentAnimationType.moveUpComponent}
372
338
  additionalData={{ saveArea: true }}
@@ -410,11 +376,11 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
410
376
  animationType={ComponentAnimationType.componentFade}
411
377
  >
412
378
  <PlayerDetails
379
+ isAudioPlayer
413
380
  configuration={configuration}
414
381
  style={Styles.playerDetails}
415
382
  entry={entry}
416
383
  isTabletLandscape={isTabletLandscape}
417
- isAudioPlayer={true}
418
384
  />
419
385
  </AnimationComponent>
420
386
  </View>
@@ -5,7 +5,6 @@ import { dayjs } from "@applicaster/zapp-react-native-utils/dateUtils";
5
5
  import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
6
6
  import {
7
7
  Controls as MobileTransportControls,
8
- CountDown,
9
8
  ProgressBar,
10
9
  } from "@applicaster/quick-brick-mobile-transport-controls";
11
10
  import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
@@ -29,8 +28,6 @@ import {
29
28
  speedButton,
30
29
  } from "./utils";
31
30
 
32
- import { PlayerState, LayoutState } from "../types";
33
-
34
31
  const styles = StyleSheet.create({
35
32
  flex: {
36
33
  flex: 1,
@@ -41,24 +38,29 @@ const styles = StyleSheet.create({
41
38
  progressBar: {
42
39
  flex: 0,
43
40
  },
41
+ progressBarTrackStyles: {
42
+ borderRadius: 3,
43
+ height: 6,
44
+ },
45
+ progressBarThumbStyles: {
46
+ width: 14,
47
+ height: 14,
48
+ borderRadius: 7,
49
+ },
50
+ progressBarThumbStyles_pressed: {
51
+ width: 20,
52
+ height: 20,
53
+ borderRadius: 10,
54
+ },
44
55
  });
45
56
 
46
- const controlsStyles = ({
47
- isTablet,
48
- isLiveShowFullControls,
49
- }: {
50
- isTablet: boolean;
51
- isLiveShowFullControls: boolean;
52
- }) => ({
53
- height: isTablet ? undefined : 50,
54
- marginHorizontal: isTablet ? undefined : 10,
55
- justifyContent: isLiveShowFullControls ? "space-between" : "space-evenly",
56
- });
57
+ const getControlJustifyContent = (countOfButtons: number) =>
58
+ countOfButtons <= 1 ? "center" : "space-between";
57
59
 
58
60
  type Props = {
59
61
  entry: ZappEntry;
60
- layoutState: LayoutState;
61
- playerState: PlayerState;
62
+ layoutState: QuickBrickPlayer.LayoutState;
63
+ playerState: QuickBrickPlayer.PlayerState;
62
64
  value: GetValue;
63
65
  title: string | number;
64
66
  summary: string | number;
@@ -119,14 +121,19 @@ export const Controls = (props: Props) => {
119
121
  showFullControls = !!(controller?.hasSeekableDuration?.() && seekEnabled);
120
122
  }
121
123
 
122
- const sleepTitle = value("playback_sleep_countdown_label");
123
-
124
124
  const [timeLeft, setTimeLeft] = React.useState(
125
125
  sleepTimerDate !== 0 ? sleepTimerDate - Date.now() : 0
126
126
  );
127
127
 
128
128
  const showCounter = React.useMemo(() => sleepTimerDate > 0, [sleepTimerDate]);
129
129
 
130
+ const countDownOptions = React.useMemo(() => {
131
+ return {
132
+ showCounter: showCounter && timeLeft >= 0,
133
+ timeLeft,
134
+ };
135
+ }, [showCounter, timeLeft]);
136
+
130
137
  React.useEffect(() => {
131
138
  if (showCounter && sleepTimerDate !== 0) {
132
139
  setTimeLeft(sleepTimerDate - Date.now());
@@ -284,12 +291,12 @@ export const Controls = (props: Props) => {
284
291
  isDateBasedLiveContent={isDateBasedLiveContent}
285
292
  onSkipLive={onSkipLive}
286
293
  progressBarStyles={styles.progressBar}
294
+ countDownOptions={countDownOptions}
295
+ thumbStyles={styles.progressBarThumbStyles}
296
+ thumbStylesPressed={styles.progressBarThumbStyles_pressed}
297
+ trackStyles={styles.progressBarTrackStyles}
287
298
  />
288
299
 
289
- {showCounter && timeLeft >= 0 ? (
290
- <CountDown timeLeft={timeLeft} value={value} title={sleepTitle} />
291
- ) : null}
292
-
293
300
  <VerticalGutter />
294
301
  </>
295
302
  ) : null}
@@ -299,7 +306,9 @@ export const Controls = (props: Props) => {
299
306
  visible={true}
300
307
  keepAlive={null}
301
308
  buttons={controlButtons}
302
- style={controlsStyles({ isTablet, isLiveShowFullControls })}
309
+ style={{
310
+ justifyContent: getControlJustifyContent(controlButtons().length),
311
+ }}
303
312
  playerState={playerState}
304
313
  />
305
314
  </AnimationComponent>
@@ -1,16 +1,7 @@
1
- import { PlayerState } from "../types";
2
-
3
- const rewindButtonSize = (isTablet: boolean): keyof ButtonSizeStyles =>
4
- isTablet ? "big" : "smallMargins";
5
-
6
- const playbackButtonSize = (isTablet: boolean): keyof ButtonSizeStyles =>
7
- isTablet ? "bigExtended" : "mediumExtended";
8
-
9
1
  const playbackButtonMargins = (
10
2
  isTablet: boolean,
11
3
  isLiveShowFullControls: boolean
12
- ): number =>
13
- isLiveShowFullControls ? (isTablet ? 65 : 10) : isTablet ? undefined : 40;
4
+ ): number => (isLiveShowFullControls ? (isTablet ? 65 : 10) : undefined);
14
5
 
15
6
  export const playbackButton = ({
16
7
  playerState,
@@ -19,7 +10,7 @@ export const playbackButton = ({
19
10
  isLiveShowFullControls,
20
11
  onPress,
21
12
  }: {
22
- playerState: PlayerState;
13
+ playerState: QuickBrickPlayer.PlayerState;
23
14
  liveButton: boolean;
24
15
  isTablet: boolean;
25
16
  isLiveShowFullControls: boolean;
@@ -32,7 +23,7 @@ export const playbackButton = ({
32
23
  : "pause";
33
24
 
34
25
  return {
35
- size: playbackButtonSize(isTablet),
26
+ size: "bigExtended",
36
27
  icon: playerState.isBuffering ? "buffering" : icon,
37
28
  preferredFocus: true,
38
29
  onPress,
@@ -54,10 +45,9 @@ type ButtonsByNameProps = ButtonsProps & { name?: string };
54
45
  const rewindButtonByName = ({
55
46
  name,
56
47
  onPress,
57
- isTablet,
58
48
  style,
59
49
  }: ButtonsByNameProps): ControlsButton => ({
60
- size: rewindButtonSize(isTablet),
50
+ size: "big",
61
51
  icon: name,
62
52
  onPress,
63
53
  style,
@@ -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
+ );
@@ -16,6 +16,7 @@ import {
16
16
  } from "@applicaster/quick-brick-mobile-transport-controls";
17
17
 
18
18
  import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
19
+
19
20
  import {
20
21
  AnimationComponent,
21
22
  ComponentAnimationType,
@@ -24,15 +25,13 @@ import {
24
25
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
25
26
  import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
26
27
 
27
- import { LayoutState, PlayerState, Configuration, DimensionsT } from "../types";
28
-
29
28
  type Props = {
30
29
  entry: ZappEntry;
31
- layoutState: LayoutState;
32
- playerState: PlayerState;
30
+ layoutState: QuickBrickPlayer.LayoutState;
31
+ playerState: QuickBrickPlayer.PlayerState;
33
32
  value: GetValue;
34
- configuration: Configuration;
35
- dimensions: DimensionsT;
33
+ configuration: QuickBrickPlayer.AudioPlayerProps["configuration"];
34
+ dimensions: QuickBrickPlayer.AudioPlayerProps["dimensions"];
36
35
  onCloseVideoModal: () => void;
37
36
  onPlayerSeek: (targetTime: number) => void;
38
37
  playNextData: PlayNextData;
@@ -110,7 +109,7 @@ const animatedContainerStyle = (
110
109
  });
111
110
 
112
111
  const backgroundImageStyle = (
113
- dimensions: DimensionsT,
112
+ dimensions: QuickBrickPlayer.AudioPlayerProps["dimensions"],
114
113
  minimisedHeight: number,
115
114
  isActiveGesture: boolean
116
115
  ): ViewStyle => ({
@@ -219,6 +218,7 @@ export const DockedControls = (props: Props) => {
219
218
  isActiveGesture || layoutState.docked,
220
219
  progressBarHeight
221
220
  ),
221
+ { height: minimisedHeight },
222
222
  ]}
223
223
  >
224
224
  {!playerState.isLive &&
@@ -6,15 +6,21 @@ import {
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";
10
- import { Props } from "./types";
9
+ import { MOBILE, NAVBAR_HEIGHT } from "./const";
11
10
  import { TransportInfo } from "./TransportInfo";
12
11
  import { PlayerImage } from "./PlayerImage";
13
12
  import { Controls } from "./Controls";
14
13
 
15
- import { useImageSize, useTransportInfoHeight } from "./hooks";
14
+ import { useMobileLayoutImageSize, useTransportInfoHeight } from "./hooks";
16
15
  import { DockedControls } from "./DockedControls";
17
- import { withDebug } from "./debug";
16
+ import { withDebug, DEBUG } from "./debug";
17
+ import {
18
+ LeftDebugSquare,
19
+ RightDebugSquare,
20
+ BottomDebugSquare,
21
+ } from "./Debug/index";
22
+
23
+ import { Props } from "./types";
18
24
 
19
25
  const styles = StyleSheet.create({
20
26
  container: {
@@ -29,6 +35,8 @@ const styles = StyleSheet.create({
29
35
  flex: 1,
30
36
  justifyContent: "flex-start",
31
37
 
38
+ minHeight: MOBILE.MIN_HEIGHT,
39
+
32
40
  marginLeft: MOBILE.MARGIN_HORIZONTAL,
33
41
  marginRight: MOBILE.MARGIN_HORIZONTAL,
34
42
 
@@ -87,11 +95,27 @@ export function MobileLayout({
87
95
  const { height: screenHeight } = useSafeAreaFrame();
88
96
  const { progressBarHeight } = useModalAnimationContext();
89
97
 
90
- const { imageSize, onLayout } = useImageSize();
98
+ const { imageSize } = useMobileLayoutImageSize();
91
99
 
92
100
  const { height: transportInfoHeight, onLayout: onTransportInfoLayout } =
93
101
  useTransportInfoHeight();
94
102
 
103
+ const controlsContainerHeight = React.useMemo(() => {
104
+ return (
105
+ screenHeight -
106
+ topInset -
107
+ imageSize -
108
+ NAVBAR_HEIGHT -
109
+ MOBILE.MARGIN_BOTTOM -
110
+ MOBILE.MARGIN_TOP -
111
+ bottomInset
112
+ );
113
+ }, [screenHeight, topInset, imageSize, bottomInset]);
114
+
115
+ const verticalOffsetForImage = React.useMemo(() => {
116
+ return transportInfoHeight + MOBILE.MARGIN_TOP - progressBarHeight;
117
+ }, [transportInfoHeight, progressBarHeight]);
118
+
95
119
  return (
96
120
  <View
97
121
  style={[
@@ -104,6 +128,10 @@ export function MobileLayout({
104
128
  }),
105
129
  ]}
106
130
  >
131
+ {DEBUG ? <LeftDebugSquare /> : null}
132
+ {DEBUG ? <RightDebugSquare /> : null}
133
+ {DEBUG ? <BottomDebugSquare /> : null}
134
+
107
135
  {/* TransportInfo */}
108
136
  <TransportInfo
109
137
  entry={entry}
@@ -136,7 +164,6 @@ export function MobileLayout({
136
164
  }),
137
165
  },
138
166
  ]}
139
- onLayout={onLayout}
140
167
  >
141
168
  <PlayerImage
142
169
  entry={entry}
@@ -152,20 +179,15 @@ export function MobileLayout({
152
179
  summary={summary}
153
180
  docked={docked}
154
181
  imageWidth={imageSize}
155
- verticalOffset={
156
- transportInfoHeight + MOBILE.MARGIN_TOP - progressBarHeight
157
- }
182
+ verticalOffset={verticalOffsetForImage}
158
183
  />
159
184
  </View>
160
185
  {/* PlayerImage */}
161
186
 
162
187
  <View
163
- style={[
164
- styles.flex,
165
- {
166
- marginBottom: MOBILE.MARGIN_BOTTOM,
167
- },
168
- ]}
188
+ style={{
189
+ height: controlsContainerHeight,
190
+ }}
169
191
  >
170
192
  <Controls
171
193
  entry={entry}
@@ -1,5 +1,5 @@
1
1
  import React, { PropsWithChildren } from "react";
2
- import { ImageBackground, Animated, StyleSheet } from "react-native";
2
+ import { Image, Animated, StyleSheet, ViewStyle } from "react-native";
3
3
 
4
4
  import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
5
5
  import {
@@ -14,6 +14,7 @@ const styles = StyleSheet.create({
14
14
  // we have to specify flex:0 and dimensions to make animation work
15
15
  flex: 0,
16
16
  aspectRatio: 1,
17
+ overflow: "hidden",
17
18
  },
18
19
  });
19
20
 
@@ -21,13 +22,15 @@ type Props = PropsWithChildren<{
21
22
  entry: ZappEntry;
22
23
  style?: { [K: string]: any };
23
24
  imageStyle?: { [K: string]: any };
25
+ wrapperViewStyle?: ViewStyle;
24
26
  imageWidth: number;
25
27
  }>;
26
28
 
27
- export const ScaledImage = ({
29
+ export const AnimatedImage = ({
28
30
  entry,
29
31
  style,
30
32
  imageStyle,
33
+ wrapperViewStyle,
31
34
  imageWidth,
32
35
  }: Props) => {
33
36
  const heightAnim = React.useRef(new Animated.Value(imageWidth)).current;
@@ -59,25 +62,22 @@ export const ScaledImage = ({
59
62
  }
60
63
  }, [playerAnimationState, imageWidth]);
61
64
 
62
- if (!source) return <></>;
65
+ if (!source) return null;
63
66
 
64
67
  return (
65
68
  <Animated.View
66
69
  style={[
67
70
  styles.container,
71
+ wrapperViewStyle,
72
+ imageStyle,
68
73
  {
69
74
  width: heightAnim,
70
75
  },
71
76
  ]}
72
77
  >
73
- <ImageBackground
74
- resizeMode="cover"
75
- style={style}
76
- imageStyle={imageStyle}
77
- source={source}
78
- >
78
+ <Image resizeMode="cover" style={style} source={source}>
79
79
  {null}
80
- </ImageBackground>
80
+ </Image>
81
81
  </Animated.View>
82
82
  );
83
83
  };