@applicaster/zapp-react-native-ui-components 15.1.0-rc.8 → 15.1.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 (32) hide show
  1. package/Components/BackgroundImage/BackgroundImage.tv.android.tsx +28 -0
  2. package/Components/BackgroundImage/BackgroundImage.tv.ios.tsx +24 -0
  3. package/Components/BackgroundImage/BackgroundImage.tv.web.tsx +42 -0
  4. package/Components/BackgroundImage/index.ts +8 -0
  5. package/Components/CellRendererResolver/index.ts +1 -1
  6. package/Components/ComponentResolver/__tests__/componentResolver.test.js +1 -1
  7. package/Components/FocusableGroup/FocusableTvOS.tsx +11 -7
  8. package/Components/Layout/FullWidthRow.tsx +38 -0
  9. package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +0 -1
  10. package/Components/Layout/TV/index.tsx +2 -3
  11. package/Components/Layout/TV/index.web.tsx +2 -3
  12. package/Components/MasterCell/dataAdapter.ts +15 -5
  13. package/Components/MasterCell/index.tsx +10 -1
  14. package/Components/MasterCell/utils/__tests__/resolveColor.test.js +169 -132
  15. package/Components/MasterCell/utils/__tests__/resolveColorForProp.test.js +92 -0
  16. package/Components/MasterCell/utils/index.ts +89 -46
  17. package/Components/PlayerContainer/PlayerContainer.tsx +16 -12
  18. package/Components/PlayerContainer/__tests__/PlayerContainer.test.tsx +286 -0
  19. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +0 -15
  20. package/Components/Screen/index.tsx +8 -4
  21. package/Components/ScreenRevealManager/Overlay.tsx +34 -0
  22. package/Components/ScreenRevealManager/__tests__/Overlay.test.tsx +88 -0
  23. package/Components/ScreenRevealManager/withScreenRevealManager.tsx +8 -19
  24. package/Components/VideoModal/utils.ts +7 -1
  25. package/Components/ZappFrameworkComponents/BarView/BarView.tsx +9 -4
  26. package/Contexts/CachedDimensionsContext/index.ts +17 -2
  27. package/Helpers/ComponentCellSelectionHelper/index.js +0 -6
  28. package/Helpers/index.js +7 -40
  29. package/package.json +5 -5
  30. package/Components/Layout/TV/LayoutBackground.tsx +0 -28
  31. package/Components/Screen/utils.ts +0 -16
  32. package/Helpers/Analytics/index.js +0 -95
@@ -262,9 +262,14 @@ const PlayerContainerComponent = (props: Props) => {
262
262
 
263
263
  showNavBar(true);
264
264
  navigator.goBack();
265
- }, [isModal, navigator.goBack, state.playerId, showNavBar]);
265
+ }, [isModal, state.playerId, showNavBar, navigator]);
266
266
 
267
- const playEntry = (entry) => navigator.replaceTop(entry, { mode });
267
+ const pluginConfiguration = React.useMemo(
268
+ () => player?.getPluginConfiguration(),
269
+ [player]
270
+ );
271
+
272
+ const playEntry = (entry: ZappEntry) => navigator.replaceTop(entry, { mode });
268
273
 
