@applicaster/zapp-react-native-ui-components 12.0.0-rc.3 → 12.0.0-rc.30
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/AnimatedInOut/index.tsx +18 -10
- package/Components/AudioPlayer/AudioPlayer.tsx +9 -1
- package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +5 -0
- package/Components/AudioPlayer/helpers.tsx +1 -0
- package/Components/FocusableList/FocusableChild.ts +24 -14
- package/Components/FocusableList/FocusableItem.tsx +1 -1
- package/Components/FocusableList/FocusableListItemWrapper.tsx +76 -0
- package/Components/FocusableList/hooks/useCellState.android.ts +3 -1
- package/Components/FocusableList/index.tsx +26 -25
- package/Components/GeneralContentScreen/GeneralContentScreen.tsx +11 -8
- package/Components/HandlePlayable/HandlePlayable.tsx +1 -1
- package/Components/HookRenderer/index.tsx +1 -4
- package/Components/Image/Image.android.tsx +33 -2
- package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +1 -41
- package/Components/Layout/TV/__tests__/index.test.tsx +0 -21
- package/Components/Layout/TV/index.tsx +20 -36
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +0 -1
- package/Components/MasterCell/DefaultComponents/CellBadge/index.tsx +21 -8
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +8 -10
- package/Components/MasterCell/utils/index.ts +2 -2
- package/Components/ModalComponent/BottomSheetModalContent.tsx +121 -0
- package/Components/ModalComponent/Button/Item.tsx +82 -0
- package/Components/ModalComponent/Button/ItemIcon.tsx +60 -0
- package/Components/ModalComponent/Button/ItemLabel.tsx +101 -0
- package/Components/ModalComponent/Button/assets.ts +4 -0
- package/Components/ModalComponent/Button/index.tsx +111 -0
- package/Components/ModalComponent/Header/CloseButton.tsx +59 -0
- package/Components/ModalComponent/Header/Title.tsx +70 -0
- package/Components/ModalComponent/Header/assets.ts +4 -0
- package/Components/ModalComponent/Header/index.tsx +71 -0
- package/Components/ModalComponent/Header/utils.ts +79 -0
- package/Components/ModalComponent/index.tsx +38 -0
- package/Components/ModalComponent/utils.ts +126 -0
- package/Components/PlayerContainer/ErrorDisplay/ErrorDisplay.tsx +4 -7
- package/Components/River/ComponentsMap/ComponentsMap.tsx +25 -0
- package/Components/River/River.tsx +8 -5
- package/Components/River/TV/River.tsx +2 -2
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +1 -1
- package/Components/River/useScreenConfiguration.ts +5 -6
- package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +1 -0
- package/Components/RouteManager/__tests__/routeManager.test.js +9 -2
- package/Components/RouteManager/index.tsx +4 -2
- package/Components/Screen/__tests__/Screen.test.tsx +43 -35
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +10 -6
- package/Components/Screen/__tests__/navigationHandler.test.ts +1 -178
- package/Components/Screen/index.tsx +84 -45
- package/Components/Screen/navigationHandler.ts +0 -82
- package/Components/Screen/orientationHandler.ts +1 -1
- package/Components/ScreenResolver/index.tsx +1 -1
- package/Components/TrackedView/index.tsx +6 -3
- package/Components/VideoLive/LiveImageManager.ts +42 -13
- package/Components/VideoLive/PlayerLiveImageComponent.tsx +79 -73
- package/Components/VideoModal/PlayerDetails.tsx +3 -0
- package/Components/VideoModal/PlayerWrapper.tsx +66 -63
- package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +0 -2
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +4 -4
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +10 -18
- package/Components/VideoModal/hooks/useModalSize.ts +13 -4
- package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +26 -21
- package/Components/Viewport/ViewportTracker/__tests__/viewportTracker.test.js +4 -5
- package/Components/ZappUIComponent/index.tsx +22 -12
- package/Components/index.js +2 -0
- package/Contexts/ScreenContext/index.tsx +1 -4
- package/Decorators/RiverResolver/index.tsx +0 -4
- package/Decorators/index.tsx +0 -4
- package/package.json +5 -6
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
import { setUserCellPlayerMutedPreference } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/userCellPlayerMutedPreference";
|
|
7
7
|
import { loggerLiveImageManager } from "./loggerHelper";
|
|
8
8
|
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
9
|
+
import { Component } from "react";
|
|
9
10
|
|
|
10
11
|
const { log_debug, log_info, log_error } = loggerLiveImageManager;
|
|
11
12
|
|
|
@@ -36,7 +37,8 @@ type Position = {
|
|
|
36
37
|
type LiveImageProps = {
|
|
37
38
|
player: Player;
|
|
38
39
|
playerId: string;
|
|
39
|
-
setMode
|
|
40
|
+
setMode?: (type: LiveImageType) => void;
|
|
41
|
+
component: Component;
|
|
40
42
|
// TODO: ...primary, powerCell, tvGallery, etc.
|
|
41
43
|
// type: string;
|
|
42
44
|
};
|
|
@@ -164,7 +166,7 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
164
166
|
|
|
165
167
|
// Fake close event, because we unmount native view
|
|
166
168
|
item.player?.onPlayerClose();
|
|
167
|
-
item.setMode(LiveImageType.Image);
|
|
169
|
+
item.setMode?.(LiveImageType.Image);
|
|
168
170
|
|
|
169
171
|
if (item === this.currentlyPlaying) {
|
|
170
172
|
this.currentlyPlaying = null;
|
|
@@ -191,8 +193,7 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
191
193
|
}
|
|
192
194
|
|
|
193
195
|
this.currentlyPlaying = item;
|
|
194
|
-
|
|
195
|
-
item.setMode(LiveImageType.Video);
|
|
196
|
+
item.setMode?.(LiveImageType.Video);
|
|
196
197
|
|
|
197
198
|
if (item.player.playerState.isReadyToPlay) {
|
|
198
199
|
item.player.play();
|
|
@@ -209,6 +210,11 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
209
210
|
this.pauseItem(item);
|
|
210
211
|
};
|
|
211
212
|
|
|
213
|
+
public onLiveImageCompleted = (_item: LiveImage) => {
|
|
214
|
+
// TODO: Notify listeners that player has died
|
|
215
|
+
// Do not try look for new playable, otherwise you will restart video finish to play
|
|
216
|
+
};
|
|
217
|
+
|
|
212
218
|
public muteAll = () => {
|
|
213
219
|
log_debug("muteAll");
|
|
214
220
|
|
|
@@ -235,6 +241,14 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
235
241
|
const playerItem = this.findNextPlayableItem();
|
|
236
242
|
|
|
237
243
|
if (playerItem) {
|
|
244
|
+
if (!playerItem.isFullyVisible) {
|
|
245
|
+
log_error(
|
|
246
|
+
`checkPlayerPosition: trying to start playback currently invisible item: ${playerInfo(
|
|
247
|
+
playerItem.player
|
|
248
|
+
)}`
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
238
252
|
// Will also check if it's item that already playing
|
|
239
253
|
this.playLiveImage(playerItem);
|
|
240
254
|
}
|
|
@@ -242,7 +256,6 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
242
256
|
|
|
243
257
|
onPrimaryPlayerClosed = () => {
|
|
244
258
|
const playerItem = this.findNextPlayableItem();
|
|
245
|
-
|
|
246
259
|
log_info("onPrimaryPlayerClosed: starting to play visible live-image");
|
|
247
260
|
|
|
248
261
|
this.currentlyPlaying = null;
|
|
@@ -356,12 +369,12 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
356
369
|
// TODO: This branch was used when we had play button to toggle replay.
|
|
357
370
|
// Now we mute button instead but we keep it just in case.
|
|
358
371
|
if (IS_ALLOWED_REPLAY && !isTV() && isCurrentItemEnded) {
|
|
359
|
-
this.currentlyPlaying
|
|
360
|
-
this.currentlyPlaying
|
|
372
|
+
this.currentlyPlaying?.player.seekTo(0);
|
|
373
|
+
this.currentlyPlaying?.player.pause();
|
|
361
374
|
|
|
362
375
|
// TODO: ...Maybe player some other item
|
|
363
376
|
} else {
|
|
364
|
-
item.setMode(LiveImageType.Image);
|
|
377
|
+
item.setMode?.(LiveImageType.Image);
|
|
365
378
|
}
|
|
366
379
|
|
|
367
380
|
// Prevent receiving onEnd event from both `close` and `end` player events
|
|
@@ -377,10 +390,25 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
377
390
|
};
|
|
378
391
|
|
|
379
392
|
onLiveImageError = (item: LiveImage, error: Error) => {
|
|
380
|
-
item.setMode(LiveImageType.Image);
|
|
393
|
+
item.setMode?.(LiveImageType.Image);
|
|
381
394
|
|
|
382
|
-
|
|
395
|
+
const currentItem = this.currentlyPlaying;
|
|
396
|
+
|
|
397
|
+
log_debug(
|
|
398
|
+
`onLiveImageError: error: ${error.message}, live-image ${playerInfo(
|
|
399
|
+
item.player
|
|
400
|
+
)}, currentPlayingId: ${
|
|
401
|
+
this.currentlyPlaying?.playerId
|
|
402
|
+
}, primaryPlayerId: ${this.primaryPlayer?.playerId}`
|
|
403
|
+
);
|
|
404
|
+
|
|
405
|
+
if (currentItem === item) {
|
|
383
406
|
this.currentlyPlaying = null;
|
|
407
|
+
|
|
408
|
+
log_debug(
|
|
409
|
+
`onLiveImageError: currentitem: ${currentItem.playerId} was removed`
|
|
410
|
+
);
|
|
411
|
+
|
|
384
412
|
// TODO: ...Maybe player some other item
|
|
385
413
|
}
|
|
386
414
|
|
|
@@ -389,8 +417,8 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
389
417
|
event: {
|
|
390
418
|
item,
|
|
391
419
|
error,
|
|
392
|
-
playerId:
|
|
393
|
-
primaryPlayerId:
|
|
420
|
+
playerId: currentItem?.playerId,
|
|
421
|
+
primaryPlayerId: currentItem?.playerId,
|
|
394
422
|
},
|
|
395
423
|
});
|
|
396
424
|
};
|
|
@@ -446,12 +474,13 @@ export class LiveImage implements QuickBrickPlayer.SharedPlayerCallBacks {
|
|
|
446
474
|
};
|
|
447
475
|
|
|
448
476
|
readonly playerId: string;
|
|
477
|
+
readonly component: Component;
|
|
449
478
|
|
|
450
479
|
constructor(props: LiveImageProps) {
|
|
451
480
|
this.player = props.player;
|
|
452
481
|
this.setMode = props.setMode;
|
|
453
482
|
this.playerId = this.player.playerId;
|
|
454
|
-
|
|
483
|
+
this.component = props.component;
|
|
455
484
|
this.player.addListener({ id: "live-image", listener: this });
|
|
456
485
|
}
|
|
457
486
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// /// <reference types="@applicaster/applicaster-types" />
|
|
2
2
|
//
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
import * as R from "ramda";
|
|
5
4
|
|
|
6
5
|
import { AppState, AppStateStatus } from "react-native";
|
|
7
6
|
import { TrackedView } from "../TrackedView";
|
|
@@ -9,7 +8,6 @@ import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks/l
|
|
|
9
8
|
|
|
10
9
|
import { playerFactory } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/playerFactory";
|
|
11
10
|
|
|
12
|
-
import { BufferAnimation } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/BufferAnimation";
|
|
13
11
|
import {
|
|
14
12
|
isApplePlatform,
|
|
15
13
|
isTV,
|
|
@@ -25,12 +23,13 @@ import { loggerLiveImageComponent } from "./loggerHelper";
|
|
|
25
23
|
import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer";
|
|
26
24
|
import { PlayerRole } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/conts";
|
|
27
25
|
import { getAutoplaySettings } from "./utils";
|
|
26
|
+
import { isString } from "@applicaster/zapp-react-native-utils/stringUtils";
|
|
27
|
+
import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
|
|
28
28
|
|
|
29
29
|
const { log_error } = loggerLiveImageComponent;
|
|
30
30
|
|
|
31
|
-
const isMeasurement = (item) =>
|
|
32
|
-
|
|
33
|
-
};
|
|
31
|
+
const isMeasurement = (item: ZappEntry) =>
|
|
32
|
+
isString(item.id) && item.id.startsWith("pre-measurement-");
|
|
34
33
|
|
|
35
34
|
type Props = {
|
|
36
35
|
item: ZappEntry;
|
|
@@ -55,69 +54,66 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
55
54
|
isTV() ? false : getUserCellPlayerMutedPreference(props.audioMutedByDefault)
|
|
56
55
|
);
|
|
57
56
|
|
|
58
|
-
const [PlayerViewComponent, setPlayerViewComponent] = React.useState(null);
|
|
59
|
-
const Player: any = PlayerViewComponent || BufferAnimation;
|
|
60
|
-
|
|
61
57
|
const ref = React.useRef(null);
|
|
62
58
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (type ===
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
timeoutRef.current = setTimeout(() => {
|
|
78
|
-
setMode(type);
|
|
79
|
-
}, 1000) as unknown as NodeJS.Timeout;
|
|
80
|
-
} else {
|
|
81
|
-
if (timeoutRef.current) {
|
|
82
|
-
clearTimeout(timeoutRef.current);
|
|
83
|
-
}
|
|
59
|
+
/**
|
|
60
|
+
* Debounced setMode function.
|
|
61
|
+
*
|
|
62
|
+
* Sets to video with a 1sec delay. Set to image happens immediately and cancels the timeout.
|
|
63
|
+
*
|
|
64
|
+
* @param type video or image
|
|
65
|
+
*/
|
|
66
|
+
const setModeDebounced = React.useCallback((type: LiveImageType) => {
|
|
67
|
+
if (type === LiveImageType.Video) {
|
|
68
|
+
if (type === mode) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
84
71
|
|
|
72
|
+
timeoutRef.current = setTimeout(() => {
|
|
85
73
|
setMode(type);
|
|
74
|
+
}, 1000) as unknown as NodeJS.Timeout;
|
|
75
|
+
} else {
|
|
76
|
+
if (timeoutRef.current) {
|
|
77
|
+
clearTimeout(timeoutRef.current);
|
|
78
|
+
timeoutRef.current = null;
|
|
86
79
|
}
|
|
87
|
-
};
|
|
88
80
|
|
|
81
|
+
setMode(type);
|
|
82
|
+
}
|
|
83
|
+
}, [mode]);
|
|
84
|
+
|
|
85
|
+
const { screenConfig, playerPluginId } = props;
|
|
86
|
+
|
|
87
|
+
const liveImageItem: LiveImage = React.useMemo(() => {
|
|
89
88
|
const playerFactoryItem = playerFactory({
|
|
90
89
|
player: ref,
|
|
91
|
-
listener: props as Record<string, any>,
|
|
92
90
|
playerId,
|
|
93
91
|
autoplay: false,
|
|
94
92
|
entry: item,
|
|
95
|
-
muted,
|
|
96
|
-
playerPluginId:
|
|
97
|
-
screenConfig:
|
|
93
|
+
muted, // Initial muted state, not needed in dependencies
|
|
94
|
+
playerPluginId: playerPluginId,
|
|
95
|
+
screenConfig: screenConfig,
|
|
98
96
|
playerRole: PlayerRole.Cell,
|
|
99
97
|
});
|
|
100
98
|
|
|
101
|
-
const Component = playerFactoryItem?.Component;
|
|
102
|
-
|
|
103
|
-
if (!R.isNil(Component) && Component !== PlayerViewComponent) {
|
|
104
|
-
setPlayerViewComponent(Component);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
99
|
if (playerFactoryItem) {
|
|
108
100
|
return new LiveImage({
|
|
109
101
|
playerId,
|
|
110
102
|
player: playerFactoryItem.controller,
|
|
111
|
-
|
|
103
|
+
component: playerFactoryItem?.Component
|
|
112
104
|
});
|
|
113
105
|
} else {
|
|
114
106
|
throw new Error("Player factory item is null");
|
|
115
107
|
}
|
|
116
|
-
}, [playerId, item
|
|
108
|
+
}, [playerId, item, playerPluginId, screenConfig]);
|
|
109
|
+
|
|
110
|
+
React.useEffect(() => {
|
|
111
|
+
liveImageItem.setMode = setModeDebounced;
|
|
112
|
+
}, [setModeDebounced, liveImageItem]);
|
|
117
113
|
|
|
118
114
|
const { start, end } = React.useMemo(
|
|
119
115
|
() => getAutoplaySettings(item),
|
|
120
|
-
[item
|
|
116
|
+
[item]
|
|
121
117
|
);
|
|
122
118
|
|
|
123
119
|
const controller = liveImageItem.getPlayer();
|
|
@@ -127,6 +123,10 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
127
123
|
ref.current = component;
|
|
128
124
|
};
|
|
129
125
|
|
|
126
|
+
const onLiveImageCompleted = React.useCallback(() => {
|
|
127
|
+
LiveImageManager.instance.onLiveImageCompleted(liveImageItem);
|
|
128
|
+
}, [liveImageItem]);
|
|
129
|
+
|
|
130
130
|
const onStop = React.useCallback(() => {
|
|
131
131
|
LiveImageManager.instance.pauseLiveImage(liveImageItem);
|
|
132
132
|
}, [liveImageItem]);
|
|
@@ -140,13 +140,14 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
140
140
|
const unregister = LiveImageManager.instance.register(liveImageItem);
|
|
141
141
|
|
|
142
142
|
return () => {
|
|
143
|
-
unregister();
|
|
144
|
-
|
|
145
143
|
if (timeoutRef.current) {
|
|
146
144
|
clearTimeout(timeoutRef.current);
|
|
145
|
+
timeoutRef.current = null;
|
|
147
146
|
}
|
|
147
|
+
|
|
148
|
+
unregister();
|
|
148
149
|
};
|
|
149
|
-
}, [
|
|
150
|
+
}, [item, liveImageItem]);
|
|
150
151
|
|
|
151
152
|
React.useEffect(() => {
|
|
152
153
|
if (!player) {
|
|
@@ -178,11 +179,12 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
178
179
|
setMuted(false);
|
|
179
180
|
},
|
|
180
181
|
onPlayerClose: () => {
|
|
182
|
+
onLiveImageCompleted();
|
|
181
183
|
setIsReady(false);
|
|
182
184
|
},
|
|
183
185
|
},
|
|
184
186
|
});
|
|
185
|
-
}, [player, onStop]);
|
|
187
|
+
}, [player, onStop, onLiveImageCompleted, start, end]);
|
|
186
188
|
|
|
187
189
|
React.useEffect(() => {
|
|
188
190
|
const subscription = AppState.addEventListener(
|
|
@@ -233,40 +235,43 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
233
235
|
};
|
|
234
236
|
}
|
|
235
237
|
}
|
|
236
|
-
}, [liveImageItem]);
|
|
238
|
+
}, [liveImageItem, playerId, controller]);
|
|
237
239
|
|
|
238
|
-
const onPositionUpdated = (
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
240
|
+
const onPositionUpdated = React.useCallback(
|
|
241
|
+
(data) => {
|
|
242
|
+
const normalizedRect = (rect: {left: number, right: number, top: number, bottom: number }) => {
|
|
243
|
+
if (!rect) {
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
243
246
|
|
|
244
|
-
|
|
247
|
+
const { left, right, top, bottom } = rect;
|
|
245
248
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
249
|
+
return {
|
|
250
|
+
left: left / dimensions.width,
|
|
251
|
+
right: right / dimensions.width,
|
|
252
|
+
top: top / dimensions.height,
|
|
253
|
+
bottom: bottom / dimensions.height,
|
|
254
|
+
centerX: (left + right) / 2 / dimensions.width,
|
|
255
|
+
centerY: (top + bottom) / 2 / dimensions.height,
|
|
256
|
+
};
|
|
253
257
|
};
|
|
254
|
-
};
|
|
255
258
|
|
|
256
|
-
|
|
259
|
+
liveImageItem.position = normalizedRect(data.rect);
|
|
257
260
|
|
|
258
|
-
|
|
261
|
+
const newIsFullyVisible = !!data.rect;
|
|
259
262
|
|
|
260
|
-
|
|
261
|
-
|
|
263
|
+
if (liveImageItem.isFullyVisible !== newIsFullyVisible) {
|
|
264
|
+
liveImageItem.isFullyVisible = newIsFullyVisible;
|
|
262
265
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
266
|
+
liveImageItem.isFullyVisible
|
|
267
|
+
? LiveImageManager.instance.onViewportEnter(liveImageItem)
|
|
268
|
+
: LiveImageManager.instance.onViewportLeave(liveImageItem);
|
|
269
|
+
} else {
|
|
270
|
+
LiveImageManager.instance.checkPlayerPosition(liveImageItem);
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
[liveImageItem, dimensions]
|
|
274
|
+
);
|
|
270
275
|
|
|
271
276
|
const platformSpecificProps = isApplePlatform()
|
|
272
277
|
? { hideNativeControls: true, controls: false }
|
|
@@ -276,6 +281,7 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
276
281
|
const isVideoMode = mode === LiveImageType.Video;
|
|
277
282
|
const isBackgroundImageVisible = isImageMode || !isReadyToPlay;
|
|
278
283
|
const videoStyles = { ...style, position: "absolute", zIndex: -100 };
|
|
284
|
+
const Player: any = liveImageItem.component || BufferAnimation;
|
|
279
285
|
|
|
280
286
|
return (
|
|
281
287
|
<TrackedView
|
|
@@ -23,6 +23,8 @@ const containerStyle = ({
|
|
|
23
23
|
backgroundColor: modal_background_color,
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
+
// const audioMarginStyle = { marginTop: 0, marginBottom: 0 };
|
|
27
|
+
|
|
26
28
|
export const PlayerDetails = ({
|
|
27
29
|
entry,
|
|
28
30
|
style,
|
|
@@ -75,6 +77,7 @@ export const PlayerDetails = ({
|
|
|
75
77
|
transform: [{ translateY }],
|
|
76
78
|
opacity,
|
|
77
79
|
},
|
|
80
|
+
// isAudioPlayer && audioMarginStyle,
|
|
78
81
|
]}
|
|
79
82
|
>
|
|
80
83
|
{screenData && (
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Dimensions,
|
|
4
|
+
Platform,
|
|
5
|
+
StyleSheet,
|
|
6
|
+
View,
|
|
7
|
+
ViewStyle,
|
|
8
|
+
} from "react-native";
|
|
3
9
|
import { Edge, SafeAreaView } from "react-native-safe-area-context";
|
|
4
10
|
|
|
5
11
|
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
6
|
-
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks
|
|
12
|
+
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
7
13
|
import { PlayerDetails } from "./PlayerDetails";
|
|
8
14
|
import { playerDimesionsHack } from "./utils";
|
|
9
15
|
import { PathnameContext } from "../../Contexts/PathnameContext";
|
|
10
|
-
import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
11
16
|
import { ScreenContextProvider } from "../../Contexts/ScreenContext";
|
|
12
17
|
|
|
13
|
-
type
|
|
14
|
-
width: number;
|
|
15
|
-
height: number;
|
|
18
|
+
type DimensionsT = {
|
|
19
|
+
width: number | string;
|
|
20
|
+
height: number | string;
|
|
21
|
+
aspectRatio?: number;
|
|
16
22
|
};
|
|
17
23
|
|
|
18
24
|
type Configuration = {
|
|
@@ -23,14 +29,15 @@ type Configuration = {
|
|
|
23
29
|
|
|
24
30
|
type Props = {
|
|
25
31
|
entry: ZappEntry;
|
|
26
|
-
style: ViewStyle &
|
|
32
|
+
style: ViewStyle & DimensionsT;
|
|
27
33
|
containerStyle?: ViewStyle;
|
|
28
34
|
inline?: boolean;
|
|
29
35
|
docked?: boolean;
|
|
36
|
+
pip?: boolean;
|
|
30
37
|
isModal?: boolean;
|
|
31
38
|
fullscreen?: boolean;
|
|
32
39
|
isTabletPortrait?: boolean;
|
|
33
|
-
children: (playerDimensions:
|
|
40
|
+
children: (playerDimensions: DimensionsT) => React.ReactNode;
|
|
34
41
|
configuration: Configuration;
|
|
35
42
|
};
|
|
36
43
|
|
|
@@ -52,6 +59,15 @@ const directionStyles = (isTabletLandscape: boolean): ViewStyle => {
|
|
|
52
59
|
return orientationStyles.portrait;
|
|
53
60
|
};
|
|
54
61
|
|
|
62
|
+
const getScreenAspectRatio = () => {
|
|
63
|
+
const { width, height } = Dimensions.get("screen");
|
|
64
|
+
|
|
65
|
+
const longEdge = Math.max(width, height);
|
|
66
|
+
const shortEdge = Math.min(width, height);
|
|
67
|
+
|
|
68
|
+
return longEdge / shortEdge;
|
|
69
|
+
};
|
|
70
|
+
|
|
55
71
|
const safeAreaStyles = (
|
|
56
72
|
configuration: Configuration,
|
|
57
73
|
isTablet: boolean
|
|
@@ -66,34 +82,6 @@ const safeAreaStyles = (
|
|
|
66
82
|
};
|
|
67
83
|
};
|
|
68
84
|
|
|
69
|
-
const getTabletWidth = (
|
|
70
|
-
configuration: Configuration,
|
|
71
|
-
dimensions: Dimensions
|
|
72
|
-
) => {
|
|
73
|
-
const tablet_landscape_sidebar_width =
|
|
74
|
-
configuration?.tablet_landscape_sidebar_width;
|
|
75
|
-
|
|
76
|
-
const { width } = dimensions;
|
|
77
|
-
|
|
78
|
-
const sidebarWidth = Number(tablet_landscape_sidebar_width?.replace("%", ""));
|
|
79
|
-
|
|
80
|
-
if (tablet_landscape_sidebar_width?.includes("%")) {
|
|
81
|
-
return width * (1 - sidebarWidth / 100);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (Number.isNaN(sidebarWidth)) {
|
|
85
|
-
return width * 0.65;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return width - sidebarWidth;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
export const defaultAspectRatioHeight = (width: number): number =>
|
|
92
|
-
(width / 16) * 9;
|
|
93
|
-
|
|
94
|
-
export const defaultAspectRatioWidth = (height: number): number =>
|
|
95
|
-
(height / 9) * 16;
|
|
96
|
-
|
|
97
85
|
const getEdges = (
|
|
98
86
|
isTablet: boolean,
|
|
99
87
|
docked: boolean,
|
|
@@ -115,6 +103,28 @@ const getEdges = (
|
|
|
115
103
|
return ["top"];
|
|
116
104
|
};
|
|
117
105
|
|
|
106
|
+
const getTabletWidth = (
|
|
107
|
+
configuration: Configuration,
|
|
108
|
+
dimensions: DimensionsT
|
|
109
|
+
) => {
|
|
110
|
+
const tablet_landscape_sidebar_width =
|
|
111
|
+
configuration?.tablet_landscape_sidebar_width;
|
|
112
|
+
|
|
113
|
+
const { width } = dimensions;
|
|
114
|
+
|
|
115
|
+
const sidebarWidth = Number(tablet_landscape_sidebar_width?.replace("%", ""));
|
|
116
|
+
|
|
117
|
+
if (tablet_landscape_sidebar_width?.includes("%")) {
|
|
118
|
+
return Number(width) * (1 - sidebarWidth / 100);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (Number.isNaN(sidebarWidth)) {
|
|
122
|
+
return Number(width) * 0.65;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return Number(width) - sidebarWidth;
|
|
126
|
+
};
|
|
127
|
+
|
|
118
128
|
export const PlayerWrapper = (props: Props) => {
|
|
119
129
|
const {
|
|
120
130
|
entry,
|
|
@@ -126,6 +136,7 @@ export const PlayerWrapper = (props: Props) => {
|
|
|
126
136
|
children,
|
|
127
137
|
isTabletPortrait,
|
|
128
138
|
configuration,
|
|
139
|
+
pip,
|
|
129
140
|
} = props;
|
|
130
141
|
|
|
131
142
|
const isTablet = useIsTablet();
|
|
@@ -136,40 +147,38 @@ export const PlayerWrapper = (props: Props) => {
|
|
|
136
147
|
|
|
137
148
|
const tabletWidth = getTabletWidth(configuration, style);
|
|
138
149
|
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
const containerDimensions: Dimensions = React.useMemo(
|
|
150
|
+
const baseDimensions: DimensionsT = React.useMemo(
|
|
142
151
|
() => ({
|
|
143
152
|
width:
|
|
144
|
-
isInlineModal && !docked && isTabletLandscape
|
|
145
|
-
|
|
146
|
-
: style.width,
|
|
147
|
-
height:
|
|
148
|
-
isInlineModal && !docked
|
|
149
|
-
? defaultAspectRatioHeight(
|
|
150
|
-
isTabletLandscape ? tabletWidth : screenWidth
|
|
151
|
-
)
|
|
152
|
-
: style.height,
|
|
153
|
+
isInlineModal && !docked && isTabletLandscape ? tabletWidth : "100%",
|
|
154
|
+
height: isInlineModal && docked ? style.height : undefined,
|
|
153
155
|
}),
|
|
154
|
-
[isInlineModal,
|
|
156
|
+
[isInlineModal, tabletWidth, style.height, docked]
|
|
155
157
|
);
|
|
156
158
|
|
|
157
|
-
const playerDimensions:
|
|
159
|
+
const playerDimensions: DimensionsT = React.useMemo(
|
|
158
160
|
() => ({
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
161
|
+
...baseDimensions,
|
|
162
|
+
width: isInlineModal && docked ? undefined : baseDimensions.width,
|
|
163
|
+
aspectRatio: !isInlineModal && !pip ? getScreenAspectRatio() : 16 / 9,
|
|
164
|
+
}),
|
|
165
|
+
[baseDimensions, isInlineModal, pip]
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
const containerDimensions: DimensionsT = React.useMemo(
|
|
169
|
+
() => ({
|
|
170
|
+
...baseDimensions,
|
|
171
|
+
aspectRatio:
|
|
172
|
+
isInlineModal && docked ? undefined : playerDimensions.aspectRatio,
|
|
164
173
|
}),
|
|
165
|
-
[isInlineModal, docked,
|
|
174
|
+
[baseDimensions, isInlineModal, docked, playerDimensions.aspectRatio]
|
|
166
175
|
);
|
|
167
176
|
|
|
168
177
|
const WrapperView = React.useMemo(() => (isTV() ? View : SafeAreaView), []);
|
|
169
178
|
|
|
170
179
|
const childrenStyles = React.useMemo(
|
|
171
180
|
() => ({ ...playerDimensions, ...playerDimesionsHack }),
|
|
172
|
-
[
|
|
181
|
+
[containerDimensions, playerDimesionsHack]
|
|
173
182
|
);
|
|
174
183
|
|
|
175
184
|
return (
|
|
@@ -190,12 +199,6 @@ export const PlayerWrapper = (props: Props) => {
|
|
|
190
199
|
defaultStyles.playerContainer,
|
|
191
200
|
containerDimensions,
|
|
192
201
|
containerStyle,
|
|
193
|
-
{
|
|
194
|
-
height:
|
|
195
|
-
isInlineModal && !docked
|
|
196
|
-
? containerDimensions.height + 10
|
|
197
|
-
: containerDimensions.height,
|
|
198
|
-
},
|
|
199
202
|
playerDimesionsHack,
|
|
200
203
|
]}
|
|
201
204
|
>
|
|
@@ -19,8 +19,6 @@ const props = {
|
|
|
19
19
|
|
|
20
20
|
const useIsTablet = jest.fn();
|
|
21
21
|
|
|
22
|
-
jest.mock("react-native");
|
|
23
|
-
|
|
24
22
|
jest.mock("../PlayerDetails", () => ({ PlayerDetails: View }));
|
|
25
23
|
|
|
26
24
|
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/device", () => ({
|
|
@@ -38,6 +36,7 @@ jest.mock("@applicaster/zapp-react-native-utils/reactUtils", () => ({
|
|
|
38
36
|
}));
|
|
39
37
|
|
|
40
38
|
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
|
|
39
|
+
isNavBarVisible: jest.fn(() => true),
|
|
41
40
|
useRoute: jest.fn(() => ({
|
|
42
41
|
pathname: "/river/testId",
|
|
43
42
|
})),
|
|
@@ -50,7 +49,7 @@ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
|
|
|
50
49
|
|
|
51
50
|
jest.mock("../utils", () => ({ playerDimesionsHack: {} }));
|
|
52
51
|
|
|
53
|
-
const { PlayerWrapper
|
|
52
|
+
const { PlayerWrapper } = require("../PlayerWrapper");
|
|
54
53
|
|
|
55
54
|
jest.useFakeTimers();
|
|
56
55
|
const children = jest.fn(() => {});
|
|
@@ -110,7 +109,8 @@ describe("PlayerWrapper", () => {
|
|
|
110
109
|
|
|
111
110
|
const expectDimensions = {
|
|
112
111
|
...dimensions,
|
|
113
|
-
width:
|
|
112
|
+
width: undefined,
|
|
113
|
+
aspectRatio: 16 / 9,
|
|
114
114
|
};
|
|
115
115
|
|
|
116
116
|
expect(element).toMatchSnapshot();
|