@applicaster/zapp-react-native-ui-components 12.0.0-rc.4 → 12.0.0-rc.40
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/Cell/Cell.tsx +2 -2
- package/Components/Cell/CellWithFocusable.tsx +21 -14
- package/Components/Cell/TvOSCellComponent.tsx +2 -2
- package/Components/ErrorScreen/index.tsx +1 -1
- package/Components/FocusableCell/index.tsx +7 -7
- 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 -6
- package/Components/Image/Image.android.tsx +11 -2
- package/Components/Image/Image.tsx +18 -2
- package/Components/Image/utils/index.ts +39 -0
- package/Components/Layout/TV/__tests__/index.test.tsx +1 -34
- 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/DefaultComponents/Image/Image.android.tsx +9 -26
- package/Components/MasterCell/DefaultComponents/Image/hooks/useImageSize.ts +65 -0
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +3 -1
- package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +3 -2
- package/Components/MasterCell/DefaultComponents/Toggle.tsx +5 -1
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +8 -10
- 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/PlayerContainer/PlayerContainer.tsx +52 -28
- package/Components/PlayerContainer/ProgramInfo/index.tsx +3 -1
- 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/__tests__/componentsMap.test.js +1 -0
- 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 +5 -3
- package/Components/Screen/__tests__/Screen.test.tsx +48 -36
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +20 -6
- package/Components/Screen/__tests__/navigationHandler.test.ts +1 -178
- package/Components/Screen/index.tsx +91 -43
- package/Components/Screen/navigationHandler.ts +0 -82
- package/Components/Screen/orientationHandler.ts +1 -1
- package/Components/ScreenResolver/index.tsx +1 -1
- package/Components/Tabs/TV/styles.ts +1 -1
- package/Components/TrackedView/index.tsx +6 -3
- package/Components/VideoLive/LiveImageManager.ts +42 -13
- package/Components/VideoLive/PlayerLiveImageComponent.tsx +81 -72
- package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +30 -3
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +22 -27
- 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 +202 -162
- 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/ComponentsMapWrapper/withComponentsMapProvider.tsx +7 -2
- package/Decorators/RiverResolver/index.tsx +0 -4
- package/Decorators/index.tsx +0 -4
- package/package.json +5 -6
|
@@ -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,14 +8,13 @@ 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,
|
|
16
14
|
} from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
17
15
|
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
|
|
18
16
|
import { getUserCellPlayerMutedPreference } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/userCellPlayerMutedPreference";
|
|
19
|
-
import
|
|
17
|
+
import Image from "@applicaster/zapp-react-native-ui-components/Components/MasterCell/DefaultComponents/Image";
|
|
20
18
|
import { LiveImage, LiveImageManager, LiveImageType } from "./LiveImageManager";
|
|
21
19
|
|
|
22
20
|
import { AnimatedInOut } from "@applicaster/zapp-react-native-ui-components/Components/AnimatedInOut";
|
|
@@ -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;
|
|
@@ -40,12 +39,13 @@ type Props = {
|
|
|
40
39
|
imageKey?: string;
|
|
41
40
|
screenConfig: Record<string, any>;
|
|
42
41
|
audioMutedByDefault?: boolean;
|
|
42
|
+
uri: string; // cover image url
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
const PlayerLiveImageComponent = (props: Props) => {
|
|
46
46
|
const dimensions = useDimensions("screen", { fullDimensions: true });
|
|
47
47
|
|
|
48
|
-
const { item, style, playerId
|
|
48
|
+
const { item, style, playerId } = props;
|
|
49
49
|
|
|
50
50
|
const timeoutRef = React.useRef<NodeJS.Timeout | null>(null);
|
|
51
51
|
const [mode, setMode] = React.useState(LiveImageType.Image);
|
|
@@ -55,20 +55,17 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
55
55
|
isTV() ? false : getUserCellPlayerMutedPreference(props.audioMutedByDefault)
|
|
56
56
|
);
|
|
57
57
|
|
|
58
|
-
const [PlayerViewComponent, setPlayerViewComponent] = React.useState(null);
|
|
59
|
-
const Player: any = PlayerViewComponent || BufferAnimation;
|
|
60
|
-
|
|
61
58
|
const ref = React.useRef(null);
|
|
62
59
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Debounced setMode function.
|
|
62
|
+
*
|
|
63
|
+
* Sets to video with a 1sec delay. Set to image happens immediately and cancels the timeout.
|
|
64
|
+
*
|
|
65
|
+
* @param type video or image
|
|
66
|
+
*/
|
|
67
|
+
const setModeDebounced = React.useCallback(
|
|
68
|
+
(type: LiveImageType) => {
|
|
72
69
|
if (type === LiveImageType.Video) {
|
|
73
70
|
if (type === mode) {
|
|
74
71
|
return;
|
|
@@ -80,45 +77,45 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
80
77
|
} else {
|
|
81
78
|
if (timeoutRef.current) {
|
|
82
79
|
clearTimeout(timeoutRef.current);
|
|
80
|
+
timeoutRef.current = null;
|
|
83
81
|
}
|
|
84
82
|
|
|
85
83
|
setMode(type);
|
|
86
84
|
}
|
|
87
|
-
}
|
|
85
|
+
},
|
|
86
|
+
[mode]
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const { screenConfig, playerPluginId } = props;
|
|
88
90
|
|
|
91
|
+
const liveImageItem: LiveImage = React.useMemo(() => {
|
|
89
92
|
const playerFactoryItem = playerFactory({
|
|
90
93
|
player: ref,
|
|
91
|
-
listener: props as Record<string, any>,
|
|
92
94
|
playerId,
|
|
93
95
|
autoplay: false,
|
|
94
96
|
entry: item,
|
|
95
|
-
muted,
|
|
96
|
-
playerPluginId:
|
|
97
|
-
screenConfig:
|
|
97
|
+
muted, // Initial muted state, not needed in dependencies
|
|
98
|
+
playerPluginId: playerPluginId,
|
|
99
|
+
screenConfig: screenConfig,
|
|
98
100
|
playerRole: PlayerRole.Cell,
|
|
99
101
|
});
|
|
100
102
|
|
|
101
|
-
const Component = playerFactoryItem?.Component;
|
|
102
|
-
|
|
103
|
-
if (!R.isNil(Component) && Component !== PlayerViewComponent) {
|
|
104
|
-
setPlayerViewComponent(Component);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
103
|
if (playerFactoryItem) {
|
|
108
104
|
return new LiveImage({
|
|
109
105
|
playerId,
|
|
110
106
|
player: playerFactoryItem.controller,
|
|
111
|
-
|
|
107
|
+
component: playerFactoryItem?.Component,
|
|
112
108
|
});
|
|
113
109
|
} else {
|
|
114
110
|
throw new Error("Player factory item is null");
|
|
115
111
|
}
|
|
116
|
-
}, [playerId, item
|
|
112
|
+
}, [playerId, item, playerPluginId, screenConfig]);
|
|
117
113
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
114
|
+
React.useEffect(() => {
|
|
115
|
+
liveImageItem.setMode = setModeDebounced;
|
|
116
|
+
}, [setModeDebounced, liveImageItem]);
|
|
117
|
+
|
|
118
|
+
const { start, end } = React.useMemo(() => getAutoplaySettings(item), [item]);
|
|
122
119
|
|
|
123
120
|
const controller = liveImageItem.getPlayer();
|
|
124
121
|
const player = usePlayer(playerId);
|
|
@@ -127,6 +124,10 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
127
124
|
ref.current = component;
|
|
128
125
|
};
|
|
129
126
|
|
|
127
|
+
const onLiveImageCompleted = React.useCallback(() => {
|
|
128
|
+
LiveImageManager.instance.onLiveImageCompleted(liveImageItem);
|
|
129
|
+
}, [liveImageItem]);
|
|
130
|
+
|
|
130
131
|
const onStop = React.useCallback(() => {
|
|
131
132
|
LiveImageManager.instance.pauseLiveImage(liveImageItem);
|
|
132
133
|
}, [liveImageItem]);
|
|
@@ -140,13 +141,14 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
140
141
|
const unregister = LiveImageManager.instance.register(liveImageItem);
|
|
141
142
|
|
|
142
143
|
return () => {
|
|
143
|
-
unregister();
|
|
144
|
-
|
|
145
144
|
if (timeoutRef.current) {
|
|
146
145
|
clearTimeout(timeoutRef.current);
|
|
146
|
+
timeoutRef.current = null;
|
|
147
147
|
}
|
|
148
|
+
|
|
149
|
+
unregister();
|
|
148
150
|
};
|
|
149
|
-
}, [
|
|
151
|
+
}, [item, liveImageItem]);
|
|
150
152
|
|
|
151
153
|
React.useEffect(() => {
|
|
152
154
|
if (!player) {
|
|
@@ -178,11 +180,12 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
178
180
|
setMuted(false);
|
|
179
181
|
},
|
|
180
182
|
onPlayerClose: () => {
|
|
183
|
+
onLiveImageCompleted();
|
|
181
184
|
setIsReady(false);
|
|
182
185
|
},
|
|
183
186
|
},
|
|
184
187
|
});
|
|
185
|
-
}, [player, onStop]);
|
|
188
|
+
}, [player, onStop, onLiveImageCompleted, start, end]);
|
|
186
189
|
|
|
187
190
|
React.useEffect(() => {
|
|
188
191
|
const subscription = AppState.addEventListener(
|
|
@@ -233,40 +236,48 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
233
236
|
};
|
|
234
237
|
}
|
|
235
238
|
}
|
|
236
|
-
}, [liveImageItem]);
|
|
237
|
-
|
|
238
|
-
const onPositionUpdated = (
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
239
|
+
}, [liveImageItem, playerId, controller]);
|
|
240
|
+
|
|
241
|
+
const onPositionUpdated = React.useCallback(
|
|
242
|
+
(data) => {
|
|
243
|
+
const normalizedRect = (rect: {
|
|
244
|
+
left: number;
|
|
245
|
+
right: number;
|
|
246
|
+
top: number;
|
|
247
|
+
bottom: number;
|
|
248
|
+
}) => {
|
|
249
|
+
if (!rect) {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
243
252
|
|
|
244
|
-
|
|
253
|
+
const { left, right, top, bottom } = rect;
|
|
245
254
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
255
|
+
return {
|
|
256
|
+
left: left / dimensions.width,
|
|
257
|
+
right: right / dimensions.width,
|
|
258
|
+
top: top / dimensions.height,
|
|
259
|
+
bottom: bottom / dimensions.height,
|
|
260
|
+
centerX: (left + right) / 2 / dimensions.width,
|
|
261
|
+
centerY: (top + bottom) / 2 / dimensions.height,
|
|
262
|
+
};
|
|
253
263
|
};
|
|
254
|
-
};
|
|
255
264
|
|
|
256
|
-
|
|
265
|
+
liveImageItem.position = normalizedRect(data.rect);
|
|
257
266
|
|
|
258
|
-
|
|
267
|
+
const newIsFullyVisible = !!data.rect;
|
|
259
268
|
|
|
260
|
-
|
|
261
|
-
|
|
269
|
+
if (liveImageItem.isFullyVisible !== newIsFullyVisible) {
|
|
270
|
+
liveImageItem.isFullyVisible = newIsFullyVisible;
|
|
262
271
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
272
|
+
liveImageItem.isFullyVisible
|
|
273
|
+
? LiveImageManager.instance.onViewportEnter(liveImageItem)
|
|
274
|
+
: LiveImageManager.instance.onViewportLeave(liveImageItem);
|
|
275
|
+
} else {
|
|
276
|
+
LiveImageManager.instance.checkPlayerPosition(liveImageItem);
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
[liveImageItem, dimensions]
|
|
280
|
+
);
|
|
270
281
|
|
|
271
282
|
const platformSpecificProps = isApplePlatform()
|
|
272
283
|
? { hideNativeControls: true, controls: false }
|
|
@@ -276,7 +287,9 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
276
287
|
const isVideoMode = mode === LiveImageType.Video;
|
|
277
288
|
const isBackgroundImageVisible = isImageMode || !isReadyToPlay;
|
|
278
289
|
const videoStyles = { ...style, position: "absolute", zIndex: -100 };
|
|
290
|
+
const Player: any = liveImageItem.component || BufferAnimation;
|
|
279
291
|
|
|
292
|
+
// TODO: nice to have - resolve imageKey when imageUrl is not provided
|
|
280
293
|
return (
|
|
281
294
|
<TrackedView
|
|
282
295
|
testId={`tracked-view-${playerId}-${item.title}`}
|
|
@@ -301,11 +314,7 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
301
314
|
animationConfig={overlayFadeIn}
|
|
302
315
|
staticStyles={style}
|
|
303
316
|
>
|
|
304
|
-
<
|
|
305
|
-
entry={item}
|
|
306
|
-
style={style}
|
|
307
|
-
imageKey={imageKey}
|
|
308
|
-
/>
|
|
317
|
+
<Image {...props} resizeMode="cover" style={style} applyMaxSize />
|
|
309
318
|
</AnimatedInOut>
|
|
310
319
|
}
|
|
311
320
|
</TrackedView>
|
|
@@ -3,6 +3,9 @@ import * as React from "react";
|
|
|
3
3
|
import { render } from "@testing-library/react-native";
|
|
4
4
|
import * as PlayerFactory from "@applicaster/zapp-react-native-utils/appUtils/playerManager/playerFactory";
|
|
5
5
|
import { Player } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/player";
|
|
6
|
+
import { ThemeContext } from "@applicaster/zapp-react-native-utils/theme";
|
|
7
|
+
import * as navigationHooks from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
|
|
8
|
+
|
|
6
9
|
import { PlayerLiveImage } from "../PlayerLiveImageComponent";
|
|
7
10
|
|
|
8
11
|
const seekTo = jest.fn();
|
|
@@ -16,6 +19,16 @@ jest.mock(
|
|
|
16
19
|
})
|
|
17
20
|
);
|
|
18
21
|
|
|
22
|
+
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation");
|
|
23
|
+
|
|
24
|
+
const Wrapper = ({ children }: { children: React.ReactChildren }) => (
|
|
25
|
+
<ThemeContext.Provider
|
|
26
|
+
value={{ themes: { myTheme: {} }, selectedThemeId: "myTheme" }}
|
|
27
|
+
>
|
|
28
|
+
{children}
|
|
29
|
+
</ThemeContext.Provider>
|
|
30
|
+
);
|
|
31
|
+
|
|
19
32
|
describe("PlayerLiveImageComponent", () => {
|
|
20
33
|
const defaultProps = {
|
|
21
34
|
item: { id: "1", title: "Test", type: { value: "" } },
|
|
@@ -36,10 +49,16 @@ describe("PlayerLiveImageComponent", () => {
|
|
|
36
49
|
controller: new Player({}),
|
|
37
50
|
Component: () => null,
|
|
38
51
|
}));
|
|
52
|
+
|
|
53
|
+
jest.spyOn(navigationHooks, "useIsScreenActive").mockReturnValue(true);
|
|
39
54
|
});
|
|
40
55
|
|
|
41
56
|
it("should render correctly with default props", () => {
|
|
42
|
-
const component = render(
|
|
57
|
+
const component = render(
|
|
58
|
+
<Wrapper>
|
|
59
|
+
<PlayerLiveImage {...defaultProps} />
|
|
60
|
+
</Wrapper>
|
|
61
|
+
);
|
|
43
62
|
|
|
44
63
|
expect(component.toJSON()).toMatchSnapshot();
|
|
45
64
|
});
|
|
@@ -53,7 +72,11 @@ describe("PlayerLiveImageComponent", () => {
|
|
|
53
72
|
},
|
|
54
73
|
};
|
|
55
74
|
|
|
56
|
-
render(
|
|
75
|
+
render(
|
|
76
|
+
<Wrapper>
|
|
77
|
+
<PlayerLiveImage {...props} />
|
|
78
|
+
</Wrapper>
|
|
79
|
+
);
|
|
57
80
|
|
|
58
81
|
// TODO: implement this test
|
|
59
82
|
});
|
|
@@ -67,7 +90,11 @@ describe("PlayerLiveImageComponent", () => {
|
|
|
67
90
|
},
|
|
68
91
|
};
|
|
69
92
|
|
|
70
|
-
render(
|
|
93
|
+
render(
|
|
94
|
+
<Wrapper>
|
|
95
|
+
<PlayerLiveImage {...props} />
|
|
96
|
+
</Wrapper>
|
|
97
|
+
);
|
|
71
98
|
|
|
72
99
|
// TODO: implement this test
|
|
73
100
|
});
|
|
@@ -13,35 +13,30 @@ exports[`PlayerLiveImageComponent should render correctly with default props 1`]
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
>
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
16
|
+
<Image
|
|
17
|
+
applyMaxSize={true}
|
|
18
|
+
audioMutedByDefault={false}
|
|
19
|
+
imageKey="image1"
|
|
20
|
+
item={
|
|
21
|
+
Object {
|
|
22
|
+
"id": "1",
|
|
23
|
+
"title": "Test",
|
|
24
|
+
"type": Object {
|
|
25
|
+
"value": "",
|
|
26
|
+
},
|
|
26
27
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
},
|
|
36
|
-
Object {
|
|
37
|
-
"height": undefined,
|
|
38
|
-
"width": undefined,
|
|
39
|
-
},
|
|
40
|
-
undefined,
|
|
41
|
-
]
|
|
28
|
+
}
|
|
29
|
+
onError={[Function]}
|
|
30
|
+
playerId="player1"
|
|
31
|
+
resizeMode="cover"
|
|
32
|
+
screenConfig={Object {}}
|
|
33
|
+
source={
|
|
34
|
+
Object {
|
|
35
|
+
"uri": "",
|
|
42
36
|
}
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
}
|
|
38
|
+
style={Object {}}
|
|
39
|
+
/>
|
|
45
40
|
</View>
|
|
46
41
|
</TrackedView>
|
|
47
42
|
`;
|
|
@@ -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();
|