@applicaster/zapp-react-native-ui-components 15.0.0-rc.99 → 15.1.0-alpha.1852552014

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 (137) hide show
  1. package/Components/BackgroundImage/BackgroundImage.tv.android.tsx +28 -0
  2. package/Components/BackgroundImage/BackgroundImage.tv.ios.tsx +24 -0
  3. package/Components/BackgroundImage/BackgroundImage.tv.web.tsx +42 -0
  4. package/Components/BackgroundImage/index.ts +8 -0
  5. package/Components/BaseFocusable/index.ios.ts +2 -12
  6. package/Components/Cell/FocusableWrapper.tsx +0 -3
  7. package/Components/Cell/TvOSCellComponent.tsx +0 -5
  8. package/Components/CellRendererResolver/index.ts +1 -1
  9. package/Components/ComponentResolver/__tests__/componentResolver.test.js +1 -1
  10. package/Components/Focusable/Focusable.tsx +2 -4
  11. package/Components/Focusable/FocusableTvOS.tsx +1 -18
  12. package/Components/Focusable/__tests__/__snapshots__/FocusableTvOS.test.tsx.snap +0 -1
  13. package/Components/FocusableGroup/FocusableTvOS.tsx +12 -37
  14. package/Components/GeneralContentScreen/GeneralContentScreen.tsx +39 -28
  15. package/Components/GeneralContentScreen/__tests__/GeneralContentScreen.test.tsx +104 -0
  16. package/Components/GeneralContentScreen/utils/__tests__/getScreenDataSource.test.ts +19 -0
  17. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +1 -1
  18. package/Components/GeneralContentScreen/utils/getScreenDataSource.ts +9 -0
  19. package/Components/HandlePlayable/HandlePlayable.tsx +24 -42
  20. package/Components/HandlePlayable/utils.ts +31 -0
  21. package/Components/HookRenderer/HookRenderer.tsx +40 -10
  22. package/Components/HookRenderer/__tests__/HookRenderer.test.tsx +60 -0
  23. package/Components/Layout/FullWidthRow.tsx +38 -0
  24. package/Components/Layout/TV/ScreenContainer.tsx +11 -2
  25. package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +5 -1
  26. package/Components/Layout/TV/index.tsx +6 -6
  27. package/Components/Layout/TV/index.web.tsx +6 -6
  28. package/Components/LinkHandler/LinkHandler.tsx +2 -2
  29. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +10 -4
  30. package/Components/MasterCell/DefaultComponents/Image/Image.android.tsx +1 -5
  31. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +3 -11
  32. package/Components/MasterCell/DefaultComponents/Image/Image.web.tsx +1 -9
  33. package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +14 -15
  34. package/Components/MasterCell/DefaultComponents/LiveImage/__tests__/prepareEntry.test.ts +352 -0
  35. package/Components/MasterCell/DefaultComponents/LiveImage/executePreloadHooks.ts +136 -0
  36. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +34 -16
  37. package/Components/MasterCell/DefaultComponents/SecondaryImage/hooks/__tests__/useGetImageDimensions.test.ts +6 -7
  38. package/Components/MasterCell/DefaultComponents/Text/index.tsx +2 -6
  39. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +2 -6
  40. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/getPluginIdentifier.test.ts +11 -233
  41. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +15 -19
  42. package/Components/MasterCell/dataAdapter.ts +15 -5
  43. package/Components/MasterCell/index.tsx +10 -1
  44. package/Components/MasterCell/utils/__tests__/resolveColor.test.js +169 -132
  45. package/Components/MasterCell/utils/__tests__/resolveColorForProp.test.js +92 -0
  46. package/Components/MasterCell/utils/index.ts +89 -46
  47. package/Components/Navigator/StackNavigator.tsx +6 -0
  48. package/Components/OfflineHandler/NotificationView/NotificationView.tsx +2 -2
  49. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +18 -17
  50. package/Components/OfflineHandler/__tests__/index.test.tsx +18 -27
  51. package/Components/PlayerContainer/PlayerContainer.tsx +20 -34
  52. package/Components/PlayerContainer/__tests__/PlayerContainer.test.tsx +286 -0
  53. package/Components/PreloaderWrapper/__tests__/index.test.tsx +26 -0
  54. package/Components/PreloaderWrapper/index.tsx +15 -0
  55. package/Components/River/ComponentsMap/ComponentsMap.tsx +3 -4
  56. package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +1 -1
  57. package/Components/River/RefreshControl.tsx +9 -3
  58. package/Components/River/RiverItem.tsx +26 -20
  59. package/Components/River/TV/River.tsx +14 -31
  60. package/Components/River/TV/index.tsx +4 -8
  61. package/Components/River/TV/withTVEventHandler.tsx +36 -0
  62. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +0 -16
  63. package/Components/River/__tests__/componentsMap.test.js +0 -38
  64. package/Components/Screen/TV/hooks/__tests__/useAfterPaint.test.ts +60 -0
  65. package/Components/Screen/TV/hooks/index.ts +2 -0
  66. package/Components/Screen/TV/hooks/useAfterPaint.ts +23 -0
  67. package/Components/Screen/TV/index.web.tsx +18 -11
  68. package/Components/Screen/__tests__/Screen.test.tsx +43 -65
  69. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +44 -68
  70. package/Components/Screen/hooks.ts +76 -5
  71. package/Components/Screen/index.tsx +18 -7
  72. package/Components/Screen/orientationHandler.ts +3 -3
  73. package/Components/ScreenFeedLoader/ScreenFeedLoader.tsx +46 -0
  74. package/Components/ScreenFeedLoader/__tests__/ScreenFeedLoader.test.tsx +94 -0
  75. package/Components/ScreenFeedLoader/index.ts +1 -0
  76. package/Components/ScreenResolver/__tests__/screenResolver.test.js +24 -0
  77. package/Components/ScreenResolver/hooks/index.ts +3 -0
  78. package/Components/ScreenResolver/hooks/useGetComponent.ts +15 -0
  79. package/Components/ScreenResolver/hooks/useScreenComponentResolver.tsx +90 -0
  80. package/Components/ScreenResolver/index.tsx +9 -115
  81. package/Components/ScreenResolver/utils/__tests__/getScreenTypeProps.test.ts +45 -0
  82. package/Components/ScreenResolver/utils/getScreenTypeProps.ts +43 -0
  83. package/Components/ScreenResolver/utils/index.ts +1 -0
  84. package/Components/ScreenResolver/withDefaultScreenContext.tsx +16 -0
  85. package/Components/ScreenResolverFeedProvider/ScreenResolverFeedProvider.tsx +25 -0
  86. package/Components/ScreenResolverFeedProvider/__tests__/ScreenResolverFeedProvider.test.tsx +44 -0
  87. package/Components/ScreenResolverFeedProvider/index.ts +1 -0
  88. package/Components/ScreenRevealManager/Overlay.tsx +34 -0
  89. package/Components/ScreenRevealManager/ScreenRevealManager.ts +8 -40
  90. package/Components/ScreenRevealManager/__tests__/Overlay.test.tsx +88 -0
  91. package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +69 -86
  92. package/Components/ScreenRevealManager/withScreenRevealManager.tsx +10 -18
  93. package/Components/Tabs/TabContent.tsx +4 -7
  94. package/Components/Transitioner/Scene.tsx +9 -15
  95. package/Components/Transitioner/index.js +3 -3
  96. package/Components/VideoLive/LiveImageManager.ts +209 -53
  97. package/Components/VideoLive/PlayerLiveImageComponent.tsx +32 -32
  98. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +2 -17
  99. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +5 -5
  100. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +7 -15
  101. package/Components/VideoModal/utils.ts +16 -13
  102. package/Components/Viewport/ViewportEvents/__tests__/viewportEvents.test.js +1 -1
  103. package/Components/ZappFrameworkComponents/BarView/BarView.tsx +12 -5
  104. package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +2 -2
  105. package/Components/ZappUIComponent/index.tsx +12 -6
  106. package/Components/index.js +1 -1
  107. package/Contexts/CachedDimensionsContext/index.ts +17 -2
  108. package/Contexts/ScreenContext/__tests__/index.test.tsx +57 -0
  109. package/Contexts/ScreenContext/index.tsx +64 -26
  110. package/Contexts/ScreenTrackedViewPositionsContext/__tests__/index.test.tsx +1 -1
  111. package/Contexts/ZappPipesContext/ZappPipesContextFactory.tsx +18 -7
  112. package/Decorators/Analytics/index.tsx +5 -6
  113. package/Decorators/ConfigurationWrapper/__tests__/__snapshots__/withConfigurationProvider.test.tsx.snap +0 -1
  114. package/Decorators/ConfigurationWrapper/const.ts +0 -1
  115. package/Decorators/ZappPipesDataConnector/ResolverSelector.tsx +25 -7
  116. package/Decorators/ZappPipesDataConnector/__tests__/ResolverSelector.test.tsx +212 -5
  117. package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +1 -1
  118. package/Decorators/ZappPipesDataConnector/index.tsx +2 -2
  119. package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +1 -1
  120. package/Helpers/ComponentCellSelectionHelper/index.js +0 -6
  121. package/Helpers/DataSourceHelper/index.js +19 -0
  122. package/Helpers/index.js +7 -40
  123. package/package.json +5 -5
  124. package/Components/Layout/TV/LayoutBackground.tsx +0 -31
  125. package/Components/MasterCell/DefaultComponents/Text/utils/__tests__/withAdjustedLineHeight.test.ts +0 -46
  126. package/Components/MasterCell/DefaultComponents/Text/utils/index.ts +0 -21
  127. package/Components/PlayerContainer/ErrorDisplay/ErrorDisplay.tsx +0 -57
  128. package/Components/PlayerContainer/ErrorDisplay/index.ts +0 -9
  129. package/Components/PlayerContainer/useRestrictMobilePlayback.tsx +0 -101
  130. package/Components/River/TV/utils/__tests__/toStringOrEmpty.test.ts +0 -30
  131. package/Components/River/TV/utils/index.ts +0 -4
  132. package/Components/River/TV/withFocusableGroupForContent.tsx +0 -71
  133. package/Components/Screen/utils.ts +0 -16
  134. package/Helpers/Analytics/index.js +0 -95
  135. package/Helpers/DataSourceHelper/__tests__/itemLimitForData.test.ts +0 -80
  136. package/Helpers/DataSourceHelper/index.ts +0 -19
  137. /package/Components/HookRenderer/{index.tsx → index.ts} +0 -0
