@applicaster/zapp-react-native-ui-components 14.0.0-alpha.1661204539 → 14.0.0-alpha.2332850672

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 (33) hide show
  1. package/Components/AudioPlayer/Artwork.tsx +17 -12
  2. package/Components/AudioPlayer/AudioPlayer.tsx +48 -11
  3. package/Components/AudioPlayer/AudioPlayerMobileLayout.tsx +61 -0
  4. package/Components/AudioPlayer/{AudioPlayerLayout.tsx → AudioPlayerTVLayout.tsx} +31 -72
  5. package/Components/AudioPlayer/Runtime.tsx +2 -1
  6. package/Components/AudioPlayer/Summary.tsx +12 -9
  7. package/Components/AudioPlayer/Title.tsx +12 -9
  8. package/Components/AudioPlayer/__tests__/__snapshots__/Runtime.test.js.snap +2 -2
  9. package/Components/AudioPlayer/__tests__/__snapshots__/artWork.test.js.snap +9 -4
  10. package/Components/AudioPlayer/__tests__/__snapshots__/{audioPlayerLayout.test.js.snap → audioPlayerMobileLayout.test.js.snap} +2 -2
  11. package/Components/AudioPlayer/__tests__/__snapshots__/summary.test.js.snap +1 -1
  12. package/Components/AudioPlayer/__tests__/__snapshots__/title.test.js.snap +1 -1
  13. package/Components/AudioPlayer/__tests__/audioPlayerMobileLayout.test.js +18 -0
  14. package/Components/AudioPlayer/helpers.tsx +2 -2
  15. package/Components/GeneralContentScreen/GeneralContentScreen.tsx +0 -2
  16. package/Components/MasterCell/DefaultComponents/Text/index.tsx +1 -0
  17. package/Components/MasterCell/utils/behaviorProvider.ts +12 -67
  18. package/Components/MasterCell/utils/index.ts +3 -13
  19. package/Components/PlayerContainer/PlayerContainer.tsx +24 -38
  20. package/Components/River/ComponentsMap/ComponentsMap.tsx +1 -5
  21. package/Components/River/RiverItem.tsx +8 -8
  22. package/Components/River/TV/River.tsx +0 -3
  23. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +0 -6
  24. package/Components/TopMarginApplicator/TopMarginApplicator.tsx +16 -15
  25. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +60 -0
  26. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +17 -55
  27. package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +15 -26
  28. package/Decorators/RiverFeedLoader/index.tsx +2 -8
  29. package/Decorators/RiverFeedLoader/utils/index.ts +2 -7
  30. package/Decorators/ZappPipesDataConnector/index.tsx +2 -16
  31. package/index.d.ts +0 -1
  32. package/package.json +5 -5
  33. package/Components/AudioPlayer/__tests__/audioPlayerLayout.test.js +0 -26
@@ -1,54 +1,28 @@
1
1
  import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
2
- import { StorageSingleValueProvider } from "@applicaster/zapp-react-native-utils/storage/StorageSingleSelectProvider";
2
+ import { StorageSingleValueProvider } from "@applicaster/zapp-react-native-bridge/ZappStorage/StorageSingleSelectProvider";
3
3
  import { PushTopicManager } from "@applicaster/zapp-react-native-bridge/PushNotifications/PushTopicManager";
4
- import { StorageMultiSelectProvider } from "@applicaster/zapp-react-native-utils/storage/StorageMultiSelectProvider";
4
+ import { StorageMultiSelectProvider } from "@applicaster/zapp-react-native-bridge/ZappStorage/StorageMultiSelectProvider";
5
5
  import React, { useEffect } from "react";
6
6
  import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer";
7
7
  import { BehaviorSubject } from "rxjs";
8
8
  import { masterCellLogger } from "../logger";
9
9
  import get from "lodash/get";
10
- import { ScreenMultiSelectProvider } from "@applicaster/zapp-react-native-utils/storage/ScreenStateMultiSelectProvider";
11
- import { ScreenSingleValueProvider } from "@applicaster/zapp-react-native-utils/storage/ScreenSingleValueProvider";
12
- import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks";
13
10
 
