@applicaster/zapp-react-native-ui-components 13.0.0-alpha.7138263059 → 13.0.0-alpha.7193146510

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 (77) hide show
  1. package/Components/AudioPlayer/AudioPlayer.tsx +5 -9
  2. package/Components/AudioPlayer/helpers.tsx +1 -2
  3. package/Components/Cell/Cell.tsx +3 -13
  4. package/Components/Cell/CellWithFocusable.tsx +21 -15
  5. package/Components/Cell/CellWrapper.tsx +18 -0
  6. package/Components/Cell/styles.ts +17 -0
  7. package/Components/CellRendererResolver/index.ts +2 -1
  8. package/Components/ErrorScreen/index.tsx +8 -0
  9. package/Components/FocusableCell/index.tsx +1 -1
  10. package/Components/FocusableGroup/FocusableTvOS.tsx +3 -6
  11. package/Components/FocusableGroup/index.tsx +0 -1
  12. package/Components/GeneralContentScreen/GeneralContentScreen.tsx +3 -0
  13. package/Components/GeneralContentScreen/utils/useCurationAPI.ts +4 -2
  14. package/Components/GeneralContentScreen/utils/useEventAlerts.ts +30 -0
  15. package/Components/HandlePlayable/HandlePlayable.tsx +21 -27
  16. package/Components/Layout/TV/LayoutBackground.tsx +28 -0
  17. package/Components/Layout/TV/ScreenContainer.tsx +0 -1
  18. package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +15 -10
  19. package/Components/Layout/TV/__tests__/index.test.tsx +8 -2
  20. package/Components/Layout/TV/index.tsx +6 -20
  21. package/Components/Layout/TV/index.web.tsx +4 -1
  22. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +4 -3
  23. package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +11 -7
  24. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/const.ts +3 -0
  25. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +6 -6
  26. package/Components/MasterCell/utils/behaviorProvider.ts +136 -0
  27. package/Components/MasterCell/utils/index.ts +8 -134
  28. package/Components/ModalComponent/BottomSheetModalContent.tsx +49 -41
  29. package/Components/ModalComponent/Button/Item.tsx +6 -5
  30. package/Components/ModalComponent/Button/assets.ts +1 -1
  31. package/Components/ModalComponent/Button/index.tsx +45 -62
  32. package/Components/ModalComponent/Header/index.tsx +9 -8
  33. package/Components/ModalComponent/utils.ts +55 -7
  34. package/Components/OfflineHandler/utils/index.ts +1 -1
  35. package/Components/PlayerContainer/PlayerContainer.tsx +34 -7
  36. package/Components/PlayerImageBackground/index.tsx +4 -24
  37. package/Components/River/ComponentsMap/ComponentsMap.tsx +3 -0
  38. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +3 -3
  39. package/Components/River/RiverItem.tsx +2 -1
  40. package/Components/Screen/TV/__tests__/index.web.test.tsx +26 -0
  41. package/Components/Screen/TV/index.web.tsx +5 -6
  42. package/Components/Screen/__tests__/Screen.test.tsx +22 -14
  43. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +2 -2
  44. package/Components/Screen/hooks.ts +3 -6
  45. package/Components/TopMarginApplicator/TopMarginApplicator.tsx +2 -3
  46. package/Components/Transitioner/AnimationManager.js +15 -15
  47. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +1 -1
  48. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +43 -19
  49. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +3 -3
  50. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +38 -14
  51. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +10 -3
  52. package/Components/VideoModal/ModalAnimation/__tests__/getMoveUpValue.test.ts +108 -0
  53. package/Components/VideoModal/ModalAnimation/const.ts +5 -0
  54. package/Components/VideoModal/ModalAnimation/index.ts +2 -0
  55. package/Components/VideoModal/ModalAnimation/utils.ts +30 -0
  56. package/Components/VideoModal/PlayerDetails.tsx +9 -4
  57. package/Components/VideoModal/PlayerWrapper.tsx +35 -22
  58. package/Components/VideoModal/VideoModal.tsx +19 -4
  59. package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -40
  60. package/Components/VideoModal/utils.ts +3 -4
  61. package/Components/ZappUIComponent/index.tsx +4 -4
  62. package/Contexts/FocusableGroupContext/withFocusableContext.tsx +4 -10
  63. package/Contexts/HeaderOffsetContext/index.tsx +4 -6
  64. package/Contexts/ScreenContext/index.tsx +3 -10
  65. package/Decorators/RiverResolver/index.tsx +5 -7
  66. package/Decorators/ZappPipesDataConnector/index.tsx +12 -31
  67. package/Decorators/ZappPipesDataConnector/utils/mongoFilter.ts +738 -0
  68. package/Decorators/ZappPipesDataConnector/utils/useFilter.tsx +102 -0
  69. package/package.json +5 -9
  70. package/tsconfig.json +2 -3
  71. package/.babelrc +0 -8
  72. package/Components/Cell/CellStyles/FallbackCellStyle/index.js +0 -157
  73. package/Components/Cell/CellStyles/Hero/index.js +0 -111
  74. package/Components/Cell/CellStyles/ScreenSelector/index.js +0 -68
  75. package/Components/Cell/CellStyles/cellStylesResolver.ts +0 -19
  76. package/Components/Cell/CellStyles/colors.js +0 -40
  77. package/Components/Cell/CellStyles/index.js +0 -15