269
274
  const onPlayNextPerformNextVideoPlay = React.useCallback(() => {
270
275
  if (!playNextOverlayState.entry) {
@@ -338,11 +343,15 @@ const PlayerContainerComponent = (props: Props) => {
338
343
  setIsLoadingNextVideo(false);
339
344
 
340
345
  const resumeTime = Number(item?.extensions?.resumeTime);
346
+ const activePlayer = playerManager.getActivePlayer();
341
347
 
342
- // Сhecking that the player itself knows where to start playing, and there is no need to call seekTo after returning from the Сhromecast
348
+ // Сhecking that the player itself knows where to start playing, and there is no need to call seekTo after returning from the Сhromecast.
349
+ // Live streams and a missing/zero resume position are skipped: seeking to 0 on
350
+ // a live stream pulls playback off the live edge into a buffer-starvation seek loop.
343
351
  if (
344
- !playerManager.getActivePlayer()?.hasResumePosition() &&
345
- !isNaN(resumeTime)
352
+ !activePlayer?.hasResumePosition() &&
353
+ resumeTime > 0 &&
354
+ !activePlayer?.isLive()
346
355
  ) {
347
356
  player?.seekTo(resumeTime);
348
357
  }
@@ -448,13 +457,6 @@ const PlayerContainerComponent = (props: Props) => {
448
457
  }
449
458
  }, []);
450
459
 
451
- const pluginConfiguration = React.useMemo(() => {
452
- return (
453
- playerManager.getPluginConfiguration() ||
454
- R.prop("__plugin_configuration", Player)
455
- );
456
- }, [playerManager.isRegistered()]);
457
-
458
460
  const disableMiniPlayer = React.useMemo(() => {
459
461
  return pluginConfiguration?.disable_mini_player_when_inline;
460
462
  }, [pluginConfiguration]);
@@ -467,6 +469,8 @@ const PlayerContainerComponent = (props: Props) => {
467
469
  if (isModal && mode === VideoModalMode.MAXIMIZED) {
468
470
  if (disableMiniPlayer) {
469
471
  navigator.closeVideoModal();
472
+ } else {
473
+ navigator.minimiseVideoModal();
470
474
  }
471
475
  }
472
476
 
@@ -0,0 +1,286 @@
1
+ import * as React from "react";
2
+ import { render } from "@testing-library/react-native";
3
+
4
+ jest.mock(
5
+ "@applicaster/zapp-react-native-utils/appUtils/playerManager",
6
+ () => ({
7
+ playerManager: {
8
+ invokeHandler: jest.fn(),
9
+ getPluginConfiguration: jest.fn(() => ({})),
10
+ isRegistered: jest.fn(() => true),
11
+ on: jest.fn().mockReturnThis(),
12
+ removeHandler: jest.fn().mockReturnThis(),
13
+ getActivePlayer: jest.fn(() => null),
14
+ closeNativePlayer: jest.fn(),
15
+ },
16
+ })
17
+ );
18
+
19
+ jest.mock("@applicaster/zapp-react-native-utils/reactUtils", () => ({
20
+ isTV: jest.fn(() => false),
21
+ isAndroidTVPlatform: jest.fn(() => false),
22
+ isTvOSPlatform: jest.fn(() => false),
23
+ platformSelect: jest.fn(({ native }) => native),
24
+ }));
25
+
26
+ jest.mock("@applicaster/zapp-react-native-utils/playerUtils", () => ({
27
+ isAudioItem: jest.fn(() => false),
28
+ isInlineTV: jest.fn(() => false),
29
+ }));
30
+
31
+ jest.mock(
32
+ "@applicaster/zapp-react-native-tvos-ui-components/Components/TVEventHandlerComponent",
33
+ () => ({
34
+ TVEventHandlerComponent: ({ children }) => children,
35
+ })
36
+ );
37
+
38
+ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/utils", () => ({
39
+ usePrevious: jest.fn(),
40
+ }));
41
+
42
+ jest.mock("@applicaster/zapp-react-native-utils/reactHooks", () => {
43
+ const navigator = {
44
+ closeVideoModal: jest.fn(),
45
+ minimiseVideoModal: jest.fn(),
46
+ maximiseVideoModal: jest.fn(),
47
+ fullscreenVideoModal: jest.fn(),
48
+ isVideoModalDocked: jest.fn(() => false),
49
+ goBack: jest.fn(),
50
+ replaceTop: jest.fn(),
51
+ push: jest.fn(),
52
+ setPlayNextOverlay: jest.fn(),
53
+ currentRoute: "/playable/entry-1",
54
+ };
55
+
56
+ const backHandlerRef: { current: (() => boolean) | null } = {
57
+ current: null,
58
+ };
59
+
60
+ return {
61
+ useBackHandler: jest.fn((cb) => {
62
+ backHandlerRef.current = cb;
63
+ }),
64
+ useNavigation: jest.fn(() => navigator),
65
+ __navigator: navigator,
66
+ __backHandlerRef: backHandlerRef,
67
+ };
68
+ });
69
+
70
+ jest.mock("@applicaster/zapp-react-native-bridge/QuickBrick", () => ({
71
+ QUICK_BRICK_EVENTS: {
72
+ IDLE_TIMER_DISABLED: "IDLE_TIMER_DISABLED",
73
+ MOVE_APP_TO_BACKGROUND: "MOVE_APP_TO_BACKGROUND",
74
+ },
75
+ sendQuickBrickEvent: jest.fn(),
76
+ }));
77
+
78
+ jest.mock("../ProgramInfo", () => ({
79
+ ProgramInfo: () => null,
80
+ }));
81
+
82
+ jest.mock("../../AudioPlayer", () => ({
83
+ AudioPlayer: () => null,
84
+ }));
85
+
86
+ jest.mock("../logger", () => ({
87
+ log_debug: jest.fn(),
88
+ log_info: jest.fn(),
89
+ log_warning: jest.fn(),
90
+ playerContainerLogger: { error: jest.fn() },
91
+ }));
92
+
93
+ jest.mock(
94
+ "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer",
95
+ () => {
96
+ const player = {
97
+ addListener: jest.fn(),
98
+ removeListener: jest.fn(),
99
+ isPaused: jest.fn(() => false),
100
+ isAd: jest.fn(() => false),
101
+ seekTo: jest.fn(),
102
+ getPluginConfiguration: jest.fn(() => ({})),
103
+ getOverlayObservable: jest.fn(() => ({ getPlayNextEntry: () => null })),
104
+ };
105
+
106
+ return {
107
+ usePlayer: jest.fn(() => player),
108
+ __player: player,
109
+ };
110
+ }
111
+ );
112
+
113
+ jest.mock(
114
+ "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayNextOverlay",
115
+ () => ({
116
+ usePlayNextOverlay: jest.fn(() => null),
117
+ })
118
+ );
119
+
120
+ jest.mock(
121
+ "@applicaster/zapp-react-native-utils/appUtils/playerManager/playerNativeCommand",
122
+ () => ({
123
+ PlayerNativeCommandTypes: { clearPlayerData: "clearPlayerData" },
124
+ PlayerNativeSendCommand: jest.fn(),
125
+ })
126
+ );
127
+
128
+ jest.mock(
129
+ "@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenContext",
130
+ () => ({
131
+ useSetNavbarState: jest.fn(() => ({ setVisible: jest.fn() })),
132
+ })
133
+ );
134
+
135
+ jest.mock(
136
+ "@applicaster/zapp-react-native-utils/reactHooks/screen/useTargetScreenData",
137
+ () => ({
138
+ useTargetScreenData: jest.fn(() => ({ id: "screen-id", styles: {} })),
139
+ })
140
+ );
141
+
142
+ jest.mock("../PlayerContainerContext", () => {
143
+ const ReactActual = require("react");
144
+
145
+ return {
146
+ PlayerContainerContext: ReactActual.createContext({
147
+ isLanguageOverlayVisible: false,
148
+ bottomFocusableId: "bottom",
149
+ showComponentsContainer: false,
150
+ refs: null,
151
+ }),
152
+ PlayerContainerContextProvider: ({ children }) => children,
153
+ };
154
+ });
155
+
156
+ jest.mock(
157
+ "@applicaster/zapp-react-native-ui-components/Components/FocusableGroup",
158
+ () => ({
159
+ FocusableGroup: ({ children }) => children,
160
+ })
161
+ );
162
+
163
+ jest.mock("../WappersView/PlayerFocusableWrapperView", () => ({
164
+ PlayerFocusableWrapperView: ({ children }) => children,
165
+ }));
166
+
167
+ jest.mock("../WappersView/ComponentFocusableWrapperView", () => ({
168
+ ComponentFocusableWrapperView: () => null,
169
+ }));
170
+
171
+ jest.mock("../index", () => ({
172
+ FocusableGroupMainContainerId: "player-container-general",
173
+ }));
174
+
175
+ jest.mock(
176
+ "@applicaster/zapp-react-native-utils/navigationUtils/itemTypeMatchers",
177
+ () => ({
178
+ isPlayable: jest.fn(() => true),
179
+ })
180
+ );
181
+
182
+ jest.mock("../../GeneralContentScreen", () => ({
183
+ GeneralContentScreen: () => null,
184
+ }));
185
+
186
+ jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
187
+ usePickFromState: jest.fn(() => ({
188
+ appData: { isTabletPortrait: false },
189
+ })),
190
+ }));
191
+
192
+ import { PlayerContainer, VideoModalMode } from "../PlayerContainer";
193
+
194
+ const { __navigator: mockNavigator, __backHandlerRef: mockBackHandlerRef } =
195
+ jest.requireMock("@applicaster/zapp-react-native-utils/reactHooks");
196
+
197
+ const { playerManager: mockPlayerManager } = jest.requireMock(
198
+ "@applicaster/zapp-react-native-utils/appUtils/playerManager"
199
+ );
200
+
201
+ const { __player: mockPlayer } = jest.requireMock(
202
+ "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer"
203
+ );
204
+
205
+ const Player = React.forwardRef(() => null);
206
+
207
+ const item = {
208
+ id: "entry-1",
209
+ title: "Test entry",
210
+ summary: "",
211
+ content: { src: "https://example.com/video.m3u8" },
212
+ extensions: {},
213
+ } as any;
214
+
215
+ const renderPlayerContainer = (props = {}) =>
216
+ render(
217
+ <PlayerContainer
218
+ Player={Player}
219
+ item={item}
220
+ style={{}}
221
+ loadPipesData={jest.fn()}
222
+ isModal={true}
223
+ mode={VideoModalMode.MAXIMIZED}
224
+ {...props}
225
+ />
226
+ );
227
+
228
+ const pressHardwareBack = () => {
229
+ if (!mockBackHandlerRef.current) {
230
+ throw new Error("back handler was not registered via useBackHandler");
231
+ }
232
+
233
+ return mockBackHandlerRef.current();
234
+ };
235
+
236
+ describe("PlayerContainer hardware back handling", () => {
237
+ beforeEach(() => {
238
+ jest.clearAllMocks();
239
+ mockBackHandlerRef.current = null;
240
+ mockPlayer.getPluginConfiguration.mockReturnValue({});
241
+ mockPlayer.isPaused.mockReturnValue(false);
242
+ mockPlayer.isAd.mockReturnValue(false);
243
+
244
+ mockPlayer.getOverlayObservable.mockReturnValue({
245
+ getPlayNextEntry: () => null,
246
+ });
247
+
248
+ mockPlayerManager.getPluginConfiguration.mockReturnValue({});
249
+ mockPlayerManager.on.mockReturnThis();
250
+ mockPlayerManager.removeHandler.mockReturnThis();
251
+ });
252
+
253
+ it("minimises the video modal on back press when mini player is enabled", () => {
254
+ renderPlayerContainer();
255
+
256
+ const handled = pressHardwareBack();
257
+
258
+ expect(mockNavigator.minimiseVideoModal).toHaveBeenCalled();
259
+ expect(mockNavigator.closeVideoModal).not.toHaveBeenCalled();
260
+ expect(handled).toBe(true);
261
+ });
262
+
263
+ it("closes the video modal on back press when mini player is disabled", () => {
264
+ mockPlayer.getPluginConfiguration.mockReturnValue({
265
+ disable_mini_player_when_inline: true,
266
+ });
267
+
268
+ renderPlayerContainer();
269
+
270
+ const handled = pressHardwareBack();
271
+
272
+ expect(mockNavigator.closeVideoModal).toHaveBeenCalled();
273
+ expect(mockNavigator.minimiseVideoModal).not.toHaveBeenCalled();
274
+ expect(handled).toBe(true);
275
+ });
276
+
277
+ it("does not handle back press when the player is already minimised", () => {
278
+ renderPlayerContainer({ mode: VideoModalMode.MINIMIZED });
279
+
280
+ const handled = pressHardwareBack();
281
+
282
+ expect(handled).toBe(false);
283
+ expect(mockNavigator.minimiseVideoModal).not.toHaveBeenCalled();
284
+ expect(mockNavigator.closeVideoModal).not.toHaveBeenCalled();
285
+ });
286
+ });
@@ -10,11 +10,6 @@ exports[`componentsMap renders renders components map correctly 1`] = `
10
10
  >
11
11
  <View
12
12
  onLayout={[Function]}
13
- style={
14
- {
15
- "flex": 1,
16
- }
17
- }
18
13
  >
19
14
  <RCTScrollView
20
15
  ListFooterComponent={
@@ -166,11 +161,6 @@ exports[`componentsMap renders renders components map correctly 1`] = `
166
161
  >