@@ -7,15 +7,30 @@ import { UrlFeedResolver } from "../resolvers/UrlFeedResolver";
7
7
  import { NullFeedResolver } from "../resolvers/NullFeedResolver";
8
8
 
9
9
  jest.mock("../resolvers/StaticFeedResolver", () => ({
10
- StaticFeedResolver: jest.fn(() => null),
10
+ StaticFeedResolver: jest.fn(({ children }) =>
11
+ children({
12
+ zappPipesData: { loading: true, data: null, error: null },
13
+ reloadData: jest.fn(),
14
+ })
15
+ ),
11
16
  }));
12
17
 
13
18
  jest.mock("../resolvers/UrlFeedResolver", () => ({
14
- UrlFeedResolver: jest.fn(() => null),
19
+ UrlFeedResolver: jest.fn(({ children }) =>
20
+ children({
21
+ zappPipesData: { loading: true, data: null, error: null },
22
+ reloadData: jest.fn(),
23
+ })
24
+ ),
15
25
  }));
16
26
 
17
27
  jest.mock("../resolvers/NullFeedResolver", () => ({
18
- NullFeedResolver: jest.fn(() => null),
28
+ NullFeedResolver: jest.fn(({ children }) =>
29
+ children({
30
+ zappPipesData: { loading: false, data: null, error: null },
31
+ reloadData: jest.fn(),
32
+ })
33
+ ),
19
34
  }));
