@applicaster/zapp-react-native-ui-components 14.0.0-rc.9 → 15.0.0-alpha.1089439460

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 (183) hide show
  1. package/Components/AnimatedInOut/index.tsx +68 -23
  2. package/Components/AudioPlayer/index.tsx +15 -0
  3. package/Components/AudioPlayer/mobile/Layout.tsx +66 -0
  4. package/Components/AudioPlayer/{__tests__/__snapshots__/audioPlayer.test.js.snap → mobile/__tests__/__snapshots__/audioPlayerMobileLayout.test.js.snap} +2 -2
  5. package/Components/AudioPlayer/mobile/__tests__/audioPlayerMobileLayout.test.js +18 -0
  6. package/Components/AudioPlayer/mobile/index.tsx +18 -0
  7. package/Components/AudioPlayer/{Artwork.tsx → tv/Artwork.tsx} +3 -2
  8. package/Components/AudioPlayer/{Channel.tsx → tv/Channel.tsx} +7 -7
  9. package/Components/AudioPlayer/tv/Layout.tsx +168 -0
  10. package/Components/AudioPlayer/{Runtime.tsx → tv/Runtime.tsx} +7 -1
  11. package/Components/AudioPlayer/{Summary.tsx → tv/Summary.tsx} +6 -2
  12. package/Components/AudioPlayer/{Title.tsx → tv/Title.tsx} +6 -2
  13. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/Runtime.test.js.snap +2 -2
  14. package/Components/AudioPlayer/tv/__tests__/__snapshots__/audioPlayer.test.js.snap +164 -0
  15. package/Components/AudioPlayer/tv/__tests__/__snapshots__/channel.test.js.snap +19 -0
  16. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/summary.test.js.snap +1 -2
  17. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/title.test.js.snap +1 -2
  18. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/audioPlayer.test.js +7 -3
  19. package/Components/AudioPlayer/{helpers.tsx → tv/helpers.tsx} +11 -5
  20. package/Components/AudioPlayer/{AudioPlayer.tsx → tv/index.tsx} +17 -58
  21. package/Components/AudioPlayer/types.ts +40 -0
  22. package/Components/BaseFocusable/index.tsx +23 -12
  23. package/Components/Cell/Cell.tsx +91 -64
  24. package/Components/Cell/CellWithFocusable.tsx +3 -0
  25. package/Components/Cell/FocusableWrapper.tsx +44 -0
  26. package/Components/Cell/TvOSCellComponent.tsx +92 -17
  27. package/Components/Cell/__tests__/CellWIthFocusable.test.js +3 -2
  28. package/Components/Cell/index.js +7 -3
  29. package/Components/ComponentResolver/index.ts +1 -1
  30. package/Components/FeedLoader/FeedLoader.tsx +7 -16
  31. package/Components/FeedLoader/FeedLoaderHOC.tsx +21 -0
  32. package/Components/FeedLoader/index.js +2 -8
  33. package/Components/Focusable/Focusable.tsx +12 -3
  34. package/Components/Focusable/FocusableTvOS.tsx +5 -5
  35. package/Components/Focusable/FocusableiOS.tsx +2 -2
  36. package/Components/Focusable/Touchable.tsx +5 -3
  37. package/Components/Focusable/__tests__/index.android.test.tsx +3 -0
  38. package/Components/Focusable/index.android.tsx +19 -11
  39. package/Components/Focusable/index.tsx +1 -1
  40. package/Components/FocusableGroup/FocusableTvOS.tsx +1 -1
  41. package/Components/FocusableList/FocusableItem.tsx +4 -3
  42. package/Components/FocusableList/FocusableListItemWrapper.tsx +2 -1
  43. package/Components/FocusableList/hooks/useCellState.android.ts +13 -3
  44. package/Components/FocusableList/index.tsx +20 -9
  45. package/Components/FreezeWithCallback/__tests__/index.test.tsx +67 -43
  46. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +42 -59
  47. package/Components/GeneralContentScreen/utils/useCurationAPI.ts +22 -21
  48. package/Components/HandlePlayable/HandlePlayable.tsx +39 -74
  49. package/Components/HandlePlayable/const.ts +3 -0
  50. package/Components/HandlePlayable/utils.ts +74 -0
  51. package/Components/HookRenderer/HookRenderer.tsx +5 -1
  52. package/Components/Layout/TV/LayoutBackground.tsx +1 -1
  53. package/Components/Layout/TV/__tests__/index.test.tsx +0 -1
  54. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +6 -2
  55. package/Components/MasterCell/DefaultComponents/Button.tsx +1 -1
  56. package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -39
  57. package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +1 -1
  58. package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +1 -1
  59. package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +65 -17
  60. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/Image.test.tsx +21 -3
  61. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/__snapshots__/Image.test.tsx.snap +6 -3
  62. package/Components/MasterCell/DefaultComponents/Text/index.tsx +26 -6
  63. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +10 -10
  64. package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +18 -18
  65. package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/index.test.tsx +10 -10
  66. package/Components/MasterCell/elementMapper.tsx +1 -2
  67. package/Components/MasterCell/index.tsx +1 -1
  68. package/Components/MasterCell/utils/behaviorProvider.ts +82 -14
  69. package/Components/MasterCell/utils/index.ts +11 -5
  70. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +13 -18
  71. package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +9 -0
  72. package/Components/OfflineHandler/__tests__/index.test.tsx +26 -35
  73. package/Components/PlayerContainer/ErrorDisplay/index.ts +1 -1
  74. package/Components/PlayerContainer/PlayerContainer.tsx +45 -47
  75. package/Components/PlayerContainer/ProgramInfo/index.tsx +1 -1
  76. package/Components/PlayerContainer/index.ts +1 -1
  77. package/Components/PlayerImageBackground/index.tsx +4 -23
  78. package/Components/River/ComponentsMap/ComponentsMap.tsx +49 -43
  79. package/Components/River/ComponentsMap/ContextProviders/ComponentsMapHeightContext.ts +8 -0
  80. package/Components/River/ComponentsMap/ContextProviders/ComponentsMapRefContext.ts +8 -0
  81. package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +378 -0
  82. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +2 -2
  83. package/Components/River/RefreshControl.tsx +11 -17
  84. package/Components/River/RiverItem.tsx +3 -0
  85. package/Components/River/TV/River.tsx +2 -17
  86. package/Components/River/TV/index.tsx +3 -1
  87. package/Components/River/TV/withPipesV1DataLoader.tsx +43 -0
  88. package/Components/River/TV/withRiverDataLoader.tsx +17 -0
  89. package/Components/River/TV/withTVEventHandler.tsx +1 -1
  90. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +2 -0
  91. package/Components/River/__tests__/river.test.js +12 -26
  92. package/Components/River/index.tsx +1 -1
  93. package/Components/Screen/TV/hooks/useInitialFocus.ts +14 -4
  94. package/Components/Screen/__tests__/Screen.test.tsx +28 -29
  95. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +2 -0
  96. package/Components/Screen/__tests__/navigationHandler.test.ts +133 -22
  97. package/Components/Screen/index.tsx +22 -5
  98. package/Components/Screen/navigationHandler.ts +20 -2
  99. package/Components/ScreenResolver/index.tsx +22 -1
  100. package/Components/ScreenRevealManager/ScreenRevealManager.ts +76 -0
  101. package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +107 -0
  102. package/Components/ScreenRevealManager/__tests__/withScreenRevealManager.test.tsx +96 -0
  103. package/Components/ScreenRevealManager/index.ts +1 -0
  104. package/Components/ScreenRevealManager/utils/index.ts +23 -0
  105. package/Components/ScreenRevealManager/withScreenRevealManager.tsx +109 -0
  106. package/Components/Tabs/TV/Tabs.android.tsx +1 -3
  107. package/Components/Tabs/Tabs.tsx +2 -3
  108. package/Components/TextInputTv/__tests__/__snapshots__/TextInputTv.test.js.snap +13 -0
  109. package/Components/TextInputTv/index.tsx +11 -0
  110. package/Components/Touchable/__tests__/__snapshots__/touchable.test.tsx.snap +34 -0
  111. package/Components/Touchable/__tests__/touchable.test.tsx +12 -17
  112. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +15 -9
  113. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +1 -0
  114. package/Components/VideoLive/animationUtils.ts +3 -3
  115. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +120 -133
  116. package/Components/VideoModal/ModalAnimation/index.ts +2 -13
  117. package/Components/VideoModal/ModalAnimation/utils.ts +1 -327
  118. package/Components/VideoModal/PlayerDetails.tsx +29 -7
  119. package/Components/VideoModal/PlayerWrapper.tsx +25 -215
  120. package/Components/VideoModal/VideoModal.tsx +4 -22
  121. package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +5 -5
  122. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +2 -7
  123. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +44 -240
  124. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +9 -1
  125. package/Components/VideoModal/hooks/index.ts +0 -2
  126. package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +40 -15
  127. package/Components/VideoModal/hooks/useModalSize.ts +23 -2
  128. package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +2 -2
  129. package/Components/VideoModal/hooks/utils/index.ts +4 -0
  130. package/Components/VideoModal/playerWrapperStyle.ts +70 -0
  131. package/Components/VideoModal/playerWrapperUtils.ts +91 -0
  132. package/Components/VideoModal/utils.ts +13 -0
  133. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -16
  134. package/Components/Viewport/ViewportTracker/__tests__/viewportTracker.test.js +84 -24
  135. package/Components/Viewport/VisibilitySensor/VisibilitySensor.tsx +3 -3
  136. package/Components/ZappFrameworkComponents/BarView/BarView.tsx +4 -6
  137. package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +2 -2
  138. package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/index.ts +3 -3
  139. package/Contexts/CellFocusedStateContext/index.tsx +27 -0
  140. package/Contexts/ConfigutaionContext/__tests__/ConfigurationProvider.test.tsx +3 -3
  141. package/Contexts/ScreenContext/index.tsx +46 -6
  142. package/Decorators/ConfigurationWrapper/__tests__/withConfigurationProvider.test.tsx +3 -3
  143. package/Decorators/ConfigurationWrapper/withConfigurationProvider.tsx +2 -2
  144. package/Decorators/RiverFeedLoader/__tests__/__snapshots__/riverFeedLoader.test.tsx.snap +221 -209
  145. package/Decorators/RiverFeedLoader/__tests__/riverFeedLoader.test.tsx +14 -16
  146. package/Decorators/RiverFeedLoader/__tests__/utils.test.ts +0 -20
  147. package/Decorators/RiverFeedLoader/index.tsx +22 -4
  148. package/Decorators/RiverFeedLoader/utils/getDatasourceUrl.ts +6 -10
  149. package/Decorators/RiverFeedLoader/utils/index.ts +0 -18
  150. package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +3 -6
  151. package/Decorators/ZappPipesDataConnector/ResolverSelector.tsx +25 -0
  152. package/Decorators/ZappPipesDataConnector/__tests__/NullFeedResolver.test.tsx +78 -0
  153. package/Decorators/ZappPipesDataConnector/__tests__/ResolverSelector.test.tsx +205 -0
  154. package/Decorators/ZappPipesDataConnector/__tests__/StaticFeedResolver.test.tsx +251 -0
  155. package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +368 -0
  156. package/Decorators/ZappPipesDataConnector/__tests__/utils.test.ts +39 -0
  157. package/Decorators/ZappPipesDataConnector/index.tsx +26 -293
  158. package/Decorators/ZappPipesDataConnector/resolvers/NullFeedResolver.tsx +25 -0
  159. package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +87 -0
  160. package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +266 -0
  161. package/Decorators/ZappPipesDataConnector/types.ts +29 -0
  162. package/Decorators/ZappPipesDataConnector/utils/mongoFilter.ts +738 -0
  163. package/Decorators/ZappPipesDataConnector/utils/useFilter.tsx +157 -0
  164. package/events/index.ts +3 -0
  165. package/package.json +5 -10
  166. package/Components/AudioPlayer/AudioPlayerLayout.tsx +0 -202
  167. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +0 -66
  168. package/Components/AudioPlayer/__tests__/__snapshots__/channel.test.js.snap +0 -28
  169. package/Components/AudioPlayer/__tests__/audioPlayerLayout.test.js +0 -26
  170. package/Components/AudioPlayer/index.ts +0 -1
  171. package/Components/River/__tests__/__snapshots__/river.test.js.snap +0 -27
  172. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +0 -60
  173. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +0 -421
  174. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +0 -176
  175. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +0 -500
  176. package/Components/VideoModal/ModalAnimation/__tests__/getMoveUpValue.test.ts +0 -108
  177. package/Components/VideoModal/hooks/useBackgroundColor.ts +0 -10
  178. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/Runtime.test.js +0 -0
  179. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/artWork.test.js.snap +0 -0
  180. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/artWork.test.js +0 -0
  181. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/channel.test.js +0 -0
  182. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/summary.test.js +0 -0
  183. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/title.test.js +0 -0
