@applicaster/zapp-react-native-ui-components 13.0.0-alpha.1488035644 → 13.0.0-alpha.1503493274

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 (162) hide show
  1. package/Components/AppContainer/__tests__/AppContainer.test.js +4 -6
  2. package/Components/AudioPlayer/AudioPlayer.tsx +5 -9
  3. package/Components/AudioPlayer/AudioPlayerLayout.tsx +8 -9
  4. package/Components/AudioPlayer/__tests__/Runtime.test.js +5 -8
  5. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +54 -111
  6. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +36 -20
  7. package/Components/AudioPlayer/__tests__/artWork.test.js +3 -5
  8. package/Components/AudioPlayer/__tests__/audioPlayer.test.js +3 -5
  9. package/Components/AudioPlayer/__tests__/audioPlayerLayout.test.js +7 -8
  10. package/Components/AudioPlayer/__tests__/channel.test.js +3 -5
  11. package/Components/AudioPlayer/__tests__/summary.test.js +3 -5
  12. package/Components/AudioPlayer/__tests__/title.test.js +3 -5
  13. package/Components/AudioPlayer/helpers.tsx +1 -2
  14. package/Components/BaseFocusable/index.tsx +1 -2
  15. package/Components/Cell/Cell.tsx +4 -13
  16. package/Components/Cell/CellWithFocusable.tsx +43 -55
  17. package/Components/Cell/CellWrapper.tsx +18 -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/CellRendererResolver/index.ts +2 -1
  24. package/Components/ComponentResolver/__tests__/__snapshots__/componentResolver.test.js.snap +1 -42
  25. package/Components/ComponentResolver/__tests__/componentResolver.test.js +16 -22
  26. package/Components/ContentScreen/__tests__/contentScreen.test.js +3 -3
  27. package/Components/ErrorScreen/index.tsx +14 -6
  28. package/Components/Focusable/Focusable.tsx +1 -0
  29. package/Components/Focusable/FocusableTvOS.tsx +5 -1
  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/GeneralContentScreen/GeneralContentScreen.tsx +3 -0
  37. package/Components/GeneralContentScreen/utils/useCurationAPI.ts +4 -2
  38. package/Components/GeneralContentScreen/utils/useEventAlerts.ts +30 -0
  39. package/Components/HandlePlayable/HandlePlayable.tsx +21 -27
  40. package/Components/Layout/TV/LayoutBackground.tsx +28 -0
  41. package/Components/Layout/TV/NavBarContainer.tsx +19 -23
  42. package/Components/Layout/TV/ScreenContainer.tsx +8 -2
  43. package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +5 -0
  44. package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +2 -1
  45. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +3 -2
  46. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +3 -2
  47. package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +15 -10
  48. package/Components/Layout/TV/__tests__/index.test.tsx +8 -2
  49. package/Components/Layout/TV/index.tsx +6 -20
  50. package/Components/Layout/TV/index.web.tsx +4 -1
  51. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -3
  52. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +4 -3
  53. package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +11 -7
  54. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -2
  55. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/const.ts +3 -0
  56. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +6 -6
  57. package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +2 -8
  58. package/Components/MasterCell/__tests__/__snapshots__/elementMapper.test.js.snap +4 -12
  59. package/Components/MasterCell/__tests__/__snapshots__/masterCell.test.js.snap +2 -220
  60. package/Components/MasterCell/__tests__/elementMapper.test.js +18 -5
  61. package/Components/MasterCell/__tests__/masterCell.test.js +26 -26
  62. package/Components/MasterCell/elementMapper.tsx +1 -12
  63. package/Components/MasterCell/hooks/useAsyncRendering/MasterCellAsyncRenderManager.ts +2 -2
  64. package/Components/MasterCell/index.tsx +18 -84
  65. package/Components/MasterCell/utils/behaviorProvider.ts +136 -0
  66. package/Components/MasterCell/utils/index.ts +8 -134
  67. package/Components/ModalComponent/BottomSheetModalContent.tsx +66 -54
  68. package/Components/ModalComponent/Button/Item.tsx +6 -5
  69. package/Components/ModalComponent/Button/assets.ts +1 -1
  70. package/Components/ModalComponent/Button/index.tsx +45 -62
  71. package/Components/ModalComponent/Header/index.tsx +12 -11
  72. package/Components/ModalComponent/utils.ts +55 -7
  73. package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +2 -2
  74. package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +2 -2
  75. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -5
  76. package/Components/OfflineHandler/utils/index.ts +1 -1
  77. package/Components/PlayerContainer/PlayerContainer.tsx +63 -54
  78. package/Components/PlayerContainer/ProgramInfo/index.tsx +2 -2
  79. package/Components/PlayerImageBackground/index.tsx +1 -1
  80. package/Components/River/ComponentsMap/ComponentsMap.tsx +53 -68
  81. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +78 -51
  82. package/Components/River/RiverFooter.tsx +39 -9
  83. package/Components/River/RiverItem.tsx +43 -3
  84. package/Components/River/TV/index.tsx +6 -1
  85. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +107 -32
  86. package/Components/River/__tests__/__snapshots__/river.test.js.snap +20 -82
  87. package/Components/River/__tests__/componentsMap.test.js +3 -4
  88. package/Components/River/__tests__/river.test.js +75 -40
  89. package/Components/RouteManager/TestId.tsx +1 -5
  90. package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +10 -4
  91. package/Components/RouteManager/__tests__/routeManager.test.js +29 -14
  92. package/Components/RouteManager/__tests__/testId.test.js +4 -6
  93. package/Components/Screen/TV/__tests__/index.web.test.tsx +26 -0
  94. package/Components/Screen/TV/index.web.tsx +5 -6
  95. package/Components/Screen/__tests__/Screen.test.tsx +22 -14
  96. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +2 -2
  97. package/Components/Screen/hooks.ts +53 -0
  98. package/Components/Screen/index.tsx +16 -42
  99. package/Components/ScreenResolver/__tests__/screenResolver.test.js +91 -70
  100. package/Components/Tabs/Tab.tsx +5 -3
  101. package/Components/TextInputTv/index.tsx +2 -1
  102. package/Components/TopMarginApplicator/TopMarginApplicator.tsx +2 -3
  103. package/Components/TrackedView/index.tsx +1 -0
  104. package/Components/Transitioner/AnimationManager.js +15 -15
  105. package/Components/Transitioner/Scene.tsx +53 -24
  106. package/Components/Transitioner/Transitioner.tsx +3 -3
  107. package/Components/Transitioner/__tests__/Scene.test.js +25 -14
  108. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +9 -49
  109. package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +2 -2
  110. package/Components/Transitioner/__tests__/transitioner.test.js +13 -4
  111. package/Components/Transitioner/index.js +8 -4
  112. package/Components/VideoLive/PlayerLiveImageComponent.tsx +18 -8
  113. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +1 -0
  114. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +1 -1
  115. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +46 -30
  116. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +3 -3
  117. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +45 -21
  118. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +13 -6
  119. package/Components/VideoModal/ModalAnimation/__tests__/getMoveUpValue.test.ts +108 -0
  120. package/Components/VideoModal/ModalAnimation/const.ts +5 -0
  121. package/Components/VideoModal/ModalAnimation/index.ts +2 -0
  122. package/Components/VideoModal/ModalAnimation/utils.ts +30 -0
  123. package/Components/VideoModal/PlayerDetails.tsx +18 -10
  124. package/Components/VideoModal/PlayerWrapper.tsx +37 -24
  125. package/Components/VideoModal/VideoModal.tsx +19 -4
  126. package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -40
  127. package/Components/VideoModal/utils.ts +3 -4
  128. package/Components/Viewport/ViewportAware/__tests__/__snapshots__/viewportAware.test.js.snap +24 -36
  129. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -18
  130. package/Components/Viewport/__tests__/utils.test.js +5 -4
  131. package/Components/ZappUIComponent/Placeholder.tsx +3 -1
  132. package/Components/ZappUIComponent/__tests__/{ZappUIComponent.test.js → ZappUIComponent.test.tsx} +26 -10
  133. package/Components/ZappUIComponent/index.tsx +4 -17
  134. package/Components/default-cell-renderer/__tests__/defaultCellRenderer.test.tsx +20 -17
  135. package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/__tests__/DefaultCell.test.tsx +15 -11
  136. package/Contexts/ComponentsMapOffsetContext/index.tsx +49 -0
  137. package/Contexts/FocusableGroupContext/withFocusableContext.tsx +4 -10
  138. package/Contexts/HeaderOffsetContext/index.tsx +4 -6
  139. package/Contexts/ScreenContext/index.tsx +3 -10
  140. package/Contexts/ScreenLayoutContext/index.tsx +5 -3
  141. package/Decorators/Navigator/__tests__/navigator.test.js +16 -16
  142. package/Decorators/Navigator/index.tsx +1 -1
  143. package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +18 -24
  144. package/Decorators/RiverResolver/index.tsx +6 -8
  145. package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +29 -22
  146. package/Decorators/ZappPipesDataConnector/index.tsx +4 -30
  147. package/package.json +7 -11
  148. package/tsconfig.json +2 -3
  149. package/.babelrc +0 -8
  150. package/Components/Cell/CellStyles/FallbackCellStyle/index.js +0 -157
  151. package/Components/Cell/CellStyles/Hero/index.js +0 -111
  152. package/Components/Cell/CellStyles/ScreenSelector/index.js +0 -68
  153. package/Components/Cell/CellStyles/cellStylesResolver.ts +0 -19
  154. package/Components/Cell/CellStyles/colors.js +0 -40
  155. package/Components/Cell/CellStyles/index.js +0 -15
  156. package/Components/CellRendererResolver/__tests__/__snapshots__/cellRendererResolver.test.js.snap +0 -53
  157. package/Components/RouteManager/__tests__/__snapshots__/testId.test.js.snap +0 -17
  158. package/Components/ScreenResolver/__tests__/__snapshots__/screenResolver.test.js.snap +0 -17
  159. package/Components/ZappUIComponent/__tests__/__snapshots__/ZappUIComponent.test.js.snap +0 -91
  160. package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +0 -306
  161. package/Decorators/Navigator/__tests__/__snapshots__/navigator.test.js.snap +0 -18
  162. package/Decorators/RiverResolver/__tests__/__snapshots__/riverResolver.test.tsx.snap +0 -28
