@applicaster/zapp-react-native-ui-components 13.0.0-alpha.3528549047 → 13.0.0-alpha.3546196593

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 (145) hide show
  1. package/Components/AppContainer/__tests__/AppContainer.test.js +4 -6
  2. package/Components/AudioPlayer/AudioPlayer.tsx +7 -0
  3. package/Components/AudioPlayer/__tests__/Runtime.test.js +5 -8
  4. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +54 -111
  5. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +36 -20
  6. package/Components/AudioPlayer/__tests__/artWork.test.js +3 -5
  7. package/Components/AudioPlayer/__tests__/audioPlayer.test.js +3 -5
  8. package/Components/AudioPlayer/__tests__/audioPlayerLayout.test.js +7 -8
  9. package/Components/AudioPlayer/__tests__/channel.test.js +3 -5
  10. package/Components/AudioPlayer/__tests__/summary.test.js +3 -5
  11. package/Components/AudioPlayer/__tests__/title.test.js +3 -5
  12. package/Components/AudioPlayer/helpers.tsx +1 -0
  13. package/Components/BaseFocusable/index.ios.ts +1 -1
  14. package/Components/BaseFocusable/index.tsx +2 -3
  15. package/Components/Cell/Cell.tsx +11 -16
  16. package/Components/Cell/CellWithFocusable.tsx +48 -59
  17. package/Components/Cell/CellWrapper.ts +5 -0
  18. package/Components/Cell/TvOSCellComponent.tsx +20 -22
  19. package/Components/Cell/__tests__/CellWIthFocusable.test.js +13 -6
  20. package/Components/Cell/index.js +3 -1
  21. package/Components/Cell/styles.ts +17 -0
  22. package/Components/CellRendererResolver/__tests__/cellRendererResolver.test.js +46 -48
  23. package/Components/ComponentResolver/__tests__/__snapshots__/componentResolver.test.js.snap +1 -42
  24. package/Components/ComponentResolver/__tests__/componentResolver.test.js +16 -22
  25. package/Components/ContentScreen/__tests__/contentScreen.test.js +3 -3
  26. package/Components/ErrorScreen/index.tsx +14 -6
  27. package/Components/Focusable/Focusable.tsx +1 -0
  28. package/Components/Focusable/FocusableTvOS.tsx +5 -1
  29. package/Components/Focusable/Touchable.tsx +19 -20
  30. package/Components/Focusable/index.android.tsx +10 -3
  31. package/Components/FocusableCell/index.tsx +1 -1
  32. package/Components/FocusableGroup/FocusableTvOS.tsx +34 -86
  33. package/Components/FocusableGroup/index.tsx +0 -3
  34. package/Components/FocusableList/index.tsx +26 -9
  35. package/Components/FocusableScrollView/index.tsx +43 -13
  36. package/Components/HandlePlayable/HandlePlayable.tsx +14 -27
  37. package/Components/Layout/TV/NavBarContainer.tsx +19 -23
  38. package/Components/Layout/TV/ScreenContainer.tsx +8 -1
  39. package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +5 -0
  40. package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +2 -1
  41. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +3 -2
  42. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +3 -2
  43. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -3
  44. package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +66 -0
  45. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +4 -1
  46. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +9 -14
  47. package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +11 -7
  48. package/Components/MasterCell/DefaultComponents/ImageBorderContainer/__tests__/index.test.ts +93 -0
  49. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -2
  50. package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +1 -1
  51. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
  52. package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +2 -8
  53. package/Components/MasterCell/__tests__/__snapshots__/elementMapper.test.js.snap +4 -12
  54. package/Components/MasterCell/__tests__/__snapshots__/masterCell.test.js.snap +0 -229
  55. package/Components/MasterCell/__tests__/elementMapper.test.js +18 -5
  56. package/Components/MasterCell/__tests__/masterCell.test.js +26 -26
  57. package/Components/MasterCell/hooks/useAsyncRendering/MasterCellAsyncRenderManager.ts +2 -2
  58. package/Components/MasterCell/utils/behaviorProvider.ts +136 -0
  59. package/Components/MasterCell/utils/index.ts +9 -135
  60. package/Components/ModalComponent/Button/assets.ts +1 -1
  61. package/Components/ModalComponent/Button/index.tsx +6 -6
  62. package/Components/ModalComponent/Header/index.tsx +3 -3
  63. package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +2 -2
  64. package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +2 -2
  65. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -5
  66. package/Components/OfflineHandler/utils/index.ts +1 -1
  67. package/Components/PlayerContainer/PlayerContainer.tsx +17 -13
  68. package/Components/PlayerContainer/ProgramInfo/index.tsx +2 -2
  69. package/Components/PlayerImageBackground/index.tsx +1 -1
  70. package/Components/River/ComponentsMap/ComponentsMap.tsx +42 -65
  71. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +78 -51
  72. package/Components/River/RiverFooter.tsx +39 -9
  73. package/Components/River/RiverItem.tsx +37 -2
  74. package/Components/River/TV/index.tsx +6 -1
  75. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +100 -31
  76. package/Components/River/__tests__/__snapshots__/river.test.js.snap +20 -82
  77. package/Components/River/__tests__/componentsMap.test.js +3 -4
  78. package/Components/River/__tests__/river.test.js +75 -40
  79. package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +11 -4
  80. package/Components/RouteManager/__tests__/routeManager.test.js +29 -14
  81. package/Components/RouteManager/__tests__/testId.test.js +8 -6
  82. package/Components/Screen/TV/index.web.tsx +5 -6
  83. package/Components/Screen/hooks.ts +53 -0
  84. package/Components/Screen/index.tsx +16 -42
  85. package/Components/ScreenResolver/__tests__/screenResolver.test.js +91 -70
  86. package/Components/Tabs/Tab.tsx +11 -9
  87. package/Components/TextInputTv/index.tsx +4 -3
  88. package/Components/TrackedView/index.tsx +1 -0
  89. package/Components/Transitioner/AnimationManager.js +15 -15
  90. package/Components/Transitioner/Scene.tsx +53 -24
  91. package/Components/Transitioner/Transitioner.tsx +3 -3
  92. package/Components/Transitioner/__tests__/Scene.test.js +25 -14
  93. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +9 -49
  94. package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +2 -2
  95. package/Components/Transitioner/__tests__/transitioner.test.js +13 -4
  96. package/Components/Transitioner/index.js +8 -4
  97. package/Components/VideoLive/LiveImageManager.ts +27 -1
  98. package/Components/VideoLive/PlayerLiveImageComponent.tsx +36 -24
  99. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +51 -1
  100. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +1 -5
  101. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +1 -1
  102. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +44 -30
  103. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +3 -3
  104. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +31 -17
  105. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +4 -5
  106. package/Components/VideoModal/ModalAnimation/utils.ts +2 -2
  107. package/Components/VideoModal/PlayerDetails.tsx +9 -6
  108. package/Components/VideoModal/PlayerWrapper.tsx +2 -2
  109. package/Components/VideoModal/VideoModal.tsx +2 -2
  110. package/Components/Viewport/ViewportAware/__tests__/__snapshots__/viewportAware.test.js.snap +24 -36
  111. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -18
  112. package/Components/Viewport/__tests__/utils.test.js +5 -4
  113. package/Components/ZappUIComponent/Placeholder.tsx +3 -1
  114. package/Components/ZappUIComponent/__tests__/{ZappUIComponent.test.js → ZappUIComponent.test.tsx} +26 -10
  115. package/Components/ZappUIComponent/index.tsx +11 -17
  116. package/Components/default-cell-renderer/__tests__/defaultCellRenderer.test.tsx +20 -17
  117. package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/__tests__/DefaultCell.test.tsx +15 -11
  118. package/Contexts/ComponentsMapOffsetContext/index.tsx +49 -0
  119. package/Contexts/FocusableGroupContext/withFocusableContext.tsx +4 -10
  120. package/Contexts/HeaderOffsetContext/index.tsx +4 -6
  121. package/Contexts/ScreenContext/index.tsx +6 -12
  122. package/Contexts/ScreenLayoutContext/index.tsx +5 -3
  123. package/Decorators/Navigator/__tests__/navigator.test.js +16 -16
  124. package/Decorators/Navigator/index.tsx +1 -1
  125. package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +18 -24
  126. package/Decorators/RiverResolver/index.tsx +6 -8
  127. package/Decorators/ZappPipesDataConnector/__tests__/Hero.js +1 -1
  128. package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +29 -22
  129. package/Decorators/ZappPipesDataConnector/index.tsx +4 -30
  130. package/package.json +7 -11
  131. package/tsconfig.json +2 -3
  132. package/.babelrc +0 -8
  133. package/Components/Cell/CellStyles/FallbackCellStyle/index.js +0 -157
  134. package/Components/Cell/CellStyles/Hero/index.js +0 -111
  135. package/Components/Cell/CellStyles/ScreenSelector/index.js +0 -68
  136. package/Components/Cell/CellStyles/cellStylesResolver.ts +0 -19
  137. package/Components/Cell/CellStyles/colors.js +0 -40
  138. package/Components/Cell/CellStyles/index.js +0 -15
  139. package/Components/CellRendererResolver/__tests__/__snapshots__/cellRendererResolver.test.js.snap +0 -53
  140. package/Components/RouteManager/__tests__/__snapshots__/testId.test.js.snap +0 -17
  141. package/Components/ScreenResolver/__tests__/__snapshots__/screenResolver.test.js.snap +0 -17
  142. package/Components/ZappUIComponent/__tests__/__snapshots__/ZappUIComponent.test.js.snap +0 -91
  143. package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +0 -338
  144. package/Decorators/Navigator/__tests__/__snapshots__/navigator.test.js.snap +0 -18
  145. package/Decorators/RiverResolver/__tests__/__snapshots__/riverResolver.test.tsx.snap +0 -28