@@ -22,8 +22,7 @@ type Props = {
22
22
  audio_player_title_color?: string;
23
23
  audio_player_summary_color?: string;
24
24
  audio_player_rtl?: boolean;
25
- magic_background?: boolean;
26
- audio_player_background_image_query?: string;
25
+ audio_player_background_image_default_color?: string;
27
26
  start_time?: string;
28
27
  end_time?: string;
29
28
  };
@@ -33,8 +32,7 @@ type Props = {
33
32
  audio_player_title_color?: string;
34
33
  audio_player_summary_color?: string;
35
34
  audio_player_rtl?: string;
36
- magic_background?: string;
37
- audio_player_background_image_query?: string;
35
+ audio_player_background_image_default_color?: string;
38
36
  audio_player_background_image?: string;
39
37
  audio_player_artwork_aspect_ratio?: string;
40
38
  lg_tv_audio_player_title_font_family?: string;
@@ -74,10 +72,9 @@ export function AudioPlayer(props: Props) {
74
72
  const artworkAspectRatio = getProp("audio_player_artwork_aspect_ratio");
75
73
  const channelIcon = getProp("audio_player_channel_icon");
76
74
  const rtlFlag = getProp("audio_player_rtl");
77
- const magicBackground = getProp("magic_background");
78
75
 
79
- const audioPlayerBackgroundImageQuery = getProp(
80
- "audio_player_background_image_query"
76
+ const audioPlayerBackgroundImageDefaultColor = getProp(
77
+ "audio_player_background_image_default_color"
81
78
  );
82
79
 
83
80
  const isRTL = rtlFlag === "1" || rtlFlag === "true" || rtlFlag === true;
@@ -156,8 +153,7 @@ export function AudioPlayer(props: Props) {
156
153
  runTimeFontSize,
157
154
  artworkAspectRatio,
158
155
  channelIcon,
159
- magicBackground,
160
- audioPlayerBackgroundImageQuery,
156
+ audioPlayerBackgroundImageDefaultColor,
161
157
  };
162
158
  }, [getProp]);
163
159
 
@@ -4,8 +4,7 @@ const defaults = {
4
4
  audio_player_background_color: "black",
5
5
  audio_player_artwork_aspect_ratio: "1:1",
6
6
  audio_player_rtl: false,
7
- magic_background: false,
8
- audio_player_background_image_query: "",
7
+ audio_player_background_image_default_color: "",
9
8
  };
10
9
 
11
10
  export function getPropertyFromEntryOrConfig({ entry, plugin_configuration }) {
@@ -12,6 +12,7 @@ import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
12
12
  import { CellWithFocusable } from "./CellWithFocusable";
13
13
  import { BaseFocusable } from "../BaseFocusable";
14
14
  import { AccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager";
15
+ import { styles } from "./styles";
15
16
 
16
17
  type Props = {
17
18
  item: ZappEntry;
@@ -68,17 +69,6 @@ type State = {
68
69
  hasFocusableInside: boolean;
69
70
  };
70
71
 
71
- const baseCellStyles = {
72
- height: "100%",
73
- display: "flex",
74
- flex: 1,
75
- } as const;
76
-
77
- const touchableStyles = {
78
- flex: 1,
79
- height: "100%",
80
- } as const;
81
-
82
72
  export class CellComponent extends React.Component<Props, State> {
83
73
  constructor(props) {
84
74
  super(props);
@@ -252,7 +242,7 @@ export class CellComponent extends React.Component<Props, State> {
252
242
  <View
253
243
  testID={`${component?.id}-${id}`}
254
244
  accessible={false}
255
- style={touchableStyles}
245
+ style={styles.touchableCell}
256
246
  >
257
247
  <Focusable
258
248
  id={focusableId}
@@ -264,7 +254,7 @@ export class CellComponent extends React.Component<Props, State> {
264
254
  hasReceivedFocus={hasReceivedFocus || this.hasReceivedFocus}
265
255
  preferredFocus={preferredFocus}
266
256
  offsetUpdater={offsetUpdater}
267
- style={baseCellStyles}
257
+ style={styles.baseCell}
268
258
  isFocusable={isFocusable}
269
259
  skipFocusManagerRegistration={skipFocusManagerRegistration}
270
260
  >
@@ -5,6 +5,8 @@ import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/
5
5
 
6
6
  import { useCellState } from "../MasterCell/utils";
7
7
  import { FocusableGroup } from "../FocusableGroup";
8
+ import { CellWrapper } from "./CellWrapper";
9
+ import { styles } from "./styles";
8
10
 
9
11
  type Props = {
10
12
  item: ZappEntry;
@@ -21,6 +23,8 @@ type Props = {
21
23
  focused?: boolean;
22
24
  };
23
25
 
26
+ const addPrefix = (id: string) => `focusable-cell-wrapper-${id}`;
27
+
24
28
  export function CellWithFocusable(props: Props) {
25
29
  const {
26
30
  index,
@@ -40,7 +44,7 @@ export function CellWithFocusable(props: Props) {
40
44
  const [isFocused, setIsFocused] = React.useState(false);
41
45
 
42
46
  const state = useCellState({
43
- id: item.id,
47
+ item,
44
48
  behavior,
45
49
  focused: isFocused || toBooleanWithDefaultFalse(focused),
46
50
  });
@@ -79,7 +83,7 @@ export function CellWithFocusable(props: Props) {
79
83
 
80
84
  return (
81
85
  <FocusableGroup
82
- id={`focusable-cell-wrapper-${id}`}
86
+ id={addPrefix(id)}
83
87
  testID={"cell-with-focusable-cell-renderer-focusable-group"}
84
88
  groupId={groupId}
85
89
  preferredFocus={preferredFocus}
@@ -88,19 +92,21 @@ export function CellWithFocusable(props: Props) {
88
92
  onBlur={onGroupBlur}
89
93
  skipFocusManagerRegistration={skipFocusManagerRegistration}
90
94
  >
91
- <CellRenderer
92
- testID={"cell-with-focusable-cell-renderer"}
93
- item={item}
94
- groupId={`focusable-cell-wrapper-${id}`}
95
- onToggleFocus={handleToggleFocus}
96
- state={state}
97
- prefixId={id}
98
- focusedButtonId={focusedButtonId}
99
- preferredFocus={true}
100
- skipFocusManagerRegistration={skipFocusManagerRegistration}
101
- isFocusable={isFocusable}
102
- focused={focused}
103
- />
95
+ <CellWrapper style={styles.cellWrapper}>
96
+ <CellRenderer
97
+ testID={"cell-with-focusable-cell-renderer"}
98
+ item={item}
99
+ groupId={addPrefix(id)}
100
+ onToggleFocus={handleToggleFocus}
101
+ state={state}
102
+ prefixId={id}
103
+ focusedButtonId={focusedButtonId}
104
+ preferredFocus={true}
105
+ skipFocusManagerRegistration={skipFocusManagerRegistration}
106
+ isFocusable={isFocusable}
107
+ focused={focused}
108
+ />
109
+ </CellWrapper>
104
110
  </FocusableGroup>
105
111
  );
106
112
  }
@@ -0,0 +1,18 @@
1
+ import * as React from "react";
2
+ import { View, ViewStyle } from "react-native";
3
+ import { isTvOSPlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
4
+
5
+ const isTvOS = isTvOSPlatform();
6
+
7
+ type Props = {
8
+ style: ViewStyle;
9
+ children: React.ReactNode;
10
+ };
11
+
12
+ export const CellWrapper = ({ style, children }: Props) => {
13
+ if (isTvOS) {
14
+ return <View style={style}>{children}</View>;
15
+ }
16
+
17
+ return <>{children}</>;
18
+ };
@@ -0,0 +1,17 @@
1
+ import { StyleSheet } from "react-native";
2
+
3
+ export const styles = StyleSheet.create({
4
+ cellWrapper: {
5
+ flex: 0,
6
+ height: "100%",
7
+ },
8
+ baseCell: {
9
+ height: "100%",
10
+ display: "flex",
11
+ flex: 1,
12
+ },
13
+ touchableCell: {
14
+ flex: 1,
15
+ height: "100%",
16
+ },
17
+ });
@@ -1,4 +1,5 @@
1
1
  import { findPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";
2
+ import { isGroup } from "@applicaster/zapp-react-native-utils/componentsUtils";
2
3
 
3
4
  import { componentsLogger } from "../../Helpers/logger";
4
5
  import defaultCellRenderer from "../default-cell-renderer";
@@ -80,7 +81,7 @@ export function CellRendererResolver({
80
81
  }: Props) {
81
82
  const cellRendererPlugin = getRendererPlugin(component, plugins, cellStyles);
82
83
 
83
- if (!cellRendererPlugin && component.component_type !== "group-qb") {
84
+ if (!cellRendererPlugin && !isGroup(component)) {
84
85
  logger.warning({
85
86
  message: "Could not resolve cell builder plugin",
86
87
  data: { component },
@@ -105,6 +105,11 @@ const defaultProps = {
105
105
  alignItems: "center",
106
106
  justifyContent: "center",
107
107
  },
108
+ focusedButton: {
109
+ backgroundColor: "#3a3a3a",
110
+ borderColor: "#ffffff",
111
+ borderWidth: 2,
112
+ },
108
113
  buttonText: {
109
114
  fontFamily: platformSelect({
110
115
  ios: "SFProText-Medium",
@@ -116,6 +121,9 @@ const defaultProps = {
116
121
  color: "rgba(255, 255, 255, 1)",
117
122
  textTransform: "uppercase",
118
123
  },
124
+ focusedText: {
125
+ color: "#ffffff",
126
+ },
119
127
  },
120
128
  };
121
129
 
@@ -23,7 +23,7 @@ export function FocusableCell(props: Props) {
23
23
  behavior,
24
24
  } = props;
25
25
 
26
- const state = useCellState({ id: item.id, behavior, focused });
26
+ const state = useCellState({ item, behavior, focused });
27
27
 
28
28
  React.useEffect(() => {
29
29
  if (focused && scrollTo && !isAndroid) {
@@ -24,8 +24,7 @@ type Props = {
24
24
  id: string;
25
25
  children: (arg1: boolean) => React.ComponentType<any>;
26
26
  isFocusDisabled: boolean;
27
- initialItemId: string;
28
- isPreferredFocusDisabled: boolean;
27
+ isWithMemory: boolean;
29
28
  focusGroupRef: React.Component;
30
29
  shouldUsePreferredFocus: boolean;
31
30
  groupId: string;
@@ -40,8 +39,7 @@ export class FocusableGroup extends BaseFocusable<Props> {
40
39
  children,
41
40
  id,
42
41
  isFocusDisabled,
43
- initialItemId,
44
- isPreferredFocusDisabled,
42
+ isWithMemory,
45
43
  style = {},
46
44
  groupId,
47
45
  ...otherProps
@@ -63,8 +61,7 @@ export class FocusableGroup extends BaseFocusable<Props> {
63
61
  itemId={id}
64
62
  ref={this.ref}
65
63
  isFocusDisabled={isFocusDisabled}
66
- initialItemId={initialItemId}
67
- isPreferredFocusDisabled={isPreferredFocusDisabled}
64
+ isWithMemory={isWithMemory}
68
65
  onGroupFocus={onGroupFocus}
69
66
  onGroupBlur={onGroupBlur}
70
67
  style={style}
@@ -16,7 +16,6 @@ type Props = {
16
16
  prioritiseFocusOn?: number;
17
17
  groupId?: string;
18
18
  hasTVPreferredFocus?: boolean;
19
- isPreferredFocusDisabled?: boolean;
20
19
  onFocus?: () => void;
21
20
  onBlur?: () => void;
22
21
  willReceiveFocus?: (event?: any) => void;
@@ -11,6 +11,7 @@ import { allSettled } from "promise";
11
11
  import { createLogger } from "@applicaster/zapp-react-native-utils/logger";
12
12
  import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
13
13
  import { ScreenTrackedViewPositionsContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenTrackedViewPositionsContext";
14
+ import { useEventAlerts } from "./utils/useEventAlerts";
14
15
 
15
16
  const { log_info } = createLogger({
16
17
  category: "ScreenContainer",
@@ -103,6 +104,8 @@ export const GeneralContentScreen = ({
103
104
  [typeof cellTapAction === "function" ? cellTapAction : onCellTapAction]
104
105
  );
105
106
 
107
+ useEventAlerts(screenData);
108
+
106
109
  if (!isReady || isNilOrEmpty(components || uiComponents)) return null;
107
110
 
108
111
  return (
@@ -3,8 +3,10 @@ import { all, equals, path, prop, isEmpty, pluck, values } from "ramda";
3
3
  import { useEffect, useMemo } from "react";
4
4
  import { useDispatch } from "react-redux";
5
5
 
6
- import { useLayoutPresets } from "@applicaster/zapp-react-native-redux/hooks/useLayoutPresets";
7
- import { useZappPipesFeeds } from "@applicaster/zapp-react-native-redux/hooks/useZappPipesFeeds";
6
+ import {
7
+ useLayoutPresets,
8
+ useZappPipesFeeds,
9
+ } from "@applicaster/zapp-react-native-redux/hooks";
8
10
  import { loadPipesData } from "@applicaster/zapp-react-native-redux/ZappPipes";
9
11
  import { isEmptyOrNil } from "@applicaster/zapp-react-native-utils/cellUtils";
10
12
  import { Categories } from "./logger";
@@ -0,0 +1,30 @@
1
+ import React from "react";
2
+ import { showAlertDialog } from "@applicaster/zapp-react-native-utils/alertUtils";
3
+ import { TOGGLE_FLAG_MAX_ITEMS_REACHED_EVENT } from "@applicaster/zapp-react-native-utils/actionsExecutor/consts";
4
+ import { useLocalizedStrings } from "@applicaster/zapp-react-native-utils/localizationUtils";
5
+ import { useIsScreenActive } from "@applicaster/zapp-react-native-utils/reactHooks";
6
+ import { useSubscriberFor } from "@applicaster/zapp-react-native-utils/reactHooks/useSubscriberFor";
7
+
8
+ export const useEventAlerts = (screenData: ZappRiver) => {
9
+ const localizations = useLocalizedStrings({
10
+ localizations: screenData?.localizations || {},
11
+ });
12
+
13
+ const isActive = useIsScreenActive();
14
+
15
+ const onMaxTagsReached = React.useCallback(() => {
16
+ // We can't skip subscribe hook call, so we have to check.
17
+ if (!isActive || !localizations?.msg_maximum_selection_reached_message) {
18
+ return;
19
+ }
20
+
21
+ showAlertDialog({
22
+ title: "",
23
+ message: localizations.msg_maximum_selection_reached_message,
24
+ okButtonText:
25
+ localizations.msg_maximum_selection_reached_message_ok_button || "OK",
26
+ });
27
+ }, [localizations, isActive]);
28
+
29
+ useSubscriberFor(TOGGLE_FLAG_MAX_ITEMS_REACHED_EVENT, onMaxTagsReached);
30
+ };
@@ -1,17 +1,18 @@
1
1
  import * as React from "react";
2
2
  import * as R from "ramda";
3
- import { ViewStyle } from "react-native";
4
3
  import {
5
4
  findPluginByType,
6
5
  findPluginByIdentifier,
7
6
  } from "@applicaster/zapp-react-native-utils/pluginUtils";
8
- import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks/layout";
9
7
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
10
- import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
11
- import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
8
+ import {
9
+ useDimensions,
10
+ useNavigation,
11
+ } from "@applicaster/zapp-react-native-utils/reactHooks";
12
12
 
13
13
  import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
14
14
  import { PlayerContainer } from "../PlayerContainer";
15
+ import { useModalSize } from "../VideoModal/hooks";
15
16
 
16
17
  type Props = {
17
18
  item: ZappEntry;
@@ -78,12 +79,6 @@ const getPlayer = (
78
79
  return getPlayerWithModuleProperties(PlayerModule);
79
80
  };
80
81
 
81
- const dimensionsContext: "window" | "screen" = platformSelect({
82
- android_tv: "window",
83
- amazon: "window",
84
- default: "screen",
85
- });
86
-
87
82
  type PlayableComponent = {
88
83
  Component: React.ComponentType<any>;
89
84
  };
@@ -91,16 +86,11 @@ type PlayableComponent = {
91
86
  export function HandlePlayable({
92
87
  item,
93
88
  isModal,
94
- modalHeight,
95
- modalWidth,
96
89
  mode,
97
90
  groupId,
98
91
  }: Props): React.ReactElement | null {
99
92
  const state = usePickFromState();
100
93
 
101
- const { width: screenWidth, height: screenHeight } =
102
- useDimensions(dimensionsContext);
103
-
104
94
  const { closeVideoModal } = useNavigation();
105
95
 
106
96
  const [Player, playerModuleProperties] = getPlayer(item, state);
@@ -118,9 +108,7 @@ export function HandlePlayable({
118
108
  if (!isModal) {
119
109
  closeVideoModal();
120
110
  }
121
- }, []);
122
111
 
123
- React.useEffect(() => {
124
112
  const castStateHandler = async () => {
125
113
  const castState = await CastPlugin?.getCastState();
126
114
  setCasting(castState === "Connected");
@@ -142,23 +130,29 @@ export function HandlePlayable({
142
130
  }, []);
143
131
 
144
132
  React.useEffect(() => {
145
- if (casting) {
146
- setPlayable({ Component: CastPlugin?.CastHandler });
147
- } else {
148
- setPlayable({ Component: PlayerContainer });
149
- }
133
+ setPlayable({
134
+ Component: casting ? CastPlugin?.CastHandler : PlayerContainer,
135
+ });
150
136
  }, [casting]);
151
137
 
152
- const Component = playable?.Component;
138
+ const { width: screenWidth, height: screenHeight } = useDimensions("window");
139
+
140
+ const modalSize = useModalSize();
153
141
 
154
142
  const style = React.useMemo(
155
143
  () => ({
156
- width: isModal ? modalWidth : mode === "PIP" ? "100%" : screenWidth,
157
- height: isModal ? modalHeight : mode === "PIP" ? "100%" : screenHeight,
144
+ width: isModal ? modalSize.width : mode === "PIP" ? "100%" : screenWidth,
145
+ height: isModal
146
+ ? modalSize.height
147
+ : mode === "PIP"
148
+ ? "100%"
149
+ : screenHeight,
158
150
  }),
159
- [screenWidth, screenHeight, modalHeight, modalWidth, isModal, mode]
151
+ [screenWidth, screenHeight, modalSize, isModal, mode]
160
152
  );
161
153
 
154
+ const Component = playable?.Component;
155
+
162
156
  if (Component) {
163
157
  return (
164
158
  <Component
@@ -174,5 +168,5 @@ export function HandlePlayable({
174
168
  );
175
169
  }
176
170
 
177
- return !isModal ? <BufferAnimation videoStyle={style as ViewStyle} /> : null;
171
+ return !isModal ? <BufferAnimation videoStyle={style} /> : null;
178
172
  }
@@ -0,0 +1,28 @@
1
+ import React from "react";
2
+ import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks/usePickFromState";
3
+ import { getBackgroundImageUrl } from "../utils";
4
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
5
+
6
+ export const LayoutBackground = ({
7
+ Background,
8
+ children,
9
+ }: {
10
+ Background: React.ComponentType<any>;
11
+ children: React.ReactNode;
12
+ }) => {
13
+ const theme = useTheme();
14
+
15
+ const { remoteConfigurations } = usePickFromState(["remoteConfigurations"]);
16
+
17
+ const backgroundColor = theme.app_background_color;
18
+ const backgroundImageUrl = getBackgroundImageUrl(remoteConfigurations);
19
+
20
+ return (
21
+ <Background
22
+ backgroundColor={backgroundColor}
23
+ backgroundImageUrl={backgroundImageUrl}
24
+ >
25
+ {children}
26
+ </Background>
27
+ );
28
+ };
@@ -22,7 +22,6 @@ import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
22
22
  import { NavBarContainer } from "./NavBarContainer";
23
23
 
24
24
  type ComponentsExtraProps = {
25
- Background?: Record<string, any>;
26
25
  NavBar?: Record<string, any>;
27
26
  };
28
27
 
@@ -2,18 +2,23 @@
2
2
 
3
3
  exports[`Layout TV renders 1`] = `
4
4
  <View
5
- excludeFromFocusSearching={true}
6
- id="/river/A1234"
7
- preferredFocus={true}
5
+ backgroundColor="#000000"
6
+ testID="background-component"
8
7
  >
9
8
  <View
10
- Components={
11
- {
12
- "Background": [Function],
13
- "NavBar": [Function],
9
+ excludeFromFocusSearching={true}
10
+ id="/river/A1234"
11
+ preferredFocus={true}
12
+ >
13
+ <View
14
+ Components={
15
+ {
16
+ "Background": [Function],
17
+ "NavBar": [Function],
18
+ }
14
19
  }
15
- }
16
- route="/river/A1234"
17
- />
20
+ route="/river/A1234"
21
+ />
22
+ </View>
18
23
  </View>
19
24
  `;
@@ -5,6 +5,14 @@ import { render } from "@testing-library/react-native";
5
5
  import { Provider } from "react-redux";
6
6
  import { NavigationContext } from "@applicaster/zapp-react-native-ui-components/Contexts/NavigationContext";
7
7
  import configureStore from "redux-mock-store";
8
+ import Layout from "../index.web";
9
+
10
+ // mock useTheme to provide app_background_color
11
+ jest.mock("@applicaster/zapp-react-native-utils/theme", () => ({
12
+ useTheme: () => ({
13
+ app_background_color: "#000000",
14
+ }),
15
+ }));
8
16
 
9
17
  const withoutChildren = omit(["children"]);
10
18
 
@@ -16,8 +24,6 @@ jest.mock("../../../Screen/TV/index.web", () => {
16
24
  };
17
25
  });
18
26
 
19
- const Layout = require("../index.web").default;
20
-
21
27
  const mockStore = configureStore()({
22
28
  appState: { appReady: true },
23
29
  });
@@ -1,10 +1,7 @@
1
1
  import * as React from "react";
2
- import * as R from "ramda";
3
2
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
4
3
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
5
- import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
6
4
 
7
- import { getBackgroundImageUrl } from "../utils";
8
5
  import { LayoutContainer } from "./LayoutContainer";
9
6
  import { ScreenContainer } from "./ScreenContainer";
10
7
 
@@ -12,6 +9,7 @@ import { ScreenLayoutContextProvider } from "./ScreenLayoutContextProvider";
12
9
  import { PathnameContext } from "../../../Contexts/PathnameContext";
13
10
  import { ScreenDataContext } from "../../../Contexts/ScreenDataContext";
14
11
  import { ScreenContextProvider } from "../../../Contexts/ScreenContext";
12
+ import { LayoutBackground } from "./LayoutBackground";
15
13
 
16
14
  type Components = {
17
15
  NavBar: React.ComponentType<any>;
@@ -19,7 +17,6 @@ type Components = {
19
17
  };
20
18
 
21
19
  type ComponentsExtraProps = {
22
- Background?: Record<string, any>;
23
20
  NavBar?: Record<string, any>;
24
21
  };
25
22
 
@@ -31,17 +28,10 @@ type Props = {
31
28
 
32
29
  const Layout = ({ Components, ComponentsExtraProps, children }: Props) => {
33
30
  const navigator = useNavigation();
34
- const theme = useTheme();
35
31
 
36
- const { appState: { appReady = false } = {}, remoteConfigurations } =
37
- usePickFromState(["appState", "remoteConfigurations", "plugins"]);
38
-
39
- const backgroundColor = React.useMemo(() => theme.app_background_color, []);
40
-
41
- const backgroundImageUrl = React.useMemo(
42
- () => getBackgroundImageUrl(remoteConfigurations),
43
- [remoteConfigurations]
44
- );
32
+ const { appState: { appReady = false } = {} } = usePickFromState([
33
+ "appState",
34
+ ]);
45
35
 
46
36
  if (!appReady) {
47
37
  return null;
@@ -50,11 +40,7 @@ const Layout = ({ Components, ComponentsExtraProps, children }: Props) => {
50
40
  return (
51
41
  <LayoutContainer>
52
42
  <ScreenLayoutContextProvider>
53
- <Components.Background
54
- backgroundColor={backgroundColor}
55
- backgroundImageUrl={backgroundImageUrl}
56
- {...R.omit(["ref"])(ComponentsExtraProps?.Background)}
57
- >
43
+ <LayoutBackground Background={Components.Background}>
58
44
  <ScreenDataContext.Provider value={navigator.data}>
59
45
  <PathnameContext.Provider value={navigator.currentRoute}>
60
46
  <ScreenContextProvider pathname={navigator.currentRoute}>
@@ -67,7 +53,7 @@ const Layout = ({ Components, ComponentsExtraProps, children }: Props) => {
67
53
  </ScreenContextProvider>
68
54
  </PathnameContext.Provider>
69
55
  </ScreenDataContext.Provider>
70
- </Components.Background>
56
+ </LayoutBackground>
71
57
  </ScreenLayoutContextProvider>
72
58
  </LayoutContainer>
73
59
  );
@@ -5,6 +5,7 @@ import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
5
5
 
6
6
  import { ScreenLayoutContextProvider } from "./ScreenLayoutContextProvider";
7
7
  import { StackNavigator } from "../../Navigator";
8
+ import { LayoutBackground } from "./LayoutBackground";
8
9
 
9
10
  type Components = {
10
11
  NavBar: React.ComponentType<any>;
@@ -25,7 +26,9 @@ const Layout = ({ Components }: Props) => {
25
26
 
26
27
  return (
27
28
  <ScreenLayoutContextProvider>
28
- <StackNavigator Components={Components} />
29
+ <LayoutBackground Background={Components.Background}>
30
+ <StackNavigator Components={Components} />
31
+ </LayoutBackground>
29
32
  </ScreenLayoutContextProvider>
30
33
  );
31
34
  };