@applicaster/zapp-react-native-ui-components 14.0.0-alpha.5974411329 → 14.0.0-alpha.6000342231
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.
- package/Components/AnimatedInOut/index.tsx +69 -26
- package/Components/BaseFocusable/index.tsx +23 -12
- package/Components/Cell/Cell.tsx +91 -64
- package/Components/Cell/CellWithFocusable.tsx +3 -0
- package/Components/Cell/FocusableWrapper.tsx +44 -0
- package/Components/Cell/TvOSCellComponent.tsx +80 -14
- package/Components/Cell/__tests__/CellWIthFocusable.test.js +3 -2
- package/Components/FeedLoader/FeedLoader.tsx +7 -16
- package/Components/FeedLoader/FeedLoaderHOC.tsx +21 -0
- package/Components/FeedLoader/index.js +2 -8
- package/Components/Focusable/Focusable.tsx +10 -3
- package/Components/Focusable/FocusableTvOS.tsx +2 -2
- package/Components/Focusable/Touchable.tsx +5 -3
- package/Components/Focusable/index.android.tsx +8 -4
- package/Components/FocusableGroup/FocusableTvOS.tsx +1 -1
- package/Components/FocusableList/FocusableItem.tsx +4 -3
- package/Components/FocusableList/FocusableListItemWrapper.tsx +2 -1
- package/Components/FocusableList/hooks/useCellState.android.ts +13 -3
- package/Components/FocusableList/index.tsx +16 -9
- package/Components/FreezeWithCallback/__tests__/index.test.tsx +67 -43
- package/Components/GeneralContentScreen/utils/useCurationAPI.ts +14 -17
- package/Components/HandlePlayable/HandlePlayable.tsx +14 -65
- package/Components/HandlePlayable/const.ts +3 -0
- package/Components/HandlePlayable/utils.ts +74 -0
- package/Components/Layout/TV/__tests__/index.test.tsx +0 -1
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +6 -2
- package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +0 -12
- package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +65 -17
- package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/Image.test.tsx +21 -3
- package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/__snapshots__/Image.test.tsx.snap +6 -3
- package/Components/MasterCell/DefaultComponents/Text/index.tsx +26 -6
- package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +10 -10
- package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +18 -18
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/index.test.tsx +10 -10
- package/Components/MasterCell/utils/behaviorProvider.ts +2 -2
- package/Components/MasterCell/utils/index.ts +1 -19
- package/Components/OfflineHandler/__tests__/index.test.tsx +6 -13
- package/Components/PlayerContainer/PlayerContainer.tsx +5 -17
- package/Components/PlayerImageBackground/index.tsx +3 -22
- package/Components/River/ComponentsMap/ComponentsMap.tsx +49 -42
- package/Components/River/ComponentsMap/ContextProviders/ComponentsMapHeightContext.ts +8 -0
- package/Components/River/ComponentsMap/ContextProviders/ComponentsMapRefContext.ts +8 -0
- package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +0 -1
- package/Components/River/RefreshControl.tsx +11 -19
- package/Components/River/__tests__/river.test.js +12 -26
- package/Components/Screen/TV/hooks/useInitialFocus.ts +14 -4
- package/Components/Screen/__tests__/Screen.test.tsx +5 -17
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +2 -0
- package/Components/Screen/__tests__/navigationHandler.test.ts +133 -22
- package/Components/Screen/index.tsx +22 -5
- package/Components/Screen/navigationHandler.ts +20 -2
- package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +2 -2
- package/Components/ScreenRevealManager/utils/index.ts +23 -0
- package/Components/ScreenRevealManager/withScreenRevealManager.tsx +54 -24
- package/Components/Tabs/TV/Tabs.android.tsx +1 -1
- package/Components/Tabs/Tabs.tsx +2 -3
- package/Components/TextInputTv/__tests__/__snapshots__/TextInputTv.test.js.snap +13 -0
- package/Components/TextInputTv/index.tsx +11 -0
- package/Components/Touchable/__tests__/touchable.test.tsx +12 -17
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +1 -0
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +117 -157
- package/Components/VideoModal/ModalAnimation/index.ts +2 -13
- package/Components/VideoModal/ModalAnimation/utils.ts +1 -327
- package/Components/VideoModal/PlayerDetails.tsx +5 -5
- package/Components/VideoModal/PlayerWrapper.tsx +14 -88
- package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +5 -5
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -0
- package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +9 -1
- package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +40 -15
- package/Components/VideoModal/hooks/useModalSize.ts +10 -5
- package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +2 -2
- package/Components/VideoModal/hooks/utils/index.ts +4 -0
- package/Components/VideoModal/playerWrapperStyle.ts +70 -0
- package/Components/VideoModal/playerWrapperUtils.ts +91 -0
- package/Contexts/CellFocusedStateContext/index.tsx +27 -0
- package/Contexts/ConfigutaionContext/__tests__/ConfigurationProvider.test.tsx +3 -3
- package/Contexts/ScreenContext/index.tsx +28 -32
- package/Decorators/ConfigurationWrapper/__tests__/withConfigurationProvider.test.tsx +3 -3
- package/Decorators/RiverFeedLoader/__tests__/__snapshots__/riverFeedLoader.test.tsx.snap +221 -209
- package/Decorators/RiverFeedLoader/__tests__/riverFeedLoader.test.tsx +14 -16
- package/Decorators/RiverFeedLoader/__tests__/utils.test.ts +0 -20
- package/Decorators/RiverFeedLoader/index.tsx +21 -13
- package/Decorators/RiverFeedLoader/utils/getDatasourceUrl.ts +6 -10
- package/Decorators/RiverFeedLoader/utils/index.ts +0 -35
- package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +27 -27
- package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +3 -5
- package/Decorators/ZappPipesDataConnector/utils/useFilter.tsx +68 -76
- package/events/index.ts +3 -0
- package/package.json +5 -5
- package/Components/River/__tests__/__snapshots__/river.test.js.snap +0 -27
- package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +0 -60
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +0 -421
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +0 -176
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +0 -500
- package/Components/VideoModal/ModalAnimation/__tests__/getMoveUpValue.test.ts +0 -108
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import
|
|
3
|
+
import { render } from "@testing-library/react-native";
|
|
4
4
|
|
|
5
5
|
import { CollapsibleTextContainer } from "../CollapsibleTextContainer";
|
|
6
6
|
|
|
7
7
|
describe("CollapsibleTextContainer", () => {
|
|
8
8
|
it("render container+children when label is presented", () => {
|
|
9
|
-
const
|
|
9
|
+
const { toJSON } = render(
|
|
10
10
|
<CollapsibleTextContainer
|
|
11
11
|
backgroundColor="#000000"
|
|
12
12
|
label={"label"}
|
|
@@ -16,36 +16,36 @@ describe("CollapsibleTextContainer", () => {
|
|
|
16
16
|
</CollapsibleTextContainer>
|
|
17
17
|
);
|
|
18
18
|
|
|
19
|
-
const result =
|
|
19
|
+
const result = toJSON();
|
|
20
20
|
|
|
21
21
|
expect(result).not.toBeNull();
|
|
22
|
-
expect(
|
|
22
|
+
expect(toJSON()).toMatchSnapshot();
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
it("render nothing when label is empty", () => {
|
|
26
|
-
const
|
|
26
|
+
const { toJSON } = render(
|
|
27
27
|
<CollapsibleTextContainer backgroundColor="#000000" label={""} style={{}}>
|
|
28
28
|
<View />
|
|
29
29
|
</CollapsibleTextContainer>
|
|
30
30
|
);
|
|
31
31
|
|
|
32
|
-
const result =
|
|
32
|
+
const result = toJSON();
|
|
33
33
|
expect(result).toBeNull();
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
it("render nothing when label is not passed", () => {
|
|
37
|
-
const
|
|
37
|
+
const { toJSON } = render(
|
|
38
38
|
<CollapsibleTextContainer backgroundColor="#000000" label={""} style={{}}>
|
|
39
39
|
<View />
|
|
40
40
|
</CollapsibleTextContainer>
|
|
41
41
|
);
|
|
42
42
|
|
|
43
|
-
const result =
|
|
43
|
+
const result = toJSON();
|
|
44
44
|
expect(result).toBeNull();
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
it("render nothing when label is undefined", () => {
|
|
48
|
-
const
|
|
48
|
+
const { toJSON } = render(
|
|
49
49
|
<CollapsibleTextContainer
|
|
50
50
|
backgroundColor="#000000"
|
|
51
51
|
label={undefined}
|
|
@@ -55,7 +55,7 @@ describe("CollapsibleTextContainer", () => {
|
|
|
55
55
|
</CollapsibleTextContainer>
|
|
56
56
|
);
|
|
57
57
|
|
|
58
|
-
const result =
|
|
58
|
+
const result = toJSON();
|
|
59
59
|
expect(result).toBeNull();
|
|
60
60
|
});
|
|
61
61
|
});
|
|
@@ -24,7 +24,7 @@ const parseContextKey = (
|
|
|
24
24
|
const getDataSourceProvider = (
|
|
25
25
|
behavior: Behavior,
|
|
26
26
|
screenRoute: string,
|
|
27
|
-
screenStateStore:
|
|
27
|
+
screenStateStore: ReturnType<typeof useScreenStateStore>
|
|
28
28
|
): BehaviorSubject<string[] | string> | null => {
|
|
29
29
|
if (!behavior) return null;
|
|
30
30
|
|
|
@@ -116,7 +116,7 @@ export const isCellSelected = ({
|
|
|
116
116
|
}: {
|
|
117
117
|
item: ZappEntry;
|
|
118
118
|
screenRoute: string;
|
|
119
|
-
screenStateStore:
|
|
119
|
+
screenStateStore: ReturnType<typeof useScreenStateStore>;
|
|
120
120
|
behavior?: Behavior;
|
|
121
121
|
}): boolean => {
|
|
122
122
|
if (!behavior) return false;
|
|
@@ -192,20 +192,6 @@ export const getFocusedButtonId = (focusable) => {
|
|
|
192
192
|
});
|
|
193
193
|
};
|
|
194
194
|
|
|
195
|
-
export const isSelected = ({
|
|
196
|
-
item,
|
|
197
|
-
screenRoute,
|
|
198
|
-
screenStateStore,
|
|
199
|
-
behavior,
|
|
200
|
-
}: {
|
|
201
|
-
item: ZappEntry;
|
|
202
|
-
screenRoute: string;
|
|
203
|
-
screenStateStore: ScreenStateStore;
|
|
204
|
-
behavior?: Behavior;
|
|
205
|
-
}) => {
|
|
206
|
-
return isCellSelected({ item, screenRoute, screenStateStore, behavior });
|
|
207
|
-
};
|
|
208
|
-
|
|
209
195
|
export const useCellState = ({
|
|
210
196
|
item,
|
|
211
197
|
behavior,
|
|
@@ -217,15 +203,11 @@ export const useCellState = ({
|
|
|
217
203
|
}): CellState => {
|
|
218
204
|
const lastUpdate = useBehaviorUpdate(behavior);
|
|
219
205
|
const router = useRoute();
|
|
220
|
-
/** Could be replaced with existing store from useScreenContextV2
|
|
221
|
-
* const screenContextV2 = useScreenContextV2();
|
|
222
|
-
const screenStateStore = screenContextV2._stateStore();
|
|
223
|
-
*/
|
|
224
206
|
const screenStateStore = useScreenStateStore();
|
|
225
207
|
|
|
226
208
|
const _isSelected = useMemo(
|
|
227
209
|
() =>
|
|
228
|
-
|
|
210
|
+
isCellSelected({
|
|
229
211
|
item,
|
|
230
212
|
screenRoute: router?.pathname,
|
|
231
213
|
screenStateStore,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
|
|
3
|
-
import renderer, { act } from "react-test-renderer";
|
|
2
|
+
import { render } from "@testing-library/react-native";
|
|
4
3
|
|
|
5
4
|
jest.useFakeTimers({ legacyFakeTimers: true });
|
|
6
5
|
|
|
@@ -49,24 +48,18 @@ describe("OfflineHandler", () => {
|
|
|
49
48
|
const { OfflineHandler, NotificationView } = require("../");
|
|
50
49
|
|
|
51
50
|
it("renders", () => {
|
|
52
|
-
const
|
|
53
|
-
expect(
|
|
51
|
+
const { toJSON } = render(<OfflineHandler />);
|
|
52
|
+
expect(toJSON()).toMatchSnapshot();
|
|
54
53
|
});
|
|
55
54
|
|
|
56
55
|
it("renders Notification mode if component was rendered while online", () => {
|
|
57
56
|
mockConnectionStatus = true;
|
|
58
57
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
act(() => {
|
|
62
|
-
instance = renderer.create(<OfflineHandler />);
|
|
63
|
-
});
|
|
58
|
+
const { rerender, UNSAFE_getByType } = render(<OfflineHandler />);
|
|
64
59
|
|
|
65
|
-
|
|
66
|
-
instance.update(<OfflineHandler />);
|
|
67
|
-
});
|
|
60
|
+
rerender(<OfflineHandler />);
|
|
68
61
|
|
|
69
|
-
const notificationsView =
|
|
62
|
+
const notificationsView = UNSAFE_getByType(NotificationView);
|
|
70
63
|
expect(notificationsView).toBeDefined();
|
|
71
64
|
});
|
|
72
65
|
});
|
|
@@ -56,11 +56,6 @@ import { toNumber } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
|
56
56
|
import { usePlayNextOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayNextOverlay";
|
|
57
57
|
import { PlayNextState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/OverlayObserver/OverlaysObserver";
|
|
58
58
|
|
|
59
|
-
import {
|
|
60
|
-
PlayerAnimationStateEnum,
|
|
61
|
-
useModalAnimationContext,
|
|
62
|
-
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
63
|
-
|
|
64
59
|
import {
|
|
65
60
|
PlayerNativeCommandTypes,
|
|
66
61
|
PlayerNativeSendCommand,
|
|
@@ -248,9 +243,6 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
248
243
|
const screenData = useTargetScreenData(item);
|
|
249
244
|
const { setVisible: showNavBar } = useSetNavbarState();
|
|
250
245
|
|
|
251
|
-
const { isActiveGesture, startComponentsAnimation, setPlayerAnimationState } =
|
|
252
|
-
useModalAnimationContext();
|
|
253
|
-
|
|
254
246
|
const playerEvent = (event, ...args) => {
|
|
255
247
|
playerManager.invokeHandler(event, ...args);
|
|
256
248
|
};
|
|
@@ -423,7 +415,10 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
423
415
|
id: playerContainerId,
|
|
424
416
|
listener: {
|
|
425
417
|
onVideoEnd,
|
|
426
|
-
onError
|
|
418
|
+
onError: (err: Error) => {
|
|
419
|
+
// Adapt Error to the expected shape for onError
|
|
420
|
+
onError({ error: err });
|
|
421
|
+
},
|
|
427
422
|
onLoad,
|
|
428
423
|
onPlayerClose: close,
|
|
429
424
|
onPlayerDetached: close,
|
|
@@ -479,8 +474,6 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
479
474
|
if (isModal && mode === VideoModalMode.MAXIMIZED) {
|
|
480
475
|
if (disableMiniPlayer) {
|
|
481
476
|
navigator.closeVideoModal();
|
|
482
|
-
} else {
|
|
483
|
-
setPlayerAnimationState(PlayerAnimationStateEnum.minimize);
|
|
484
477
|
}
|
|
485
478
|
}
|
|
486
479
|
|
|
@@ -677,11 +670,7 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
677
670
|
autoplay={true}
|
|
678
671
|
controls={false}
|
|
679
672
|
disableCastAction={disableCastAction}
|
|
680
|
-
docked={
|
|
681
|
-
navigator.isVideoModalDocked() &&
|
|
682
|
-
!startComponentsAnimation &&
|
|
683
|
-
!isActiveGesture
|
|
684
|
-
}
|
|
673
|
+
docked={navigator.isVideoModalDocked()}
|
|
685
674
|
entry={item}
|
|
686
675
|
fullscreen={mode === VideoModalMode.FULLSCREEN}
|
|
687
676
|
inline={inline}
|
|
@@ -699,7 +688,6 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
699
688
|
setNextVideoPreloadThresholdPercentage={
|
|
700
689
|
setNextVideoPreloadThresholdPercentage
|
|
701
690
|
}
|
|
702
|
-
startComponentsAnimation={startComponentsAnimation}
|
|
703
691
|
>
|
|
704
692
|
{renderApplePlayer(applePlayerProps)}
|
|
705
693
|
</Player>
|
|
@@ -2,12 +2,6 @@ import React, { PropsWithChildren } from "react";
|
|
|
2
2
|
import { ImageBackground, View } from "react-native";
|
|
3
3
|
|
|
4
4
|
import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
|
|
5
|
-
import {
|
|
6
|
-
AnimationComponent,
|
|
7
|
-
ComponentAnimationType,
|
|
8
|
-
useModalAnimationContext,
|
|
9
|
-
PlayerAnimationStateEnum,
|
|
10
|
-
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
11
5
|
|
|
12
6
|
type Props = PropsWithChildren<{
|
|
13
7
|
entry: ZappEntry;
|
|
@@ -25,30 +19,17 @@ const PlayerImageBackgroundComponent = ({
|
|
|
25
19
|
style,
|
|
26
20
|
imageStyle,
|
|
27
21
|
imageKey,
|
|
28
|
-
defaultImageDimensions,
|
|
29
22
|
}: Props) => {
|
|
30
23
|
const source = React.useMemo(
|
|
31
24
|
() => ({ uri: imageSrcFromMediaItem(entry, [imageKey]) }),
|
|
32
25
|
[imageKey, entry]
|
|
33
26
|
);
|
|
34
27
|
|
|
35
|
-
const { playerAnimationState } = useModalAnimationContext();
|
|
36
|
-
|
|
37
28
|
if (!source) return <>{children}</>;
|
|
38
29
|
|
|
39
30
|
return (
|
|
40
|
-
<View
|
|
41
|
-
style={
|
|
42
|
-
playerAnimationState === PlayerAnimationStateEnum.maximize
|
|
43
|
-
? defaultImageDimensions
|
|
44
|
-
: style
|
|
45
|
-
}
|
|
46
|
-
>
|
|
47
|
-
<AnimationComponent
|
|
48
|
-
style={style}
|
|
49
|
-
animationType={ComponentAnimationType.player}
|
|
50
|
-
additionalData={defaultImageDimensions}
|
|
51
|
-
>
|
|
31
|
+
<View style={style}>
|
|
32
|
+
<View style={style}>
|
|
52
33
|
<ImageBackground
|
|
53
34
|
resizeMode="cover"
|
|
54
35
|
style={imageSize}
|
|
@@ -57,7 +38,7 @@ const PlayerImageBackgroundComponent = ({
|
|
|
57
38
|
>
|
|
58
39
|
{children}
|
|
59
40
|
</ImageBackground>
|
|
60
|
-
</
|
|
41
|
+
</View>
|
|
61
42
|
</View>
|
|
62
43
|
);
|
|
63
44
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
|
-
import {
|
|
3
|
+
import { FlatList, StyleSheet, View } from "react-native";
|
|
4
4
|
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
5
5
|
import { RiverItem } from "../RiverItem";
|
|
6
6
|
import { RiverFooter } from "../RiverFooter";
|
|
@@ -9,8 +9,8 @@ import { useScreenConfiguration } from "../useScreenConfiguration";
|
|
|
9
9
|
import { RefreshControl } from "../RefreshControl";
|
|
10
10
|
import { ifEmptyUseFallback } from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
11
11
|
import {
|
|
12
|
-
useProfilerLogging,
|
|
13
12
|
usePipesCacheReset,
|
|
13
|
+
useProfilerLogging,
|
|
14
14
|
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
15
15
|
import { useLoadingState } from "./hooks/useLoadingState";
|
|
16
16
|
import { ViewportTracker } from "../../Viewport";
|
|
@@ -25,6 +25,8 @@ import { useScreenContextV2 } from "@applicaster/zapp-react-native-utils/reactHo
|
|
|
25
25
|
import { useShallow } from "zustand/react/shallow";
|
|
26
26
|
|
|
27
27
|
import { isAndroidPlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
28
|
+
import { ComponentsMapHeightContext } from "./ContextProviders/ComponentsMapHeightContext";
|
|
29
|
+
import { ComponentsMapRefContext } from "./ContextProviders/ComponentsMapRefContext";
|
|
28
30
|
|
|
29
31
|
const isAndroid = isAndroidPlatform();
|
|
30
32
|
|
|
@@ -70,6 +72,7 @@ function ComponentsMapComponent(props: Props) {
|
|
|
70
72
|
} = props;
|
|
71
73
|
|
|
72
74
|
const flatListRef = React.useRef<FlatList | null>(null);
|
|
75
|
+
const flatListWrapperRef = React.useRef<View | null>(null);
|
|
73
76
|
const screenConfig = useScreenConfiguration(riverId);
|
|
74
77
|
const screenData = useScreenData(riverId);
|
|
75
78
|
const pullToRefreshEnabled = screenData?.rules?.pull_to_refresh_enabled;
|
|
@@ -265,47 +268,51 @@ function ComponentsMapComponent(props: Props) {
|
|
|
265
268
|
// The Screen Picker in Mobile is completly different than the TV
|
|
266
269
|
// so the various offsets / margins in TV do not apply here.
|
|
267
270
|
return (
|
|
268
|
-
<View style={styles.container}>
|
|
269
|
-
<
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
271
|
+
<View style={styles.container} ref={flatListWrapperRef}>
|
|
272
|
+
<ComponentsMapHeightContext.Provider value={flatListHeight}>
|
|
273
|
+
<ComponentsMapRefContext.Provider value={flatListWrapperRef}>
|
|
274
|
+
<ScreenLoadingMeasurements
|
|
275
|
+
riverId={riverId}
|
|
276
|
+
numberOfComponents={riverComponents.length}
|
|
277
|
+
>
|
|
278
|
+
<ViewportTracker>
|
|
279
|
+
<FlatList
|
|
280
|
+
ref={(ref) => {
|
|
281
|
+
flatListRef.current = ref;
|
|
282
|
+
}}
|
|
283
|
+
// Fix for WebView rerender crashes on Android API 28+
|
|
284
|
+
// https://github.com/react-native-webview/react-native-webview/issues/1915#issuecomment-964035468
|
|
285
|
+
overScrollMode={isAndroid ? "never" : "auto"}
|
|
286
|
+
scrollIndicatorInsets={scrollIndicatorInsets}
|
|
287
|
+
extraData={feed}
|
|
288
|
+
stickyHeaderIndices={stickyHeaderIndices}
|
|
289
|
+
removeClippedSubviews={isAndroid}
|
|
290
|
+
onLayout={handleOnLayout}
|
|
291
|
+
initialNumToRender={3}
|
|
292
|
+
maxToRenderPerBatch={10}
|
|
293
|
+
windowSize={12}
|
|
294
|
+
keyExtractor={keyExtractor}
|
|
295
|
+
renderItem={renderRiverItem}
|
|
296
|
+
data={riverComponents}
|
|
297
|
+
contentContainerStyle={contentContainerStyle}
|
|
298
|
+
ListFooterComponent={
|
|
299
|
+
<RiverFooter
|
|
300
|
+
flatListHeight={flatListHeight}
|
|
301
|
+
loadingState={loadingState}
|
|
302
|
+
/>
|
|
303
|
+
}
|
|
304
|
+
refreshControl={refreshControl}
|
|
305
|
+
onScrollBeginDrag={onScrollBeginDrag}
|
|
306
|
+
onScroll={onScroll}
|
|
307
|
+
onMomentumScrollEnd={_onMomentumScrollEnd}
|
|
308
|
+
onScrollEndDrag={_onScrollEndDrag}
|
|
309
|
+
scrollEventThrottle={16}
|
|
310
|
+
{...scrollViewExtraProps}
|
|
297
311
|
/>
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
onMomentumScrollEnd={_onMomentumScrollEnd}
|
|
303
|
-
onScrollEndDrag={_onScrollEndDrag}
|
|
304
|
-
scrollEventThrottle={16}
|
|
305
|
-
{...scrollViewExtraProps}
|
|
306
|
-
/>
|
|
307
|
-
</ViewportTracker>
|
|
308
|
-
</ScreenLoadingMeasurements>
|
|
312
|
+
</ViewportTracker>
|
|
313
|
+
</ScreenLoadingMeasurements>
|
|
314
|
+
</ComponentsMapRefContext.Provider>
|
|
315
|
+
</ComponentsMapHeightContext.Provider>
|
|
309
316
|
</View>
|
|
310
317
|
);
|
|
311
318
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
|
|
4
|
+
export const ComponentsMapRefContext =
|
|
5
|
+
React.createContext<React.RefObject<View | null> | null>(null);
|
|
6
|
+
|
|
7
|
+
export const useComponentsMapRef = () =>
|
|
8
|
+
React.useContext(ComponentsMapRefContext);
|
|
@@ -2,7 +2,6 @@ import { renderHook, act } from "@testing-library/react-hooks";
|
|
|
2
2
|
import { BehaviorSubject } from "rxjs";
|
|
3
3
|
import { useLoadingState } from "../useLoadingState";
|
|
4
4
|
|
|
5
|
-
// Mock the useRefWithInitialValue hook
|
|
6
5
|
jest.mock(
|
|
7
6
|
"@applicaster/zapp-react-native-utils/reactHooks/state/useRefWithInitialValue",
|
|
8
7
|
() => ({
|
|
@@ -13,10 +13,7 @@ import { useCurrentScreenData } from "@applicaster/zapp-react-native-utils/react
|
|
|
13
13
|
import { useShallow } from "zustand/react/shallow";
|
|
14
14
|
import { useScreenContextV2 } from "@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenContext";
|
|
15
15
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
16
|
-
import {
|
|
17
|
-
ZappPipes,
|
|
18
|
-
useAppDispatch,
|
|
19
|
-
} from "@applicaster/zapp-react-native-redux";
|
|
16
|
+
import { useLoadPipesDataDispatch } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
20
17
|
|
|
21
18
|
const BRIGHTNESS_THRESHOLD = 160;
|
|
22
19
|
const ABOVE_DEFAULT_COLOR = "gray";
|
|
@@ -63,38 +60,33 @@ export const usePullToRefresh = (
|
|
|
63
60
|
) => {
|
|
64
61
|
const isPipesV1 = !!pullToRefreshPipesV1RefreshingStateUpdater;
|
|
65
62
|
|
|
66
|
-
const dispatch = useAppDispatch();
|
|
67
|
-
|
|
68
63
|
const [refreshing, setRefreshing] = React.useState(false);
|
|
69
64
|
|
|
70
65
|
const feeds: string[] =
|
|
71
66
|
riverComponents?.map(R.path(["data", "source"])).filter((feed) => !!feed) ??
|
|
72
67
|
[];
|
|
73
68
|
|
|
74
|
-
const screenData = useCurrentScreenData();
|
|
75
|
-
|
|
76
69
|
const feedsLength = feeds.length;
|
|
77
70
|
|
|
78
71
|
const [requestsCompletedCounter, setRequestsCompletedCounter] =
|
|
79
72
|
React.useState(0);
|
|
80
73
|
|
|
74
|
+
const loadPipesDataDispatcher = useLoadPipesDataDispatch();
|
|
75
|
+
|
|
81
76
|
React.useEffect(() => {
|
|
82
77
|
// will not work for pipes v1 on 1st level screens
|
|
83
78
|
if (refreshing && !isPipesV1) {
|
|
84
79
|
feeds.forEach((feed) => {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
riverId: screenData.id,
|
|
93
|
-
})
|
|
94
|
-
);
|
|
80
|
+
loadPipesDataDispatcher(feed, {
|
|
81
|
+
silentRefresh: true,
|
|
82
|
+
clearCache: true,
|
|
83
|
+
callback: () => {
|
|
84
|
+
setRequestsCompletedCounter(R.inc);
|
|
85
|
+
},
|
|
86
|
+
});
|
|
95
87
|
});
|
|
96
88
|
}
|
|
97
|
-
}, [refreshing, isPipesV1]);
|
|
89
|
+
}, [refreshing, isPipesV1, feeds, loadPipesDataDispatcher]);
|
|
98
90
|
|
|
99
91
|
React.useEffect(() => {
|
|
100
92
|
if (requestsCompletedCounter === feedsLength) {
|
|
@@ -1,20 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
3
|
-
import configureStore from "redux-mock-store";
|
|
2
|
+
import { screen } from "@testing-library/react-native";
|
|
4
3
|
import { renderWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
|
|
5
|
-
import { Provider } from "react-redux";
|
|
6
4
|
|
|
7
|
-
import { River } from "../";
|
|
8
5
|
import { ScreenResolver } from "../../ScreenResolver";
|
|
9
6
|
import { RiverComponent } from "../River";
|
|
10
7
|
|
|
11
|
-
jest.mock(
|
|
12
|
-
"@applicaster/zapp-react-native-utils/reactHooks/navigation/useIsScreenActive",
|
|
13
|
-
() => ({
|
|
14
|
-
useIsScreenActive: jest.fn(() => true),
|
|
15
|
-
})
|
|
16
|
-
);
|
|
17
|
-
|
|
18
8
|
jest.mock(
|
|
19
9
|
"@applicaster/zapp-react-native-ui-components/Components/GeneralContentScreen",
|
|
20
10
|
() => {
|
|
@@ -46,6 +36,13 @@ jest.mock(
|
|
|
46
36
|
})
|
|
47
37
|
);
|
|
48
38
|
|
|
39
|
+
jest.mock(
|
|
40
|
+
"@applicaster/zapp-react-native-utils/reactHooks/navigation/useIsScreenActive",
|
|
41
|
+
() => ({
|
|
42
|
+
useIsScreenActive: jest.fn(() => true),
|
|
43
|
+
})
|
|
44
|
+
);
|
|
45
|
+
|
|
49
46
|
const river = {
|
|
50
47
|
home: true,
|
|
51
48
|
id: "A1234",
|
|
@@ -89,28 +86,17 @@ const riverProps = {
|
|
|
89
86
|
|
|
90
87
|
const appData = { layoutVersion: "v1" };
|
|
91
88
|
|
|
92
|
-
const store =
|
|
89
|
+
const store = { rivers, appData };
|
|
93
90
|
|
|
94
91
|
describe("When River has a general_content type", () => {
|
|
95
92
|
it("renders GeneralContentScreen correctly", () => {
|
|
96
|
-
const { getByTestId } =
|
|
97
|
-
<
|
|
98
|
-
|
|
99
|
-
</Provider>
|
|
93
|
+
const { getByTestId } = renderWithProviders(
|
|
94
|
+
<RiverComponent {...riverProps} />,
|
|
95
|
+
store
|
|
100
96
|
);
|
|
101
97
|
|
|
102
98
|
expect(getByTestId("general-content-screen")).toBeTruthy();
|
|
103
99
|
});
|
|
104
|
-
|
|
105
|
-
it("renders River component correctly", () => {
|
|
106
|
-
const wrapper = render(
|
|
107
|
-
<Provider store={store}>
|
|
108
|
-
<River screenId="A1234" />
|
|
109
|
-
</Provider>
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
expect(wrapper.toJSON()).toMatchSnapshot();
|
|
113
|
-
});
|
|
114
100
|
});
|
|
115
101
|
|
|
116
102
|
describe("When River has any other type other than general_content", () => {
|
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
setFocusOnMenu,
|
|
11
11
|
} from "@applicaster/zapp-react-native-utils/appUtils/focusManagerAux";
|
|
12
12
|
|
|
13
|
+
import { waitUntilScreenRevealManagerIsReady } from "@applicaster/zapp-react-native-ui-components/Components/ScreenRevealManager/utils";
|
|
14
|
+
|
|
13
15
|
type Return =
|
|
14
16
|
| {
|
|
15
17
|
onContent: true;
|
|
@@ -57,14 +59,22 @@ export const useInitialFocus = (): void => {
|
|
|
57
59
|
React.useEffect(() => {
|
|
58
60
|
const initialFocus = getInitialFocus(focusOnContent, isNavBarVisible);
|
|
59
61
|
|
|
60
|
-
if (initialFocus.
|
|
61
|
-
|
|
62
|
+
if (initialFocus.onMenu) {
|
|
63
|
+
setFocusOnMenu(currentRoute);
|
|
62
64
|
|
|
63
65
|
return;
|
|
64
66
|
}
|
|
65
67
|
|
|
66
|
-
if (initialFocus.
|
|
67
|
-
|
|
68
|
+
if (initialFocus.onContent) {
|
|
69
|
+
const subscription = waitUntilScreenRevealManagerIsReady().subscribe(
|
|
70
|
+
() => {
|
|
71
|
+
setFocusOnContent(currentRoute);
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
return () => {
|
|
76
|
+
subscription.unsubscribe();
|
|
77
|
+
};
|
|
68
78
|
}
|
|
69
79
|
}, []);
|
|
70
80
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import {
|
|
3
|
+
import { render } from "@testing-library/react-native";
|
|
4
4
|
|
|
5
5
|
const Mocked_RouteManager = jest.fn((props) => (
|
|
6
6
|
<View testID="routeManager" {...props} />
|
|
@@ -152,8 +152,6 @@ const screenProps = {
|
|
|
152
152
|
const { Screen } = require("..");
|
|
153
153
|
|
|
154
154
|
describe("<Screen Component />", () => {
|
|
155
|
-
let wrapper;
|
|
156
|
-
|
|
157
155
|
beforeEach(() => {
|
|
158
156
|
allowedOrientationsForScreen.mockClear();
|
|
159
157
|
getOrientation.mockClear();
|
|
@@ -161,26 +159,16 @@ describe("<Screen Component />", () => {
|
|
|
161
159
|
});
|
|
162
160
|
|
|
163
161
|
describe("when the navbar should show", () => {
|
|
164
|
-
act(() => {
|
|
165
|
-
wrapper = create(<Screen {...screenProps} />);
|
|
166
|
-
});
|
|
167
|
-
|
|
168
162
|
it("renders correctly", () => {
|
|
169
|
-
|
|
163
|
+
const { toJSON } = render(<Screen {...screenProps} />);
|
|
164
|
+
expect(toJSON()).toMatchSnapshot();
|
|
170
165
|
});
|
|
171
166
|
});
|
|
172
167
|
|
|
173
168
|
describe("when the navbar should be hidden", () => {
|
|
174
|
-
beforeEach(() => {
|
|
175
|
-
wrapper = create(<Screen {...screenProps} />);
|
|
176
|
-
});
|
|
177
|
-
|
|
178
169
|
it("renders correctly", () => {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
expect(wrapper.toJSON()).toMatchSnapshot();
|
|
170
|
+
const { toJSON } = render(<Screen {...screenProps} />);
|
|
171
|
+
expect(toJSON()).toMatchSnapshot();
|
|
184
172
|
});
|
|
185
173
|
});
|
|
186
174
|
});
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`<Screen Component /> when the navbar should be hidden renders correctly 1`] = `
|
|
4
4
|
<View
|
|
5
|
+
importantForAccessibility="yes"
|
|
5
6
|
style={
|
|
6
7
|
{
|
|
7
8
|
"backgroundColor": "blue",
|
|
@@ -34,6 +35,7 @@ exports[`<Screen Component /> when the navbar should be hidden renders correctly
|
|
|
34
35
|
|
|
35
36
|
exports[`<Screen Component /> when the navbar should show renders correctly 1`] = `
|
|
36
37
|
<View
|
|
38
|
+
importantForAccessibility="yes"
|
|
37
39
|
style={
|
|
38
40
|
{
|
|
39
41
|
"backgroundColor": "blue",
|