20
35
 
21
36
  const testPlugin = {
@@ -52,7 +67,7 @@ describe("ResolverSelector", () => {
52
67
  expect.objectContaining({
53
68
  getStaticComponentFeed: props.getStaticComponentFeed,
54
69
  component: mockComponent,
55
- children: mockChildren,
70
+ children: expect.any(Function),
56
71
  }),
57
72
  expect.anything()
58
73
  );
@@ -151,7 +166,10 @@ describe("ResolverSelector", () => {
151
166
  render(<ResolverSelector {...props} />);
152
167
 
153
168
  expect(StaticFeedResolver).toHaveBeenCalledWith(
154
- expect.objectContaining(props),
169
+ expect.objectContaining({
170
+ ...props,
171
+ children: expect.any(Function),
172
+ }),
155
173
  expect.anything()
156
174
  );
157
175
  });
@@ -202,4 +220,193 @@ describe("ResolverSelector", () => {
202
220
  expect(UrlFeedResolver).not.toHaveBeenCalled();
203
221
  expect(NullFeedResolver).not.toHaveBeenCalled();
204
222
  });
223
+
224
+ describe("Fallback Logic", () => {
225
+ it("should fallback to UrlFeedResolver when StaticFeedResolver returns null and feedUrl is present", () => {
226
+ const props = {
227
+ getStaticComponentFeed: jest.fn(),
228
+ feedUrl: "https://example.com/feed",
229
+ component: mockComponent,
230
+ children: mockChildren,
231
+ riverId: "test-river",
232
+ };
233
+
234
+ (StaticFeedResolver as jest.Mock).mockImplementation(({ children }) =>
235
+ children({
236
+ zappPipesData: { loading: false, data: null, error: null },
237
+ reloadData: jest.fn(),
238
+ })
239
+ );
240
+
241
+ render(<ResolverSelector {...props} />);
242
+
243
+ expect(StaticFeedResolver).toHaveBeenCalled();
244
+
245
+ expect(UrlFeedResolver).toHaveBeenCalledWith(
246
+ expect.objectContaining({
247
+ feedUrl: props.feedUrl,
248
+ component: mockComponent,
249
+ children: mockChildren,
250
+ }),
251
+ expect.anything()
252
+ );
253
+ });
254
+
255
+ it("should fallback to UrlFeedResolver when StaticFeedResolver returns null and component.data.source is present", () => {
256
+ const componentWithSource = {
257
+ ...mockComponent,
258
+ data: {
259
+ source: "data-source",
260
+ },
261
+ };
262
+
263
+ const props = {
264
+ getStaticComponentFeed: jest.fn(),
265
+ component: componentWithSource,
266
+ children: mockChildren,
267
+ riverId: "test-river",
268
+ };
269
+
270
+ (StaticFeedResolver as jest.Mock).mockImplementation(({ children }) =>
271
+ children({
272
+ zappPipesData: { loading: false, data: null, error: null },
273
+ reloadData: jest.fn(),
274
+ })
275
+ );
276
+
277
+ render(<ResolverSelector {...props} />);
278
+
279
+ expect(StaticFeedResolver).toHaveBeenCalled();
280
+
281
+ expect(UrlFeedResolver).toHaveBeenCalledWith(
282
+ expect.objectContaining({
283
+ component: componentWithSource,
284
+ children: mockChildren,
285
+ }),
286
+ expect.anything()
287
+ );
288
+ });
289
+
290
+ it("should fallback to NullFeedResolver when StaticFeedResolver returns null and no feedUrl/source is present", () => {
291
+ const props = {
292
+ getStaticComponentFeed: jest.fn(),
293
+ component: mockComponent,
294
+ children: mockChildren,
295
+ riverId: "test-river",
296
+ };
297
+
298
+ (StaticFeedResolver as jest.Mock).mockImplementation(({ children }) =>
299
+ children({
300
+ zappPipesData: { loading: false, data: null, error: null },
301
+ reloadData: jest.fn(),
302
+ })
303
+ );
304
+
305
+ render(<ResolverSelector {...props} />);
306
+
307
+ expect(StaticFeedResolver).toHaveBeenCalled();
308
+ expect(UrlFeedResolver).not.toHaveBeenCalled();
309
+
310
+ expect(NullFeedResolver).toHaveBeenCalledWith(
311
+ expect.objectContaining({
312
+ children: mockChildren,
313
+ }),
314
+ expect.anything()
315
+ );
316
+ });
317
+
318
+ it("should NOT fallback and call children with static data when StaticFeedResolver returns data", () => {
319
+ const staticData = { entry: [{ id: "1" }] };
320
+
321
+ const props = {
322
+ getStaticComponentFeed: jest.fn(),
323
+ feedUrl: "https://example.com/feed",
324
+ component: mockComponent,
325
+ children: mockChildren,
326
+ riverId: "test-river",
327
+ };
328
+
329
+ (StaticFeedResolver as jest.Mock).mockImplementation(({ children }) =>
330
+ children({
331
+ zappPipesData: { loading: false, data: staticData, error: null },
332
+ reloadData: jest.fn(),
333
+ })
334
+ );
335
+
336
+ render(<ResolverSelector {...props} />);
337
+
338
+ expect(StaticFeedResolver).toHaveBeenCalled();
339
+ expect(UrlFeedResolver).not.toHaveBeenCalled();
340
+
341
+ expect(mockChildren).toHaveBeenCalledWith(
342
+ expect.objectContaining({
343
+ zappPipesData: expect.objectContaining({
344
+ data: staticData,
345
+ }),
346
+ })
347
+ );
348
+ });
349
+
350
+ it("should NOT fallback and call children with loading state when StaticFeedResolver is loading", () => {
351
+ const props = {
352
+ getStaticComponentFeed: jest.fn(),
353
+ feedUrl: "https://example.com/feed",
354
+ component: mockComponent,
355
+ children: mockChildren,
356
+ riverId: "test-river",
357
+ };
358
+
359
+ (StaticFeedResolver as jest.Mock).mockImplementation(({ children }) =>
360
+ children({
361
+ zappPipesData: { loading: true, data: null, error: null },
362
+ reloadData: jest.fn(),
363
+ })
364
+ );
365
+
366
+ render(<ResolverSelector {...props} />);
367
+
368
+ expect(StaticFeedResolver).toHaveBeenCalled();
369
+ expect(UrlFeedResolver).not.toHaveBeenCalled();
370
+
371
+ expect(mockChildren).toHaveBeenCalledWith(
372
+ expect.objectContaining({
373
+ zappPipesData: expect.objectContaining({
374
+ loading: true,
375
+ }),
376
+ })
377
+ );
378
+ });
379
+
380
+ it("should NOT fallback and call children with error when StaticFeedResolver returns error", () => {
381
+ const error = new Error("Static error");
382
+
383
+ const props = {
384
+ getStaticComponentFeed: jest.fn(),
385
+ feedUrl: "https://example.com/feed",
386
+ component: mockComponent,
387
+ children: mockChildren,
388
+ riverId: "test-river",
389
+ };
390
+
391
+ (StaticFeedResolver as jest.Mock).mockImplementation(({ children }) =>
392
+ children({
393
+ zappPipesData: { loading: false, data: null, error },
394
+ reloadData: jest.fn(),
395
+ })
396
+ );
397
+
398
+ render(<ResolverSelector {...props} />);
399
+
400
+ expect(StaticFeedResolver).toHaveBeenCalled();
401
+ expect(UrlFeedResolver).not.toHaveBeenCalled();
402
+
403
+ expect(mockChildren).toHaveBeenCalledWith(
404
+ expect.objectContaining({
405
+ zappPipesData: expect.objectContaining({
406
+ error,
407
+ }),
408
+ })
409
+ );
410
+ });
411
+ });
205
412
  });
