@applicaster/zapp-react-native-ui-components 13.0.0-rc.10 → 13.0.0-rc.101

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 (209) hide show
  1. package/Components/AppContainer/__tests__/AppContainer.test.js +4 -6
  2. package/Components/AppContainer/__tests__/__snapshots__/AppContainer.test.js.snap +1 -1
  3. package/Components/AudioPlayer/AudioPlayer.tsx +7 -0
  4. package/Components/AudioPlayer/__tests__/Runtime.test.js +5 -8
  5. package/Components/AudioPlayer/__tests__/__snapshots__/Runtime.test.js.snap +4 -4
  6. package/Components/AudioPlayer/__tests__/__snapshots__/artWork.test.js.snap +3 -3
  7. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +56 -113
  8. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +39 -23
  9. package/Components/AudioPlayer/__tests__/__snapshots__/channel.test.js.snap +3 -3
  10. package/Components/AudioPlayer/__tests__/__snapshots__/summary.test.js.snap +2 -2
  11. package/Components/AudioPlayer/__tests__/__snapshots__/title.test.js.snap +2 -2
  12. package/Components/AudioPlayer/__tests__/artWork.test.js +3 -5
  13. package/Components/AudioPlayer/__tests__/audioPlayer.test.js +3 -5
  14. package/Components/AudioPlayer/__tests__/audioPlayerLayout.test.js +7 -8
  15. package/Components/AudioPlayer/__tests__/channel.test.js +3 -5
  16. package/Components/AudioPlayer/__tests__/summary.test.js +3 -5
  17. package/Components/AudioPlayer/__tests__/title.test.js +3 -5
  18. package/Components/AudioPlayer/helpers.tsx +1 -0
  19. package/Components/BaseFocusable/index.ios.ts +1 -1
  20. package/Components/BaseFocusable/index.tsx +67 -31
  21. package/Components/Cell/Cell.tsx +18 -22
  22. package/Components/Cell/CellWithFocusable.tsx +51 -60
  23. package/Components/Cell/CellWrapper.tsx +18 -0
  24. package/Components/Cell/TvOSCellComponent.tsx +23 -30
  25. package/Components/Cell/__tests__/CellWIthFocusable.test.js +13 -6
  26. package/Components/Cell/index.js +3 -1
  27. package/Components/Cell/styles.ts +17 -0
  28. package/Components/CellRendererResolver/__tests__/cellRendererResolver.test.js +50 -50
  29. package/Components/CellRendererResolver/index.ts +2 -1
  30. package/Components/ComponentResolver/__tests__/__snapshots__/componentResolver.test.js.snap +1 -42
  31. package/Components/ComponentResolver/__tests__/componentResolver.test.js +26 -30
  32. package/Components/ContentScreen/__tests__/contentScreen.test.js +3 -3
  33. package/Components/DisplayState/__tests__/__snapshots__/displayState.test.js.snap +2 -2
  34. package/Components/ErrorScreen/index.tsx +14 -6
  35. package/Components/Focusable/Focusable.tsx +1 -54
  36. package/Components/Focusable/FocusableTvOS.tsx +6 -2
  37. package/Components/Focusable/Touchable.tsx +19 -20
  38. package/Components/Focusable/index.android.tsx +10 -3
  39. package/Components/FocusableCell/index.tsx +1 -1
  40. package/Components/FocusableGroup/FocusableTvOS.tsx +34 -86
  41. package/Components/FocusableGroup/index.tsx +0 -3
  42. package/Components/FocusableList/index.tsx +26 -10
  43. package/Components/FocusableScrollView/index.tsx +43 -13
  44. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +76 -7
  45. package/Components/GeneralContentScreen/utils/useCurationAPI.ts +53 -9
  46. package/Components/HandlePlayable/HandlePlayable.tsx +21 -27
  47. package/Components/Layout/TV/LayoutBackground.tsx +28 -0
  48. package/Components/Layout/TV/NavBarContainer.tsx +19 -23
  49. package/Components/Layout/TV/ScreenContainer.tsx +8 -2
  50. package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +5 -0
  51. package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +3 -1
  52. package/Components/Layout/TV/__tests__/__snapshots__/LayoutContainer.test.tsx.snap +1 -1
  53. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +6 -5
  54. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +12 -11
  55. package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +15 -10
  56. package/Components/Layout/TV/__tests__/index.test.tsx +14 -4
  57. package/Components/Layout/TV/index.tsx +6 -20
  58. package/Components/Layout/TV/index.web.tsx +4 -1
  59. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -3
  60. package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +66 -0
  61. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +4 -1
  62. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +10 -15
  63. package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +11 -7
  64. package/Components/MasterCell/DefaultComponents/ImageBorderContainer/__tests__/index.test.ts +93 -0
  65. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -2
  66. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/__snapshots__/Image.test.tsx.snap +3 -3
  67. package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +1 -1
  68. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
  69. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/const.ts +3 -0
  70. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +6 -6
  71. package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/__snapshots__/index.test.tsx.snap +1 -1
  72. package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +2 -8
  73. package/Components/MasterCell/__tests__/__snapshots__/dataAdapter.test.js.snap +180 -180
  74. package/Components/MasterCell/__tests__/__snapshots__/elementMapper.test.js.snap +11 -19
  75. package/Components/MasterCell/__tests__/__snapshots__/masterCell.test.js.snap +6 -235
  76. package/Components/MasterCell/__tests__/elementMapper.test.js +18 -5
  77. package/Components/MasterCell/__tests__/masterCell.test.js +26 -26
  78. package/Components/MasterCell/hooks/useAsyncRendering/MasterCellAsyncRenderManager.ts +2 -2
  79. package/Components/MasterCell/hooks/useAsyncRendering/index.ts +2 -2
  80. package/Components/MasterCell/utils/behaviorProvider.ts +136 -0
  81. package/Components/MasterCell/utils/index.ts +9 -135
  82. package/Components/ModalComponent/BottomSheetModalContent.tsx +45 -19
  83. package/Components/ModalComponent/Button/Item.tsx +6 -5
  84. package/Components/ModalComponent/Button/assets.ts +1 -1
  85. package/Components/ModalComponent/Button/index.tsx +30 -43
  86. package/Components/ModalComponent/Header/index.tsx +3 -3
  87. package/Components/ModalComponent/utils.ts +55 -7
  88. package/Components/NativeFocusables/{index.js → index.ts} +4 -2
  89. package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +2 -2
  90. package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +2 -2
  91. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -5
  92. package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +7 -7
  93. package/Components/OfflineHandler/__tests__/index.test.tsx +28 -25
  94. package/Components/OfflineHandler/utils/index.ts +1 -1
  95. package/Components/PlayerContainer/PlayerContainer.tsx +45 -25
  96. package/Components/PlayerContainer/PlayerContainerContext.tsx +9 -0
  97. package/Components/PlayerContainer/ProgramInfo/index.tsx +2 -2
  98. package/Components/PlayerImageBackground/index.tsx +1 -1
  99. package/Components/River/ComponentsMap/ComponentsMap.tsx +42 -65
  100. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +78 -51
  101. package/Components/River/RefreshControl.tsx +1 -1
  102. package/Components/River/RiverFooter.tsx +39 -9
  103. package/Components/River/RiverItem.tsx +39 -3
  104. package/Components/River/TV/index.tsx +6 -1
  105. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +114 -45
  106. package/Components/River/__tests__/__snapshots__/river.test.js.snap +21 -83
  107. package/Components/River/__tests__/componentsMap.test.js +64 -17
  108. package/Components/River/__tests__/river.test.js +75 -40
  109. package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +12 -5
  110. package/Components/RouteManager/__tests__/routeManager.test.js +29 -14
  111. package/Components/RouteManager/__tests__/testId.test.js +8 -6
  112. package/Components/Screen/TV/index.web.tsx +5 -6
  113. package/Components/Screen/__tests__/Screen.test.tsx +41 -27
  114. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +4 -4
  115. package/Components/Screen/hooks.ts +53 -0
  116. package/Components/Screen/index.tsx +16 -42
  117. package/Components/ScreenResolver/__tests__/screenResolver.test.js +95 -70
  118. package/Components/Tabs/Tab.tsx +12 -9
  119. package/Components/TextInputTv/__tests__/TextInputTv.test.js +42 -42
  120. package/Components/TextInputTv/__tests__/__snapshots__/TextInputTv.test.js.snap +7 -0
  121. package/Components/TextInputTv/index.tsx +6 -5
  122. package/Components/TopMarginApplicator/TopMarginApplicator.tsx +2 -3
  123. package/Components/Touchable/__tests__/__snapshots__/touchable.test.tsx.snap +2 -2
  124. package/Components/TrackedView/index.tsx +1 -0
  125. package/Components/Transitioner/AnimationManager.js +15 -15
  126. package/Components/Transitioner/Scene.tsx +53 -24
  127. package/Components/Transitioner/Transitioner.tsx +3 -3
  128. package/Components/Transitioner/__tests__/Scene.test.js +25 -14
  129. package/Components/Transitioner/__tests__/__snapshots__/AnimationManager.test.js.snap +26 -26
  130. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +10 -50
  131. package/Components/Transitioner/__tests__/__snapshots__/config.test.js.snap +20 -20
  132. package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +4 -4
  133. package/Components/Transitioner/__tests__/transitioner.test.js +13 -4
  134. package/Components/Transitioner/index.js +8 -4
  135. package/Components/VideoLive/LiveImageManager.ts +27 -1
  136. package/Components/VideoLive/PlayerLiveImageComponent.tsx +36 -24
  137. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +63 -8
  138. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +6 -10
  139. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +1 -1
  140. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +51 -31
  141. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +8 -4
  142. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +48 -22
  143. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +15 -15
  144. package/Components/VideoModal/ModalAnimation/__tests__/getMoveUpValue.test.ts +108 -0
  145. package/Components/VideoModal/ModalAnimation/const.ts +5 -0
  146. package/Components/VideoModal/ModalAnimation/index.ts +4 -1
  147. package/Components/VideoModal/ModalAnimation/useModalAnimationContext.ts +6 -0
  148. package/Components/VideoModal/ModalAnimation/utils.ts +38 -2
  149. package/Components/VideoModal/OpaqueLayer.tsx +33 -0
  150. package/Components/VideoModal/PlayerDetails.tsx +18 -10
  151. package/Components/VideoModal/PlayerWrapper.tsx +43 -39
  152. package/Components/VideoModal/VideoModal.tsx +17 -11
  153. package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +5 -2
  154. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +13 -10
  155. package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -40
  156. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +66 -156
  157. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +89 -0
  158. package/Components/VideoModal/hooks/index.ts +7 -0
  159. package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +49 -0
  160. package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +91 -0
  161. package/Components/VideoModal/hooks/utils/index.ts +33 -0
  162. package/Components/VideoModal/utils.ts +6 -9
  163. package/Components/Viewport/ViewportAware/__tests__/__snapshots__/viewportAware.test.js.snap +24 -36
  164. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -18
  165. package/Components/Viewport/ViewportTracker/__tests__/__snapshots__/viewportTracker.test.js.snap +1 -1
  166. package/Components/Viewport/__tests__/utils.test.js +5 -4
  167. package/Components/ZappUIComponent/Placeholder.tsx +3 -1
  168. package/Components/ZappUIComponent/__tests__/{ZappUIComponent.test.js → ZappUIComponent.test.tsx} +26 -10
  169. package/Components/ZappUIComponent/index.tsx +4 -17
  170. package/Components/default-cell-renderer/__tests__/defaultCellRenderer.test.tsx +20 -17
  171. package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/__tests__/DefaultCell.test.tsx +15 -11
  172. package/Contexts/ComponentsMapOffsetContext/index.tsx +49 -0
  173. package/Contexts/ConfigutaionContext/__tests__/__snapshots__/ConfigurationProvider.test.tsx.snap +1 -1
  174. package/Contexts/FocusableGroupContext/withFocusableContext.tsx +4 -10
  175. package/Contexts/HeaderOffsetContext/index.tsx +4 -6
  176. package/Contexts/ScreenContext/index.tsx +6 -12
  177. package/Contexts/ScreenLayoutContext/index.tsx +5 -3
  178. package/Decorators/Analytics/{index.js → index.tsx} +11 -11
  179. package/Decorators/Navigator/__tests__/navigator.test.js +16 -16
  180. package/Decorators/Navigator/index.tsx +1 -1
  181. package/Decorators/RiverFeedLoader/__tests__/__snapshots__/riverFeedLoader.test.tsx.snap +77 -77
  182. package/Decorators/RiverFeedLoader/__tests__/riverFeedLoader.test.tsx +34 -39
  183. package/Decorators/RiverFeedLoader/__tests__/utils.test.ts +0 -9
  184. package/Decorators/RiverFeedLoader/index.tsx +1 -1
  185. package/Decorators/RiverFeedLoader/utils/getDatasourceUrl.ts +39 -0
  186. package/Decorators/RiverFeedLoader/utils/index.ts +29 -0
  187. package/Decorators/RiverFeedLoader/utils/usePipesContexts.ts +40 -0
  188. package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +27 -27
  189. package/Decorators/RiverResolver/index.tsx +6 -8
  190. package/Decorators/ZappPipesDataConnector/__tests__/Hero.js +1 -1
  191. package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +29 -22
  192. package/Decorators/ZappPipesDataConnector/index.tsx +7 -3
  193. package/package.json +13 -11
  194. package/tsconfig.json +2 -3
  195. package/.babelrc +0 -8
  196. package/Components/Cell/CellStyles/FallbackCellStyle/index.js +0 -157
  197. package/Components/Cell/CellStyles/Hero/index.js +0 -111
  198. package/Components/Cell/CellStyles/ScreenSelector/index.js +0 -68
  199. package/Components/Cell/CellStyles/cellStylesResolver.ts +0 -19
  200. package/Components/Cell/CellStyles/colors.js +0 -40
  201. package/Components/Cell/CellStyles/index.js +0 -15
  202. package/Components/CellRendererResolver/__tests__/__snapshots__/cellRendererResolver.test.js.snap +0 -53
  203. package/Components/RouteManager/__tests__/__snapshots__/testId.test.js.snap +0 -17
  204. package/Components/ScreenResolver/__tests__/__snapshots__/screenResolver.test.js.snap +0 -17
  205. package/Components/ZappUIComponent/__tests__/__snapshots__/ZappUIComponent.test.js.snap +0 -91
  206. package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +0 -338
  207. package/Decorators/Navigator/__tests__/__snapshots__/navigator.test.js.snap +0 -18
  208. package/Decorators/RiverFeedLoader/utils.ts +0 -100
  209. package/Decorators/RiverResolver/__tests__/__snapshots__/riverResolver.test.tsx.snap +0 -28
