@applicaster/zapp-react-native-ui-components 12.0.0-alpha.3977160850 → 12.0.0-alpha.4400210593

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/Components/Cell/Cell.tsx +2 -2
  2. package/Components/Cell/CellWithFocusable.tsx +21 -14
  3. package/Components/Cell/TvOSCellComponent.tsx +2 -2
  4. package/Components/ErrorScreen/index.tsx +1 -1
  5. package/Components/FocusableCell/index.tsx +7 -7
  6. package/Components/HookRenderer/index.tsx +1 -3
  7. package/Components/Image/Image.android.tsx +3 -25
  8. package/Components/Image/Image.tsx +18 -2
  9. package/Components/Image/utils/index.ts +39 -0
  10. package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +41 -1
  11. package/Components/Layout/TV/__tests__/index.test.tsx +1 -13
  12. package/Components/Layout/TV/index.tsx +1 -1
  13. package/Components/MasterCell/DefaultComponents/Image/Image.android.tsx +9 -26
  14. package/Components/MasterCell/DefaultComponents/Image/hooks/useImageSize.ts +65 -0
  15. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +3 -1
  16. package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +3 -2
  17. package/Components/MasterCell/DefaultComponents/Toggle.tsx +5 -1
  18. package/Components/MasterCell/utils/index.ts +2 -2
  19. package/Components/PlayerContainer/PlayerContainer.tsx +46 -28
  20. package/Components/PlayerContainer/ProgramInfo/index.tsx +3 -1
  21. package/Components/River/__tests__/componentsMap.test.js +1 -0
  22. package/Components/RouteManager/index.tsx +2 -2
  23. package/Components/Screen/__tests__/Screen.test.tsx +5 -1
  24. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +10 -0
  25. package/Components/Screen/index.tsx +15 -6
  26. package/Components/Tabs/TV/styles.ts +1 -1
  27. package/Components/VideoLive/PlayerLiveImageComponent.tsx +31 -28
  28. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +30 -3
  29. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +22 -27
  30. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +211 -163
  31. package/Decorators/ComponentsMapWrapper/withComponentsMapProvider.tsx +7 -2
  32. package/package.json +5 -5
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { View } from "react-native";
3
- import { create, act } from "react-test-renderer";
3
+ import { act, create } from "react-test-renderer";
4
4
 
5
5
  const Mocked_RouteManager = jest.fn((props) => (
6
6
  <View testID="routeManager" {...props} />
@@ -69,12 +69,16 @@ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
69
69
  isNavBarVisible: mockIsNavBarVisible,
70
70
  useRoute: jest.fn(() => ({
71
71
  pathname: "/river/testId",
72
+ screenData: { id: "testId" },
72
73
  })),
73
74
  useNavigation: jest.fn(() => ({
74
75
  canGoBack: () => false,
75
76
  currentRoute: "/river/testId",
77
+ activeRiver: { id: "testId" },
78
+ screenData: { id: "testId" },
76
79
  data: { screen: { id: "testId" } },
77
80
  })),
81
+ useIsScreenActive: jest.fn().mockReturnValue(true),
78
82
  }));
79
83
 
80
84
  jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