@@ -1,63 +1,23 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`<Scene /> renders correctly 1`] = `
4
- <ForwardRef(AnimatedComponentWrapper)
5
- pointerEvents="auto"
6
- style={
7
- [
4
+ <View>
5
+ <View
6
+ collapsable={false}
7
+ pointerEvents="auto"
8
+ style={
8
9
  {
9
10
  "flex": 1,
10
- },
11
- {
12
- "paddingBottom": 49,
13
- },
14
- {
15
11
  "fontScale": 2,
16
12
  "height": 1334,
13
+ "paddingBottom": 49,
17
14
  "scale": 2,
18
15
  "statusBarHeight": null,
19
16
  "width": 750,
20
- },
21
- ]
22
- }
23
- >
24
- <ContextProvider>
25
- <ContextProvider>
26
- <ScreenContextProvider />
27
- </ContextProvider>
28
- </ContextProvider>
29
- </ForwardRef(AnimatedComponentWrapper)>
30
- `;
31
-
32
- exports[`<Scene /> renders the overlay while animating 1`] = `
33
- <ForwardRef(AnimatedComponentWrapper)
34
- pointerEvents="auto"
35
- style={
36
- [
37
- {
38
- "flex": 1,
39
- },
40
- {
41
- "paddingBottom": 49,
42
- },
43
- {
44
- "height": "100%",
45
- "width": "100%",
46
- },
47
- ]
48
- }
49
- >
50
- <ContextProvider>
51
- <ContextProvider>
52
- <ScreenContextProvider />
53
- </ContextProvider>
54
- </ContextProvider>
55
- <ForwardRef(AnimatedComponentWrapper)
56
- style={
57
- {
58
- "opacity": 1,
59
17
  }
60
18
  }
61
19
  />
62
- </ForwardRef(AnimatedComponentWrapper)>
20
+ </View>
63
21
  `;