@@ -0,0 +1,107 @@
1
+ import {
2
+ ScreenRevealManager,
3
+ COMPONENT_LOADING_STATE,
4
+ } from "../ScreenRevealManager";
5
+
6
+ describe("ScreenRevealManager", () => {
7
+ const mockCallback = jest.fn();
8
+
9
+ beforeEach(() => {
10
+ jest.clearAllMocks();
11
+ });
12
+
13
+ it("should initialize with the correct number of components to wait for", () => {
14
+ const componentsToRender: ZappUIComponent[] = [
15
+ { component_type: "component1" },
16
+ { component_type: "component2" },
17
+ { component_type: "component3" },
18
+ ];
19
+
20
+ const manager = new ScreenRevealManager(componentsToRender, mockCallback);
21
+
22
+ expect(manager.numberOfComponentsWaitToLoadBeforePresent).toBe(3);
23
+
24
+ expect(manager.renderingState).toEqual([
25
+ COMPONENT_LOADING_STATE.UNKNOWN,
26
+ COMPONENT_LOADING_STATE.UNKNOWN,
27
+ COMPONENT_LOADING_STATE.UNKNOWN,
28
+ ]);
29
+ });
30
+
31
+ it("should call the callback when the required number of components are loaded successfully", () => {
32
+ const componentsToRender: ZappUIComponent[] = [
33
+ { component_type: "component1" },
34
+ { component_type: "component2" },
35
+ { component_type: "component3" },
36
+ ];
37
+
38
+ const manager = new ScreenRevealManager(componentsToRender, mockCallback);
39
+
40
+ manager.onLoadFinished(0);
41
+ manager.onLoadFinished(1);
42
+ manager.onLoadFinished(2);
43
+
44
+ expect(mockCallback).toHaveBeenCalledTimes(1);
45
+ });
46
+
47
+ it("should call the callback when the required number of components fail to load", () => {
48
+ const componentsToRender: ZappUIComponent[] = [
49
+ { component_type: "component1" },
50
+ { component_type: "component2" },
51
+ { component_type: "component3" },
52
+ ];
53
+
54
+ const manager = new ScreenRevealManager(componentsToRender, mockCallback);
55
+
56
+ manager.onLoadFailed(0);
57
+ manager.onLoadFailed(1);
58
+ manager.onLoadFailed(2);
59
+
60
+ expect(mockCallback).toHaveBeenCalledTimes(1);
61
+ });
62
+
63
+ it("should call the callback when a mix of successful and failed loads meet the required number", () => {
64
+ const componentsToRender: ZappUIComponent[] = [
65
+ { component_type: "component1" },
66
+ { component_type: "component2" },
67
+ { component_type: "component3" },
68
+ ];
69
+
70
+ const manager = new ScreenRevealManager(componentsToRender, mockCallback);
71
+
72
+ manager.onLoadFinished(0);
73
+ manager.onLoadFailed(1);
74
+ manager.onLoadFinished(2);
75
+
76
+ expect(mockCallback).toHaveBeenCalledTimes(1);
77
+ });
78
+
79
+ it("should not call the callback if the required number of components are not loaded", () => {
80
+ const componentsToRender: ZappUIComponent[] = [
81
+ { component_type: "component1" },
82
+ { component_type: "component2" },
83
+ { component_type: "component3" },
84
+ ];
85
+
86
+ const manager = new ScreenRevealManager(componentsToRender, mockCallback);
87
+
88
+ manager.onLoadFinished(0);
89
+ manager.onLoadFailed(1);
90
+
91
+ expect(mockCallback).not.toHaveBeenCalled();
92
+ });
93
+
94
+ it("should call the callback when the when first component is gallery and it was loaded successfully", () => {
95
+ const componentsToRender: ZappUIComponent[] = [
96
+ { component_type: "gallery-qb" },
97
+ { component_type: "component2" },
98
+ { component_type: "component3" },
99
+ ];
100
+
101
+ const manager = new ScreenRevealManager(componentsToRender, mockCallback);
102
+
103
+ manager.onLoadFinished(0);
104
+
105
+ expect(mockCallback).toHaveBeenCalledTimes(1);
106
+ });
107
+ });
@@ -0,0 +1,96 @@
1
+ /* eslint-disable react/prop-types */
2
+
3
+ import * as React from "react";
4
+ import { render, screen, act } from "@testing-library/react-native";
5
+ import { View } from "react-native";
6
+ import {
7
+ withScreenRevealManager,
8
+ SHOWN,
9
+ TIMEOUT,
10
+ } from "../withScreenRevealManager";
11
+
12
+ // jest.mock("react-native/Libraries/Animated/NativeAnimatedHelper");
13
+
14
+ const MockComponent = ({
15
+ initialNumberToLoad,
16
+ onLoadFinishedFromScreenRevealManager,
17
+ onLoadFailedFromScreenRevealManager,
18
+ }) => {
19
+ React.useEffect(() => {
20
+ // Simulate loading components
21
+ for (let i = 0; i < initialNumberToLoad; i++) {
22
+ onLoadFinishedFromScreenRevealManager(i);
23
+ }
24
+ }, [initialNumberToLoad, onLoadFinishedFromScreenRevealManager]);
25
+
26
+ return (
27
+ <View
28
+ testID="mock-component"
29
+ initialNumberToLoad={initialNumberToLoad}
30
+ onLoadFinishedFromScreenRevealManager={
31
+ onLoadFinishedFromScreenRevealManager
32
+ }
33
+ onLoadFailedFromScreenRevealManager={onLoadFailedFromScreenRevealManager}
34
+ />
35
+ );
36
+ };
37
+
38
+ const WrappedComponent = withScreenRevealManager(MockComponent);
39
+
40
+ describe.skip("withScreenRevealManager", () => {
41
+ beforeEach(() => {
42
+ jest.clearAllMocks();
43
+ jest.useFakeTimers();
44
+ });
45
+
46
+ afterEach(() => {
47
+ jest.runOnlyPendingTimers();
48
+ jest.useRealTimers();
49
+ });
50
+
51
+ it("should render the wrapped component", () => {
52
+ render(
53
+ <WrappedComponent
54
+ componentsToRender={[{ id: "1" }, { id: "2" }, { id: "3" }]}
55
+ />
56
+ );
57
+
58
+ expect(screen.getByTestId("mock-component")).toBeTruthy();
59
+ });
60
+
61
+ it("should animate opacity when ready to show", () => {
62
+ render(
63
+ <WrappedComponent
64
+ componentsToRender={[{ id: "1" }, { id: "2" }, { id: "3" }]}
65
+ />
66
+ );
67
+
68
+ const animatedView = screen.getByTestId("animated-component");
69
+
70
+ act(() => {
71
+ jest.advanceTimersByTime(TIMEOUT + 100);
72
+ });
73
+
74
+ expect(animatedView.props.style.opacity).toBe(SHOWN);
75
+ });
76
+
77
+ it("should pass initialNumberToLoad, onLoadFinishedFromScreenRevealManager, and onLoadFailedFromScreenRevealManager to the wrapped component", () => {
78
+ render(
79
+ <WrappedComponent
80
+ componentsToRender={[{ id: "1" }, { id: "2" }, { id: "3" }]}
81
+ />
82
+ );
83
+
84
+ const mockComponent = screen.getByTestId("mock-component");
85
+
86
+ expect(mockComponent.props.initialNumberToLoad).toBe(3);
87
+
88
+ expect(
89
+ mockComponent.props.onLoadFinishedFromScreenRevealManager
90
+ ).toBeInstanceOf(Function);
91
+
92
+ expect(
93
+ mockComponent.props.onLoadFailedFromScreenRevealManager
94
+ ).toBeInstanceOf(Function);
95
+ });
96
+ });
@@ -0,0 +1 @@
1
+ export { withScreenRevealManager } from "./withScreenRevealManager";
@@ -0,0 +1,23 @@
1
+ import { ReplaySubject } from "rxjs";
2
+ import { pairwise, filter, first } from "rxjs/operators";
3
+
4
+ // we are interested in last 2 events, because we wait transition from <false> to <true>
5
+ const screenRevealManagerSubject$ = new ReplaySubject<boolean>(2);
6
+
7
+ export const emitScreenRevealManagerIsReadyToShow = () => {
8
+ screenRevealManagerSubject$.next(true);
9
+ };
10
+
11
+ export const emitScreenRevealManagerIsNotReadyToShow = () => {
12
+ screenRevealManagerSubject$.next(false);
13
+ };
14
+
15
+ export const waitUntilScreenRevealManagerIsReady = () => {
16
+ return screenRevealManagerSubject$.pipe(
17
+ pairwise(), // emit consecutive pairs: [prev, curr]
18
+ filter(
19
+ ([previousIsReady, currentIsReady]) => !previousIsReady && currentIsReady
20
+ ), // detect transition from not_ready to ready
21
+ first()
22
+ );
23
+ };
@@ -0,0 +1,109 @@
1
+ import * as React from "react";
2
+ import { Animated, StyleSheet } from "react-native";
3
+ import { isFirstComponentScreenPicker } from "@applicaster/zapp-react-native-utils/componentsUtils";
4
+ import { useRefWithInitialValue } from "@applicaster/zapp-react-native-utils/reactHooks/state/useRefWithInitialValue";
5
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
6
+
7
+ import { ScreenRevealManager } from "./ScreenRevealManager";
8
+ import {
9
+ emitScreenRevealManagerIsReadyToShow,
10
+ emitScreenRevealManagerIsNotReadyToShow,
11
+ } from "./utils";
12
+
13
+ const styles = StyleSheet.create({
14
+ container: {
15
+ ...StyleSheet.absoluteFillObject,
16
+ position: "absolute",
17
+ },
18
+ });
19
+
20
+ export const TIMEOUT = 300; // 300 ms
21
+
22
+ const HIDDEN = 0; // opacity = 0
23
+
24
+ export const SHOWN = 1; // opacity = 1
25
+
26
+ type Props = {
27
+ componentsToRender: ZappUIComponent[];
28
+ };
29
+
30
+ export const withScreenRevealManager = (Component) => {
31
+ return function WithScreenRevealManager(props: Props) {
32
+ const { componentsToRender } = props;
33
+
34
+ const [isContentReadyToBeShown, setIsContentReadyToBeShown] =
35
+ React.useState(false);
36
+
37
+ const [isShowOverlay, setIsShowOverlay] = React.useState(true);
38
+
39
+ const theme = useTheme<BaseThemePropertiesTV>();
40
+
41
+ const handleSetIsContentReadyToBeShown = React.useCallback(() => {
42
+ setIsContentReadyToBeShown(true);
43
+ }, []);
44
+
45
+ const managerRef = useRefWithInitialValue<ScreenRevealManager>(
46
+ () =>
47
+ new ScreenRevealManager(
48
+ componentsToRender,
49
+ handleSetIsContentReadyToBeShown
50
+ )
51
+ );
52
+
53
+ const opacityRef = useRefWithInitialValue<Animated.Value>(
54
+ () => new Animated.Value(SHOWN)
55
+ );
56
+
57
+ React.useEffect(() => {
58
+ if (!isContentReadyToBeShown) {
59
+ emitScreenRevealManagerIsNotReadyToShow();
60
+ } else {
61
+ emitScreenRevealManagerIsReadyToShow();
62
+ }
63
+ }, [isContentReadyToBeShown]);
64
+
65
+ React.useEffect(() => {
66
+ if (isContentReadyToBeShown) {
67
+ Animated.timing(opacityRef.current, {
68
+ toValue: HIDDEN,
69
+ duration: TIMEOUT,
70
+ useNativeDriver: true,
71
+ }).start(() => {
72
+ setIsShowOverlay(false);
73
+ });
74
+ }
75
+ }, [isContentReadyToBeShown]);
76
+
77
+ if (isFirstComponentScreenPicker(componentsToRender)) {
78
+ // for screen-picker with have additional internal ComponentsMap, no need to add this wrapper
79
+ return <Component {...props} />;
80
+ }
81
+
82
+ return (
83
+ <>
84
+ <Component
85
+ {...props}
86
+ initialNumberToLoad={
87
+ managerRef.current.numberOfComponentsWaitToLoadBeforePresent
88
+ }
89
+ onLoadFinishedFromScreenRevealManager={
90
+ managerRef.current.onLoadFinished
91
+ }
92
+ onLoadFailedFromScreenRevealManager={managerRef.current.onLoadFailed}
93
+ />
94
+ {isShowOverlay ? (
95
+ <Animated.View
96
+ style={[
97
+ styles.container,
98
+ {
99
+ opacity: opacityRef.current,
100
+ backgroundColor: theme.app_background_color,
101
+ },
102
+ ]}
103
+ testID="animated-component"
104
+ />
105
+ ) : null}
106
+ </>
107
+ );
108
+ };
109
+ };
@@ -7,7 +7,6 @@ import { isEmptyOrNil } from "@applicaster/zapp-react-native-utils/cellUtils";
7
7
 
