@applicaster/zapp-react-native-ui-components 16.0.0-alpha.9225550512 → 16.0.0-alpha.9506982263

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.
@@ -1,15 +1,85 @@
1
- import {
2
- toFiniteNumberWithDefault,
3
- toNumber,
4
- } from "@applicaster/zapp-react-native-utils/numberUtils";
1
+ import { toFiniteNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
5
2
  import { isNil } from "ramda";
3
+ import { coreLogger } from "@applicaster/zapp-react-native-utils/logger";
6
4
 
7
- const dimensionRegex = /\b(width|height)=(\d+)\b/gi;
5
+ const imageResizingLogger = coreLogger
6
+ ?.addSubsystem("components")
7
+ ?.addSubsystem("ImageResizing");
8
8
 
9
+ const TEMPLATE_REGEX = /{{(width|height)}}/gi;
10
+ const UNRESOLVED_PLACEHOLDER_REGEX = /{{[^}]*}}?/;
11
+ const INVALID_PLACEHOLDER_EXTRACT_REGEX = /{{([^}]*)}}?/g;
12
+ const ALLOWED_PLACEHOLDERS = ["width", "height"];
13
+
14
+ /**
15
+ * Merges query-param string `paramsString` into `baseUrl`.
16
+ * Params from `paramsString` override any existing params with the same key.
17
+ */
18
+ export const mergeQueryParams = (
19
+ baseUrl: string,
20
+ paramsString: string
21
+ ): string => {
22
+ try {
23
+ const urlObj = new URL(baseUrl);
24
+ const newParams = new URLSearchParams(paramsString);
25
+
26
+ newParams.forEach((value, key) => {
27
+ urlObj.searchParams.set(key, value);
28
+ });
29
+
30
+ return urlObj.toString();
31
+ } catch {
32
+ // If URL parsing fails, return original
33
+ return baseUrl;
34
+ }
35
+ };
36
+
37
+ /**
38
+ * Extracts unresolved placeholder names from a param pair and logs a warning.
39
+ */
40
+ const logInvalidPlaceholders = (pair: string): void => {
41
+ const invalidNames: string[] = [];
42
+ let match: RegExpExecArray | null;
43
+
44
+ // Reset lastIndex before using the global regex
45
+ INVALID_PLACEHOLDER_EXTRACT_REGEX.lastIndex = 0;
46
+
47
+ while ((match = INVALID_PLACEHOLDER_EXTRACT_REGEX.exec(pair)) !== null) {
48
+ const name = match[1];
49
+
50
+ if (!ALLOWED_PLACEHOLDERS.includes(name?.toLowerCase())) {
51
+ invalidNames.push(name);
52
+ }
53
+ }
54
+
55
+ if (invalidNames.length > 0) {
56
+ imageResizingLogger?.warning({
57
+ message: `Image resizing: invalid placeholder(s) found: ${invalidNames.map((n) => `{{${n}}}`).join(", ")}. Allowed placeholders are: {{width}}, {{height}}. The param "${pair}" was ignored.`,
58
+ data: { pair, invalidNames, allowedPlaceholders: ALLOWED_PLACEHOLDERS },
59
+ });
60
+ }
61
+ };
62
+
63
+ /**
64
+ * Parses a dimension mapping template string (query param format) and injects
65
+ * the resolved width/height values into the given URL.
66
+ *
67
+ * The template uses `{{width}}` and `{{height}}` placeholders.
68
+ * It is treated as query-param key=value pairs (e.g. "w={{width}}&h={{height}}"
69
+ * or "size={{width}}x{{height}}").
70
+ *
71
+ * Resolved params are **merged** into the original URL – existing params with
72
+ * the same key are replaced; new ones are appended.
73
+ *
74
+ * Invalid mappings (containing unresolved placeholders like `{{heit}}` or
75
+ * malformed `{{heit}`) are silently dropped and logged as warnings.
76
+ * A leading `?` in the template is stripped.
77
+ */
9
78
  export const withDimensions = (
10
79
  url: Option<string>,
11
80
  width: Option<number | string>,
12
- height: Option<number | string>
81
+ height: Option<number | string>,
82
+ dimensionMappingTemplate?: Option<string>
13
83
  ) => {
14
84
  if (isNil(url)) {
15
85
  return url;
@@ -22,23 +92,48 @@ export const withDimensions = (
22
92
  const newWidth = Math.trunc(toFiniteNumberWithDefault(0, width));
23
93
  const newHeight = Math.trunc(toFiniteNumberWithDefault(0, height));
24
94
 
25
- return url.replace(dimensionRegex, (match, name, originalValue) => {
26
- if (name.toLocaleLowerCase() === "width" && newWidth > 0) {
27
- const originalWidth = toNumber(originalValue);
95
+ if (newWidth <= 0 && newHeight <= 0) {
96
+ return url;
97
+ }
98
+
99
+ // Strip leading `?` and whitespace from the template
100
+ const template = dimensionMappingTemplate?.trim()?.replace(/^\?/, "");
28
101
 
29
- if (originalWidth > 0 && originalWidth > newWidth) {
30
- return `${name}=${newWidth}`;
31
- }
32
- }
102
+ if (!template) {
103
+ return url;
104
+ }
33
105
 
34
- if (name.toLocaleLowerCase() === "height" && newHeight > 0) {
35
- const originalHeight = toNumber(originalValue);
106
+ // Replace {{width}} / {{height}} placeholders in the template
107
+ const resolvedTemplate = template.replace(TEMPLATE_REGEX, (_match, name) => {
108
+ if (name.toLowerCase() === "width") {
109
+ return newWidth > 0 ? String(newWidth) : _match;
110
+ }
36
111
 
37
- if (originalHeight > 0 && originalHeight > newHeight) {
38
- return `${name}=${newHeight}`;
39
- }
112
+ if (name.toLowerCase() === "height") {
113
+ return newHeight > 0 ? String(newHeight) : _match;
40
114
  }
41
115
 
42
- return match;
116
+ return _match;
43
117
  });
118
+
119
+ // Filter out param pairs that still contain unresolved / malformed placeholders
120
+ const cleanedParams = resolvedTemplate
121
+ .split("&")
122
+ .filter((pair) => {
123
+ if (UNRESOLVED_PLACEHOLDER_REGEX.test(pair)) {
124
+ logInvalidPlaceholders(pair);
125
+
126
+ return false;
127
+ }
128
+
129
+ return true;
130
+ })
131
+ .join("&");
132
+
133
+ if (!cleanedParams) {
134
+ return url;
135
+ }
136
+
137
+ // Parse the resolved template as query params and merge into URL
138
+ return mergeQueryParams(url, cleanedParams);
44
139
  };
@@ -14,25 +14,36 @@ type Style = {
14
14
  height: Option<number | string>;
15
15
  };
16
16
 
17
- const withAppliedDimensions = (style: Style) => (source: Source) => ({
18
- ...source,
19
- uri: withDimensions(source?.uri, style?.width, style?.height),
20
- });
17
+ const withAppliedDimensions =
18
+ (style: Style, dimensionMappingTemplate: string) => (source: Source) => ({
19
+ ...source,
20
+ uri: withDimensions(
21
+ source?.uri,
22
+ style?.width,
23
+ style?.height,
24
+ dimensionMappingTemplate
25
+ ),
26
+ });
21
27
 
22
28
  export const withDimensionsHOC = (Component) => {
23
29
  return function WithDimensions(props: Record<string, unknown>) {
24
30
  const theme = useTheme<BaseThemePropertiesMobile>();
25
31
 
26
- const useDownScalingImages = toBooleanWithDefaultFalse(
27
- theme.use_downscaling_images
32
+ const useImageResizing = toBooleanWithDefaultFalse(
33
+ theme.use_image_resizing ?? theme.use_downscaling_images
28
34
  );
29
35
 
36
+ const dimensionMappingTemplate = theme.image_resizing_template;
37
+
30
38
  return (
31
39
  <Component
32
40
  {...props}
33
41
  withDimensions={
34
- useDownScalingImages
35
- ? withAppliedDimensions((props?.style || {}) as Style)
42
+ useImageResizing
43
+ ? withAppliedDimensions(
44
+ (props?.style || {}) as Style,
45
+ dimensionMappingTemplate
46
+ )
36
47
  : identity
37
48
  }
38
49
  />
@@ -0,0 +1,33 @@
1
+ import React from "react";
2
+ import { PanGestureHandler } from "react-native-gesture-handler";
3
+ import { View } from "react-native";
4
+ import { useBottomSheet } from "@applicaster/zapp-react-native-utils/bottomSheet";
5
+
6
+ /**
7
+ * Turns its children into a drag zone for the enclosing DraggableBottomSheet:
8
+ * dragging here moves/dismisses the sheet (used for the modal header bar).
9
+ * Outside a sheet (no context) it renders children unchanged.
10
+ */
11
+ export const BottomSheetDragArea = ({
12
+ children,
13
+ }: {
14
+ children: React.ReactElement;
15
+ }) => {
16
+ const sheet = useBottomSheet();
17
+
18
+ // Outside a sheet (no context) render children unchanged.
19
+ if (!sheet) return children;
20
+
21
+ return (
22
+ <PanGestureHandler
23
+ simultaneousHandlers={[sheet.masterDrawerRef]}
24
+ shouldCancelWhenOutside={false}
25
+ onGestureEvent={sheet.onDragGestureEvent}
26
+ onHandlerStateChange={sheet.onDragStateChange}
27
+ >
28
+ {/* Old-API PanGestureHandler needs a host-component child; children may
29
+ be a function component (e.g. ModalHeader), so wrap in a View. */}
30
+ <View>{children}</View>
31
+ </PanGestureHandler>
32
+ );
33
+ };
@@ -6,11 +6,11 @@ import { ItemProps } from "./Button/Item";
6
6
  import { ItemLabelProps } from "./Button/ItemLabel";
7
7
  import { getItemIconProps, getItemLabelProps, getItemProps } from "./utils";
8
8
  import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
9
-
10
9
  import type { PluginConfiguration } from "./";
11
10
 
12
11
  import { ModalHeader as DefaultModalHeader } from "./Header";
13
12
  import { useSafeAreaInsets } from "react-native-safe-area-context";
13
+ import { BottomSheetDragArea } from "./BottomSheetDragArea";
14
14
 
15
15
  type ModalComponentProps = {
16
16
  items: any[];
@@ -55,8 +55,7 @@ export function BottomSheetModalContent(props: ModalComponentProps) {
55
55
  dismiss,
56
56
  summary,
57
57
  title,
58
- headerComponent: ModalHeader = DefaultModalHeader,
59
-
58
+ headerComponent = DefaultModalHeader,
60
59
  scrollViewContent = null,
61
60
 
62
61
  buttonComponent: ButtonComponent = Button,
@@ -72,6 +71,8 @@ export function BottomSheetModalContent(props: ModalComponentProps) {
72
71
  const paddingTop = Number(theme.modal_bottom_sheet_padding_top);
73
72
  const paddingBottom = Number(theme.modal_bottom_sheet_padding_bottom);
74
73
 
74
+ const Header = headerComponent;
75
+
75
76
  useEffect(() => {
76
77
  if (currentRoute !== route.current) {
77
78
  props.dismiss();
@@ -107,13 +108,20 @@ export function BottomSheetModalContent(props: ModalComponentProps) {
107
108
  paddingTop: paddingTop,
108
109
  }}
109
110
  >
110
- <ModalHeader
111
- dismiss={dismiss}
112
- configuration={theme}
113
- summary={summary}
114
- title={title}
115
- />
111
+ {Header ? (
112
+ <BottomSheetDragArea>
113
+ <Header
114
+ dismiss={dismiss}
115
+ configuration={theme}
116
+ summary={summary}
117
+ title={title}
118
+ />
119
+ </BottomSheetDragArea>
120
+ ) : null}
116
121
  <ScrollView
122
+ overScrollMode="never"
123
+ bounces={false}
124
+ showsVerticalScrollIndicator={false}
117
125
  contentContainerStyle={{
118
126
  paddingBottom: paddingBottom + bottomInset,
119
127
  }}
@@ -123,7 +131,6 @@ export function BottomSheetModalContent(props: ModalComponentProps) {
123
131
  scrollViewContent.renderItem(item, index)
124
132
  )
125
133
  : null}
126
-
127
134
  {!scrollViewContent &&
128
135
  items.map((item, index) =>
129
136
  item ? (
@@ -0,0 +1,74 @@
1
+ import React from "react";
2
+ import { Text } from "react-native";
3
+ import { render, screen } from "@testing-library/react-native";
4
+ import { BottomSheetDragArea } from "../BottomSheetDragArea";
5
+ import { BottomSheetContext } from "@applicaster/zapp-react-native-utils/bottomSheet";
6
+
7
+ // Reveal PanGestureHandler and capture its props.
8
+ jest.mock("react-native-gesture-handler", () => {
9
+ const { View } = require("react-native");
10
+ const actual = jest.requireActual("react-native-gesture-handler");
11
+
12
+ return {
13
+ __esModule: true,
14
+ ...actual,
15
+ PanGestureHandler: ({
16
+ children,
17
+ onGestureEvent,
18
+ onHandlerStateChange,
19
+ simultaneousHandlers,
20
+ }: any) => (
21
+ <View
22
+ testID="drag-pan"
23
+ onGestureEvent={onGestureEvent}
24
+ onHandlerStateChange={onHandlerStateChange}
25
+ simultaneousHandlers={simultaneousHandlers}
26
+ >
27
+ {children}
28
+ </View>
29
+ ),
30
+ };
31
+ });
32
+
33
+ const makeValue = () => ({
34
+ scrollRef: React.createRef<any>(),
35
+ masterDrawerRef: React.createRef<any>(),
36
+ drawerRef: React.createRef<any>(),
37
+ onScroll: jest.fn(),
38
+ setBodyDragEnabled: jest.fn(),
39
+ onDragGestureEvent: jest.fn(),
40
+ onDragStateChange: jest.fn(),
41
+ });
42
+
43
+ describe("BottomSheetDragArea", () => {
44
+ it("wraps children in a sheet-wired PanGestureHandler when inside a sheet", () => {
45
+ const value = makeValue();
46
+
47
+ render(
48
+ <BottomSheetContext.Provider value={value}>
49
+ <BottomSheetDragArea>
50
+ <Text testID="child">hi</Text>
51
+ </BottomSheetDragArea>
52
+ </BottomSheetContext.Provider>
53
+ );
54
+
55
+ const pan = screen.getByTestId("drag-pan");
56
+ expect(pan.props.onGestureEvent).toBe(value.onDragGestureEvent);
57
+ expect(pan.props.onHandlerStateChange).toBe(value.onDragStateChange);
58
+
59
+ expect(pan.props.simultaneousHandlers).toEqual([value.masterDrawerRef]);
60
+
61
+ expect(screen.getByTestId("child")).toBeTruthy();
62
+ });
63
+
64
+ it("renders children bare when used outside a sheet", () => {
65
+ render(
66
+ <BottomSheetDragArea>
67
+ <Text testID="child">hi</Text>
68
+ </BottomSheetDragArea>
69
+ );
70
+
71
+ expect(screen.queryByTestId("drag-pan")).toBeNull();
72
+ expect(screen.getByTestId("child")).toBeTruthy();
73
+ });
74
+ });
@@ -9,6 +9,7 @@ import {
9
9
  platformSelect,
10
10
  isAndroidTVPlatform,
11
11
  isTvOSPlatform,
12
+ isApplePlatform,
12
13
  } from "@applicaster/zapp-react-native-utils/reactUtils";
13
14
  import {
14
15
  isAudioItem,
@@ -60,6 +61,7 @@ import {
60
61
  PlayerNativeSendCommand,
61
62
  } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/playerNativeCommand";
62
63
  import { useAppData } from "@applicaster/zapp-react-native-redux";
64
+ import { PLAYER_EVENTS } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/const";
63
65
 
64
66
  type Props = {
65
67
  Player: React.ComponentType<any>;
@@ -188,12 +190,10 @@ const renderApplePlayer = ({
188
190
  return null;
189
191
  }
190
192
 
191
- const { title, summary } = item || {};
192
-
193
+ // Title/Subtitle are not resolved here: `ProgramInfo` reads them from the
194
+ // player manager's content channel via `usePlayerContent`.
193
195
  return (
194
196
  <ProgramInfo
195
- title={title}
196
- subtitle={summary}
197
197
  plugin_configuration={pluginConfiguration}
198
198
  videoStyle={videoStyle}
199
199
  />
@@ -282,12 +282,16 @@ const PlayerContainerComponent = (props: Props) => {
282
282
  }
283
283
 
284
284
  log_debug(
285
- `onPlayNextPerformNextVideoPlay: delay completed, replaceTop to item: ${playNextOverlayState.entry.title}, id: ${playNextOverlayState.entry.id}`
285
+ `onPlayNextPerformNextVideoPlay: delay completed, replaceTop to item: ${playNextOverlayState.entry.title}, id: ${playNextOverlayState.entry.id}, outgoing item id: ${item?.id}`
286
286
  );
287
287
 
288
+ playNextOverlayState.hidePlayNext();
289
+
290
+ playerEvent(PLAYER_EVENTS.PlayNextTriggered, { id: item?.id });
291
+
288
292
  setIsLoadingNextVideo(true);
289
293
  playEntry(playNextOverlayState.entry);
290
- }, [playNextOverlayState]);
294
+ }, [playNextOverlayState, item?.id]);
291
295
 
292
296
  const playNextData: Nullable<PlayNextData> = React.useMemo(() => {
293
297
  if (!playNextOverlayState) {
@@ -495,7 +499,7 @@ const PlayerContainerComponent = (props: Props) => {
495
499
  const isAudioContent = isAudioItem(item);
496
500
 
497
501
  useEffect(() => {
498
- if (!isAudioContent) {
502
+ if (!isAudioContent && isApplePlatform()) {
499
503
  sendQuickBrickEvent(
500
504
  QUICK_BRICK_EVENTS.IDLE_TIMER_DISABLED as QuickBrickEvent,
501
505
  {
@@ -7,12 +7,11 @@ import * as React from "react";
7
7
  import { Text, TextStyle, View, ViewStyle } from "react-native";
8
8
  import { QBImage as Image } from "@applicaster/zapp-react-native-ui-components/Components/Image";
9
9
 
10
+ import { usePlayerContent } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerContent";
10
11
  import * as programStyles from "./styles";
11
12
 
12
13
  type Props = {
13
14
  logo?: string;
14
- title: string;
15
- subtitle: string;
16
15
  isAudioContent: boolean;
17
16
  styles: {};
18
17
  plugin_configuration: {
@@ -28,13 +27,13 @@ const defaultColor = "#EFEFEF";
28
27
 
29
28
  function ProgramInfoComponent({
30
29
  logo,
31
- title = "",
32
- subtitle = "",
33
30
  isAudioContent,
34
31
  styles,
35
32
  plugin_configuration = {},
36
33
  videoStyle = {},
37
34
  }: Props) {
35
+ const { title = "", summary: subtitle = "" } = usePlayerContent();
36
+
38
37
  const platformKey = styleKeys.style_namespace;
39
38
 
40
39
  const colorTitle =
@@ -17,16 +17,37 @@ jest.mock(
17
17
  );
18
18
 
19
19
  jest.mock("@applicaster/zapp-react-native-utils/reactUtils", () => ({
20
+ // Defaults to `false` for the hardware-back-handling tests below, which
21
+ // key off `isTV`. The ProgramInfo/content-context describe block below
22
+ // overrides this per test (`isTV()` is also what PlayerContainer's
23
+ // `playerContentValue` uses to pick TV vs mobile data keys, decoupled
24
+ // from `isTvOSPlatform` below).
20
25
  isTV: jest.fn(() => false),
21
26
  isAndroidTVPlatform: jest.fn(() => false),
22
- isTvOSPlatform: jest.fn(() => false),
27
+ // `isTvOSPlatform` backs a module-level constant in PlayerContainer.tsx that
28
+ // is read once at import time, so it must already be `true` here in order
29
+ // to exercise `renderApplePlayer`'s tvOS-only ProgramInfo branch in this
30
+ // test file. It does not affect the hardware-back-handling tests below,
31
+ // which key off `isTV` instead.
32
+ isTvOSPlatform: jest.fn(() => true),
33
+ isApplePlatform: jest.fn(() => true),
23
34
  platformSelect: jest.fn(({ native }) => native),
24
35
  }));
25
36
 
26
- jest.mock("@applicaster/zapp-react-native-utils/playerUtils", () => ({
27
- isAudioItem: jest.fn(() => false),
28
- isInlineTV: jest.fn(() => false),
29
- }));
37
+ jest.mock("@applicaster/zapp-react-native-utils/playerUtils", () => {
38
+ // Keep the real data-key resolver (createConfigValueGetter,
39
+ // resolvePlayerContentText, VIDEO_PLAYER_CONTENT_DATA_KEYS) so the tvOS
40
+ // ProgramInfo data-key tests exercise actual resolution logic, not a stub.
41
+ const actual = jest.requireActual(
42
+ "@applicaster/zapp-react-native-utils/playerUtils"
43
+ );
44
+
45
+ return {
46
+ ...actual,
47
+ isAudioItem: jest.fn(() => false),
48
+ isInlineTV: jest.fn(() => false),
49
+ };
50
+ });
30
51
 
31
52
  jest.mock(
32
53
  "@applicaster/zapp-react-native-tvos-ui-components/Components/TVEventHandlerComponent",
@@ -75,6 +96,11 @@ jest.mock("@applicaster/zapp-react-native-bridge/QuickBrick", () => ({
75
96
  sendQuickBrickEvent: jest.fn(),
76
97
  }));
77
98
 
99
+ // Stubbed so PlayerContainer can render without ProgramInfo's own
100
+ // redux/style plumbing. It no longer needs to capture Title/Subtitle: those
101
+ // come from the player manager's content channel, and the key-set selection
102
+ // they depend on is covered directly in
103
+ // `playerManager/__tests__/playerContent.test.ts`.
78
104
  jest.mock("../ProgramInfo", () => ({
79
105
  ProgramInfo: () => null,
80
106
  }));
@@ -142,14 +168,33 @@ jest.mock(
142
168
  jest.mock("../PlayerContainerContext", () => {
143
169
  const ReactActual = require("react");
144
170
 
171
+ const PlayerContainerContext = ReactActual.createContext({
172
+ isLanguageOverlayVisible: false,
173
+ bottomFocusableId: "bottom",
174
+ showComponentsContainer: false,
175
+ refs: null,
176
+ });
177
+
145
178
  return {
146
- PlayerContainerContext: ReactActual.createContext({
147
- isLanguageOverlayVisible: false,
148
- bottomFocusableId: "bottom",
149
- showComponentsContainer: false,
150
- refs: null,
151
- }),
152
- PlayerContainerContextProvider: ({ children }) => children,
179
+ PlayerContainerContext,
180
+ // Mirrors just enough of the real provider for these tests: renders an
181
+ // actual `PlayerContainerContext.Provider` so the real
182
+ // `PlayerContainerContext.Consumer` inside PlayerContainer.tsx sees the
183
+ // container fields a real provider would give it, instead of a bare
184
+ // `({ children }) => children` passthrough.
185
+ PlayerContainerContextProvider: ({ children }: any) =>
186
+ ReactActual.createElement(
187
+ PlayerContainerContext.Provider,
188
+ {
189
+ value: {
190
+ isLanguageOverlayVisible: false,
191
+ bottomFocusableId: "bottom",
192
+ showComponentsContainer: false,
193
+ refs: null,
194
+ },
195
+ },
196
+ children
197
+ ),
153
198
  };
154
199
  });
155
200
 
@@ -200,7 +245,14 @@ const { __player: mockPlayer } = jest.requireMock(
200
245
  "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer"
201
246
  );
202
247
 
203
- const Player = React.forwardRef(() => null);
248
+ const { isTV: mockIsTV } = jest.requireMock(
249
+ "@applicaster/zapp-react-native-utils/reactUtils"
250
+ );
251
+
252
+ // Renders children so that `renderApplePlayer`'s returned <ProgramInfo>
253
+ // element (passed as this component's `children` prop) actually mounts —
254
+ // otherwise React never invokes the ProgramInfo function component at all.
255
+ const Player = React.forwardRef((props: any, _ref) => props.children ?? null);
204
256
 
205
257
  const item = {
206
258
  id: "entry-1",
@@ -234,6 +286,7 @@ const pressHardwareBack = () => {
234
286
  describe("PlayerContainer hardware back handling", () => {
235
287
  beforeEach(() => {
236
288
  jest.clearAllMocks();
289
+ mockIsTV.mockReturnValue(false);
237
290
  mockBackHandlerRef.current = null;
238
291
  mockPlayer.getPluginConfiguration.mockReturnValue({});
239
292
  mockPlayer.isPaused.mockReturnValue(false);
@@ -5,7 +5,7 @@ import {
5
5
  } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
6
6
  import { setUserCellPlayerMutedPreference } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/userCellPlayerMutedPreference";
7
7
  import { playerFactory } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/playerFactory";
8
- import { PlayerRole } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/conts";
8
+ import { PlayerRole } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/const";
9
9
  import { loggerLiveImageManager } from "./loggerHelper";
10
10
  import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
11
11
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "16.0.0-alpha.9225550512",
3
+ "version": "16.0.0-alpha.9506982263",
4
4
  "description": "Applicaster Zapp React Native ui components for the Quick Brick App",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -28,10 +28,10 @@
28
28
  },
29
29
  "homepage": "https://github.com/applicaster/quickbrick#readme",
30
30
  "dependencies": {
31
- "@applicaster/applicaster-types": "16.0.0-alpha.9225550512",
32
- "@applicaster/zapp-react-native-bridge": "16.0.0-alpha.9225550512",
33
- "@applicaster/zapp-react-native-redux": "16.0.0-alpha.9225550512",
34
- "@applicaster/zapp-react-native-utils": "16.0.0-alpha.9225550512",
31
+ "@applicaster/applicaster-types": "16.0.0-alpha.9506982263",
32
+ "@applicaster/zapp-react-native-bridge": "16.0.0-alpha.9506982263",
33
+ "@applicaster/zapp-react-native-redux": "16.0.0-alpha.9506982263",
34
+ "@applicaster/zapp-react-native-utils": "16.0.0-alpha.9506982263",
35
35
  "fast-json-stable-stringify": "^2.1.0",
36
36
  "promise": "^8.3.0",
37
37
  "url": "^0.11.0",