22
+
23
+ exports[`<Scene /> renders the overlay while animating 1`] = `[Function]`;
@@ -9,7 +9,7 @@ exports[`<TransitionerComponent /> renders correctly 1`] = `
9
9
  }
10
10
  }
11
11
  >
12
- <Scene
12
+ <View
13
13
  isActive={true}
14
14
  screenUniqueId="mocked-uuid"
15
15
  style={{}}
@@ -23,6 +23,6 @@ exports[`<TransitionerComponent /> renders correctly 1`] = `
23
23
  children
24
24
  </Text>
25
25
  </View>
26
- </Scene>
26
+ </View>
27
27
  </View>
28
28
  `;
@@ -1,9 +1,18 @@
1
1
  import React from "react";
2
2
  import { Text, View } from "react-native";
3
- import { shallow } from "enzyme";
4
- import { shallowToJson } from "enzyme-to-json";
5
3
 
6
4
  import { TransitionerComponent } from "../Transitioner";
5
+ import { render } from "@testing-library/react-native";
6
+
7
+ jest.mock("../Scene", () => {
8
+ const View = jest.requireActual("react-native").View;
9
+
10
+ return {
11
+ Scene(props) {
12
+ return <View {...props} />;
13
+ },
14
+ };
15
+ });
7
16
 
8
17
  const children = (
9
18
  <View foo="bar">
@@ -33,12 +42,12 @@ jest.mock("uuid");
33
42
 
34
43
  describe("<TransitionerComponent />", () => {
35
44
  it("renders correctly", () => {
36
- const wrapper = shallow(
45
+ const wrapper = render(
37
46
  <TransitionerComponent {...transitionerComponentProps}>
38
47
  {children}
39
48
  </TransitionerComponent>
40
49
  );
41
50
 
42
- expect(shallowToJson(wrapper)).toMatchSnapshot();
51
+ expect(wrapper.toJSON()).toMatchSnapshot();
43
52
  });
44
53
  });
@@ -1,5 +1,4 @@
1
1
  import * as React from "react";
2
- import { useWindowDimensions } from "react-native";
3
2
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
4
3
  import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks/layout";
5
4
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
@@ -7,10 +6,15 @@ import { TransitionerComponent } from "./Transitioner";
7
6
 
8
7
  export const Transitioner = (props) => {
9
8
  const navigator = useNavigation();
10
- const { height, width } = useWindowDimensions();
11
9
 
12
- const dimensions = useDimensions("window", { deviceInfo: true });
13
- const isTablet = dimensions?.deviceInfo?.isTablet;
10
+ const {
11
+ width,
12
+ height,
13
+ deviceInfo: { isTablet },
14
+ } = useDimensions("window", {
15
+ updateForInactiveScreens: false,
16
+ deviceInfo: true,
17
+ });
14
18
 
15
19
  const { appData } = usePickFromState(["appData"]);
16
20
  const isTabletPortrait = appData?.isTabletPortrait;
@@ -8,6 +8,8 @@ import { loggerLiveImageManager } from "./loggerHelper";
8
8
  import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
9
9
  import { Component } from "react";
10
10
 
11
+ const TIMEOUT_FOR_DELAY_CHECK_PLAYER_POSITION = 500; // ms
12
+
11
13
  const { log_debug, log_info, log_error } = loggerLiveImageManager;
12
14
 
13
15
  export type LiveImageManagerEvent =
@@ -62,6 +64,9 @@ export class LiveImageManager implements PlayerLifecycleListener {
62
64
  protected currentlyPlaying: LiveImage | null = null;
63
65
  protected primaryPlayer: Player | null = null;
64
66
 
67
+ private checkPlayerPositionTimeout: ReturnType<typeof setTimeout> | null =
68
+ null;
69
+
65
70
  protected listeners: Record<
66
71
  string,
67
72
  Record<LiveImageManagerEvent, (event?: Record<string, any>) => void>
@@ -118,6 +123,11 @@ export class LiveImageManager implements PlayerLifecycleListener {
118
123
  });
119
124
  };
120
125
 
126
+ private cancelCheckPlayerPositionTimeout = () => {
127
+ clearTimeout(this.checkPlayerPositionTimeout);
128
+ this.checkPlayerPositionTimeout = null;
129
+ };
130
+
121
131
  public onViewportEnter = (item: LiveImage) => {
122
132
  log_debug(
123
133
  `onViewportEnter: live-image ${playerInfo(
@@ -125,7 +135,21 @@ export class LiveImageManager implements PlayerLifecycleListener {
125
135
  )}, primary ${playerInfo(this.primaryPlayer)}`
126
136
  );
127
137
 
128
- this.checkPlayerPosition(item);
138
+ if (!isTV()) {
139
+ // mobile only
140
+ // we have to delay running checkPlayerPosition, because sometimes on fast scrolling we get wrong order onEnter, then onLeave.
141
+ // which could cause select wrong item to play
142
+
143
+ this.cancelCheckPlayerPositionTimeout();
144
+
145
+ this.checkPlayerPositionTimeout = setTimeout(() => {
146
+ this.cancelCheckPlayerPositionTimeout();
147
+
148
+ this.checkPlayerPosition(item);
149
+ }, TIMEOUT_FOR_DELAY_CHECK_PLAYER_POSITION);
150
+ } else {
151
+ this.checkPlayerPosition(item);
152
+ }
129
153
  };
130
154
 
131
155
  public onViewportLeave = (item: LiveImage) => {
@@ -246,6 +270,8 @@ export class LiveImageManager implements PlayerLifecycleListener {
246
270
  };
247
271
 
248
272
  public checkPlayerPosition = (item: LiveImage) => {
273
+ this.cancelCheckPlayerPositionTimeout();
274
+
249
275
  log_debug(
250
276
  `checkPlayerPosition: live-image playerId: ${playerInfo(
251
277
  item.player
@@ -1,6 +1,7 @@
1
1
  // /// <reference types="@applicaster/applicaster-types" />
2
2
  //
3
3
  import * as React from "react";
4
+ import { useEffect } from "react";
4
5
 
5
6
  import { AppState, AppStateStatus, View } from "react-native";
6
7
  import { TrackedView } from "../TrackedView";
@@ -25,13 +26,15 @@ import { PlayerRole } from "@applicaster/zapp-react-native-utils/appUtils/player
25
26
  import { getAutoplaySettings } from "./utils";
26
27
  import { isString } from "@applicaster/zapp-react-native-utils/stringUtils";
27
28
  import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
28
- import { useEffect } from "react";
29
29
 
30
30
  const { log_error, log_debug } = loggerLiveImageComponent;
31
31
 
32
32
  const isMeasurement = (item: ZappEntry) =>
33
33
  isString(item.id) && item.id.startsWith("pre-measurement-");
34
34
 
35
+ // Pixels by which the view can slightly extend outside the viewport and still be considered fully visible.
36
+ const CLIP_THRESHOLD = 10;
37
+
35
38
  type Props = {
36
39
  item: ZappEntry;
37
40
  style: Record<string, any>;
@@ -44,7 +47,10 @@ type Props = {
44
47
  };
45
48
 
46
49
  const PlayerLiveImageComponent = (props: Props) => {
47
- const dimensions = useDimensions("screen", { fullDimensions: true });
50
+ const dimensions = useDimensions("screen", {
51
+ fullDimensions: true,
52
+ updateForInactiveScreens: false,
53
+ });
48
54
 
49
55
  const { item, style, playerId } = props;
50
56
 
@@ -135,13 +141,16 @@ const PlayerLiveImageComponent = (props: Props) => {
135
141
  } else {
136
142
  throw new Error("Player factory item is null");
137
143
  }
138
- }, [playerId, item, playerPluginId, screenConfig]);
144
+ }, [playerId, item.id, playerPluginId, screenConfig]);
139
145
 
140
146
  React.useEffect(() => {
141
147
  liveImageItem.setMode = setModeDebounced;
142
148
  }, [setModeDebounced, liveImageItem]);
143
149
 
144
- const { start, end } = React.useMemo(() => getAutoplaySettings(item), [item]);
150
+ const { start, end } = React.useMemo(
151
+ () => getAutoplaySettings(item),
152
+ [item.id]
153
+ );
145
154
 
146
155
  const controller = liveImageItem.getPlayer();
147
156
  const player = usePlayer(playerId);
@@ -174,7 +183,7 @@ const PlayerLiveImageComponent = (props: Props) => {
174
183
 
175
184
  unregister();
176
185
  };
177
- }, [item, liveImageItem]);
186
+ }, [item.id, liveImageItem]);
178
187
 