8
8
  import Tab from "./Tab";
9
9
  import { Gutter } from "../Gutter";
10
- import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
11
10
  import { ImageBackground, View } from "react-native";
12
11
  import { getStyles } from "./styles";
13
12
  import {
@@ -63,7 +62,7 @@ const TabsComponent = ({
63
62
  );
64
63
 
65
64
  const renderItem = useCallback(
66
- ({ item, index, focused }) => {
65
+ ({ item, index, focused }: { item: any; index: any; focused?: any }) => {
67
66
  const itemId = generateFocusableId(getId(item));
68
67
 
69
68
  const isSelected = R.equals(index, selectedEntryIndex);
@@ -100,7 +99,6 @@ const TabsComponent = ({
100
99
  >
101
100
  <FocusableList
102
101
  horizontal
103
- onScrollToIndexFailed={noop}
104
102
  onLayout={onLayoutChange}
105
103
  contentContainerStyle={tabsListContentContainer}
106
104
  ref={flatListRef}
@@ -158,12 +158,11 @@ const TabsComponent = ({
158
158
 
159
159
  const renderItem = React.useCallback(
160
160
  ({ item, index, item: { id } }: RenderItemProps) => (
161
- <>
161
+ <React.Fragment key={id}>
162
162
  <Tab
163
163
  ref={(ref) => {
164
164
  tabRefs.current[index] = ref;
165
165
  }}
166
- key={id}
167
166
  {...{
168
167
  title: getTitle(item),
169
168
  id,
@@ -177,7 +176,7 @@ const TabsComponent = ({
177
176
  {display_mode === "fractional" &&
178
177
  index !== tabs?.length - 1 &&
179
178
  renderGutter()}
180
- </>
179
+ </React.Fragment>
181
180
  ),
182
181
  [tabs, display_mode, configuration, onTabPress, getTitle, getSelectedItem]
183
182
  );
@@ -2,6 +2,19 @@
2
2
 
3
3
  exports[`<TextInputTv /> renders 1`] = `
4
4
  <input
5
+ accessibilityProps={
6
+ {
7
+ "accessibilityHint": "Enter text into Search",
8
+ "accessibilityLabel": "Search",
9
+ "accessibilityRole": "searchbox",
10
+ "accessible": true,
11
+ "aria-description": "Enter text into Search",
12
+ "aria-label": "Search",
13
+ "aria-role": "searchbox",
14
+ "role": "searchbox",
15
+ "tabindex": 0,
16
+ }
17
+ }
5
18
  testID="TextInput-tv"
6
19
  />
7
20
  `;
@@ -4,6 +4,7 @@ import { Appearance, Platform, StyleSheet, TextInput } from "react-native";
4
4
  import { isFunction } from "@applicaster/zapp-react-native-utils/functionUtils";
5
5
  import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
6
6
  import { useIsRTL } from "@applicaster/zapp-react-native-utils/localizationUtils";
7
+ import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
7
8
 
8
9
  type Props = Partial<{
9
10
  style: any;
@@ -42,6 +43,8 @@ function TextInputTV(props: Props, ref) {
42
43
  const [colorScheme, setColorScheme] = useState(getInitialColorScheme());
43
44
  const isRTL = useIsRTL();
44
45
 
46
+ const accessibilityManager = useAccessibilityManager({});
47
+
45
48
  const onColorChange = useCallback(
46
49
  ({ colorScheme: color }) => {
47
50
  if (color !== colorScheme) {
@@ -153,6 +156,13 @@ function TextInputTV(props: Props, ref) {
153
156
  ])
154
157
  )(props);
155
158
 
159
+ const getAccessibilityProps = () => {
160
+ return {
161
+ accessibilityProps:
162
+ accessibilityManager.getInputAccessibilityProps("Search"),
163
+ };
164
+ };
165
+
156
166
  const inputProps = {
157
167
  ...getProps(),
158
168
  ...getStyle(),
@@ -161,6 +171,7 @@ function TextInputTV(props: Props, ref) {
161
171
  ...getSecureTextEntry(),
162
172
  ...getOnEndEditing(),
163
173
  ...getOnPress(),
174
+ ...getAccessibilityProps(),
164
175
  };
165
176
 
166
177
  if (
@@ -3,6 +3,23 @@
3
3
  exports[`<Touchable /> when not running in automated tests environment renders correctly 1`] = `
4
4
  <View
5
5
  accessibilityLabel="some-test-id"
6
+ accessibilityState={
7
+ {
8
+ "busy": undefined,
9
+ "checked": undefined,
10
+ "disabled": undefined,
11
+ "expanded": undefined,
12
+ "selected": undefined,
13
+ }
14
+ }
15
+ accessibilityValue={
16
+ {
17
+ "max": undefined,
18
+ "min": undefined,
19
+ "now": undefined,
20
+ "text": undefined,
21
+ }
22
+ }
6
23
  accessible={true}
7
24
  collapsable={false}
8
25
  focusable={true}
@@ -29,6 +46,23 @@ exports[`<Touchable /> when not running in automated tests environment renders c
29
46
  exports[`<Touchable /> when running in automated tests environment has accessible flag set to false 1`] = `
30
47
  <View
31
48
  accessibilityLabel="some-test-id"
49
+ accessibilityState={
50
+ {
51
+ "busy": undefined,
52
+ "checked": undefined,
53
+ "disabled": undefined,
54
+ "expanded": undefined,
55
+ "selected": undefined,
56
+ }
57
+ }
58
+ accessibilityValue={
59
+ {
60
+ "max": undefined,
61
+ "min": undefined,
62
+ "now": undefined,
63
+ "text": undefined,
64
+ }
65
+ }
32
66
  accessible={false}
33
67
  collapsable={false}
34
68
  focusable={true}
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { View, TouchableOpacity } from "react-native";
3
- import { create, act } from "react-test-renderer";
3
+ import { render } from "@testing-library/react-native";
4
4
 
5
5
  import { Touchable } from "..";
6
6
 
@@ -23,38 +23,31 @@ describe("<Touchable />", () => {
23
23
  });
24
24
 
25
25
  it("has accessible flag set to false", () => {
26
- let wrapper;
26
+ const { toJSON, UNSAFE_getByType } = render(<Touchable {...props} />);
27
27
 
28
- act(() => {
29
- wrapper = create(<Touchable {...props} />);
30
- });
31
-
32
- const touchableWrapper = wrapper.root.findByType(TouchableOpacity);
33
- expect(wrapper.toJSON()).toMatchSnapshot();
28
+ const touchableWrapper = UNSAFE_getByType(TouchableOpacity);
29
+ expect(toJSON()).toMatchSnapshot();
34
30
  expect(touchableWrapper.props).toHaveProperty("accessible", false);
35
31
  });
36
32
  });
37
33
 
38
34
  describe("when not running in automated tests environment", () => {
39
- let wrapper;
40
-
41
- act(() => {
42
- wrapper = create(<Touchable {...props} />);
43
- });
44
-
45
- const touchableWrapper = wrapper.root.findByType(TouchableOpacity);
46
-
47
35
  beforeEach(props.onPress.mockClear);
48
36
 
49
37
  it("renders correctly", () => {
50
- expect(wrapper.toJSON()).toMatchSnapshot();
38
+ const { toJSON } = render(<Touchable {...props} />);
39
+ expect(toJSON()).toMatchSnapshot();
51
40
  });
52
41
 
53
42
  it("has accessible flag set to true", () => {
43
+ const { UNSAFE_getByType } = render(<Touchable {...props} />);
44
+ const touchableWrapper = UNSAFE_getByType(TouchableOpacity);
54
45
  expect(touchableWrapper.props).toHaveProperty("accessible", true);
55
46
  });
56
47
 
57
48
  it("assigns testID and accessibilityLabel props correctly", () => {
49
+ const { UNSAFE_getByType } = render(<Touchable {...props} />);
50
+ const touchableWrapper = UNSAFE_getByType(TouchableOpacity);
58
51
  expect(touchableWrapper.props).toHaveProperty("testID", props.testID);
59
52
 
60
53
  expect(touchableWrapper.props).toHaveProperty(
@@ -64,6 +57,8 @@ describe("<Touchable />", () => {
64
57
  });
65
58
 
66
59
  it("calls the onPress event when it is pressed", () => {
60
+ const { UNSAFE_getByType } = render(<Touchable {...props} />);
61
+ const touchableWrapper = UNSAFE_getByType(TouchableOpacity);
67
62
  touchableWrapper.props.onPress();
68
63
  expect(props.onPress).toHaveBeenCalledTimes(1);
69
64
  });
@@ -6,15 +6,21 @@ exports[`<Scene /> renders correctly 1`] = `
6
6
  collapsable={false}
7
7
  pointerEvents="auto"
8
8
  style={
9
- {
10
- "flex": 1,
11
- "fontScale": 2,
12
- "height": 1334,
13
- "paddingBottom": 49,
14
- "scale": 2,
15
- "statusBarHeight": null,
16
- "width": 750,
17
- }
9
+ [
10
+ {
11
+ "flex": 1,
12
+ },
13
+ {
14
+ "paddingBottom": 49,
15
+ },
16
+ {
17
+ "fontScale": 2,
18
+ "height": 1334,
19
+ "scale": 2,
20
+ "statusBarHeight": null,
21
+ "width": 750,
22
+ },
23
+ ]
18
24
  }
19
25
  />
20
26
  </View>
@@ -9,6 +9,7 @@ exports[`PlayerLiveImageComponent should render correctly with default props 1`]
9
9
  <View>
10
10
  <View
11
11
  collapsable={false}
12
+ renderToHardwareTextureAndroid={false}
12
13
  style={
13
14
  {
14
15
  "opacity": 1,
@@ -1,8 +1,8 @@
1
1
  import { Animated, Easing, EasingFunction, StyleProp } from "react-native";
2
2
 
3
3
  type AnimatedInterpolatedStyle =
4
- | Animated.AnimatedInterpolation
5
- | [{ [Key: string]: Animated.AnimatedInterpolation }];
4
+ | Animated.AnimatedInterpolation<number>
5
+ | [{ [Key: string]: Animated.AnimatedInterpolation<number> }];
6
6
 
7
7
  type AnimationConfig = {
8
8
  duration: number;
@@ -31,7 +31,7 @@ const interpolate = (
31
31
  animatedValue: Animated.Value,
32
32
  from: number = 0,
33
33
  to: number = 1
34
- ): Animated.AnimatedInterpolation =>
34
+ ): Animated.AnimatedInterpolation<number> =>
35
35
  animatedValue.interpolate({
36
36
  inputRange: [0, 1],
37
37
  outputRange: [from, to],