@@ -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
+ };
@@ -1,9 +1,5 @@
1
1
  import * as React from "react";
2
- import { View, StyleSheet } from "react-native";
3
- import { ScreenLayoutContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenLayoutContext";
4
- import { ifEmptyUseFallback } from "@applicaster/zapp-react-native-utils/cellUtils";
5
- import { useCurrentScreenData } from "@applicaster/zapp-react-native-utils/reactHooks/screen";
6
- import { useScreenConfiguration } from "../../River/useScreenConfiguration";
2
+ import { StyleSheet, View } from "react-native";
7
3
 
8
4
  type Props = {
9
5
  children: React.ReactNode;
@@ -12,33 +8,33 @@ type Props = {
12
8
  };
13
9
 
14
10
  const styles = StyleSheet.create({
15
- container: { position: "absolute", top: 0, zIndex: 10, width: 1920 },
11
+ container: {
12
+ position: "absolute",
13
+ top: 0,
14
+ zIndex: 10,
15
+ flex: 1,
16
+ width: "100%",
17
+ },
18
+ themeStyles: {
19
+ // limits the height of the focusable container of the TopMenuBarTV component
20
+ // to prevent it from being overlapped by the screen content,
21
+ // as it makes TopMenuBarTV unfocusable on tvOS
22
+ maxHeight: 1,
23
+ },
16
24
  });
17
25
 
18
26
  export const NavBarContainer = ({ children, isVisible, onReady }: Props) => {
19
- const screenLayout = React.useContext(ScreenLayoutContext);
20
- const screenMarginTop = screenLayout?.screenMarginTop || 0;
21
- const screen = useCurrentScreenData();
22
- const screenConfig = useScreenConfiguration(screen?.id);
23
-
24
- const themeStyles = React.useMemo(
25
- () => ({
26
- // limits the height of the focusable container of the TopMenuBarTV component
27
- // to prevent it from being overlapped by the screen content,
28
- // as it makes TopMenuBarTV unfocusable on tvOS
29
- maxHeight: ifEmptyUseFallback(screenConfig?.marginTop, screenMarginTop),
30
- }),
31
- [screenLayout, screenConfig]
32
- );
33
-
34
27
  React.useEffect(() => {
35
28
  setTimeout(() => {
36
29
  onReady?.(true);
37
30
  }, 0);
38
- }, []);
31
+ }, [onReady]);
39
32
 
40
33
  return isVisible ? (
41
- <View testID="nav-bar-container" style={[styles.container, themeStyles]}>
34
+ <View
35
+ testID="nav-bar-container"
36
+ style={[styles.container, styles.themeStyles]}
37
+ >
42
38
  {children}
43
39
  </View>
44
40
  ) : null;
@@ -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
 
@@ -55,8 +54,11 @@ export const ScreenContainer = React.memo(function ScreenContainer({
55
54
  ComponentsExtraProps,
56
55
  NavBar,
57
56
  }: Props) {
58
- const { screenMarginBottom } = React.useContext(ScreenLayoutContext);
57
+ const { screenMarginBottom, resetScreenLayout } =
58
+ React.useContext(ScreenLayoutContext);
59
+
59
60
  const { currentRoute, screenData } = useNavigation();
61
+
60
62
  const screen = useCurrentScreenData();
61
63
 
62
64
  const { marginBottom, backgroundColor, paddingTop, paddingBottom } =
@@ -65,6 +67,10 @@ export const ScreenContainer = React.memo(function ScreenContainer({
65
67
  const theme = useTheme();
66
68
  const getThemeValue = React.useCallback(R.propOr(0, R.__, theme), [theme]);
67
69
 
70
+ React.useEffect(() => {
71
+ resetScreenLayout();
72
+ }, [currentRoute]);
73
+
68
74
  const fullscreen = React.useCallback(
69
75
  displayFullScreen({ currentRoute, screenData }),
70
76
  [currentRoute, screenData]
@@ -60,10 +60,15 @@ export function ScreenLayoutContextProvider(props: {
60
60
  initialState
61
61
  );
62
62
 
63
+ const resetScreenLayout = React.useCallback(() => {
64
+ setScreenLayout(initialState);
65
+ }, [initialState]);
66
+
63
67
  const screenLayoutValue = React.useMemo(
64
68
  () => ({
65
69
  ...screenLayout,
66
70
  setScreenLayout,
71
+ resetScreenLayout,
67
72
  }),
68
73
  [screenLayout]
69
74
  );
@@ -39,6 +39,7 @@ jest.mock(
39
39
  );
40
40
 
41
41
  jest.mock("@applicaster/zapp-react-native-utils/theme", () => ({
42
+ ...jest.requireActual<any>("@applicaster/zapp-react-native-utils/theme"),
42
43
  useTheme: () => ({}),
43
44
  }));
44
45
 
@@ -55,11 +56,12 @@ describe("ScreenContainer", () => {
55
56
  };
56
57
 
57
58
  const setScreenLayout = () => {};
59
+ const resetScreenLayout = () => {};
58
60
 
59
61
  const wrapper = ({ children }) => (
60
62
  <WrappedWithProviders>
61
63
  <ScreenLayoutContext.Provider
62
- value={{ ...screenLayout, setScreenLayout }}
64
+ value={{ ...screenLayout, setScreenLayout, resetScreenLayout }}
63
65
  >
64
66
  <ScreenContainer NavBar={View}>{children}</ScreenContainer>
65
67
  </ScreenLayoutContext.Provider>
@@ -3,7 +3,7 @@
3
3
  exports[`LayoutContainer renders 1`] = `
4
4
  <View
5
5
  style={
6
- Object {
6
+ {
7
7
  "flex": 1,
8
8
  "height": 1080,
9
9
  "width": 1920,
@@ -3,15 +3,16 @@
3
3
  exports[`NavBarContainer renders 1`] = `
4
4
  <View
5
5
  style={
6
- Array [
7
- Object {
6
+ [
7
+ {
8
+ "flex": 1,
8
9
  "position": "absolute",
9
10
  "top": 0,
10
- "width": 1920,
11
+ "width": "100%",
11
12
  "zIndex": 10,
12
13
  },
13
- Object {
14
- "maxHeight": 10,
14
+ {
15
+ "maxHeight": 1,
15
16
  },
16
17
  ]
17
18
  }
@@ -4,8 +4,8 @@ exports[`ScreenContainer renders 1`] = `
4
4
  <RNCSafeAreaProvider
5
5
  onInsetsChange={[Function]}
6
6
  style={
7
- Array [
8
- Object {
7
+ [
8
+ {
9
9
  "flex": 1,
10
10
  },
11
11
  undefined,
@@ -14,15 +14,16 @@ exports[`ScreenContainer renders 1`] = `
14
14
  >
15
15
  <View
16
16
  style={
17
- Array [
18
- Object {
17
+ [
18
+ {
19
+ "flex": 1,
19
20
  "position": "absolute",
20
21
  "top": 0,
21
- "width": 1920,
22
+ "width": "100%",
22
23
  "zIndex": 10,
23
24
  },
24
- Object {
25
- "maxHeight": 10,
25
+ {
26
+ "maxHeight": 1,
26
27
  },
27
28
  ]
28
29
  }
@@ -30,7 +31,7 @@ exports[`ScreenContainer renders 1`] = `
30
31
  >
31
32
  <View
32
33
  isVisible={true}
33
- menuPlugin={Object {}}
34
+ menuPlugin={{}}
34
35
  navigationProps={null}
35
36
  />
36
37
  </View>
@@ -38,13 +39,13 @@ exports[`ScreenContainer renders 1`] = `
38
39
  `;
39
40
 
40
41
  exports[`ScreenContainer sets margins provided by the theme 1`] = `
41
- Array [
42
- Object {
42
+ [
43
+ {
43
44
  "flex": 1,
44
45
  "height": "100%",
45
46
  "width": "100%",
46
47
  },
47
- Object {
48
+ {
48
49
  "backgroundColor": "transparent",
49
50
  "marginBottom": 10,
50
51
  "paddingBottom": 0,
@@ -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
- Object {
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,14 +5,24 @@ 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
 
11
- jest.mock("../../../Screen/TV/index.web", () => ({
12
- Screen: View,
13
- }));
19
+ jest.mock("../../../Screen/TV/index.web", () => {
20
+ const View = jest.requireActual("react-native").View;
14
21
 
15
- const Layout = require("../index.web").default;
22
+ return {
23
+ Screen: View,
24
+ };
25
+ });
16
26
 
17
27
  const mockStore = configureStore()({
18
28
  appState: { appReady: true },
@@ -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
  };
@@ -4,7 +4,6 @@ import { TouchableOpacity, ViewStyle } from "react-native";
4
4
  import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
5
5
 
6
6
  import Image from "./Image";
7
-
8
7
  type Props = {
9
8
  item: ZappEntry | ZappFeed;
10
9
  flavour?: "flavour_1" | "flavour_2";
@@ -69,7 +68,7 @@ export function ActionButton(props: Props) {
69
68
  if (!((actionDisabled || !actionContext) && actionState !== null)) {
70
69
  setActionState(actionContext.initialEntryState(item));
71
70
  }
72
- }, [actionDisabled, item?.id, actionContext, action]);
71
+ }, [actionDisabled, item?.id, actionContext, action, setActionState]);
73
72
 
74
73
  const onPress = useCallback(() => {
75
74
  actionContext.invokeAction(item, {
@@ -85,7 +84,7 @@ export function ActionButton(props: Props) {
85
84
  setActionState(state);
86
85
  });
87
86
  }
88
- }, [item?.id]);
87
+ }, [item?.id, setActionState, actionContext]);
89
88
 
90
89
  if (actionDisabled || !actionContext) return null;
91
90
  const AssetComponent = actionState?.asset;
@@ -0,0 +1,66 @@
1
+ import {
2
+ BorderContainerView,
3
+ getBorderPadding, // Export for testing (using a double underscore prefix is a common convention)
4
+ } from "../index";
5
+ import * as React from "react";
6
+ import { render } from "@testing-library/react-native";
7
+ import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
8
+ import { View } from "react-native";
9
+
10
+ jest.mock("@applicaster/zapp-react-native-utils/numberUtils", () => ({
11
+ toNumberWithDefaultZero: jest.fn((value) => Number(value) || 0),
12
+ }));
13
+
14
+ describe("BorderContainerView", () => {
15
+ describe("getBorderPadding", () => {
16
+ it("returns 0 for inside", () => {
17
+ expect(getBorderPadding("inside", 10)).toBe(0);
18
+ });
19
+
20
+ it("returns borderWidth / 2 for center", () => {
21
+ expect(getBorderPadding("center", 10)).toBe(5);
22
+ });
23
+
24
+ it("returns borderWidth for outside", () => {
25
+ expect(getBorderPadding("outside", 10)).toBe(10);
26
+ });
27
+
28
+ it("returns borderWidth for invalid position", () => {
29
+ // @ts-ignore
30
+ expect(getBorderPadding("other_value", 10)).toBe(10);
31
+ });
32
+ });
33
+
34
+ it("Border component renders null if no borderPosition", () => {
35
+ const style = { borderWidth: 5, borderRadius: 10, borderColor: "red" };
36
+
37
+ const padding = {
38
+ paddingTop: 2,
39
+ paddingRight: 3,
40
+ paddingBottom: 4,
41
+ paddingLeft: 5,
42
+ };
43
+
44
+ const borderPosition = null;
45
+
46
+ const { queryByTestId } = render(
47
+ <BorderContainerView
48
+ style={style}
49
+ testID="border-container"
50
+ borderPosition={borderPosition}
51
+ borderPaddingTop={toNumberWithDefaultZero(padding.paddingTop)}
52
+ borderPaddingRight={toNumberWithDefaultZero(padding.paddingRight)}
53
+ borderPaddingBottom={toNumberWithDefaultZero(padding.paddingBottom)}
54
+ borderPaddingLeft={toNumberWithDefaultZero(padding.paddingLeft)}
55
+ >
56
+ <View testID="child" />
57
+ </BorderContainerView>
58
+ );
59
+
60
+ const children = queryByTestId("border-container").children;
61
+
62
+ expect(children[1].props.testID).toBe("child");
63
+
64
+ expect(children[0].children.length).toBe(0);
65
+ });
66
+ });
@@ -28,7 +28,10 @@ const styles = StyleSheet.create({
28
28
  },
29
29
  });
30
30
 
31
- const getBorderPadding = (borderPosition: BorderPosition, borderWidth) => {
31
+ export const getBorderPadding = (
32
+ borderPosition: BorderPosition,
33
+ borderWidth: number
34
+ ) => {
32
35
  switch (borderPosition) {
33
36
  case "inside":
34
37
  return 0;
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { Image as RnImage, ImageStyle } from "react-native";
3
- import * as R from "ramda";
3
+ import { equals, omit } from "ramda";
4
4
 
5
5
  import { useImageSource } from "./hooks";
6
6
 
@@ -17,7 +17,7 @@ type Props = Record<string, any> & {
17
17
  withDimensions: (source: Source) => Source;
18
18
  };
19
19
 
20
- const MemoizedImage = React.memo(RnImage, R.equals);
20
+ const MemoizedImage = React.memo(RnImage, equals);
21
21
 
22
22
  function Image({
23
23
  style,
@@ -38,23 +38,18 @@ function Image({
38
38
 
39
39
  const shouldRenderImg = source && !error;
40
40
 
41
- // Default placeholder image fallback is empty string because it won't rerender
42
- // in case of undefined or {uri: undefined} source
43
- // https://github.com/facebook/react-native/issues/9195
44
- const defaultPlaceHolderImage = React.useMemo(
45
- () => ({ uri: placeholderImage || "" }),
46
- [source, error]
47
- );
41
+ const _source = shouldRenderImg
42
+ ? withDimensions(source)
43
+ : { uri: placeholderImage };
48
44
 
49
45
  return (
50
- // @ts-ignore
51
46
  <MemoizedImage
47
+ key={_source?.uri || "no-image"}
52
48
  style={style as ImageStyle}
53
- onError={() => setErrorState(true)}
54
- source={
55
- shouldRenderImg ? withDimensions(source) : defaultPlaceHolderImage
56
- }
57
- {...R.omit(["source"], otherProps)}
49
+ onError={React.useCallback(() => setErrorState(true), [])}
50
+ // as we have defaults as "" for placeholder image, we need to pass undefined to source to not throw warnings
51
+ source={_source?.uri ? _source : undefined}
52
+ {...omit(["source"], otherProps)}
58
53
  />
59
54
  );
60
55
  }