@@ -1,34 +1,5 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`masterCellBuilder when using a custom data adapter renders correctly 1`] = `
4
- <View
5
- style={
6
- {
7
- "flex": 1,
8
- }
9
- }
10
- >
11
- <View
12
- cellUUID="mocked-uuid"
13
- key="0"
14
- style={
15
- {
16
- "backgroundColor": "#2F2F2F",
17
- "borderRadius": 4,
18
- "height": 436,
19
- "marginRight": 20,
20
- "width": 384,
21
- }
22
- }
23
- wrapperRef={
24
- {
25
- "current": null,
26
- }
27
- }
28
- />
29
- </View>
30
- `;
31
-
32
3
  exports[`masterCellBuilder when using custom containerStyle renders correctly 1`] = `
33
4
  <View
34
5
  style={
@@ -40,6 +11,7 @@ exports[`masterCellBuilder when using custom containerStyle renders correctly 1`
40
11
  <View
41
12
  cellUUID="mocked-uuid"
42
13
  key="0"
14
+ skipButtons={false}
43
15
  style={{}}
44
16
  wrapperRef={
45
17
  {
@@ -61,6 +33,7 @@ exports[`masterCellBuilder when using custom default components renders correctl
61
33
  <mockConstructor
62
34
  cellUUID="mocked-uuid"