@@ -19,6 +19,11 @@ exports[`<Screen Component /> when the navbar should be hidden renders correctly
19
19
  <View>
20
20
  <View
21
21
  pathname="/river/testId"
22
+ screenData={
23
+ Object {
24
+ "id": "testId",
25
+ }
26
+ }
22
27
  testID="routeManager"
23
28
  />
24
29
  </View>
@@ -44,6 +49,11 @@ exports[`<Screen Component /> when the navbar should show renders correctly 1`]
44
49
  <View>
45
50
  <View
46
51
  pathname="/river/testId"
52
+ screenData={
53
+ Object {
54
+ "id": "testId",
55
+ }
56
+ }
47
57
  testID="routeManager"
48
58
  />
49
59
  </View>
@@ -14,6 +14,7 @@ import {
14
14
  useCurrentScreenData,
15
15
  useNavbarState,
16
16
  useScreenData,
17
+ useNavigation,
17
18
  } from "@applicaster/zapp-react-native-utils/reactHooks";
18
19
  import { getNavigationPluginModule } from "@applicaster/zapp-react-native-app/App/Layout/layoutHelpers";
19
20
 
@@ -22,6 +23,17 @@ import { RouteManager } from "../RouteManager";
22
23
  import { useScreenConfiguration } from "../River/useScreenConfiguration";
23
24
  import { useScreenOrientationHandler } from "./orientationHandler";
24
25
 
26
+ const getScreenId = (
27
+ screenData: LegacyNavigationScreenData,
28
+ fallbackRiver: ZappRiver
29
+ ) => {
30
+ return screenData?.targetScreen
31
+ ? screenData?.targetScreen?.id ?? fallbackRiver.id
32
+ : "screen_id" in screenData
33
+ ? screenData.screen_id
34
+ : fallbackRiver.id;
35
+ };
36
+
25
37
  function colorIsNotTransparent(color) {
26
38
  const layers = R.compose(
27
39
  R.map(R.trim),
@@ -40,14 +52,13 @@ function isValidColor(string) {
40
52
  }
41
53
 
42
54
  type Props = {
43
- pathname: string;
44
- screenData: unknown;
45
55
  setToggleMenu: () => void;
46
56
  setCloseMenu: () => void;
47
57
  };
48
58
 
49
59
  export function Screen({ setToggleMenu, setCloseMenu }: Props) {
50
60
  const theme = useTheme<BaseThemePropertiesMobile>();
61
+ const navigation = useNavigation();
51
62
  const { plugins } = usePickFromState(["plugins"]);
52
63
 
53
64
  // Gets the data for the current screen configuration
@@ -62,9 +73,7 @@ export function Screen({ setToggleMenu, setCloseMenu }: Props) {
62
73
  const routeData = useRoute();
63
74
 
64
75
  const currentRiver = useScreenData(
65
- (routeData.screenData as ZappRiver)?.targetScreen
66
- ? (routeData.screenData as ZappRiver)?.targetScreen.id
67
- : (routeData.screenData as ZappRiver)?.screen_id
76
+ getScreenId(routeData.screenData, navigation.activeRiver)
68
77
  );
69
78
 
70
79
  const { title } = useNavbarState();
@@ -128,7 +137,7 @@ export function Screen({ setToggleMenu, setCloseMenu }: Props) {
128
137
  {...{ ...(navBarProps as MobileNavBarPluginProps), id: pathname }}
129
138
  />
130
139
 
131
- <OfflineFallbackScreen screenData={screenData}>
140
+ <OfflineFallbackScreen screenData={targetScreenData}>
132
141
  {/* @TODO RouteManager doesn't use props, can they be removed ? */}
133
142
  <RouteManager pathname={pathname} screenData={screenData} />
134
143
  </OfflineFallbackScreen>
@@ -78,7 +78,7 @@ export const getStyles = (config): Partial<TVTabsStyles> => {
78
78
  },
79
79
  tvos: {
80
80
  marginTop: -1,
81
- }
81
+ },
82
82
  }),
83
83
  },
84
84
  tabsBackground: {
@@ -14,7 +14,7 @@ import {
14
14
  } from "@applicaster/zapp-react-native-utils/reactUtils";
15
15
  import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
16
16
  import { getUserCellPlayerMutedPreference } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/userCellPlayerMutedPreference";
17
- import { PlayerImageBackground } from "../PlayerImageBackground";
17
+ import Image from "@applicaster/zapp-react-native-ui-components/Components/MasterCell/DefaultComponents/Image";
18
18
  import { LiveImage, LiveImageManager, LiveImageType } from "./LiveImageManager";
19
19
 
20
20
  import { AnimatedInOut } from "@applicaster/zapp-react-native-ui-components/Components/AnimatedInOut";
@@ -39,12 +39,13 @@ type Props = {
39
39
  imageKey?: string;
40
40
  screenConfig: Record<string, any>;
41
41
  audioMutedByDefault?: boolean;
42
+ uri: string; // cover image url
42
43
  };
43
44
 
44
45
  const PlayerLiveImageComponent = (props: Props) => {
45
46
  const dimensions = useDimensions("screen", { fullDimensions: true });
46
47
 
47
- const { item, style, playerId, imageKey } = props;
48
+ const { item, style, playerId } = props;
48
49
 
49
50
  const timeoutRef = React.useRef<NodeJS.Timeout | null>(null);
50
51
  const [mode, setMode] = React.useState(LiveImageType.Image);
@@ -63,24 +64,27 @@ const PlayerLiveImageComponent = (props: Props) => {
63
64
  *
64
65
  * @param type video or image
65
66
  */
66
- const setModeDebounced = React.useCallback((type: LiveImageType) => {
67
- if (type === LiveImageType.Video) {
68
- if (type === mode) {
69
- return;
70
- }
67
+ const setModeDebounced = React.useCallback(
68
+ (type: LiveImageType) => {
69
+ if (type === LiveImageType.Video) {
70
+ if (type === mode) {
71
+ return;
72
+ }
73
+
74
+ timeoutRef.current = setTimeout(() => {
75
+ setMode(type);
76
+ }, 1000) as unknown as NodeJS.Timeout;
77
+ } else {
78
+ if (timeoutRef.current) {
79
+ clearTimeout(timeoutRef.current);
80
+ timeoutRef.current = null;
81
+ }
71
82
 
72
- timeoutRef.current = setTimeout(() => {
73
83
  setMode(type);
74
- }, 1000) as unknown as NodeJS.Timeout;
75
- } else {
76
- if (timeoutRef.current) {
77
- clearTimeout(timeoutRef.current);
78
- timeoutRef.current = null;
79
84
  }
80
-
81
- setMode(type);
82
- }
83
- }, [mode]);
85
+ },
86
+ [mode]
87
+ );
84
88
 
85
89
  const { screenConfig, playerPluginId } = props;
86
90
 
@@ -100,7 +104,7 @@ const PlayerLiveImageComponent = (props: Props) => {
100
104
  return new LiveImage({
101
105
  playerId,
102
106
  player: playerFactoryItem.controller,
103
- component: playerFactoryItem?.Component
107
+ component: playerFactoryItem?.Component,
104
108
  });
105
109
  } else {
106
110
  throw new Error("Player factory item is null");
@@ -111,10 +115,7 @@ const PlayerLiveImageComponent = (props: Props) => {
111
115
  liveImageItem.setMode = setModeDebounced;
112
116
  }, [setModeDebounced, liveImageItem]);
113
117
 
114
- const { start, end } = React.useMemo(
115
- () => getAutoplaySettings(item),
116
- [item]
117
- );
118
+ const { start, end } = React.useMemo(() => getAutoplaySettings(item), [item]);
118
119
 
119
120
  const controller = liveImageItem.getPlayer();
120
121
  const player = usePlayer(playerId);
@@ -239,7 +240,12 @@ const PlayerLiveImageComponent = (props: Props) => {
239
240
 
240
241
  const onPositionUpdated = React.useCallback(
241
242
  (data) => {
242
- const normalizedRect = (rect: {left: number, right: number, top: number, bottom: number }) => {
243
+ const normalizedRect = (rect: {
244
+ left: number;
245
+ right: number;
246
+ top: number;
247
+ bottom: number;
248
+ }) => {
243
249
  if (!rect) {
244
250
  return null;
245
251
  }
@@ -283,6 +289,7 @@ const PlayerLiveImageComponent = (props: Props) => {
283
289
  const videoStyles = { ...style, position: "absolute", zIndex: -100 };
284
290
  const Player: any = liveImageItem.component || BufferAnimation;
285
291
 
292
+ // TODO: nice to have - resolve imageKey when imageUrl is not provided
286
293
  return (
287
294
  <TrackedView
288
295
  testId={`tracked-view-${playerId}-${item.title}`}
@@ -307,11 +314,7 @@ const PlayerLiveImageComponent = (props: Props) => {
307
314
  animationConfig={overlayFadeIn}
308
315
  staticStyles={style}
309
316
  >
310
- <PlayerImageBackground
311
- entry={item}
312
- style={style}
313
- imageKey={imageKey}
314
- />
317
+ <Image {...props} resizeMode="cover" style={style} applyMaxSize />
315
318
  </AnimatedInOut>
316
319
  }
317
320
  </TrackedView>
@@ -3,6 +3,9 @@ import * as React from "react";
3
3
  import { render } from "@testing-library/react-native";
4
4
  import * as PlayerFactory from "@applicaster/zapp-react-native-utils/appUtils/playerManager/playerFactory";
5
5
  import { Player } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/player";
6
+ import { ThemeContext } from "@applicaster/zapp-react-native-utils/theme";
7
+ import * as navigationHooks from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
8
+
6
9
  import { PlayerLiveImage } from "../PlayerLiveImageComponent";
7
10
 
8
11
  const seekTo = jest.fn();
@@ -16,6 +19,16 @@ jest.mock(
16
19
  })
17
20
  );
18
21
 
22
+ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation");
23
+
24
+ const Wrapper = ({ children }: { children: React.ReactChildren }) => (
25
+ <ThemeContext.Provider
26
+ value={{ themes: { myTheme: {} }, selectedThemeId: "myTheme" }}
27
+ >
28
+ {children}
29
+ </ThemeContext.Provider>
30
+ );
31
+
19
32
  describe("PlayerLiveImageComponent", () => {
20
33
  const defaultProps = {
21
34
  item: { id: "1", title: "Test", type: { value: "" } },
@@ -36,10 +49,16 @@ describe("PlayerLiveImageComponent", () => {
36
49
  controller: new Player({}),
37
50
  Component: () => null,
38
51
  }));
52
+
53
+ jest.spyOn(navigationHooks, "useIsScreenActive").mockReturnValue(true);
39
54
  });
40
55
 
41
56
  it("should render correctly with default props", () => {
42
- const component = render(<PlayerLiveImage {...defaultProps} />);
57
+ const component = render(
58
+ <Wrapper>
59
+ <PlayerLiveImage {...defaultProps} />
60
+ </Wrapper>
61
+ );
43
62
 
44
63
  expect(component.toJSON()).toMatchSnapshot();
45
64
  });
@@ -53,7 +72,11 @@ describe("PlayerLiveImageComponent", () => {
53
72
  },
54
73
  };
55
74
 
56
- render(<PlayerLiveImage {...props} />);
75
+ render(
76
+ <Wrapper>
77
+ <PlayerLiveImage {...props} />
78
+ </Wrapper>
79
+ );
57
80
 
58
81
  // TODO: implement this test
59
82
  });
@@ -67,7 +90,11 @@ describe("PlayerLiveImageComponent", () => {
67
90
  },
68
91
  };
69
92
 
70
- render(<PlayerLiveImage {...props} />);
93
+ render(
94
+ <Wrapper>
95
+ <PlayerLiveImage {...props} />
96
+ </Wrapper>
97
+ );
71
98
 
72
99
  // TODO: implement this test
73
100
  });
@@ -13,35 +13,30 @@ exports[`PlayerLiveImageComponent should render correctly with default props 1`]
13
13
  }
14
14
  }
15
15
  >
16
- <View
17
- accessibilityIgnoresInvertColors={true}
18
- style={Object {}}
19
- >
20
- <Image
21
- resizeMode="cover"
22
- source={
23
- Object {
24
- "uri": undefined,
25
- }
16
+ <Image
17
+ applyMaxSize={true}
18
+ audioMutedByDefault={false}
19
+ imageKey="image1"
20
+ item={
21
+ Object {
22
+ "id": "1",
23
+ "title": "Test",
24
+ "type": Object {
25
+ "value": "",
26
+ },
26
27
  }
27
- style={
28
- Array [
29
- Object {
30
- "bottom": 0,
31
- "left": 0,
32
- "position": "absolute",
33
- "right": 0,
34
- "top": 0,
35
- },
36
- Object {
37
- "height": undefined,
38
- "width": undefined,
39
- },
40
- undefined,
41
- ]
28
+ }
29
+ onError={[Function]}
30
+ playerId="player1"
31
+ resizeMode="cover"
32
+ screenConfig={Object {}}
33
+ source={
34
+ Object {
35
+ "uri": "",
42
36
  }
43
- />
44
- </View>
37
+ }
38
+ style={Object {}}
39
+ />
45
40
  </View>
46
41
  </TrackedView>
47
42
  `;