@applicaster/zapp-react-native-ui-components 14.0.0-alpha.1661204539 → 14.0.0-alpha.1887720441

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 (122) hide show
  1. package/Components/AnimatedInOut/index.tsx +5 -3
  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/tv/Artwork.tsx +41 -0
  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} +9 -2
  11. package/Components/AudioPlayer/{Summary.tsx → tv/Summary.tsx} +17 -10
  12. package/Components/AudioPlayer/tv/Title.tsx +46 -0
  13. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/Runtime.test.js.snap +4 -4
  14. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/artWork.test.js.snap +9 -4
  15. package/Components/AudioPlayer/tv/__tests__/__snapshots__/audioPlayer.test.js.snap +164 -0
  16. package/Components/AudioPlayer/tv/__tests__/__snapshots__/channel.test.js.snap +19 -0
  17. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/summary.test.js.snap +2 -3
  18. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/title.test.js.snap +2 -3
  19. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/audioPlayer.test.js +7 -3
  20. package/Components/AudioPlayer/{helpers.tsx → tv/helpers.tsx} +13 -7
  21. package/Components/AudioPlayer/{AudioPlayer.tsx → tv/index.tsx} +18 -57
  22. package/Components/AudioPlayer/types.ts +40 -0
  23. package/Components/Cell/index.js +7 -3
  24. package/Components/ComponentResolver/index.ts +1 -1
  25. package/Components/FeedLoader/index.js +1 -1
  26. package/Components/Focusable/Focusable.tsx +5 -3
  27. package/Components/Focusable/FocusableTvOS.tsx +3 -3
  28. package/Components/Focusable/FocusableiOS.tsx +2 -2
  29. package/Components/Focusable/__tests__/index.android.test.tsx +3 -0
  30. package/Components/Focusable/index.android.tsx +12 -8
  31. package/Components/Focusable/index.tsx +1 -1
  32. package/Components/FocusableList/index.tsx +4 -0
  33. package/Components/GeneralContentScreen/GeneralContentScreen.tsx +0 -2
  34. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +42 -59
  35. package/Components/GeneralContentScreen/utils/useCurationAPI.ts +12 -8
  36. package/Components/HandlePlayable/HandlePlayable.tsx +25 -9
  37. package/Components/Layout/TV/LayoutBackground.tsx +1 -1
  38. package/Components/MasterCell/DefaultComponents/Button.tsx +1 -1
  39. package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -27
  40. package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +1 -1
  41. package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +1 -1
  42. package/Components/MasterCell/DefaultComponents/Text/index.tsx +1 -0
  43. package/Components/MasterCell/elementMapper.tsx +1 -2
  44. package/Components/MasterCell/index.tsx +1 -1
  45. package/Components/MasterCell/utils/behaviorProvider.ts +12 -67
  46. package/Components/MasterCell/utils/index.ts +3 -13
  47. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +13 -18
  48. package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +9 -0
  49. package/Components/OfflineHandler/__tests__/index.test.tsx +20 -22
  50. package/Components/PlayerContainer/ErrorDisplay/index.ts +1 -1
  51. package/Components/PlayerContainer/PlayerContainer.tsx +62 -66
  52. package/Components/PlayerContainer/ProgramInfo/index.tsx +1 -1
  53. package/Components/PlayerContainer/index.ts +1 -1
  54. package/Components/PlayerImageBackground/index.tsx +1 -1
  55. package/Components/River/ComponentsMap/ComponentsMap.tsx +1 -6
  56. package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +379 -0
  57. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +2 -2
  58. package/Components/River/RefreshControl.tsx +6 -4
  59. package/Components/River/RiverItem.tsx +8 -8
  60. package/Components/River/TV/River.tsx +2 -20
  61. package/Components/River/TV/index.tsx +3 -1
  62. package/Components/River/TV/withPipesV1DataLoader.tsx +43 -0
  63. package/Components/River/TV/withRiverDataLoader.tsx +17 -0
  64. package/Components/River/TV/withTVEventHandler.tsx +1 -1
  65. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +2 -6
  66. package/Components/River/index.tsx +1 -1
  67. package/Components/Screen/__tests__/Screen.test.tsx +23 -12
  68. package/Components/ScreenRevealManager/ScreenRevealManager.ts +76 -0
  69. package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +107 -0
  70. package/Components/ScreenRevealManager/__tests__/withScreenRevealManager.test.tsx +96 -0
  71. package/Components/ScreenRevealManager/index.ts +1 -0
  72. package/Components/ScreenRevealManager/withScreenRevealManager.tsx +79 -0
  73. package/Components/Tabs/TV/Tabs.android.tsx +0 -2
  74. package/Components/TopMarginApplicator/TopMarginApplicator.tsx +16 -15
  75. package/Components/Touchable/__tests__/__snapshots__/touchable.test.tsx.snap +34 -0
  76. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +15 -9
  77. package/Components/VideoLive/animationUtils.ts +3 -3
  78. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +32 -8
  79. package/Components/VideoModal/PlayerDetails.tsx +24 -2
  80. package/Components/VideoModal/PlayerWrapper.tsx +26 -142
  81. package/Components/VideoModal/VideoModal.tsx +3 -17
  82. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -7
  83. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +44 -180
  84. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +17 -55
  85. package/Components/VideoModal/hooks/index.ts +0 -2
  86. package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +15 -26
  87. package/Components/VideoModal/hooks/useModalSize.ts +18 -2
  88. package/Components/VideoModal/utils.ts +6 -0
  89. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -16
  90. package/Components/Viewport/ViewportTracker/__tests__/viewportTracker.test.js +84 -24
  91. package/Components/Viewport/VisibilitySensor/VisibilitySensor.tsx +3 -3
  92. package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/index.ts +3 -3
  93. package/Decorators/ConfigurationWrapper/withConfigurationProvider.tsx +2 -2
  94. package/Decorators/RiverFeedLoader/index.tsx +2 -8
  95. package/Decorators/RiverFeedLoader/utils/index.ts +2 -7
  96. package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +3 -6
  97. package/Decorators/ZappPipesDataConnector/ResolverSelector.tsx +25 -0
  98. package/Decorators/ZappPipesDataConnector/__tests__/NullFeedResolver.test.tsx +78 -0
  99. package/Decorators/ZappPipesDataConnector/__tests__/ResolverSelector.test.tsx +205 -0
  100. package/Decorators/ZappPipesDataConnector/__tests__/StaticFeedResolver.test.tsx +251 -0
  101. package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +368 -0
  102. package/Decorators/ZappPipesDataConnector/__tests__/utils.test.ts +39 -0
  103. package/Decorators/ZappPipesDataConnector/index.tsx +27 -308
  104. package/Decorators/ZappPipesDataConnector/resolvers/NullFeedResolver.tsx +25 -0
  105. package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +87 -0
  106. package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +241 -0
  107. package/Decorators/ZappPipesDataConnector/types.ts +29 -0
  108. package/index.d.ts +0 -1
  109. package/package.json +5 -10
  110. package/Components/AudioPlayer/Artwork.tsx +0 -35
  111. package/Components/AudioPlayer/AudioPlayerLayout.tsx +0 -202
  112. package/Components/AudioPlayer/Title.tsx +0 -39
  113. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +0 -66
  114. package/Components/AudioPlayer/__tests__/__snapshots__/channel.test.js.snap +0 -28
  115. package/Components/AudioPlayer/__tests__/audioPlayerLayout.test.js +0 -26
  116. package/Components/AudioPlayer/index.ts +0 -1
  117. package/Components/VideoModal/hooks/useBackgroundColor.ts +0 -10
  118. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/Runtime.test.js +0 -0
  119. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/artWork.test.js +0 -0
  120. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/channel.test.js +0 -0
  121. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/summary.test.js +0 -0
  122. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/title.test.js +0 -0