63
35
  key="0"
36
+ skipButtons={false}
64
37
  style={{}}
65
38
  wrapperRef={
66
39
  {
@@ -70,194 +43,3 @@ exports[`masterCellBuilder when using custom default components renders correctl
70
43
  />
71
44
  </mockConstructor>
72
45
  `;
73
-
74
- exports[`masterCellBuilder when using default options can be invoked as a React Component 1`] = `
75
- <View
76
- style={
77
- {
78
- "flex": 1,
79
- }
80
- }
81
- >
82
- <View
83
- cellUUID="mocked-uuid"
84
- key="0"
85
- style={
86
- {
87
- "backgroundColor": "#2F2F2F",
88
- "borderRadius": 4,
89
- "height": 436,
90
- "marginRight": 20,
91
- "width": 384,
92
- }
93
- }
94
- whoAmI={
95
- {
96
- "contentType": "feed",
97
- "state": "default",
98
- }
99
- }
100
- wrapperRef={
101
- {
102
- "current": null,
103
- }
104
- }
105
- >
106
- <ImageContainer
107
- cellUUID="mocked-uuid"
108
- key="0"
109
- numberOfLines={1}
110
- style={
111
- {
112
- "borderTopLeftRadius": 4,
113
- "borderTopRightRadius": 4,
114
- "height": 216,
115
- "width": 384,
116
- }
117
- }
118
- uri="http://urlOfTheImage.net/img.png"
119
- />
120
- <View
121
- cellUUID="mocked-uuid"
122
- key="1"
123
- style={
124
- {
125
- "height": 30,
126
- "marginHorizontal": 24,
127
- "marginTop": 24,
128
- "width": 336,
129
- }
130
- }
131
- wrapperRef={
132
- {
133
- "current": null,
134
- }
135
- }
136
- >
137
- <_Text
138
- key="0"
139
- label="Test Entry"
140
- numberOfLines={1}
141
- style={
142
- {
143
- "color": "#EFEFEF",
144
- "fontSize": 26,
145
- "fontStyle": "normal",
146
- "fontWeight": "bold",
147
- }
148
- }
149
- />
150
- </View>
151
- <View
152
- cellUUID="mocked-uuid"
153
- key="2"
154
- style={
155
- {
156
- "height": 60,
157
- "marginHorizontal": 24,
158
- "marginTop": 10,
159
- "width": 336,
160
- }
161
- }
162
- wrapperRef={
163
- {
164
- "current": null,
165
- }
166
- }
167
- >
168
- <_Text
169
- key="0"
170
- label="Summary of the test entry"
171
- numberOfLines={2}
172
- style={
173
- {
174
- "color": "#EFEFEF",
175
- "fontSize": 24,
176
- "fontStyle": "normal",
177
- "fontWeight": "normal",
178
- "opacity": 0.8,
179
- }
180
- }
181
- />
182
- </View>
183
- <View
184
- cellUUID="mocked-uuid"
185
- key="3"
186
- style={
187
- {
188
- "height": 42,
189
- "margin": 24,
190
- "width": 56,
191
- }
192
- }
193
- wrapperRef={
194
- {
195
- "current": null,
196
- }
197
- }
198
- >
199
- <ImageContainer
200
- cellUUID="mocked-uuid"
201
- key="0"
202
- style={
203
- {
204
- "height": 42,
205
- "width": 56,
206
- }
207
- }
208
- uri="http://urlOfTheImage.net/channelLogo.png"
209
- />
210
- </View>
211
- </View>
212
- </View>
213
- `;
214
-
215
- exports[`masterCellBuilder when using default options renders correctly 1`] = `
216
- <View>
217
- <Memo(MasterCell)
218
- item={
219
- {
220
- "author": {
221
- "name": "John Doe",
222
- },
223
- "id": "A1234",
224
- "media_group": [
225
- {
226
- "media_item": [
227
- {
228
- "key": "image_base",
229
- "src": "http://urlOfTheImage.net/img.png",
230
- },
231
- ],
232
- "type": "image",
233
- },
234
- {
235
- "media_item": [
236
- {
237
- "key": "logo_thumbnail",
238
- "src": "http://urlOfTheImage.net/channelLogo.png",
239
- },
240
- ],
241
- "type": "thumbnail",
242
- },
243
- ],
244
- "published": "2019/03/17 02:17:46 +0000",
245
- "summary": "Summary of the test entry",
246
- "title": "Test Entry",
247
- "type": {
248
- "value": "feed",
249
- },
250
- }
251
- }
252
- />
253
- </View>
254
- `;
255
-
256
- exports[`masterCellBuilder when using default options returns a function 1`] = `
257
- {
258
- "$$typeof": Symbol(react.memo),
259
- "compare": null,
260
- "hasFocusableInside": [Function],
261
- "type": [Function],
262
- }
263
- `;
@@ -1,20 +1,33 @@
1
1
  import * as R from "ramda";
2
2
  import * as React from "react";
3
3
  import { View } from "react-native";
4
- import { shallow } from "enzyme";
5
- import { shallowToJson } from "enzyme-to-json";
4
+ import { render } from "@testing-library/react-native";
6
5
  import { elementMapper } from "../elementMapper";
7
6
  import { elements } from "./testElements";
8
7
  import { defaultComponents } from "../DefaultComponents";
9
8
 
9
+ jest.mock(
10
+ "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation"
11
+ );
12
+
10
13
  describe("elementMapper", () => {
11
14
  it("renders the nodes", () => {
12
- const wrapper = shallow(
15
+ const wrapper = render(
13
16
  <View key={1}>
14
- {R.map(elementMapper(defaultComponents, { testProp: true }), elements)}
17
+ {R.map(
18
+ elementMapper(
19
+ Object.entries(defaultComponents).reduce((acc, [key]) => {
20
+ acc[key] = View;
21
+
22
+ return acc;
23
+ }, {}),
24
+ { testProp: true }
25
+ ),
26
+ elements
27
+ )}
15
28
  </View>
16
29
  );
17
30
 
18
- expect(shallowToJson(wrapper)).toMatchSnapshot();
31
+ expect(wrapper.toJSON()).toMatchSnapshot();
19
32
  });
20
33
  });
@@ -1,16 +1,25 @@
1
1
  import * as React from "react";
2
2
  import { View } from "react-native";
3
- import { shallow } from "enzyme";
4
- import { shallowToJson } from "enzyme-to-json";
3
+ import { renderWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
5
4
 
6
5
  import { testCellStyle } from "./TestCellStyle";
7
6
  import { singleView } from "./SingleView";
8
7
  import { entry } from "./testEntry";
9
8
  import { singleElement } from "./testElements";
10
9
 
11
- jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
12
- useRoute: jest.fn(() => ({ screenData: { id: "test" } })),
13
- }));
10
+ jest.mock(
11
+ "@applicaster/zapp-react-native-utils/reactHooks/navigation/useRoute",
12
+ () => ({
13
+ useRoute: jest.fn(() => ({ screenData: { id: "test" } })),
14
+ })
15
+ );
16
+
17
+ jest.mock(
18
+ "@applicaster/zapp-react-native-utils/reactHooks/navigation/useIsScreenActive",
19
+ () => ({
20
+ useIsScreenActive: jest.fn(() => true),
21
+ })
22
+ );
14
23
 
15
24
  jest.mock("@applicaster/zapp-react-native-utils/screenState", () => ({
16
25
  useScreenState: jest.fn(() => ({
@@ -27,36 +36,27 @@ describe("masterCellBuilder", () => {
27
36
  describe("when using default options", () => {
28
37
  const MasterCell = masterCellBuilder({ cellConfiguration: testCellStyle });
29
38
 
30
- it("returns a function", () => {
31
- expect(MasterCell).toMatchSnapshot();
32
- });
33
-
34
39
  it("renders correctly", () => {
35
- const wrapper = shallow(
36
- <View>
40
+ const wrapper = renderWithProviders(
41
+ <View testID="master-cell">
37
42
  <MasterCell item={entry} />
38
43
  </View>
39
44
  );
40
45
 
41
- expect(shallowToJson(wrapper)).toMatchSnapshot();
42
- });
43
-
44
- it("can be invoked as a React Component", () => {
45
- const wrapper = shallow(<MasterCell item={entry} state={null} />);
46
-
47
- expect(shallowToJson(wrapper)).toMatchSnapshot();
46
+ expect(wrapper.getByTestId("master-cell").children[0]).toBeDefined();
48
47
  });
49
48
  });
50
49
 
51
- describe("when using custom containerStyle", () => {
50
+ describe.skip("when using custom containerStyle", () => {
52
51
  const MasterCell = masterCellBuilder({
53
52
  cellConfiguration: singleView,
54
53
  containerStyle: { backgroundColor: "black" },
55
54
  });
56
55
 
57
56
  it("renders correctly", () => {
58
- const renderer = shallow(<MasterCell item={entry} />);
59
- expect(shallowToJson(renderer)).toMatchSnapshot();
57
+ renderWithProviders(<MasterCell item={entry} />);
58
+
59
+ // TODO define the test need
60
60
  });
61
61
  });
62
62
 
@@ -69,14 +69,14 @@ describe("masterCellBuilder", () => {
69
69
  });
70
70
 
71
71
  it("renders correctly", () => {
72
- const renderer = shallow(<MasterCell item={entry} />);
73
- expect(shallowToJson(renderer)).toMatchSnapshot();
72
+ renderWithProviders(<MasterCell item={entry} />);
73
+ // TODO define the test need
74
74
 
75
75
  expect(dataAdapter).toHaveBeenCalledWith(singleView);
76
76
  });
77
77
  });
78
78
 
79
- describe("when using custom default components", () => {
79
+ describe.skip("when using custom default components", () => {
80
80
  // the collapsable prop is added here to easily check from the snapshot that the mock
81
81
  // component is being used instead of the default one
82
82
  const CustomView = jest.fn((props) => <View {...props} collapsable />);
@@ -88,8 +88,8 @@ describe("masterCellBuilder", () => {
88
88
  });
89
89
 
90
90
  it("renders correctly", () => {
91
- const renderer = shallow(<MasterCell item={entry} />);
92
- expect(shallowToJson(renderer)).toMatchSnapshot();
91
+ renderWithProviders(<MasterCell item={entry} />);
92
+ // TODO define the test need
93
93
  });
94
94
  });
95
95
  });
@@ -1,5 +1,4 @@
1
1
  import * as React from "react";
2
- import { View } from "react-native";
3
2
 
4
3
  type ElementProps = {
5
4
  type: string;
@@ -45,21 +44,11 @@ const cellPlayerTypes = new Set([
45
44
  export function elementMapper(
46
45
  components,
47
46
  otherProps?: {
48
- preferredFocus?: boolean;
49
47
  skipButtons?: boolean;
50
48
  cellUUID?: string;
49
+ [key: string]: any;
51
50
  emitAsyncElementRegistrate?: () => void;
52
51
  emitAsyncElementLayout?: () => void;
53
- focused?: boolean;
54
- focusedButtonId?: string;
55
- groupId?: string;
56
- isFocusable?: boolean;
57
- onToggleFocus?: (arg0: unknown) => void;
58
- prefixId?: string;
59
- skipFocusManagerRegistration?: boolean;
60
- component?: ZappUIComponent;
61
- componentId?: string;
62
- wrapperRef: React.RefObject<typeof View>;
63
52
  }
64
53
  ) {
65
54
  return function Element({
@@ -16,13 +16,13 @@ export class MasterCellAsyncRenderManager {
16
16
  }
17
17
 
18
18
  public emitAsyncElementRegistrate = () => {
19
- this.asyncElementRegistrate$.next();
19
+ this.asyncElementRegistrate$.next(null);
20
20
 
21
21
  return this.decrementAsyncElementRegistrationCount;
22
22
  };
23
23
 
24
24
  public emitAsyncElementLayout = () => {
25
- this.asyncElementLayout$.next();
25
+ this.asyncElementLayout$.next(null);
26
26
  };
27
27
 
28
28
  public decrementAsyncElementRegistrationCount = () => {
@@ -11,24 +11,7 @@ import { getEntryState, hasFocusableInsideBuilder } from "./utils";
11
11
 
12
12
  type Props = {
13
13
  item: ZappEntry;
14
- state: null | "selected" | "focused" | "default";
15
- emitAsyncElementRegistrate?: () => void;
16
- emitAsyncElementLayout?: () => void;
17
- skipButtons?: boolean;
18
- cellUUID?: string;
19
- // New props from CellWithFocusable
20
- groupId?: string;
21
- onToggleFocus?: (arg0: unknown) => void;
22
- prefixId?: string;
23
- focusedButtonId?: string;
24
- preferredFocus?: boolean;
25
- skipFocusManagerRegistration?: boolean;
26
- isFocusable?: boolean;
27
- focused?: boolean;
28
- // New props from Gallery
29
- component?: ZappUIComponent;
30
- componentId?: string;
31
- screenId: string;
14
+ state: null | "selected" | "focused";
32
15
  };
33
16
 
34
17
  const defaultContainerStyle = { flex: 1 };
@@ -56,24 +39,6 @@ type MasterCellBuilderOptions = {
56
39
  };
57
40
  };
58
41
 
59
- // retrieve screendata from route
60
- const useMasterCellScreen = (screenId?: string) => {
61
- let _screenId = screenId;
62
- const { screenData } = useRoute();
63
-
64
- if (!screenId) {
65
- // get screenId from targetScreen or screenData
66
- _screenId =
67
- screenData && "targetScreen" in screenData
68
- ? screenData?.targetScreen?.id
69
- : screenData?.id;
70
- }
71
-
72
- const { screen } = useScreenState(_screenId);
73
-
74
- return screen;
75
- };
76
-
77
42
  export function masterCellBuilder({
78
43
  components = defaultComponents,
79
44
  cellConfiguration,
@@ -98,8 +63,15 @@ export function masterCellBuilder({
98
63
  * inflated with the data coming from the data source
99
64
  * @param {"selected" | "focused" | null} props.state state of the component
100
65
  */
101
- function MasterCell({ item, state, screenId, ...otherProps }: Props) {
102
- const screen = useMasterCellScreen(screenId);
66
+ function MasterCell({ item, state, ...otherProps }: Props) {
67
+ const { screenData } = useRoute();
68
+
69
+ const screenId =
70
+ screenData && "targetScreen" in screenData
71
+ ? screenData?.targetScreen?.id
72
+ : screenData?.id;
73
+
74
+ const { screen } = useScreenState(screenId);
103
75
 
104
76
  const selectedState = screen?.selectedEntry;
105
77
 
@@ -125,56 +97,18 @@ export function masterCellBuilder({
125
97
  item?.id,
126
98
  ]);
127
99
 
128
- const remapElements = React.useMemo(
129
- () =>
130
- mapElementWithKey(
131
- elementMapper(componentsMap, {
132
- wrapperRef,
133
- emitAsyncElementRegistrate: otherProps.emitAsyncElementRegistrate,
134
- emitAsyncElementLayout: otherProps.emitAsyncElementLayout,
135
- preferredFocus: otherProps.preferredFocus,
136
- cellUUID: cellUUID || otherProps.cellUUID,
137
- skipButtons: skipButtons || otherProps.skipButtons,
138
- // cellWithFocusable
139
- focused: otherProps.focused,
140
- focusedButtonId: otherProps.focusedButtonId,
141
- groupId: otherProps.groupId,
142
- isFocusable: otherProps.isFocusable,
143
- onToggleFocus: otherProps.onToggleFocus,
144
- prefixId: otherProps.prefixId,
145
- skipFocusManagerRegistration:
146
- otherProps.skipFocusManagerRegistration,
147
- // gallery
148
- component: otherProps.component,
149
- componentId: otherProps.componentId,
150
- })
151
- ),
152
- [
153
- componentsMap,
154
- otherProps.emitAsyncElementRegistrate,
155
- otherProps.emitAsyncElementLayout,
156
- cellUUID || otherProps.cellUUID,
157
- skipButtons || otherProps.skipButtons,
158
- otherProps.focused,
159
- otherProps.focusedButtonId,
160
- otherProps.groupId,
161
- otherProps.isFocusable,
162
- otherProps.onToggleFocus,
163
- otherProps.prefixId,
164
- otherProps.skipFocusManagerRegistration,
165
- otherProps.component,
166
- otherProps.componentId,
167
- ]
168
- );
169
-
170
- const renderElements = React.useMemo(
171
- () => elements.map(remapElements),
172
- [remapElements, elements]
100
+ const remapElements = mapElementWithKey(
101
+ elementMapper(componentsMap, {
102
+ ...otherProps,
103
+ wrapperRef,
104
+ cellUUID,
105
+ skipButtons,
106
+ })
173
107
  );
174
108
 
175
109
  return (
176
110
  <View style={containerStyle} ref={wrapperRef}>
177
- {renderElements}
111
+ {elements.map(remapElements)}
178
112
  </View>
179
113
  );
180
114
  }
@@ -0,0 +1,136 @@
1
+ import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
2
+ import { StorageSingleValueProvider } from "@applicaster/zapp-react-native-bridge/ZappStorage/StorageSingleSelectProvider";
3
+ import { PushTopicManager } from "@applicaster/zapp-react-native-bridge/PushNotifications/PushTopicManager";
4
+ import { StorageMultiSelectProvider } from "@applicaster/zapp-react-native-bridge/ZappStorage/StorageMultiSelectProvider";
5
+ import React, { useEffect } from "react";
6
+ import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer";
7
+ import { BehaviorSubject } from "rxjs";
8
+ import { masterCellLogger } from "../logger";
9
+ import get from "lodash/get";
10
+
11
+ const parseContextKey = (key: string): string | null => {
12
+ if (!key?.startsWith("@{ctx/")) return null;
13
+
14
+ return key.substring("@{ctx/".length, key.length - 1);
15
+ };
16
+
17
+ const getDataSourceProvider = (
18
+ behavior: Behavior
19
+ ): BehaviorSubject<string[] | string> | null => {
20
+ if (!behavior) return null;
21
+
22
+ const selection = String(behavior.current_selection);
23
+ const contextKey = parseContextKey(selection);
24
+
25
+ if (contextKey) {
26
+ if (behavior.select_mode === "multi") {
27
+ return StorageMultiSelectProvider.getProvider(contextKey).getObservable();
28
+ }
29
+
30
+ if (behavior.select_mode === "single") {
31
+ return StorageSingleValueProvider.getProvider(contextKey).getObservable();
32
+ }
33
+ }
34
+
35
+ if (behavior.selection_source === "@{push/topics}") {
36
+ return PushTopicManager.getInstance().getEntryObservable();
37
+ }
38
+
39
+ return null;
40
+ };
41
+
42
+ export const useBehaviorUpdate = (behavior: Behavior) => {
43
+ const [lastUpdate, setLastUpdate] = React.useState<number | null>(null);
44
+ const player = usePlayer();
45
+
46
+ const triggerUpdate = () => setLastUpdate(Date.now());
47
+
48
+ useEffect(() => {
49
+ if (!behavior) return;
50
+
51
+ const dataSource = getDataSourceProvider(behavior);
52
+
53
+ if (dataSource) {
54
+ const subscription = dataSource.subscribe(triggerUpdate);
55
+
56
+ return () => subscription.unsubscribe();
57
+ }
58
+ }, [behavior]);
59
+
60
+ useEffect(() => {
61
+ if (!behavior || !player || behavior.selection_source !== "now_playing") {
62
+ return;
63
+ }
64
+
65
+ const subscription = player.getEntryObservable().subscribe(triggerUpdate);
66
+
67
+ return () => subscription.unsubscribe();
68
+ }, [behavior, player]);
69
+
70
+ return lastUpdate;
71
+ };
72
+
73
+ // We cant use async in this function (its inside render),
74
+ // so we rely on useBehaviorUpdate to update current value and trigger re-render
75
+ export const isCellSelected = (
76
+ item: ZappEntry,
77
+ behavior?: Behavior
78
+ ): boolean => {
79
+ if (!behavior) return false;
80
+
81
+ const id = behavior.selector ? get(item, behavior.selector) : item.id;
82
+
83
+ if (behavior.selection_source === "now_playing") {
84
+ const player = playerManager.getActivePlayer();
85
+
86
+ return player?.entry?.id === id;
87
+ }
88
+
89
+ if (behavior.selection_source === "@{push/topics}") {
90
+ if (behavior.select_mode === "single") {
91
+ masterCellLogger.warning(
92
+ "Unexpected single selection mode for push topics"
93
+ );
94
+ }
95
+
96
+ const tags = PushTopicManager.getInstance().getRegisteredTags();
97
+
98
+ return tags.includes(String(id));
99
+ }
100
+
101
+ const selection = String(behavior.current_selection);
102
+ const contextKey = parseContextKey(selection);
103
+
104
+ if (contextKey) {
105
+ if (behavior.select_mode === "single") {
106
+ const selectedItem =
107
+ StorageSingleValueProvider.getProvider(contextKey)?.getValue();
108
+
109
+ return selectedItem === String(id);
110
+ }
111
+
112
+ if (behavior.select_mode === "multi") {
113
+ const selectedItems =
114
+ StorageMultiSelectProvider.getProvider(contextKey)?.getSelectedItems();
115
+
116
+ return selectedItems?.includes(String(id));
117
+ }
118
+ }
119
+
120
+ if (behavior.select_mode === "single") {
121
+ return behavior.current_selection === id;
122
+ }
123
+
124
+ if (
125
+ behavior.select_mode === "multi" &&
126
+ Array.isArray(behavior.current_selection)
127
+ ) {
128
+ const currentSelection: string[] = behavior.current_selection.map(
129
+ (item): string => String(item)
130
+ );
131
+
132
+ return currentSelection.includes(String(id));
133
+ }
134
+
135
+ return false;
136
+ };