@@ -3,7 +3,7 @@ import { renderWithProviders } from "@applicaster/zapp-react-native-utils/testUt
3
3
 
4
4
  import * as zappPipesRedux from "@applicaster/zapp-react-native-redux/ZappPipes";
5
5
  import configureStore from "redux-mock-store";
6
- import { thunk } from "redux-thunk";
6
+ import thunk from "redux-thunk";
7
7
 
8
8
  import { zappPipesDataConnector } from "../index";
9
9
 
@@ -2,7 +2,7 @@
2
2
  /// <reference types="@applicaster/zapp-react-native-ui-components" />
3
3
  import React from "react";
4
4
  import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
5
- import { usePlugins } from "@applicaster/zapp-react-native-redux/hooks";
5
+ import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
6
6
  import { ZappPipesSearchContext } from "@applicaster/zapp-react-native-ui-components/Contexts";
7
7
  import { useScreenContext } from "@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenContext";
8
8
  import { ResolverSelector } from "./ResolverSelector";
@@ -23,7 +23,7 @@ export function zappPipesDataConnector(
23
23
  ) {
24
24
  return function WrappedWithZappPipesData(props: Props) {
25
25
  const { screenData } = useRoute();
26
- const plugins = usePlugins();
26
+ const { plugins } = usePickFromState(["plugins"]);
27
27
  const screenContextData = useScreenContext();
28
28
 
29
29
  const {
@@ -76,7 +76,7 @@ export function StaticFeedResolver({
76
76
 
77
77
  const zappPipesDataProps = useMemo(
78
78
  () => ({
79
- zappPipesData: { url, loading, data, error }, // todo: add applyItemLimit
79
+ zappPipesData: { url, loading, data, error },
80
80
  reloadData,
81
81
  loadNextData: undefined, // Static resolver doesn't support pagination
82
82
  }),
@@ -1,4 +1,3 @@
1
- import { sendTapCellEvent, sendTapMenuItem } from "../Analytics";
2
1
  import { getItemType } from "@applicaster/zapp-react-native-utils/navigationUtils";
3
2
  import { SCREEN_TYPES } from "@applicaster/zapp-react-native-utils/navigationUtils/itemTypes";
4
3
 
@@ -12,7 +11,6 @@ export function onCellPress(
12
11
  itemIndex,
13
12
  layoutVersion = "v1"
14
13
  ) {
15
- sendTapCellEvent(entry, component, headerTitle, itemIndex);
16
14
  const componentScreenType = screenTypeFromComponent(component);
17
15
  const entryScreenType = screenTypeFromEntry(entry);
18
16
  const itemType = getItemType(entry, layoutVersion);
@@ -37,7 +35,3 @@ function screenTypeFromComponent(component) {
37
35
  function screenTypeFromEntry(entry) {
38
36
  return entry && entry.screen_type;
39
37
  }
40
-
41
- export function onMenuItemFocus({ item, index, isHome }) {
42
- sendTapMenuItem({ item, index, isHome });
43
- }
@@ -0,0 +1,19 @@
1
+ import * as R from "ramda";
2
+
3
+ export function itemLimitForData(entry = [], component) {
4
+ const itemLimitValue = Number(R.path(["rules", "item_limit"], component));
5
+
6
+ const itemLimit =
7
+ itemLimitValue && itemLimitValue > 0
8
+ ? itemLimitValue
9
+ : Number.MAX_SAFE_INTEGER;
10
+
11
+ const isInRange = (min, max) => R.both(R.gte(R.__, min), R.lt(R.__, max));
12
+
13
+ const entryShouldBeSliced = (entry) =>
14
+ isInRange(0, R.length(entry))(itemLimit);
15
+
16
+ const sliceEntriesUpToItemLimit = R.slice(0, itemLimit);
17
+
18
+ return R.when(entryShouldBeSliced, sliceEntriesUpToItemLimit)(entry);
19
+ }
package/Helpers/index.js CHANGED
@@ -1,42 +1,9 @@
1
- export const ASSETS = {
2
- APP_BACKGROUND_IMAGE: "app_background_image",
3
- };
1
+ import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
4
2
 
5
- export const ANALYTICS_CORE_EVENTS = {
6
- TAP_CELL: "Tap Cell",
7
- PLAY_VOD_ITEM: "Play VOD Item",
8
- VOD_ITEM_PLAY_WAS_TRIGGERED: "VOD Item: Play Was Triggered",
9
- CHANNEL_ITEM_PLAY_WAS_TRIGGERED: "Channel Item: Play Was Triggered",
10
- PROGRAM_ITEM_PLAY_WAS_TRIGGERED: "Program Item: Play Was Triggered",
11
- TAP_MENU_ICON: "Tap Menu Item",
12
- HOME_SCREEN_VIEWED: "Home Screen: Viewed",
13
- ITEM_NOT_AVAILABLE: "N/A",
14
- };
15
-
16
- export const ANALYTICS_ENTRY_EVENTS = {
17
- ITEM_TYPE: "Item Type",
18
- ITEM_TITLE: "Item Name",
19
- ITEM_ID: "Item ID",
20
- ITEM_LINK: "Item Link",
21
- ITEM_INDEX: "Item Number",
22
- ITEM_TIME_PLAYED: "Item Total Time Played",
23
- ITEM_TOTAL_TIME_PLAYED: "Item Total Time Played",
24
- ITEM_PLAY_COMPLETED: "Completed",
25
- ITEM_CUSTOM_PROPERTY: "Custom Property",
26
- };
27
-
28
- export const ANALYTICS_COMPONENT_EVENTS = {
29
- COMPONENT_ID: "Component ID",
30
- COMPONENT_TYPE: "Component Type",
31
- CELL_STYLE: "Cell Style",
32
- HEADER_TITLE: "Header Name",
33
- COMPONENT_SOURCE: "Component Source",
34
- };
35
-
36
- export const ANALYTICS_MENU_ITEM_EVENTS = {
37
- ITEM_TYPE: "Item Type",
38
- ITEM_TITLE: "Item Name",
39
- ITEM_ID: "Item ID",
40
- ITEM_HOME_SCREEN: "Home Screen",
41
- ITEM_INDEX: "Item Number",
3
+ export const ASSETS = {
4
+ APP_BACKGROUND_IMAGE: platformSelect({
5
+ tvos: "app_background_image",
6
+ android_tv: "tv_app_background",
7
+ amazon: "tv_app_background",
8
+ }),
42
9
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "15.0.0-rc.99",
3
+ "version": "15.1.0-alpha.1852552014",
4
4
  "description": "Applicaster Zapp React Native ui components for the Quick Brick App",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -28,10 +28,10 @@
28
28
  },
29
29
  "homepage": "https://github.com/applicaster/quickbrick#readme",
30
30
  "dependencies": {
31
- "@applicaster/applicaster-types": "15.0.0-rc.99",
32
- "@applicaster/zapp-react-native-bridge": "15.0.0-rc.99",
33
- "@applicaster/zapp-react-native-redux": "15.0.0-rc.99",
34
- "@applicaster/zapp-react-native-utils": "15.0.0-rc.99",
31
+ "@applicaster/applicaster-types": "15.1.0-alpha.1852552014",
32
+ "@applicaster/zapp-react-native-bridge": "15.1.0-alpha.1852552014",
33
+ "@applicaster/zapp-react-native-redux": "15.1.0-alpha.1852552014",
34
+ "@applicaster/zapp-react-native-utils": "15.1.0-alpha.1852552014",
35
35
  "fast-json-stable-stringify": "^2.1.0",
36
36
  "promise": "^8.3.0",
37
37
  "url": "^0.11.0",
@@ -1,31 +0,0 @@
1
- import React from "react";
2
- import { getBackgroundImageUrl } from "../utils";
3
- import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
4
- import {
5
- selectRemoteConfigurations,
6
- useAppSelector,
7
- } from "@applicaster/zapp-react-native-redux";
8
-
9
- export const LayoutBackground = ({
10
- Background,
11
- children,
12
- }: {
13
- Background: React.ComponentType<any>;
14
- children: React.ReactNode;
15
- }) => {
16
- const theme = useTheme();
17
-
18
- const remoteConfigurations = useAppSelector(selectRemoteConfigurations);
19
-
20
- const backgroundColor = theme.app_background_color;
21
- const backgroundImageUrl = getBackgroundImageUrl(remoteConfigurations);
22
-
23
- return (
24
- <Background
25
- backgroundColor={backgroundColor}
26
- backgroundImageUrl={backgroundImageUrl}
27
- >
28
- {children}
29
- </Background>
30
- );
31
- };
@@ -1,46 +0,0 @@
1
- import { PixelRatio } from "react-native";
2
- import { withAdjustedLineHeight } from "..";
3
-
4
- const FONT_SCALE = 1.118;
5
- jest.spyOn(PixelRatio, "getFontScale").mockReturnValue(FONT_SCALE);
6
-
7
- describe("withAdjustedLineHeight", () => {
8
- it("with provided fontScale and styles", () => {
9
- // setup
10
- const styles = {
11
- lineHeight: 10,
12
- };
13
-
14
- // run
15
- const result = withAdjustedLineHeight(styles);
16
-
17
- // verify
18
- expect(result).toEqual({
19
- lineHeight: styles.lineHeight * FONT_SCALE,
20
- });
21
- });
22
-
23
- it("with provided fontScale and empty styles", () => {
24
- // setup
25
- const styles = {};
26
-
27
- // run
28
- const result = withAdjustedLineHeight(styles);
29
-
30
- // verify
31
- expect(result).toEqual(styles);
32
- });
33
-
34
- it("with non-number lineHeight", () => {
35
- // setup
36
- const styles = {
37
- lineHeight: NaN,
38
- };
39
-
40
- // run
41
- const result = withAdjustedLineHeight(styles);
42
-
43
- // verify
44
- expect(result).toEqual(styles);
45
- });
46
- });
@@ -1,21 +0,0 @@
1
- import { PixelRatio } from "react-native";
2
- import { isNil, identity } from "ramda";
3
- import { toNumber } from "@applicaster/zapp-react-native-utils/numberUtils";
4
- import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
5
-
6
- // HACK - to prevent text flickering
7
- export const withAdjustedLineHeight = (styles) => {
8
- const fontScale = PixelRatio.getFontScale();
9
- const lineHeight = toNumber(styles.lineHeight);
10
-
11
- if (isNil(lineHeight)) {
12
- return styles;
13
- }
14
-
15
- return { ...styles, lineHeight: lineHeight * fontScale };
16
- };
17
-
18
- export const withScaledLineHeight = platformSelect({
19
- ios: withAdjustedLineHeight,
20
- default: identity,
21
- });
@@ -1,57 +0,0 @@
1
- import * as React from "react";
2
- import * as R from "ramda";
3
- import { Text, TextStyle, View, ViewStyle } from "react-native";
4
-
5
- import { getLocalizations } from "@applicaster/zapp-react-native-utils/localizationUtils";
6
- import { getAppStylesColor } from "@applicaster/zapp-react-native-utils/stylesUtils";
7
- import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
8
- import { styleKeys } from "@applicaster/zapp-react-native-utils/styleKeysUtils";
9
-
10
- type Props = {
11
- styles: {};
12
- error: {};
13
- remoteConfigurations: { localizations: {} };
14
- };
15
-
16
- const defaultAppStyles = {
17
- loading_error_label: {
18
- color: "#aaa",
19
- },
20
- };
21
-
22
- const textStyles = (appStyles = defaultAppStyles): TextStyle => ({
23
- color: getAppStylesColor("loading_error_label", appStyles),
24
- fontSize: 36,
25
- textAlign: "center",
26
- });
27
-
28
- const errorStyles = ({ backgroundColor }): ViewStyle => ({
29
- flex: 1,
30
- width: "100%",
31
- height: "100%",
32
- justifyContent: "center",
33
- alignItems: "center",
34
- position: "absolute",
35
- zIndex: 100,
36
- backgroundColor,
37
- });
38
-
39
- export function ErrorDisplayComponent({
40
- styles,
41
- remoteConfigurations: { localizations },
42
- }: Props) {
43
- const theme = useTheme();
44
- const backgroundColor = theme?.app_background_color;
45
-
46
- const { stream_error_message = "Cannot play stream" } = getLocalizations({
47
- localizations,
48
- });
49
-
50
- const appStyles = R.prop(styleKeys.style_namespace, styles);
51
-
52
- return (
53
- <View style={errorStyles({ backgroundColor })}>
54
- <Text style={textStyles(appStyles)}>{stream_error_message}</Text>
55
- </View>
56
- );
57
- }
@@ -1,9 +0,0 @@
1
- import * as R from "ramda";
2
-
3
- import { connectToStore } from "@applicaster/zapp-react-native-redux/utils/connectToStore";
4
-
5
- import { ErrorDisplayComponent } from "./ErrorDisplay";
6
-
7
- export const ErrorDisplay = R.compose(
8
- connectToStore(R.pick(["remoteConfigurations"]))
9
- )(ErrorDisplayComponent);
@@ -1,101 +0,0 @@
1
- import { Player } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/player";
2
- import NetInfo from "@react-native-community/netinfo";
3
-
4
- import { useEffect, useMemo, useRef, useState } from "react";
5
- import { showAlertDialog } from "@applicaster/zapp-react-native-utils/alertUtils";
6
- import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
7
- import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
8
- import { log_info } from "./logger";
9
-
10
- type RestrictMobilePlaybackProps = {
11
- player?: Player;
12
- entry?: ZappEntry;
13
- pluginConfiguration?: Record<string, string>;
14
- close: () => void;
15
- };
16
-
17
- export const useRestrictMobilePlayback = ({
18
- player,
19
- entry,
20
- pluginConfiguration,
21
- close,
22
- }: RestrictMobilePlaybackProps): { isRestricted: boolean } => {
23
- const dialogVisibleRef = useRef<boolean>(false);
24
- const theme = useTheme();
25
-
26
- useEffect(() => {
27
- return () => {
28
- if (isTV()) {
29
- return;
30
- }
31
-
32
- dialogVisibleRef.current = false;
33
- };
34
- }, []);
35
-
36
- const isConnectionRestricted = useMemo(() => {
37
- if (isTV()) {
38
- return false;
39
- }
40
-
41
- return player && entry?.extensions?.connection_restricted;
42
- }, [player, entry]);
43
-
44
- const [isRestricted, setIsRestricted] = useState<boolean>(
45
- isConnectionRestricted
46
- );
47
-
48
- useEffect(() => {
49
- if (!isConnectionRestricted) {
50
- return;
51
- }
52
-
53
- const stopPlayer = () => {
54
- log_info(
55
- "Stopping player due to mobile restriction, connection_restricted: true"
56
- );
57
-
58
- player?.close();
59
-
60
- dialogVisibleRef.current = true;
61
-
62
- showAlertDialog({
63
- title:
64
- pluginConfiguration?.mobile_connection_restricted_alert_title ||
65
- "Restricted Connection Type",
66
- message:
67
- pluginConfiguration?.mobile_connection_restricted_alert_message ||
68
- "This content can only be viewed over a Wi-Fi or LAN network.",
69
- okButtonText: theme.ok_button || "OK",
70
- completion: () => {
71
- dialogVisibleRef.current = false;
72
-
73
- close();
74
- },
75
- });
76
- };
77
-
78
- return NetInfo.addEventListener((state) => {
79
- if (state.type === "cellular") {
80
- setIsRestricted(true);
81
-
82
- if (dialogVisibleRef.current) {
83
- return;
84
- }
85
-
86
- stopPlayer();
87
- } else {
88
- setIsRestricted(false);
89
- }
90
- });
91
- }, [
92
- close,
93
- entry?.extensions?.connection_restricted,
94
- pluginConfiguration,
95
- player,
96
- theme.ok_button,
97
- isConnectionRestricted,
98
- ]);
99
-
100
- return { isRestricted };
101
- };