14
- const parseContextKey = (
15
- key: string,
16
- context: string = "ctx"
17
- ): string | null => {
18
- if (!key?.startsWith(`@{${context}/`)) return null;
11
+ const parseContextKey = (key: string): string | null => {
12
+ if (!key?.startsWith("@{ctx/")) return null;
19
13
 
20
- return key.substring(`@{${context}/`.length, key.length - 1);
14
+ return key.substring("@{ctx/".length, key.length - 1);
21
15
  };
22
16
 
23
17
  const getDataSourceProvider = (
24
- behavior: Behavior,
25
- screenRoute: string
18
+ behavior: Behavior
26
19
  ): BehaviorSubject<string[] | string> | null => {
27
20
  if (!behavior) return null;
28
21
 
29
22
  const selection = String(behavior.current_selection);
30
- const screenKey = parseContextKey(selection, "screen");
31
-
32
- if (screenKey) {
33
- if (behavior.select_mode === "multi") {
34
- return ScreenMultiSelectProvider.getProvider(
35
- screenKey,
36
- screenRoute
37
- ).getObservable();
38
- }
39
-
40
- if (behavior.select_mode === "single") {
41
- return ScreenSingleValueProvider.getProvider(
42
- screenKey,
43
- screenRoute
44
- ).getObservable();
45
- }
46
- }
47
-
48
23
  const contextKey = parseContextKey(selection);
49
24
 
50
25
  if (contextKey) {
51
- // TODO: Add storage scope to behavior
52
26
  if (behavior.select_mode === "multi") {
53
27
  return StorageMultiSelectProvider.getProvider(contextKey).getObservable();
54
28
  }
@@ -67,7 +41,6 @@ const getDataSourceProvider = (
67
41
 
68
42
  export const useBehaviorUpdate = (behavior: Behavior) => {
69
43
  const [lastUpdate, setLastUpdate] = React.useState<number | null>(null);
70
- const screenRoute = useRoute()?.pathname || "";
71
44
  const player = usePlayer();
72
45
 
73
46
  const triggerUpdate = () => setLastUpdate(Date.now());
@@ -75,7 +48,7 @@ export const useBehaviorUpdate = (behavior: Behavior) => {
75
48
  useEffect(() => {
76
49
  if (!behavior) return;
77
50
 
78
- const dataSource = getDataSourceProvider(behavior, screenRoute);
51
+ const dataSource = getDataSourceProvider(behavior);
79
52
 
80
53
  if (dataSource) {
81
54
  const subscription = dataSource.subscribe(triggerUpdate);
@@ -99,15 +72,10 @@ export const useBehaviorUpdate = (behavior: Behavior) => {
99
72
 
100
73
  // We cant use async in this function (its inside render),
101
74
  // so we rely on useBehaviorUpdate to update current value and trigger re-render
102
- export const isCellSelected = ({
103
- item,
104
- screenRoute,
105
- behavior,
106
- }: {
107
- item: ZappEntry;
108
- screenRoute: string;
109
- behavior?: Behavior;
110
- }): boolean => {
75
+ export const isCellSelected = (
76
+ item: ZappEntry,
77
+ behavior?: Behavior
78
+ ): boolean => {
111
79
  if (!behavior) return false;
112
80
 
113
81
  const id = behavior.selector ? get(item, behavior.selector) : item.id;
@@ -131,30 +99,7 @@ export const isCellSelected = ({
131
99
  }
132
100
 
133
101
  const selection = String(behavior.current_selection);
134
-
135
- const screenKey = parseContextKey(selection, "screen");
136
-
137
- if (screenKey) {
138
- if (behavior.select_mode === "single") {
139
- const selectedItem = ScreenSingleValueProvider.getProvider(
140
- screenKey,
141
- screenRoute
142
- ).getValue();
143
-
144
- return selectedItem === String(id);
145
- }
146
-
147
- if (behavior.select_mode === "multi") {
148
- const selectedItems = ScreenMultiSelectProvider.getProvider(
149
- screenKey,
150
- screenRoute
151
- ).getSelectedItems();
152
-
153
- return selectedItems?.includes(String(id));
154
- }
155
- }
156
-
157
- const contextKey = parseContextKey(selection, "ctx");
102
+ const contextKey = parseContextKey(selection);
158
103
 
159
104
  if (contextKey) {
160
105
  if (behavior.select_mode === "single") {
@@ -8,7 +8,6 @@ import { masterCellLogger } from "../logger";
8
8
  import { getCellState } from "../../Cell/utils";
9
9
  import { getColorFromData } from "@applicaster/zapp-react-native-utils/cellUtils";
10
10
  import { isCellSelected, useBehaviorUpdate } from "./behaviorProvider";
11
- import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks";
12
11
 
13
12
  const hasElementSpecificViewType = (viewType) => (element) => {
14
13
  if (R.isNil(element)) {
@@ -191,16 +190,8 @@ export const getFocusedButtonId = (focusable) => {
191
190
  });
192
191
  };
193
192
 
194
- export const isSelected = ({
195
- item,
196
- screenRoute,
197
- behavior,
198
- }: {
199
- item: ZappEntry;
200
- screenRoute: string;
201
- behavior?: Behavior;
202
- }) => {
203
- return isCellSelected({ item, screenRoute, behavior });
193
+ export const isSelected = (item: ZappEntry, behavior?: Behavior) => {
194
+ return isCellSelected(item, behavior);
204
195
  };
205
196
 
206
197
  export const useCellState = ({
@@ -213,10 +204,9 @@ export const useCellState = ({
213
204
  focused: boolean;
214
205
  }): CellState => {
215
206
  const lastUpdate = useBehaviorUpdate(behavior);
216
- const router = useRoute();
217
207
 
218
208
  const _isSelected = useMemo(
219
- () => isSelected({ item, screenRoute: router?.pathname, behavior }),
209
+ () => isSelected(item, behavior),
220
210
  [behavior, item, lastUpdate]
221
211
  );
222
212
 
@@ -6,12 +6,15 @@ import * as R from "ramda";
6
6
  import uuid from "uuid/v4";
7
7
  import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
8
8
  import {
9
- isApplePlatform,
10
9
  isTV,
11
10
  platformSelect,
12
11
  isAndroidTVPlatform,
12
+ isTvOSPlatform,
13
13
  } from "@applicaster/zapp-react-native-utils/reactUtils";
14
- import { isAudioItem } from "@applicaster/zapp-react-native-utils/playerUtils";
14
+ import {
15
+ isAudioItem,
16
+ isInlineTV as isInlineTVUtil,
17
+ } from "@applicaster/zapp-react-native-utils/playerUtils";
15
18
 
16
19
  import { TVEventHandlerComponent } from "@applicaster/zapp-react-native-tvos-ui-components/Components/TVEventHandlerComponent";
17
20
  import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
@@ -22,7 +25,7 @@ import {
22
25
  } from "@applicaster/zapp-react-native-utils/reactHooks";
23
26
 
24
27
  import { PlayerStateContext } from "../../Contexts/PlayerStateContext";
25
- import { isAppleTV } from "../../Helpers/Platform";
28
+
26
29
  import {
27
30
  QUICK_BRICK_EVENTS,
28
31
  QuickBrickEvent,
@@ -97,6 +100,11 @@ const focusableBottomContainerId = "player-container-bottom";
97
100
 
98
101
  const isAndroidTV = isAndroidTVPlatform();
99
102
 
103
+ const isTvOS = isTvOSPlatform();
104
+
105
+ // height for container with additional content below player
106
+ const INLINE_CONTAINER_CONTENT_HEIGHT = 400;
107
+
100
108
  const withBorderHack = () => {
101
109
  if (isAndroidTV) {
102
110
  /* @HACK: see GH#7269 */
@@ -126,7 +134,10 @@ const webStyles = {
126
134
  flex: "initial",
127
135
  },
128
136
  inlineRiver: {
129
- height: 400,
137
+ height: INLINE_CONTAINER_CONTENT_HEIGHT,
138
+
139
+ borderWidth: 4,
140
+ borderColor: "yellow",
130
141
  },
131
142
  };
132
143
 
@@ -144,7 +155,7 @@ const nativeStyles = {
144
155
  flex: 1,
145
156
  },
146
157
  inlineRiver: {
147
- height: 400,
158
+ height: INLINE_CONTAINER_CONTENT_HEIGHT,
148
159
  },
149
160
  };
150
161
 
@@ -164,12 +175,11 @@ const renderApplePlayer = ({
164
175
  videoStyle,
165
176
  playNextData,
166
177
  }) => {
167
- const { title, summary } = item || {};
168
-
169
- if (!isAppleTV() || !player) {
178
+ if (!isTvOS || !player) {
170
179
  return null;
171
180
  }
172
181
 
182
+ // render audio_player for tvos
173
183
  if (isAudioContent) {
174
184
  return (
175
185
  <AudioPlayer
@@ -183,6 +193,8 @@ const renderApplePlayer = ({
183
193
  return null;
184
194
  }
185
195
 
196
+ const { title, summary } = item || {};
197
+
186
198
  return (
187
199
  <ProgramInfo
188
200
  title={title}
@@ -193,21 +205,6 @@ const renderApplePlayer = ({
193
205
  );
194
206
  };
195
207
 
196
- const renderRestPlayers = ({ item, showAudioPlayer, pluginConfiguration }) => {
197
- if (isApplePlatform()) {
198
- return null;
199
- }
200
-
201
- return (
202
- showAudioPlayer && (
203
- <AudioPlayer
204
- audio_item={item}
205
- plugin_configuration={pluginConfiguration}
206
- />
207
- )
208
- );
209
- };
210
-
211
208
  const PlayerContainerComponent = (props: Props) => {
212
209
  const {
213
210
  Player,
@@ -337,7 +334,7 @@ const PlayerContainerComponent = (props: Props) => {
337
334
 
338
335
  setState({ error: errorObj });
339
336
 
340
- if (!isAppleTV()) {
337
+ if (!isTvOS) {
341
338
  setTimeout(() => {
342
339
  close();
343
340
  }, 800);
@@ -568,10 +565,7 @@ const PlayerContainerComponent = (props: Props) => {
568
565
 
569
566
  const uri = item?.content ? item.content?.src : null;
570
567
 
571
- const isInlineTV =
572
- screenData?.ui_components &&
573
- screenData?.ui_components?.length > 0 &&
574
- isTV();
568
+ const isInlineTV = isInlineTVUtil(screenData);
575
569
 
576
570
  const inline =
577
571
  [VideoModalMode.MAXIMIZED, VideoModalMode.MINIMIZED].includes(mode) ||
@@ -626,12 +620,6 @@ const PlayerContainerComponent = (props: Props) => {
626
620
  playNextData,
627
621
  };
628
622
 
629
- const restPlayerProps = {
630
- item,
631
- showAudioPlayer: isAudioContent,
632
- pluginConfiguration,
633
- };
634
-
635
623
  return (
636
624
  <PlayerStateContext.Provider value={value}>
637
625
  <PlayerContainerContextProvider
@@ -707,8 +695,6 @@ const PlayerContainerComponent = (props: Props) => {
707
695
  </Player>
708
696
  </PlayerFocusableWrapperView>
709
697
 
710
- {renderRestPlayers(restPlayerProps)}
711
-
712
698
  {state.error ? <ErrorDisplay error={state.error} /> : null}
713
699
  </View>
714
700
  {/* Components container */}
@@ -732,12 +718,12 @@ const PlayerContainerComponent = (props: Props) => {
732
718
  screenId={screenData.id}
733
719
  key={item.id}
734
720
  groupId={FocusableGroupMainContainerId}
735
- cellTapAction={(event) => onCellTap(event)}
721
+ cellTapAction={onCellTap}
736
722
  extraAnchorPointYOffset={-600}
737
723
  isScreenWrappedInContainer={true}
738
724
  containerHeight={styles.inlineRiver.height}
739
725
  componentsMapExtraProps={{
740
- isNestedComponentsMap: R.T,
726
+ isNestedComponentsMap: true,
741
727
  }}
742
728
  />
743
729
  )}
@@ -281,8 +281,8 @@ function ComponentsMapComponent(props: Props) {
281
281
  scrollIndicatorInsets={scrollIndicatorInsets}
282
282
  extraData={feed}
283
283
  stickyHeaderIndices={stickyHeaderIndices}
284
- onLayout={handleOnLayout}
285
284
  removeClippedSubviews={isAndroid}
285
+ onLayout={handleOnLayout}
286
286
  initialNumToRender={3}
287
287
  maxToRenderPerBatch={10}
288
288
  windowSize={12}
@@ -303,10 +303,6 @@ function ComponentsMapComponent(props: Props) {
303
303
  onMomentumScrollEnd={_onMomentumScrollEnd}
304
304
  onScrollEndDrag={_onScrollEndDrag}
305
305
  scrollEventThrottle={16}
306
- maintainVisibleContentPosition={{
307
- minIndexForVisible: 0,
308
- autoscrollToTopThreshold: 10,
309
- }}
310
306
  {...scrollViewExtraProps}
311
307
  />
312
308
  </ViewportTracker>
@@ -39,6 +39,10 @@ function getFeedUrl(feed: ZappFeed, index: number) {
39
39
  }
40
40
  }
41
41
 
42
+ const isNextIndex = (index, readyIndex) => {
43
+ return readyIndex + 1 >= index;
44
+ };
45
+
42
46
  /**
43
47
  * useLoadingState for RiverItemComponent
44
48
  * takes currentIndex and loadingState as arguments
@@ -48,24 +52,20 @@ const useLoadingState = (
48
52
  loadingState: RiverItemType["loadingState"]
49
53
  ) => {
50
54
  const [readyToBeDisplayed, setReadyToBeDisplayed] = React.useState(
51
- loadingState.getValue().index + 1 >= currentIndex
55
+ isNextIndex(currentIndex, loadingState.getValue().index)
52
56
  );
53
57
 
54
58
  useEffect(() => {
55
59
  const subscription = loadingState.subscribe(({ index }) => {
56
- if (index + 1 >= currentIndex) {
60
+ if (isNextIndex(currentIndex, index)) {
57
61
  setReadyToBeDisplayed(true);
58
62
  }
59
63
  });
60
64
 
61
- if (loadingState.getValue().index + 1 >= currentIndex) {
62
- setReadyToBeDisplayed(true);
63
- }
64
-
65
65
  return () => {
66
66
  subscription.unsubscribe();
67
67
  };
68
- }, [loadingState, currentIndex]);
68
+ }, [currentIndex]);
69
69
 
70
70
  return readyToBeDisplayed;
71
71
  };
@@ -151,7 +151,7 @@ function RiverItemComponent(props: RiverItemType) {
151
151
  component={item}
152
152
  componentIndex={index}
153
153
  onLoadFailed={onLoadFailed}
154
- onLoadFinished={() => onLoadFinished(index)} // Keeping it here to don't break the plugins.
154
+ onLoadFinished={() => onLoadFinished(index)}
155
155
  groupId={groupId}
156
156
  feedUrl={feedUrl}
157
157
  isLast={isLast}
@@ -26,7 +26,6 @@ type Props = {
26
26
  componentsMapExtraProps?: any;
27
27
  isInsideContainer?: boolean;
28
28
  extraAnchorPointYOffset: number;
29
- extraOffset: number;
30
29
  river?: ZappRiver | ZappEntry;
31
30
  };
32
31
 
@@ -39,7 +38,6 @@ export const River = (props: Props) => {
39
38
  componentsMapExtraProps,
40
39
  isInsideContainer,
41
40
  extraAnchorPointYOffset,
42
- extraOffset,
43
41
  } = props;
44
42
 
45
43
  const { title: screenTitle, summary: screenSummary } = useNavbarState();
@@ -120,7 +118,6 @@ export const River = (props: Props) => {
120
118
  <GeneralContentScreen
121
119
  feed={feedData}
122
120
  screenId={screenId}
123
- extraOffset={extraOffset}
124
121
  isScreenWrappedInContainer={isInsideContainer}
125
122
  extraAnchorPointYOffset={extraAnchorPointYOffset}
126
123
  componentsMapExtraProps={componentsMapExtraProps}
@@ -135,12 +135,6 @@ exports[`componentsMap renders renders components map correctly 1`] = `
135
135
  getItemCount={[Function]}
136
136
  initialNumToRender={3}
137
137
  keyExtractor={[Function]}
138
- maintainVisibleContentPosition={
139
- {
140
- "autoscrollToTopThreshold": 10,
141
- "minIndexForVisible": 0,
142
- }
143
- }
144
138
  maxToRenderPerBatch={10}
145
139
  onContentSizeChange={[Function]}
146
140
  onLayout={[Function]}
@@ -1,17 +1,17 @@
1
1
  import React from "react";
2
- import { View, ViewProps, ViewStyle } from "react-native";
2
+ import { View, ViewStyle } from "react-native";
3
3
  import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
4
4
  import { useCurrentScreenData } from "@applicaster/zapp-react-native-utils/reactHooks";
5
5
  import { isFirstComponentScreenPicker } from "@applicaster/zapp-react-native-utils/componentsUtils";
6
+ import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
6
7
 
7
8
  interface IProps {
8
9
  targetScreenId?: string;
9
10
  children?: React.ReactNode;
10
11
  style?: ViewStyle;
11
- extraOffset?: number;
12
+ extraVerticalOffset: Option<number>;
12
13
  }
13
14
 
14
- type CombinedProps = IProps & ViewProps;
15
15
  /**
16
16
  * The MarginTop is essentially a feature used for managing the visibility of components on your screen.
17
17
  * A more accurate term for this might be something like a 'component visibility threshold' or 'cut-off point'.
@@ -47,7 +47,7 @@ export const useMarginTop = (targetScreenId: string): number => {
47
47
 
48
48
  // Empty string means that value is blank in the CMS. Fallback to theme
49
49
  if (String(screenData?.styles?.screen_margin_top) === "") {
50
- return Number(theme.screen_margin_top);
50
+ return toNumberWithDefault(0, theme.screen_margin_top);
51
51
  }
52
52
 
53
53
  /**
@@ -58,28 +58,29 @@ export const useMarginTop = (targetScreenId: string): number => {
58
58
  */
59
59
  if (screenData?.styles?.screen_margin_top === undefined) {
60
60
  if (isGeneralContentScreen || supportsUiComponents) {
61
- return Number(theme.screen_margin_top);
61
+ return toNumberWithDefault(0, theme.screen_margin_top);
62
62
  }
63
63
 
64
64
  return 0;
65
65
  }
66
66
 
67
- return Number(screenData?.styles?.screen_margin_top);
67
+ return toNumberWithDefault(0, screenData?.styles?.screen_margin_top);
68
68
  };
69
69
 
70
- export const TopMarginApplicator: React.FC<CombinedProps> = (
71
- props: CombinedProps
72
- ) => {
73
- const extraOffset = props?.extraOffset ?? 0;
70
+ export const TopMarginApplicator: React.FC<IProps> = ({
71
+ targetScreenId,
72
+ style,
73
+ children,
74
+ extraVerticalOffset,
75
+ }: IProps) => {
76
+ const extraOffset = toNumberWithDefault(0, extraVerticalOffset);
74
77
 
75
78
  // HACK: Remove extraOffset when focusIssue with absolute elements is fixed on tvos
76
- const marginTop = useMarginTop(props.targetScreenId) + extraOffset;
77
- const style = { ...((props.style as {}) || {}), marginTop };
79
+ const marginTop = useMarginTop(targetScreenId);
78
80
 
79
- // Then, spread the rest of the props on your returned JSX.
80
81
  return (
81
- <View {...props} style={style}>
82
- {props.children}
82
+ <View style={[style, { marginTop: marginTop + extraOffset }]}>
83
+ {children}
83
84
  </View>
84
85
  );
85
86
  };
@@ -71,6 +71,36 @@ exports[`PlayerWrapper renders inline 1`] = `
71
71
  }
72
72
  testID="test-player-container"
73
73
  />
74
+ <View
75
+ animationType="componentFade"
76
+ style={
77
+ {
78
+ "flex": 1,
79
+ }
80
+ }
81
+ >
82
+ <View
83
+ configuration={
84
+ {
85
+ "tablet_landscape_player_container_background_color": "red",
86
+ "tablet_landscape_sidebar_width": "35%",
87
+ }
88
+ }
89
+ entry={
90
+ {
91
+ "id": "test",
92
+ }
93
+ }
94
+ isTablet={false}
95
+ isTabletLandscape={false}
96
+ style={
97
+ {
98
+ "flex": 1,
99
+ "paddingTop": 20,
100
+ }
101
+ }
102
+ />
103
+ </View>
74
104
  </View>
75
105
  </RNCSafeAreaView>
76
106
  </RNCSafeAreaProvider>
@@ -239,6 +269,36 @@ exports[`PlayerWrapper renders inline on tablet in landscape orientation 1`] = `
239
269
  }
240
270
  />
241
271
  </View>
272
+ <View
273
+ animationType="componentFade"
274
+ style={
275
+ {
276
+ "flex": 1,
277
+ }
278
+ }
279
+ >
280
+ <View
281
+ configuration={
282
+ {
283
+ "tablet_landscape_player_container_background_color": "red",
284
+ "tablet_landscape_sidebar_width": "35%",
285
+ }
286
+ }
287
+ entry={
288
+ {
289
+ "id": "test",
290
+ }
291
+ }
292
+ isTablet={true}
293
+ isTabletLandscape={true}
294
+ style={
295
+ {
296
+ "flex": 1,
297
+ "paddingTop": 20,
298
+ }
299
+ }
300
+ />
301
+ </View>
242
302
  </View>
243
303
  </RNCSafeAreaView>
244
304
  </RNCSafeAreaProvider>
@@ -1,19 +1,9 @@
1
1
  import { renderHook } from "@testing-library/react-hooks";
2
2
  import { useDelayedPlayerDetails } from "../useDelayedPlayerDetails";
3
- import { withTimeout$ } from "@applicaster/zapp-react-native-utils/idleUtils";
4
- import { showDetails } from "../utils";
5
3
  import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
6
4
 
7
- jest.mock("@applicaster/zapp-react-native-utils/idleUtils", () => ({
8
- withTimeout$: jest.fn(),
9
- }));
10
-
11
- jest.mock("../utils", () => ({
12
- showDetails: jest.fn(),
13
- }));
14
-
15
5
  jest.mock("@applicaster/zapp-react-native-utils/reactHooks", () => ({
16
- useIsTablet: jest.fn(),
6
+ useIsTablet: jest.fn().mockReturnValue(false),
17
7
  }));
18
8
 
19
9
  describe("useDelayedPlayerDetails", () => {
@@ -21,69 +11,41 @@ describe("useDelayedPlayerDetails", () => {
21
11
  jest.clearAllMocks();
22
12
  });
23
13
 
24
- it("should return false initially", () => {
25
- (withTimeout$ as jest.Mock).mockReturnValue({
26
- subscribe: jest.fn().mockReturnValue({ unsubscribe: jest.fn() }),
27
- });
28
-
14
+ it("should return true initially", () => {
29
15
  const { result } = renderHook(() =>
30
16
  useDelayedPlayerDetails({ isInline: true, isDocked: false, isPip: false })
31
17
  );
32
18
 
33
- expect(result.current).toBe(false);
19
+ expect(result.current).toBe(true);
34
20
  });
35
21
 
36
- it("should return true if showDetails returns true", () => {
37
- (withTimeout$ as jest.Mock).mockReturnValue({
38
- subscribe: (callback) => {
39
- callback.next();
40
-
41
- return { unsubscribe: jest.fn() };
42
- },
43
- });
44
-
45
- (showDetails as jest.Mock).mockReturnValue(true);
46
- (useIsTablet as jest.Mock).mockReturnValue(false);
47
-
22
+ it("should return false when isPip is true", () => {
48
23
  const { result } = renderHook(() =>
49
- useDelayedPlayerDetails({ isInline: true, isDocked: false, isPip: false })
24
+ useDelayedPlayerDetails({ isInline: true, isDocked: true, isPip: true })
50
25
  );
51
26
 
52
- expect(result.current).toBe(true);
27
+ expect(result.current).toBe(false);
53
28
  });
54
29
 
55
- it("should return false if showDetails returns false", () => {
56
- (withTimeout$ as jest.Mock).mockReturnValue({
57
- subscribe: (callback) => {
58
- callback.next();
59
-
60
- return { unsubscribe: jest.fn() };
61
- },
62
- });
63
-
64
- (showDetails as jest.Mock).mockReturnValue(false);
65
- (useIsTablet as jest.Mock).mockReturnValue(false);
66
-
30
+ it("should return false when isDocked is true", () => {
67
31
  const { result } = renderHook(() =>
68
- useDelayedPlayerDetails({ isInline: true, isDocked: false, isPip: false })
32
+ useDelayedPlayerDetails({ isInline: true, isDocked: true, isPip: false })
69
33
  );
70
34
 
71
35
  expect(result.current).toBe(false);
72
36
  });
73
37
 
74
- it("should unsubscribe on unmount", () => {
75
- const unsubscribeMock = jest.fn();
38
+ it("should return true for tablet regardless of other flags", () => {
39
+ (useIsTablet as jest.Mock).mockReturnValue(true);
76
40
 
77
- (withTimeout$ as jest.Mock).mockReturnValue({
78
- subscribe: jest.fn().mockReturnValue({ unsubscribe: unsubscribeMock }),
79
- });
80
-
81
- const { unmount } = renderHook(() =>
82
- useDelayedPlayerDetails({ isInline: true, isDocked: false, isPip: false })
41
+ const { result } = renderHook(() =>
42
+ useDelayedPlayerDetails({
43
+ isInline: false,
44
+ isDocked: false,
45
+ isPip: false,
46
+ })
83
47
  );
84
48
 
85
- unmount();
86
-
87
- expect(unsubscribeMock).toHaveBeenCalled();
49
+ expect(result.current).toBe(true);
88
50
  });
89
51
  });