167
162
  <View
168
163
  onLayout={[Function]}
169
- style={
170
- {
171
- "flex": 1,
172
- }
173
- }
174
164
  >
175
165
  <View />
176
166
  </View>
@@ -182,11 +172,6 @@ exports[`componentsMap renders renders components map correctly 1`] = `
182
172
  >
183
173
  <View
184
174
  onLayout={[Function]}
185
- style={
186
- {
187
- "flex": 1,
188
- }
189
- }
190
175
  />
191
176
  </View>
192
177
  <View
@@ -19,10 +19,13 @@ import {
19
19
  useScreenData,
20
20
  } from "@applicaster/zapp-react-native-utils/reactHooks";
21
21
  import { getNavigationPluginModule } from "@applicaster/zapp-react-native-app/App/Layout/layoutHelpers";
22
+ import {
23
+ isValidColor,
24
+ isTransparentColor,
25
+ } from "@applicaster/zapp-react-native-utils/colorUtils";
22
26
 
23
27
  import { RouteManager } from "../RouteManager";
24
28
  import { useScreenConfiguration } from "../River/useScreenConfiguration";
25
- import { isValidColor } from "./utils";
26
29
  import { useWaitForValidOrientation } from "./hooks";
27
30
 
28
31
  const screenStyles = {
@@ -83,9 +86,10 @@ export function Screen(_props: Props) {
83
86
  const style = React.useMemo(
84
87
  () => ({
85
88
  ...screenStyles,
86
- backgroundColor: isValidColor(backgroundColor)
87
- ? backgroundColor
88
- : theme.app_background_color,
89
+ backgroundColor:
90
+ isValidColor(backgroundColor) && !isTransparentColor(backgroundColor)
91
+ ? backgroundColor
92
+ : theme.app_background_color,
89
93
  }),
90
94
  [theme.app_background_color, backgroundColor]
91
95
  );
@@ -0,0 +1,34 @@
1
+ import * as React from "react";
2
+ import { Animated, StyleSheet } from "react-native";
3
+
4
+ import { BackgroundImage } from "@applicaster/zapp-react-native-ui-components/Components/BackgroundImage";
5
+
6
+ const styles = StyleSheet.create({
7
+ container: {
8
+ ...StyleSheet.absoluteFillObject,
9
+ position: "absolute",
10
+ },
11
+ });
12
+
13
+ export const Overlay = ({
14
+ opacity,
15
+ backgroundColor,
16
+ }: {
17
+ opacity: Animated.Value;
18
+ backgroundColor: string;
19
+ }) => {
20
+ return (
21
+ <Animated.View
22
+ style={[
23
+ styles.container,
24
+ {
25
+ opacity,
26
+ backgroundColor,
27
+ },
28
+ ]}
29
+ testID="animated-component"
30
+ >
31
+ <BackgroundImage />
32
+ </Animated.View>
33
+ );
34
+ };
@@ -0,0 +1,88 @@
1
+ import React from "react";
2
+ import { Animated } from "react-native";
3
+ import { render } from "@testing-library/react-native";
4
+
5
+ jest.mock(
6
+ "@applicaster/zapp-react-native-ui-components/Components/BackgroundImage",
7
+ () => {
8
+ const { Text } = require("react-native");
9
+
10
+ return {
11
+ BackgroundImage: () => (
12
+ <Text testID="background-image">BackgroundImage</Text>
13
+ ),
14
+ };
15
+ }
16
+ );
17
+
18
+ import { Overlay } from "../Overlay";
19
+
20
+ const flattenStyle = (style: unknown): Record<string, unknown> => {
21
+ if (!style) {
22
+ return {};
23
+ }
24
+
25
+ if (Array.isArray(style)) {
26
+ return style.reduce<Record<string, unknown>>(
27
+ (acc, item) => ({ ...acc, ...flattenStyle(item) }),
28
+ {}
29
+ );
30
+ }
31
+
32
+ if (typeof style === "object") {
33
+ return style as Record<string, unknown>;
34
+ }
35
+
36
+ return {};
37
+ };
38
+
39
+ describe("Overlay", () => {
40
+ it("renders the animated overlay container", () => {
41
+ const opacity = new Animated.Value(1);
42
+
43
+ const { getByTestId } = render(
44
+ <Overlay opacity={opacity} backgroundColor="#000000" />
45
+ );
46
+
47
+ expect(getByTestId("animated-component")).toBeTruthy();
48
+ });
49
+
50
+ it("applies opacity and backgroundColor to the overlay", () => {
51
+ const opacity = new Animated.Value(0.5);
52
+
53
+ const { getByTestId } = render(
54
+ <Overlay opacity={opacity} backgroundColor="#ff0000" />
55
+ );
56
+
57
+ const style = flattenStyle(getByTestId("animated-component").props.style);
58
+
59
+ expect(style.backgroundColor).toBe("#ff0000");
60
+ expect(style.opacity).toBe(0.5);
61
+ });
62
+
63
+ it("positions the overlay with absolute fill layout", () => {
64
+ const opacity = new Animated.Value(1);
65
+
66
+ const { getByTestId } = render(
67
+ <Overlay opacity={opacity} backgroundColor="#000000" />
68
+ );
69
+
70
+ const style = flattenStyle(getByTestId("animated-component").props.style);
71
+
72
+ expect(style.position).toBe("absolute");
73
+ expect(style.top).toBe(0);
74
+ expect(style.left).toBe(0);
75
+ expect(style.right).toBe(0);
76
+ expect(style.bottom).toBe(0);
77
+ });
78
+
79
+ it("renders BackgroundImage inside the overlay", () => {
80
+ const opacity = new Animated.Value(1);
81
+
82
+ const { getByTestId } = render(
83
+ <Overlay opacity={opacity} backgroundColor="#000000" />
84
+ );
85
+
86
+ expect(getByTestId("background-image")).toBeTruthy();
87
+ });
88
+ });
@@ -1,8 +1,10 @@
1
1
  import * as React from "react";
2
- import { Animated, StyleSheet } from "react-native";
2
+ import { Animated } from "react-native";
3
+
3
4
  import { isFirstComponentScreenPicker } from "@applicaster/zapp-react-native-utils/componentsUtils";
4
5
  import { useRefWithInitialValue } from "@applicaster/zapp-react-native-utils/reactHooks/state/useRefWithInitialValue";
5
6
  import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
7
+ import { Overlay } from "./Overlay";
6
8
 
7
9
  import { ScreenRevealManager } from "./ScreenRevealManager";
8
10
  import {
@@ -10,13 +12,6 @@ import {
10
12
  emitScreenRevealManagerIsNotReadyToShow,
11
13
  } from "./utils";
12
14
 
13
- const styles = StyleSheet.create({
14
- container: {
15
- ...StyleSheet.absoluteFillObject,
16
- position: "absolute",
17
- },
18
- });
19
-
20
15
  export const TIMEOUT = 300; // 300 ms
21
16
 
22
17
  const HIDDEN = 0; // opacity = 0
@@ -93,17 +88,11 @@ export const withScreenRevealManager = (Component) => {
93
88
  onLoadFailedFromScreenRevealManager={managerRef.current.onLoadFailed}
94
89
  />
95
90
  {isShowOverlay ? (
96
- <Animated.View
97
- style={[
98
- styles.container,
99
- {
100
- opacity: opacityRef.current,
101
- // TODO: we should support background image as well, but for now we will use background color from theme
102
- backgroundColor:
103
- props.backgroundColor ?? theme.app_background_color,
104
- },
105
- ]}
106
- testID="animated-component"
91
+ <Overlay
92
+ opacity={opacityRef.current}
93
+ backgroundColor={
94
+ props.backgroundColor ?? theme.app_background_color
95
+ }
107
96
  />
108
97
  ) : null}
109
98
  </>
@@ -5,6 +5,7 @@ import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/n
5
5
  import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks/device/useIsTablet";
6
6
  import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
7
7
  import { create } from "zustand";
8
+ import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer";
8
9
 
9
10
  export const useConfiguration = () => {
10
11
  const {
@@ -17,13 +18,18 @@ export const useConfiguration = () => {
17
18
  "pluginConfigurations",
18
19
  ]);
19
20
 
21
+ const player = usePlayer();
22
+
20
23
  const targetScreenId = contentTypes?.[item?.type?.value]?.screen_id;
21
24
  const targetScreenConfiguration = rivers?.[targetScreenId];
22
25
 
23
26
  const pluginConfiguration =
24
27
  pluginConfigurations[targetScreenConfiguration?.type]?.configuration_json;
25
28
 
26
- const playerPluginConfig = playerManager.getPluginConfiguration();
29
+ const playerPluginConfig =
30
+ player?.getPluginConfiguration() ??
31
+ playerManager.getInstanceController()?.getPluginConfiguration() ??
32
+ {};
27
33
 
28
34
  const config = mergeRight(playerPluginConfig, {
29
35
  ...pluginConfiguration,
@@ -1,11 +1,11 @@
1
1
  import React from "react";
2
- import { StyleSheet } from "react-native";
2
+ import { StyleSheet, SafeAreaView as RNSafeAreaView } from "react-native";
3
3
  import { SafeAreaView } from "react-native-safe-area-context";
4
-
5
4
  import { useIsRTL } from "@applicaster/zapp-react-native-utils/localizationUtils";
6
5
  import CloseButton from "./Buttons/CloseButton";
7
6
  import BackButton from "./Buttons/BackButton";
8
7
  import BarTitle from "./BarTitle";
8
+ import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
9
9
 
10
10
  type Props = {
11
11
  screenStyles: {
@@ -24,6 +24,11 @@ const defaultState: NavBarState = {
24
24
  title: "",
25
25
  };
26
26
 
27
+ const SafeAreaViewPlatform = platformSelect({
28
+ ios: RNSafeAreaView,
29
+ android: SafeAreaView,
30
+ });
31
+
27
32
  const BarView = ({ screenStyles, barState = defaultState }: Props) => {
28
33
  const isRTL = useIsRTL();
29
34
 
@@ -45,7 +50,7 @@ const BarView = ({ screenStyles, barState = defaultState }: Props) => {
45
50
  );
46
51
 
47
52
  return (
48
- <SafeAreaView
53
+ <SafeAreaViewPlatform
49
54
  edges={["top", "left", "right"]}
50
55
  style={[style.view, isRTL ? style.rtlStyle : {}]}
51
56
  testID="BarView-safeAreaView"
@@ -53,7 +58,7 @@ const BarView = ({ screenStyles, barState = defaultState }: Props) => {
53
58
  {backButton}
54
59
  <BarTitle title={barState.title} screenStyles={screenStyles} />
55
60
  {closeButton}
56
- </SafeAreaView>
61
+ </SafeAreaViewPlatform>
57
62
  );
58
63
  };
59
64