179
188
  React.useEffect(() => {
180
189
  if (!player) {
@@ -244,25 +253,27 @@ const PlayerLiveImageComponent = (props: Props) => {
244
253
  }, [item.id]);
245
254
 
246
255
  React.useEffect(() => {
247
- if (playerManager) {
248
- const isPlayerRegistered = playerManager.isPlayerRegistered(playerId);
256
+ if (isMeasurement(item) || !playerManager) {
257
+ return;
258
+ }
249
259
 
250
- if (isPlayerRegistered) {
251
- log_error(
252
- `PlayerLiveImageComponent: player ${playerId} already registered`
253
- );
254
- } else {
255
- playerManager.registerPlayer({
256
- id: playerId,
257
- playerController: controller,
258
- });
260
+ const isPlayerRegistered = playerManager.isPlayerRegistered(playerId);
259
261
 
260
- return () => {
261
- playerManager.unregisterPlayer(playerId);
262
- };
263
- }
262
+ if (isPlayerRegistered) {
263
+ log_error(
264
+ `PlayerLiveImageComponent: player ${playerId} already registered`
265
+ );
266
+ } else {
267
+ playerManager.registerPlayer({
268
+ id: playerId,
269
+ playerController: controller,
270
+ });
271
+
272
+ return () => {
273
+ playerManager.unregisterPlayer(playerId);
274
+ };
264
275
  }
265
- }, [liveImageItem, playerId, controller]);
276
+ }, [liveImageItem, playerId, controller, item.id]);
266
277
 
267
278
  const onPositionUpdated = React.useCallback(
268
279
  (data) => {
@@ -302,7 +313,7 @@ const PlayerLiveImageComponent = (props: Props) => {
302
313
  LiveImageManager.instance.checkPlayerPosition(liveImageItem);
303
314
  }
304
315
  },
305
- [liveImageItem, dimensions]
316
+ [liveImageItem, dimensions.height, dimensions.width]
306
317
  );
307
318
 
308
319
  const platformSpecificProps = isApplePlatform()
@@ -320,9 +331,10 @@ const PlayerLiveImageComponent = (props: Props) => {
320
331
  <TrackedView
321
332
  testId={`tracked-view-${playerId}-${item.title}`}
322
333
  onPositionUpdated={onPositionUpdated}
334
+ clipThreshold={CLIP_THRESHOLD}
323
335
  >
324
336
  <View ref={trackViewRef}>
325
- {isVideoMode && (
337
+ {isVideoMode ? (
326
338
  <Player
327
339
  autoplay={false}
328
340
  ref={_assignRoot}
@@ -334,7 +346,7 @@ const PlayerLiveImageComponent = (props: Props) => {
334
346
  resizeMode={"cover"}
335
347
  {...platformSpecificProps}
336
348
  />
337
- )}
349
+ ) : null}
338
350
  {
339
351
  <AnimatedInOut
340
352
  visible={isBackgroundImageVisible}
@@ -4,6 +4,7 @@ import { render } from "@testing-library/react-native";
4
4
  import * as PlayerFactory from "@applicaster/zapp-react-native-utils/appUtils/playerManager/playerFactory";
5
5
  import { ThemeContext } from "@applicaster/zapp-react-native-utils/theme";
6
6
  import * as navigationHooks from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
7
+ import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
7
8
 
8
9
  import { PlayerLiveImage } from "../PlayerLiveImageComponent";
9
10
  import * as useNavigationHooks from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation";
@@ -32,7 +33,7 @@ const mockStore = configureStore();
32
33
 
33
34
  const store = mockStore({ appData: {} });
34
35
 
35
- const Wrapper = ({ children }: { children: React.ReactChildren }) => (
36
+ const Wrapper = ({ children }: { children: React.ReactNode }) => (
36
37
  /* @ts-ignore */
37
38
  <Provider store={store}>
38
39
  <ThemeContext.Provider
@@ -118,4 +119,53 @@ describe("PlayerLiveImageComponent", () => {
118
119
 
119
120
  // TODO: implement this test
120
121
  });
122
+
123
+ it("should register the player for normal item", () => {
124
+ render(
125
+ <Wrapper>
126
+ <PlayerLiveImage {...defaultProps} />
127
+ </Wrapper>
128
+ );
129
+
130
+ const isPlayerRegistered = playerManager.isPlayerRegistered(
131
+ defaultProps.playerId
132
+ );
133
+
134
+ expect(isPlayerRegistered).toBe(true);
135
+ });
136
+
137
+ it("should unregister the player for normal item", () => {
138
+ const component = render(
139
+ <Wrapper>
140
+ <PlayerLiveImage {...defaultProps} />
141
+ </Wrapper>
142
+ );
143
+
144
+ component.unmount();
145
+
146
+ const isPlayerRegistered = playerManager.isPlayerRegistered(
147
+ defaultProps.playerId
148
+ );
149
+
150
+ expect(isPlayerRegistered).toBe(false);
151
+ });
152
+
153
+ it("should not register the player for 'pre-measurement' item", () => {
154
+ const props = {
155
+ ...defaultProps,
156
+ item: {
157
+ ...defaultProps.item,
158
+ id: "pre-measurement-1",
159
+ },
160
+ };
161
+
162
+ render(
163
+ <Wrapper>
164
+ <PlayerLiveImage {...props} />
165
+ </Wrapper>
166
+ );
167
+
168
+ const isPlayerRegistered = playerManager.isPlayerRegistered(props.playerId);
169
+ expect(isPlayerRegistered).toBe(false);
170
+ });
121
171
  });
@@ -2,6 +2,7 @@
2
2
 
3
3
  exports[`PlayerLiveImageComponent should render correctly with default props 1`] = `
4
4
  <TrackedView
5
+ clipThreshold={10}
5
6
  onPositionUpdated={[Function]}
6
7
  testId="tracked-view-player1-Test"
7
8
  >
@@ -31,11 +32,6 @@ exports[`PlayerLiveImageComponent should render correctly with default props 1`]
31
32
  playerId="player1"
32
33
  resizeMode="cover"
33
34
  screenConfig={{}}
34
- source={
35
- {
36
- "uri": "",
37
- }
38
- }
39
35
  style={{}}
40
36
  />
41
37
  </View>
@@ -46,7 +46,7 @@ export const AnimatedPlayerModalWrapper = (props: Props) => {
46
46
 
47
47
  React.useEffect(() => {
48
48
  (playerAnimationState === PlayerAnimationStateEnum.minimize ||
49
- playerAnimationState === PlayerAnimationStateEnum.maximaze) &&
49
+ playerAnimationState === PlayerAnimationStateEnum.maximize) &&
50
50
  setStartComponentsAnimation(true);
51
51
  }, [playerAnimationState]);
52
52
 
@@ -1,26 +1,26 @@
1
1
  import React from "react";
2
- import { Animated, StyleSheet, View, Platform } from "react-native";
2
+ import { Animated, Platform, StyleSheet, View } from "react-native";
3
3
 
4
4
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
5
5
  import {
6
+ GestureHandlerRootView,
6
7
  NativeViewGestureHandler,
7
8
  PanGestureHandler,
8
9
  State,
9
10
  TapGestureHandler,
10
- GestureHandlerRootView,
11
11
  } from "react-native-gesture-handler";
12
12
 
13
13
  import { PlayerContainerContext } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainerContext";
14
14
  import {
15
- useModalAnimationContext,
16
15
  PlayerAnimationStateEnum,
16
+ useModalAnimationContext,
17
17
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
18
18
  import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
19
19
  import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
20
20
 
21
21
  import {
22
- setScrollModalAnimatedValue,
23
22
  resetScrollAnimatedValues,
23
+ setScrollModalAnimatedValue,
24
24
  } from "./utils";
25
25
 
26
26
  const getAnimatedConfig = (toValue) => {
@@ -70,21 +70,26 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
70
70
  const { maximiseVideoModal, minimiseVideoModal, videoModalState } =
71
71
  useNavigation();
72
72
 
73
- const { mode: videoModalMode, item: videoModalItem } = videoModalState;
74
- const isMaximazedModal = videoModalMode === "MAXIMIZED";
75
- const isMinimizedModal = videoModalMode === "MINIMIZED";
73
+ const {
74
+ mode: videoModalMode,
75
+ previousMode: previousVideoModalMode,
76
+ item: videoModalItem,
77
+ } = videoModalState;
78
+
79
+ const isMaximizedModal: boolean = videoModalMode === "MAXIMIZED";
80
+ const isMinimizedModal: boolean = videoModalMode === "MINIMIZED";
76
81
  const previousItemId = usePrevious(videoModalItem?.id);
77
82
 
78
83
  const isNotMinimizeMaximazeAnimation =
79
84
  playerAnimationState !== PlayerAnimationStateEnum.minimize &&
80
- playerAnimationState !== PlayerAnimationStateEnum.maximaze;
85
+ playerAnimationState !== PlayerAnimationStateEnum.maximize;
81
86
 
82
87
  const isEnablePanGesture =
83
88
  enableGesture &&
84
89
  !isLanguageOverlayVisible &&
85
90
  isNotMinimizeMaximazeAnimation &&
86
91
  !isSeekBarTouch &&
87
- (isMaximazedModal || isMinimizedModal);
92
+ (isMaximizedModal || isMinimizedModal);
88
93
 
89
94
  const isAudioItem = React.useMemo(
90
95
  () =>
@@ -121,7 +126,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
121
126
  const preparedTranslationY =
122
127
  Math.abs(translationY) - lastScrollYValue.current;
123
128
 
124
- if (videoModalMode === "MAXIMIZED") {
129
+ if (isMaximizedModal) {
125
130
  const endOffsetY =
126
131
  lastSnap + preparedTranslationY + dragToss * velocityY + 150;
127
132
 
@@ -137,14 +142,14 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
137
142
 
138
143
  setLastSnap(destSnapPoint);
139
144
 
140
- if (destSnapPoint === modalSnapPoints[0]) {
145
+ if (destSnapPoint === modalSnapPoints[0] && isMinimizedModal) {
141
146
  translateYOffset.extractOffset();
142
147
  translateYOffset.setValue(preparedTranslationY);
143
148
  translateYOffset.flattenOffset();
144
149
  dragScrollY.setValue(0);
145
150
 
146
- setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
147
- } else {
151
+ setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
152
+ } else if (destSnapPoint !== modalSnapPoints[0] && isMaximizedModal) {
148
153
  setPlayerAnimationState(PlayerAnimationStateEnum.minimize);
149
154
  }
150
155
  } else {
@@ -158,7 +163,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
158
163
 
159
164
  dragScrollY.setValue(0);
160
165
 
161
- setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
166
+ setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
162
167
  } else {
163
168
  resetPlayerAnimationState();
164
169
  }
@@ -168,7 +173,13 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
168
173
  resetPlayerAnimationState();
169
174
  }
170
175
  },
171
- [lastSnap, modalSnapPoints, playerAnimationState, videoModalMode]
176
+ [
177
+ lastSnap,
178
+ modalSnapPoints,
179
+ playerAnimationState,
180
+ isMinimizedModal,
181
+ isMaximizedModal,
182
+ ]
172
183
  );
173
184
 
174
185
  const onScroll = React.useCallback(({ nativeEvent }) => {
@@ -219,17 +230,18 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
219
230
  }, []);
220
231
 
221
232
  React.useEffect(() => {
222
- const { mode, previousMode, item } = videoModalState;
223
-
224
233
  if (
225
- mode === "MAXIMIZED" &&
234
+ videoModalMode === "MAXIMIZED" &&
226
235
  !enableGesture &&
227
236
  scrollPosition.current === 0
228
237
  ) {
229
238
  setIEnableGesture(true);
230
239
  }
231
240
 
232
- if (mode === "MINIMIZED" && previousMode === "MAXIMIZED") {
241
+ if (
242
+ videoModalMode === "MINIMIZED" &&
243
+ previousVideoModalMode === "MAXIMIZED"
244
+ ) {
233
245
  // set animation to the minimize values if moving from the player to another screen
234
246
  if (playerAnimationState === null) {
235
247
  setScrollModalAnimatedValue(
@@ -247,14 +259,16 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
247
259
  }
248
260
  } else if (
249
261
  playerAnimationState === null &&
250
- ((previousItemId === item?.id &&
251
- mode === "MAXIMIZED" &&
252
- (previousMode === "MINIMIZED" || previousMode === "MAXIMIZED")) ||
253
- (previousItemId !== item?.id && mode !== "FULLSCREEN"))
262
+ ((previousItemId === videoModalItem?.id &&
263
+ videoModalMode === "MAXIMIZED" &&
264
+ (previousVideoModalMode === "MINIMIZED" ||
265
+ previousVideoModalMode === "MAXIMIZED")) ||
266
+ (previousItemId !== videoModalItem?.id &&
267
+ videoModalMode !== "FULLSCREEN"))
254
268
  ) {
255
- setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
269
+ setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
256
270
  }
257
- }, [videoModalState]);
271
+ }, [videoModalMode, previousVideoModalMode, videoModalItem]);
258
272
 
259
273
  React.useEffect(() => {
260
274
  if (playerAnimationState === PlayerAnimationStateEnum.minimize) {
@@ -296,7 +310,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
296
310
 
297
311
  resetPlayerAnimationState();
298
312
  });
299
- } else if (playerAnimationState === PlayerAnimationStateEnum.maximaze) {
313
+ } else if (playerAnimationState === PlayerAnimationStateEnum.maximize) {
300
314
  Animated.timing(translateYOffset, getAnimatedConfig(0)).start(() => {
301
315
  maximiseVideoModal();
302
316
  setScrollModalAnimatedValue(translateYOffset, 0, setLastSnap);
@@ -346,6 +360,8 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
346
360
  []
347
361
  );
348
362
 
363
+ const scrollEnabled = isMaximizedModal && isNotMinimizeMaximazeAnimation;
364
+
349
365
  return (
350
366
  <Wrapper style={generalStyles.container}>
351
367
  <TapGestureHandler
@@ -359,7 +375,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
359
375
  enabled={isEnablePanGesture}
360
376
  ref={panHandlerRef}
361
377
  simultaneousHandlers={[scrollRef, tapHandlerRef]}
362
- shouldCancelWhenOutside={isMaximazedModal}
378
+ shouldCancelWhenOutside={isMaximizedModal}
363
379
  onGestureEvent={onGestureEvent}
364
380
  onHandlerStateChange={onHandlerStateChange}
365
381
  activeOffsetY={[-5, 5]}
@@ -371,9 +387,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
371
387
  simultaneousHandlers={panHandlerRef}
372
388
  >
373
389
  <Animated.ScrollView
374
- scrollEnabled={
375
- isMaximazedModal && isNotMinimizeMaximazeAnimation
376
- }
390
+ scrollEnabled={scrollEnabled}
377
391
  bounces={false}
378
392
  onScrollBeginDrag={onRegisterLastScroll}
379
393
  onScroll={onScroll}
@@ -50,7 +50,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
50
50
 
51
51
  const isNotMinimizeMaximazeAnimation =
52
52
  playerAnimationState !== PlayerAnimationStateEnum.minimize &&
53
- playerAnimationState !== PlayerAnimationStateEnum.maximaze;
53
+ playerAnimationState !== PlayerAnimationStateEnum.maximize;
54
54
 
55
55
  const isEnablePanGesture =
56
56
  !isLanguageOverlayVisible &&
@@ -89,7 +89,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
89
89
  setLastSnap(destSnapPoint);
90
90
 
91
91
  if (destSnapPoint === modalSnapPoints[0]) {
92
- setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
92
+ setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
93
93
  } else {
94
94
  lastScrollY.setValue(0);
95
95
  lastScrollYValue.current = 0;
@@ -105,7 +105,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
105
105
  modalSnapPoints[1] - preparedTranslationY
106
106
  );
107
107
 
108
- setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
108
+ setPlayerAnimationState(PlayerAnimationStateEnum.maximize);
109
109
  } else {
110
110
  resetPlayerAnimationState();
111
111
  }