@@ -30,7 +30,6 @@ export const GeneralContentScreen = ({
30
30
  isScreenWrappedInContainer,
31
31
  componentsMapExtraProps = {},
32
32
  focused,
33
- extraOffset,
34
33
  parentFocus,
35
34
  containerHeight,
36
35
  preferredFocus = false,
@@ -122,7 +121,6 @@ export const GeneralContentScreen = ({
122
121
  isScreenWrappedInContainer={isScreenWrappedInContainer}
123
122
  parentFocus={parentFocus}
124
123
  focused={focused}
125
- extraOffset={extraOffset}
126
124
  containerHeight={containerHeight}
127
125
  preferredFocus={preferredFocus}
128
126
  {...componentsMapExtraProps}
@@ -8,13 +8,10 @@ import {
8
8
  useCurationAPI,
9
9
  } from "../useCurationAPI";
10
10
  import * as redux from "react-redux";
11
- import * as layoutPresets from "@applicaster/zapp-react-native-redux/hooks/useLayoutPresets";
12
- import * as pipesFeeds from "@applicaster/zapp-react-native-redux/hooks/useZappPipesFeeds";
13
11
  import { NavigationContext } from "@applicaster/zapp-react-native-ui-components/Contexts/NavigationContext";
14
12
  import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext";
15
13
 
16
- import { Provider } from "react-redux";
17
- import configureStore from "redux-mock-store";
14
+ import { WrappedWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
18
15
 
19
16
  jest.mock(
20
17
  "@applicaster/zapp-react-native-utils/reactHooks/navigation/useRoute",
@@ -42,19 +39,20 @@ const mainStackNavigator = {
42
39
  },
43
40
  };
44
41
 
45
- const store = configureStore()({});
46
-
47
- const wrapper = ({ children }) => (
48
- <Provider store={store}>
49
- <NavigationContext.Provider
50
- value={{ ...mainStackNavigator, currentRoute: homeStack.route }}
51
- >
52
- <PathnameContext.Provider value={homeStack.route}>
53
- {children}
54
- </PathnameContext.Provider>
55
- </NavigationContext.Provider>
56
- </Provider>
57
- );
42
+ const getWrapper =
43
+ (store) =>
44
+ // eslint-disable-next-line react/display-name, react/prop-types
45
+ ({ children }) => (
46
+ <WrappedWithProviders store={store}>
47
+ <NavigationContext.Provider
48
+ value={{ ...mainStackNavigator, currentRoute: homeStack.route }}
49
+ >
50
+ <PathnameContext.Provider value={homeStack.route}>
51
+ {children}
52
+ </PathnameContext.Provider>
53
+ </NavigationContext.Provider>
54
+ </WrappedWithProviders>
55
+ );
58
56
 
59
57
  describe("getTransformedPreset should return the passed components if smartComponents is empty", () => {
60
58
  describe("getTransformedPreset function", () => {
@@ -312,19 +310,10 @@ describe("getTransformedPreset should return the passed components if smartCompo
312
310
  { id: "02", component_type: "not_smart_another" },
313
311
  ];
314
312
 
315
- // mock the hooks
316
- const mockUseZappPipesFeeds = jest.spyOn(pipesFeeds, "useZappPipesFeeds");
317
- mockUseZappPipesFeeds.mockReturnValue({});
318
-
319
- const mockUseLayoutPresets = jest.spyOn(
320
- layoutPresets,
321
- "useLayoutPresets"
322
- );
323
-
324
- mockUseLayoutPresets.mockReturnValue({});
325
-
326
313
  const { result } = renderHook(() => useCurationAPI(mockComponents), {
327
- wrapper,
314
+ wrapper: getWrapper({
315
+ zappPipes: {},
316
+ }),
328
317
  });
329
318
 
330
319
  // if there are no smart components, it should return the original array
@@ -366,18 +355,15 @@ describe("getTransformedPreset should return the passed components if smartCompo
366
355
  "http://curation": { loading: false, data: { entry: mockPresetEntry } },
367
356
  };
368
357
 
369
- const mockUseZappPipesFeeds = jest.spyOn(pipesFeeds, "useZappPipesFeeds");
370
- mockUseZappPipesFeeds.mockReturnValue(mockFeeds);
371
-
372
- const mockUseLayoutPresets = jest.spyOn(
373
- layoutPresets,
374
- "useLayoutPresets"
375
- );
376
-
377
- mockUseLayoutPresets.mockReturnValue(mockLayoutPresets);
378
-
379
358
  const { result } = renderHook(() => useCurationAPI(mockComponents), {
380
- wrapper,
359
+ wrapper: getWrapper({
360
+ zappPipes: mockFeeds,
361
+ presetsMapping: {
362
+ presets_mappings: {
363
+ ...mockLayoutPresets,
364
+ },
365
+ },
366
+ }),
381
367
  });
382
368
 
383
369
  expect(result.current).toEqual(mockTransformedComponents);
@@ -437,19 +423,15 @@ describe("getTransformedPreset should return the passed components if smartCompo
437
423
  },
438
424
  };
439
425
 
440
- // mock the hooks
441
- const mockUseZappPipesFeeds = jest.spyOn(pipesFeeds, "useZappPipesFeeds");
442
- mockUseZappPipesFeeds.mockReturnValue(mockFeeds);
443
-
444
- const mockUseLayoutPresets = jest.spyOn(
445
- layoutPresets,
446
- "useLayoutPresets"
447
- );
448
-
449
- mockUseLayoutPresets.mockReturnValue(mockLayoutPresets);
450
-
451
426
  const { result } = renderHook(() => useCurationAPI(mockComponents), {
452
- wrapper,
427
+ wrapper: getWrapper({
428
+ zappPipes: mockFeeds,
429
+ presetsMapping: {
430
+ presets_mappings: {
431
+ ...mockLayoutPresets,
432
+ },
433
+ },
434
+ }),
453
435
  });
454
436
 
455
437
  expect(result.current).toEqual(mockTransformedComponents);
@@ -495,14 +477,15 @@ describe("getTransformedPreset should return the passed components if smartCompo
495
477
  "http://curation": { loading: false, data: { entry: mockPresetEntry } },
496
478
  };
497
479
 
498
- // mock the hooks
499
- const mockUseZappPipesFeeds = jest.spyOn(pipesFeeds, "useZappPipesFeeds");
500
- mockUseZappPipesFeeds.mockReturnValue(mockFeeds);
501
- const mockUseLayoutPresets = jest.spyOn(layoutPresets, "useLayoutPresets");
502
- mockUseLayoutPresets.mockReturnValue(mockLayoutPresets);
503
-
504
480
  const { result } = renderHook(() => useCurationAPI(mockComponents), {
505
- wrapper,
481
+ wrapper: getWrapper({
482
+ zappPipes: mockFeeds,
483
+ presetsMapping: {
484
+ presets_mappings: {
485
+ ...mockLayoutPresets,
486
+ },
487
+ },
488
+ }),
506
489
  });
507
490
 
508
491
  expect(result.current).toEqual(mockTransformedComponents);
@@ -1,17 +1,18 @@
1
1
  import { all, equals, path, prop, isEmpty, pluck, values } from "ramda";
2
2
 
3
3
  import { useEffect, useMemo } from "react";
4
- import { useDispatch } from "react-redux";
5
4
 
6
5
  import {
6
+ ZappPipes,
7
+ useAppDispatch,
7
8
  useLayoutPresets,
8
- useZappPipesFeeds,
9
- } from "@applicaster/zapp-react-native-redux/hooks";
10
- import { loadPipesData } from "@applicaster/zapp-react-native-redux/ZappPipes";
9
+ useZappPipesFeed,
10
+ } from "@applicaster/zapp-react-native-redux";
11
11
  import { isEmptyOrNil } from "@applicaster/zapp-react-native-utils/cellUtils";
12
12
  import { Categories } from "./logger";
13
13
  import { createLogger } from "@applicaster/zapp-react-native-utils/logger";
14
14
  import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useRoute";
15
+
15
16
  import {
16
17
  ZappPipesEntryContext,
17
18
  ZappPipesScreenContext,
@@ -26,7 +27,10 @@ import {
26
27
  import { produce } from "immer";
27
28
  // types reference
28
29
 
29
- declare type CurationEntry = { preset_name: string; feed_url: string };
30
+ declare interface CurationEntry {
31
+ preset_name: string;
32
+ feed_url: string;
33
+ }
30
34
 
31
35
  type Feeds = Record<string, ZappPipesData>;
32
36
 
@@ -122,7 +126,7 @@ export const getFinalComponents = (
122
126
  export const useCurationAPI = (
123
127
  components: Array<ZappUIComponent>
124
128
  ): ZappUIComponent[] => {
125
- const dispatch = useDispatch();
129
+ const dispatch = useAppDispatch();
126
130
 
127
131
  const smartComponents = useMemo(
128
132
  () => components?.filter?.(isSmartComponent) ?? [],
@@ -162,7 +166,7 @@ export const useCurationAPI = (
162
166
  useEffect(() => {
163
167
  urls.forEach((url, index) => {
164
168
  if (url) {
165
- dispatch(loadPipesData(url, { clearCache: false }));
169
+ dispatch(ZappPipes.loadPipesData(url, { clearCache: false }));
166
170
  } else {
167
171
  logger.log_error("Curation url is empty", {
168
172
  componentId: smartComponents?.[index]?.id,
@@ -171,7 +175,7 @@ export const useCurationAPI = (
171
175
  });
172
176
  }, [urls]);
173
177
 
174
- const feeds = useZappPipesFeeds(urls);
178
+ const feeds = useZappPipesFeed(urls);
175
179
  const layoutPresets = useLayoutPresets();
176
180
 
177
181
  const enrichedComponents = useMemo(() => {
@@ -7,12 +7,15 @@ import {
7
7
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
8
8
  import {
9
9
  useDimensions,
10
+ useIsTablet as isTablet,
10
11
  useNavigation,
11
12
  } from "@applicaster/zapp-react-native-utils/reactHooks";
12
13
 
13
14
  import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
14
15
  import { PlayerContainer } from "../PlayerContainer";
15
16
  import { useModalSize } from "../VideoModal/hooks";
17
+ import { ViewStyle } from "react-native";
18
+ import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
16
19
 
17
20
  type Props = {
18
21
  item: ZappEntry;
@@ -83,6 +86,13 @@ type PlayableComponent = {
83
86
  Component: React.ComponentType<any>;
84
87
  };
85
88
 
89
+ const dimensionsContext: "window" | "screen" = platformSelect({
90
+ android_tv: "window",
91
+ amazon: "window",
92
+ // eslint-disable-next-line react-hooks/rules-of-hooks
93
+ default: isTablet() ? "window" : "screen", // on tablet, window represents correct values, on phone it's not as the screen could be rotated
94
+ });
95
+
86
96
  export function HandlePlayable({
87
97
  item,
88
98
  isModal,
@@ -135,19 +145,25 @@ export function HandlePlayable({
135
145
  });
136
146
  }, [casting]);
137
147
 
138
- const { width: screenWidth, height: screenHeight } = useDimensions("window");
148
+ const { width: screenWidth, height: screenHeight } =
149
+ useDimensions(dimensionsContext);
139
150
 
140
151
  const modalSize = useModalSize();
141
152
 
142
153
  const style = React.useMemo(
143
- () => ({
144
- width: isModal ? modalSize.width : mode === "PIP" ? "100%" : screenWidth,
145
- height: isModal
146
- ? modalSize.height
147
- : mode === "PIP"
148
- ? "100%"
149
- : screenHeight,
150
- }),
154
+ () =>
155
+ ({
156
+ width: isModal
157
+ ? modalSize.width
158
+ : mode === "PIP"
159
+ ? "100%"
160
+ : screenWidth,
161
+ height: isModal
162
+ ? modalSize.height
163
+ : mode === "PIP"
164
+ ? "100%"
165
+ : screenHeight,
166
+ }) as ViewStyle,
151
167
  [screenWidth, screenHeight, modalSize, isModal, mode]
152
168
  );
153
169
 
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks/usePickFromState";
2
+ import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
3
3
  import { getBackgroundImageUrl } from "../utils";
4
4
  import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
5
5
 
@@ -4,7 +4,7 @@ import * as R from "ramda";
4
4
  import { TouchableOpacity } from "react-native";
5
5
  // import { SvgUri } from "react-native-svg";
6
6
 
7
- import { connectToStore } from "@applicaster/zapp-react-native-redux";
7
+ import { connectToStore } from "@applicaster/zapp-react-native-redux/utils/connectToStore";
8
8
  import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
9
9
 
10
10
  import Image from "./Image";
@@ -2,7 +2,6 @@ import React, { useMemo } from "react";
2
2
  import { ImageStyle } from "react-native";
3
3
  import { Focusable } from "@applicaster/zapp-react-native-ui-components/Components/Focusable";
4
4
  import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
5
- import * as R from "ramda";
6
5
  import { getXray } from "@applicaster/zapp-react-native-utils/logger";
7
6
  import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
8
7
  import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
@@ -67,32 +66,10 @@ export function FocusableView({ style, children, item, ...otherProps }: Props) {
67
66
  const handleFocus = (focusable) => {
68
67
  const focusedButtonId = getFocusedButtonId(focusable);
69
68
 
70
- wrapperRef?.current?.measure((x, y, width, height, pageX, pageY) => {
71
- const top = pageY;
72
- const bottom = top + height;
73
- const left = pageX;
74
- const right = left + width;
75
-
76
- const boundingRect = {
77
- x,
78
- y,
79
- pageX,
80
- pageY,
81
- width,
82
- height,
83
- top,
84
- bottom,
85
- left,
86
- right,
87
- };
88
-
89
- otherProps?.onToggleFocus?.({
90
- focusable: {
91
- getRect: R.always(boundingRect),
92
- },
93
- focusedButtonId,
94
- mouse: focusable.mouse,
95
- });
69
+ otherProps?.onToggleFocus?.({
70
+ focusable: wrapperRef.current,
71
+ focusedButtonId,
72
+ mouse: focusable.mouse,
96
73
  });
97
74
 
98
75
  if (ttsLabel) {
@@ -20,7 +20,7 @@ const withAppliedDimensions = (style: Style) => (source: Source) => ({
20
20
  });
21
21
 
22
22
  export const withDimensionsHOC = (Component) => {
23
- return function WithDimensions(props: { style: any }) {
23
+ return function WithDimensions(props: Record<string, unknown>) {
24
24
  const theme = useTheme<BaseThemePropertiesMobile>();
25
25
 
26
26
  const useDownScalingImages = toBooleanWithDefaultFalse(
@@ -13,7 +13,7 @@ export const ImageContainer = (props: Props) => {
13
13
  const isActive = useIsScreenActive();
14
14
 
15
15
  const Component =
16
- isVideoPreviewEnabled(props) && isActive ? LiveImage : PureImage;
16
+ isVideoPreviewEnabled(props as Props) && isActive ? LiveImage : PureImage;
17
17
 
18
18
  return <Component {...props} />;
19
19
  };
@@ -52,6 +52,7 @@ const _Text = ({
52
52
  withScaledLineHeight(withFocusedStyles({ style, otherProps })),
53
53
  { height },
54
54
  ]}
55
+ allowFontScaling={false}
55
56
  {...withoutLabel(otherProps)}
56
57
  >
57
58
  {dateTransformEnabled
@@ -73,7 +73,6 @@ export function elementMapper(
73
73
  : {};
74
74
 
75
75
  const componentProps = {
76
- key,
77
76
  style,
78
77
  skipButtons: otherProps?.skipButtons,
79
78
  emitAsyncElementRegistrate: otherProps?.emitAsyncElementRegistrate,
@@ -91,7 +90,7 @@ export function elementMapper(
91
90
  const fn = mapElementWithKey(elementMapper(components, otherProps));
92
91
 
93
92
  return (
94
- <Component {...componentProps}>
93
+ <Component key={key} {...componentProps}>
95
94
  {focusableTypes.has(type) && elements.length > 0
96
95
  ? elements.map(fn)
97
96
  : null}
@@ -86,7 +86,7 @@ export function masterCellBuilder({
86
86
  entry: item,
87
87
  state: getEntryState(state, entryIsSelected),
88
88
  }),
89
- [state, item?.id, entryIsSelected] // Assuming that item won't mutate
89
+ [state, item, entryIsSelected] // Assuming that item won't mutate
90
90
  );
91
91
 
92
92
  const wrapperRef = React.useRef(null);
@@ -1,54 +1,28 @@
1
1
  import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
2
- import { StorageSingleValueProvider } from "@applicaster/zapp-react-native-utils/storage/StorageSingleSelectProvider";
2
+ import { StorageSingleValueProvider } from "@applicaster/zapp-react-native-bridge/ZappStorage/StorageSingleSelectProvider";
3
3
  import { PushTopicManager } from "@applicaster/zapp-react-native-bridge/PushNotifications/PushTopicManager";
4
- import { StorageMultiSelectProvider } from "@applicaster/zapp-react-native-utils/storage/StorageMultiSelectProvider";
4
+ import { StorageMultiSelectProvider } from "@applicaster/zapp-react-native-bridge/ZappStorage/StorageMultiSelectProvider";
5
5
  import React, { useEffect } from "react";
6
6
  import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer";
7
7
  import { BehaviorSubject } from "rxjs";
8
8
  import { masterCellLogger } from "../logger";
9
9
  import get from "lodash/get";
10
- import { ScreenMultiSelectProvider } from "@applicaster/zapp-react-native-utils/storage/ScreenStateMultiSelectProvider";
11
- import { ScreenSingleValueProvider } from "@applicaster/zapp-react-native-utils/storage/ScreenSingleValueProvider";
12
- import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks";
13
10
 
14
- const parseContextKey = (
15
- key: string,
16
- context: string = "ctx"
17
- ): string | null => {
18
- if (!key?.startsWith(`@{${context}/`)) return null;
11
+ const parseContextKey = (key: string): string | null => {
12
+ if (!key?.startsWith("@{ctx/")) return null;
19
13
 
20
- return key.substring(`@{${context}/`.length, key.length - 1);
14
+ return key.substring("@{ctx/".length, key.length - 1);
21
15
  };
22
16
 
23
17
  const getDataSourceProvider = (
24
- behavior: Behavior,
25
- screenRoute: string
18
+ behavior: Behavior
26
19
  ): BehaviorSubject<string[] | string> | null => {
27
20
  if (!behavior) return null;
28
21
 
29
22
  const selection = String(behavior.current_selection);
30
- const screenKey = parseContextKey(selection, "screen");
31
-
32
- if (screenKey) {
33
- if (behavior.select_mode === "multi") {
34
- return ScreenMultiSelectProvider.getProvider(
35
- screenKey,
36
- screenRoute
37
- ).getObservable();
38
- }
39
-
40
- if (behavior.select_mode === "single") {
41
- return ScreenSingleValueProvider.getProvider(
42
- screenKey,
43
- screenRoute
44
- ).getObservable();
45
- }
46
- }
47
-
48
23
  const contextKey = parseContextKey(selection);
49
24
 
50
25
  if (contextKey) {
51
- // TODO: Add storage scope to behavior
52
26
  if (behavior.select_mode === "multi") {
53
27
  return StorageMultiSelectProvider.getProvider(contextKey).getObservable();
54
28
  }
@@ -67,7 +41,6 @@ const getDataSourceProvider = (
67
41
 
68
42
  export const useBehaviorUpdate = (behavior: Behavior) => {
69
43
  const [lastUpdate, setLastUpdate] = React.useState<number | null>(null);
70
- const screenRoute = useRoute()?.pathname || "";
71
44
  const player = usePlayer();
72
45
 
73
46
  const triggerUpdate = () => setLastUpdate(Date.now());
@@ -75,7 +48,7 @@ export const useBehaviorUpdate = (behavior: Behavior) => {
75
48
  useEffect(() => {
76
49
  if (!behavior) return;
77
50
 
78
- const dataSource = getDataSourceProvider(behavior, screenRoute);
51
+ const dataSource = getDataSourceProvider(behavior);
79
52
 
80
53
  if (dataSource) {
81
54
  const subscription = dataSource.subscribe(triggerUpdate);
@@ -99,15 +72,10 @@ export const useBehaviorUpdate = (behavior: Behavior) => {
99
72
 
100
73
  // We cant use async in this function (its inside render),
101
74
  // so we rely on useBehaviorUpdate to update current value and trigger re-render
102
- export const isCellSelected = ({
103
- item,
104
- screenRoute,
105
- behavior,
106
- }: {
107
- item: ZappEntry;
108
- screenRoute: string;
109
- behavior?: Behavior;
110
- }): boolean => {
75
+ export const isCellSelected = (
76
+ item: ZappEntry,
77
+ behavior?: Behavior
78
+ ): boolean => {
111
79
  if (!behavior) return false;
112
80
 
113
81
  const id = behavior.selector ? get(item, behavior.selector) : item.id;
@@ -131,30 +99,7 @@ export const isCellSelected = ({
131
99
  }
132
100
 
133
101
  const selection = String(behavior.current_selection);
134
-
135
- const screenKey = parseContextKey(selection, "screen");
136
-
137
- if (screenKey) {
138
- if (behavior.select_mode === "single") {
139
- const selectedItem = ScreenSingleValueProvider.getProvider(
140
- screenKey,
141
- screenRoute
142
- ).getValue();
143
-
144
- return selectedItem === String(id);
145
- }
146
-
147
- if (behavior.select_mode === "multi") {
148
- const selectedItems = ScreenMultiSelectProvider.getProvider(
149
- screenKey,
150
- screenRoute
151
- ).getSelectedItems();
152
-
153
- return selectedItems?.includes(String(id));
154
- }
155
- }
156
-
157
- const contextKey = parseContextKey(selection, "ctx");
102
+ const contextKey = parseContextKey(selection);
158
103
 
159
104
  if (contextKey) {
160
105
  if (behavior.select_mode === "single") {
@@ -8,7 +8,6 @@ import { masterCellLogger } from "../logger";
8
8
  import { getCellState } from "../../Cell/utils";
9
9
  import { getColorFromData } from "@applicaster/zapp-react-native-utils/cellUtils";
10
10
  import { isCellSelected, useBehaviorUpdate } from "./behaviorProvider";
11
- import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks";
12
11
 
13
12
  const hasElementSpecificViewType = (viewType) => (element) => {
14
13
  if (R.isNil(element)) {
@@ -191,16 +190,8 @@ export const getFocusedButtonId = (focusable) => {
191
190
  });
192
191
  };
193
192
 
194
- export const isSelected = ({
195
- item,
196
- screenRoute,
197
- behavior,
198
- }: {
199
- item: ZappEntry;
200
- screenRoute: string;
201
- behavior?: Behavior;
202
- }) => {
203
- return isCellSelected({ item, screenRoute, behavior });
193
+ export const isSelected = (item: ZappEntry, behavior?: Behavior) => {
194
+ return isCellSelected(item, behavior);
204
195
  };
205
196
 
206
197
  export const useCellState = ({
@@ -213,10 +204,9 @@ export const useCellState = ({
213
204
  focused: boolean;
214
205
  }): CellState => {
215
206
  const lastUpdate = useBehaviorUpdate(behavior);
216
- const router = useRoute();
217
207
 
218
208
  const _isSelected = useMemo(
219
- () => isSelected({ item, screenRoute: router?.pathname, behavior }),
209
+ () => isSelected(item, behavior),
220
210
  [behavior, item, lastUpdate]
221
211
  );
222
212
 
@@ -1,9 +1,12 @@
1
1
  import React from "react";
2
2
  import { Text, Animated } from "react-native";
3
+ import { render } from "@testing-library/react-native";
3
4
 
4
- import renderer from "react-test-renderer";
5
-
6
- jest.useFakeTimers();
5
+ import {
6
+ NotificationView,
7
+ onlinePhrase,
8
+ offlinePhrase,
9
+ } from "../NotificationView";
7
10
 
8
11
  jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
9
12
  usePickFromState: () => ({
@@ -32,39 +35,31 @@ jest.mock("react-native-safe-area-context", () => ({
32
35
 
33
36
  const dismiss = jest.fn();
34
37
 
35
- const {
36
- NotificationView,
37
- onlinePhrase,
38
- offlinePhrase,
39
- } = require("../NotificationView");
40
-
41
38
  describe("NotificationView", () => {
42
39
  it("Show online message when Online", () => {
43
- const component = renderer.create(
44
- <NotificationView online dismiss={dismiss} />
45
- );
40
+ const component = render(<NotificationView online dismiss={dismiss} />);
46
41
 
47
- expect(component.root.findByType(Text).props.children).toBe(onlinePhrase);
42
+ expect(component.UNSAFE_getByType(Text).props.children).toBe(onlinePhrase);
48
43
  });
49
44
 
50
45
  it("Show offline message when Online", () => {
51
- const component = renderer.create(
46
+ const component = render(
52
47
  <NotificationView online={false} dismiss={dismiss} />
53
48
  );
54
49
 
55
- expect(component.root.findByType(Text).props.children).toBe(offlinePhrase);
50
+ expect(component.UNSAFE_getByType(Text).props.children).toBe(offlinePhrase);
56
51
  });
57
52
 
58
53
  it("When hidden is false to true notification is visible", () => {
59
- const component = renderer.create(
54
+ const component = render(
60
55
  <NotificationView online={false} hidden={false} dismiss={dismiss} />
61
56
  );
62
57
 
63
- component.update(
58
+ component.rerender(
64
59
  <NotificationView online={false} hidden={true} dismiss={dismiss} />
65
60
  );
66
61
 
67
- const animatedView = component.root.findByType(Animated.View);
62
+ const animatedView = component.UNSAFE_getByType(Animated.View);
68
63
  const animatedViewStyles = animatedView.props.style;
69
64
 
70
65
  expect(animatedViewStyles.opacity).toBe(1);
@@ -21,6 +21,15 @@ exports[`OfflineHandler renders 1`] = `
21
21
  }
22
22
  >
23
23
  <View
24
+ accessibilityState={
25
+ {
26
+ "busy": undefined,
27
+ "checked": undefined,
28
+ "disabled": undefined,
29
+ "expanded": undefined,
30
+ "selected": undefined,
31
+ }
32
+ }
24
33
  accessible={true}
25
34
  collapsable={false}
26
35
  focusable={true}