@applicaster/zapp-react-native-ui-components 14.0.0-rc.9 → 15.0.0-rc.1
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 +5 -3
- package/Components/AudioPlayer/index.tsx +15 -0
- package/Components/AudioPlayer/mobile/Layout.tsx +66 -0
- package/Components/AudioPlayer/{__tests__/__snapshots__/audioPlayer.test.js.snap → mobile/__tests__/__snapshots__/audioPlayerMobileLayout.test.js.snap} +2 -2
- package/Components/AudioPlayer/mobile/__tests__/audioPlayerMobileLayout.test.js +18 -0
- package/Components/AudioPlayer/mobile/index.tsx +18 -0
- package/Components/AudioPlayer/{Artwork.tsx → tv/Artwork.tsx} +3 -2
- package/Components/AudioPlayer/{Channel.tsx → tv/Channel.tsx} +7 -7
- package/Components/AudioPlayer/tv/Layout.tsx +168 -0
- package/Components/AudioPlayer/{Runtime.tsx → tv/Runtime.tsx} +7 -1
- package/Components/AudioPlayer/{Summary.tsx → tv/Summary.tsx} +6 -2
- package/Components/AudioPlayer/{Title.tsx → tv/Title.tsx} +6 -2
- package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/Runtime.test.js.snap +2 -2
- package/Components/AudioPlayer/tv/__tests__/__snapshots__/audioPlayer.test.js.snap +164 -0
- package/Components/AudioPlayer/tv/__tests__/__snapshots__/channel.test.js.snap +19 -0
- package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/summary.test.js.snap +1 -2
- package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/title.test.js.snap +1 -2
- package/Components/AudioPlayer/{__tests__ → tv/__tests__}/audioPlayer.test.js +7 -3
- package/Components/AudioPlayer/{helpers.tsx → tv/helpers.tsx} +11 -5
- package/Components/AudioPlayer/{AudioPlayer.tsx → tv/index.tsx} +17 -58
- package/Components/AudioPlayer/types.ts +40 -0
- package/Components/BaseFocusable/index.tsx +23 -12
- package/Components/Cell/Cell.tsx +91 -64
- package/Components/Cell/CellWithFocusable.tsx +3 -0
- package/Components/Cell/__tests__/CellWIthFocusable.test.js +3 -2
- package/Components/Cell/index.js +7 -3
- package/Components/ComponentResolver/index.ts +1 -1
- 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 +12 -3
- package/Components/Focusable/FocusableTvOS.tsx +5 -5
- package/Components/Focusable/FocusableiOS.tsx +2 -2
- package/Components/Focusable/Touchable.tsx +5 -3
- package/Components/Focusable/__tests__/index.android.test.tsx +3 -0
- package/Components/Focusable/index.android.tsx +19 -11
- package/Components/Focusable/index.tsx +1 -1
- 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 +20 -9
- package/Components/FreezeWithCallback/__tests__/index.test.tsx +67 -43
- package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +42 -59
- package/Components/GeneralContentScreen/utils/useCurationAPI.ts +13 -10
- package/Components/HandlePlayable/HandlePlayable.tsx +25 -9
- package/Components/HookRenderer/HookRenderer.tsx +5 -1
- package/Components/Layout/TV/LayoutBackground.tsx +1 -1
- package/Components/Layout/TV/__tests__/index.test.tsx +0 -1
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +6 -2
- package/Components/MasterCell/DefaultComponents/Button.tsx +1 -1
- package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -39
- package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +1 -1
- package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +1 -1
- 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/elementMapper.tsx +1 -2
- package/Components/MasterCell/index.tsx +1 -1
- package/Components/MasterCell/utils/behaviorProvider.ts +82 -14
- package/Components/MasterCell/utils/index.ts +11 -5
- package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +13 -18
- package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +9 -0
- package/Components/OfflineHandler/__tests__/index.test.tsx +26 -35
- package/Components/PlayerContainer/ErrorDisplay/index.ts +1 -1
- package/Components/PlayerContainer/PlayerContainer.tsx +46 -33
- package/Components/PlayerContainer/ProgramInfo/index.tsx +1 -1
- package/Components/PlayerContainer/index.ts +1 -1
- package/Components/PlayerImageBackground/index.tsx +1 -1
- package/Components/River/ComponentsMap/ComponentsMap.tsx +0 -1
- package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +378 -0
- package/Components/River/ComponentsMap/hooks/useLoadingState.ts +2 -2
- package/Components/River/RefreshControl.tsx +11 -17
- package/Components/River/RiverItem.tsx +3 -0
- package/Components/River/TV/River.tsx +2 -17
- package/Components/River/TV/index.tsx +3 -1
- package/Components/River/TV/withPipesV1DataLoader.tsx +43 -0
- package/Components/River/TV/withRiverDataLoader.tsx +17 -0
- package/Components/River/TV/withTVEventHandler.tsx +1 -1
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +2 -0
- package/Components/River/__tests__/river.test.js +12 -26
- package/Components/River/index.tsx +1 -1
- package/Components/Screen/__tests__/Screen.test.tsx +28 -29
- package/Components/Screen/__tests__/navigationHandler.test.ts +133 -22
- package/Components/Screen/navigationHandler.ts +20 -2
- package/Components/ScreenResolver/index.tsx +15 -0
- package/Components/ScreenRevealManager/ScreenRevealManager.ts +76 -0
- package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +107 -0
- package/Components/ScreenRevealManager/__tests__/withScreenRevealManager.test.tsx +96 -0
- package/Components/ScreenRevealManager/index.ts +1 -0
- package/Components/ScreenRevealManager/withScreenRevealManager.tsx +79 -0
- package/Components/Tabs/TV/Tabs.android.tsx +1 -3
- 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__/__snapshots__/touchable.test.tsx.snap +34 -0
- package/Components/Touchable/__tests__/touchable.test.tsx +12 -17
- package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +15 -9
- package/Components/VideoLive/animationUtils.ts +3 -3
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +3 -9
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.web.tsx +294 -0
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.web.tsx +93 -0
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +73 -29
- package/Components/VideoModal/PlayerDetails.tsx +24 -2
- package/Components/VideoModal/PlayerWrapper.tsx +26 -142
- package/Components/VideoModal/VideoModal.tsx +3 -17
- package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +5 -5
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -7
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +44 -240
- package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +9 -1
- package/Components/VideoModal/hooks/index.ts +0 -2
- package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +40 -15
- package/Components/VideoModal/hooks/useModalSize.ts +18 -2
- package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +2 -2
- package/Components/VideoModal/hooks/utils/index.ts +4 -0
- package/Components/VideoModal/utils.ts +6 -0
- package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -16
- package/Components/Viewport/ViewportTracker/__tests__/viewportTracker.test.js +84 -24
- package/Components/Viewport/VisibilitySensor/VisibilitySensor.tsx +3 -3
- package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/index.ts +3 -3
- package/Contexts/CellFocusedStateContext/index.tsx +27 -0
- package/Contexts/ConfigutaionContext/__tests__/ConfigurationProvider.test.tsx +3 -3
- package/Contexts/ScreenContext/index.tsx +46 -6
- package/Decorators/ConfigurationWrapper/__tests__/withConfigurationProvider.test.tsx +3 -3
- package/Decorators/ConfigurationWrapper/withConfigurationProvider.tsx +2 -2
- 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 +22 -4
- package/Decorators/RiverFeedLoader/utils/index.ts +0 -18
- package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +3 -6
- package/Decorators/ZappPipesDataConnector/ResolverSelector.tsx +25 -0
- package/Decorators/ZappPipesDataConnector/__tests__/NullFeedResolver.test.tsx +78 -0
- package/Decorators/ZappPipesDataConnector/__tests__/ResolverSelector.test.tsx +205 -0
- package/Decorators/ZappPipesDataConnector/__tests__/StaticFeedResolver.test.tsx +251 -0
- package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +368 -0
- package/Decorators/ZappPipesDataConnector/__tests__/utils.test.ts +39 -0
- package/Decorators/ZappPipesDataConnector/index.tsx +26 -293
- package/Decorators/ZappPipesDataConnector/resolvers/NullFeedResolver.tsx +25 -0
- package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +87 -0
- package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +266 -0
- package/Decorators/ZappPipesDataConnector/types.ts +29 -0
- package/Decorators/ZappPipesDataConnector/utils/mongoFilter.ts +738 -0
- package/Decorators/ZappPipesDataConnector/utils/useFilter.tsx +157 -0
- package/events/index.ts +3 -0
- package/package.json +5 -10
- package/Components/AudioPlayer/AudioPlayerLayout.tsx +0 -202
- package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +0 -66
- package/Components/AudioPlayer/__tests__/__snapshots__/channel.test.js.snap +0 -28
- package/Components/AudioPlayer/__tests__/audioPlayerLayout.test.js +0 -26
- package/Components/AudioPlayer/index.ts +0 -1
- package/Components/River/__tests__/__snapshots__/river.test.js.snap +0 -27
- package/Components/VideoModal/hooks/useBackgroundColor.ts +0 -10
- /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/Runtime.test.js +0 -0
- /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/artWork.test.js.snap +0 -0
- /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/artWork.test.js +0 -0
- /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/channel.test.js +0 -0
- /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/summary.test.js +0 -0
- /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/title.test.js +0 -0
|
@@ -11,6 +11,8 @@ import { withScaledLineHeight } from "./utils";
|
|
|
11
11
|
import { toNumber } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
12
12
|
import { MeasurementPortalContext } from "../../../MeasurmentsPortal";
|
|
13
13
|
import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
|
|
14
|
+
import { CellFocusedStateContext } from "@applicaster/zapp-react-native-ui-components/Contexts/CellFocusedStateContext";
|
|
15
|
+
import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
|
|
14
16
|
|
|
15
17
|
type Props = {
|
|
16
18
|
style: any;
|
|
@@ -35,10 +37,9 @@ const _Text = ({
|
|
|
35
37
|
}: Props) => {
|
|
36
38
|
const _label = useTextLabel({ label, entry });
|
|
37
39
|
const isMeasurement = React.useContext(MeasurementPortalContext);
|
|
40
|
+
const cellFocused = React.useContext(CellFocusedStateContext);
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
+
const accessibilityManager = useAccessibilityManager({});
|
|
42
43
|
|
|
43
44
|
// set maximum possible height for the text in case of measurement
|
|
44
45
|
const height =
|
|
@@ -46,6 +47,27 @@ const _Text = ({
|
|
|
46
47
|
? toNumber(otherProps.numberOfLines) * toNumber(style.lineHeight)
|
|
47
48
|
: undefined;
|
|
48
49
|
|
|
50
|
+
const textLabel = dateTransformEnabled
|
|
51
|
+
? dateFormat(dateTransform, label)
|
|
52
|
+
: textTransform(transformText, _label);
|
|
53
|
+
|
|
54
|
+
React.useLayoutEffect(() => {
|
|
55
|
+
// For FocusableCells with action buttons
|
|
56
|
+
if (otherProps.state) {
|
|
57
|
+
if (otherProps.state === "focused" && cellFocused === true) {
|
|
58
|
+
accessibilityManager.addHeading(textLabel);
|
|
59
|
+
}
|
|
60
|
+
} else {
|
|
61
|
+
if (cellFocused === true) {
|
|
62
|
+
accessibilityManager.addHeading(textLabel);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}, [cellFocused, otherProps.state, textLabel]);
|
|
66
|
+
|
|
67
|
+
if (isNilOrEmpty(_label)) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
49
71
|
return (
|
|
50
72
|
<Text
|
|
51
73
|
style={[
|
|
@@ -55,9 +77,7 @@ const _Text = ({
|
|
|
55
77
|
allowFontScaling={false}
|
|
56
78
|
{...withoutLabel(otherProps)}
|
|
57
79
|
>
|
|
58
|
-
{
|
|
59
|
-
? dateFormat(dateTransform, label)
|
|
60
|
-
: textTransform(transformText, _label)}
|
|
80
|
+
{textLabel}
|
|
61
81
|
</Text>
|
|
62
82
|
);
|
|
63
83
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import
|
|
2
|
+
import { render } from "@testing-library/react-native";
|
|
3
3
|
import { Image } from "react-native";
|
|
4
4
|
|
|
5
5
|
jest.mock("@applicaster/zapp-react-native-utils/theme", () => ({
|
|
@@ -10,35 +10,35 @@ const CustomImage = require("../Image").default;
|
|
|
10
10
|
|
|
11
11
|
describe("image with no source", () => {
|
|
12
12
|
it("Uses provided placeholder image string", () => {
|
|
13
|
-
const
|
|
13
|
+
const { UNSAFE_getByType } = render(
|
|
14
14
|
<CustomImage placeholderImage={"foo"} />
|
|
15
15
|
);
|
|
16
16
|
|
|
17
|
-
const
|
|
17
|
+
const imageComponent = UNSAFE_getByType(Image);
|
|
18
18
|
|
|
19
|
-
expect(
|
|
19
|
+
expect(imageComponent.props.source).toEqual({
|
|
20
20
|
uri: "foo",
|
|
21
21
|
});
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
it("Uses provided placeholder image object", () => {
|
|
25
|
-
const
|
|
25
|
+
const { UNSAFE_getByType } = render(
|
|
26
26
|
<CustomImage placeholderImage={"foo"} />
|
|
27
27
|
);
|
|
28
28
|
|
|
29
|
-
const
|
|
29
|
+
const imageComponent = UNSAFE_getByType(Image);
|
|
30
30
|
|
|
31
|
-
expect(
|
|
31
|
+
expect(imageComponent.props.source).toEqual({
|
|
32
32
|
uri: "foo",
|
|
33
33
|
});
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
it("Returns empty string if no image or placeholder defined", () => {
|
|
37
|
-
const
|
|
37
|
+
const { UNSAFE_getByType } = render(
|
|
38
38
|
<CustomImage placeholderImage={null} />
|
|
39
39
|
);
|
|
40
40
|
|
|
41
|
-
const
|
|
42
|
-
expect(
|
|
41
|
+
const imageComponent = UNSAFE_getByType(Image);
|
|
42
|
+
expect(imageComponent.props.source).toBeUndefined();
|
|
43
43
|
});
|
|
44
44
|
});
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import RN from "react-native";
|
|
3
|
-
import {
|
|
4
|
-
import TestRenderer from "react-test-renderer";
|
|
5
|
-
import configureStoreFn from "redux-mock-store";
|
|
3
|
+
import { renderWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
|
|
6
4
|
|
|
7
5
|
const mockUseIsRTL = jest.fn(() => true);
|
|
8
6
|
const mockGetIsRTL = jest.fn(() => true);
|
|
@@ -17,7 +15,6 @@ jest.mock("@applicaster/zapp-react-native-utils/localizationUtils", () => ({
|
|
|
17
15
|
}));
|
|
18
16
|
|
|
19
17
|
const CustomText = require("../Text").default;
|
|
20
|
-
const mockStore = configureStoreFn();
|
|
21
18
|
|
|
22
19
|
const defaultProps = {
|
|
23
20
|
entry: {},
|
|
@@ -25,16 +22,15 @@ const defaultProps = {
|
|
|
25
22
|
transformText: "default",
|
|
26
23
|
};
|
|
27
24
|
|
|
28
|
-
const getRenderedText = (label: string,
|
|
25
|
+
const getRenderedText = (label: string, storeConfig: any) => {
|
|
29
26
|
const props = { ...{ ...defaultProps, label } };
|
|
30
27
|
|
|
31
|
-
const
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
</Provider>
|
|
28
|
+
const { UNSAFE_getByType } = renderWithProviders(
|
|
29
|
+
<CustomText {...props} />,
|
|
30
|
+
storeConfig
|
|
35
31
|
);
|
|
36
32
|
|
|
37
|
-
return
|
|
33
|
+
return UNSAFE_getByType(RN.Text).props.children;
|
|
38
34
|
};
|
|
39
35
|
|
|
40
36
|
describe("RTL app: Hebrew text contains english word", () => {
|
|
@@ -42,28 +38,32 @@ describe("RTL app: Hebrew text contains english word", () => {
|
|
|
42
38
|
const textWithNotFirstEnglishWord = "השיר של נועה נועה קירל באירוויזיון Word";
|
|
43
39
|
const textWithoutEnglishWord = "השיר של נועה נועה קירל באירוויזיון";
|
|
44
40
|
|
|
45
|
-
const
|
|
41
|
+
const storeConfig = {
|
|
46
42
|
remoteConfigurations: { localizations: { he: {} } },
|
|
47
43
|
appData: {
|
|
48
44
|
languageCode: "he",
|
|
49
45
|
countryCode: "IL",
|
|
50
46
|
},
|
|
51
|
-
}
|
|
47
|
+
};
|
|
52
48
|
|
|
53
49
|
it("Hebrew text contains first english word", () => {
|
|
54
|
-
const renderedText = getRenderedText(textWithFirstEnglishWord,
|
|
50
|
+
const renderedText = getRenderedText(textWithFirstEnglishWord, storeConfig);
|
|
55
51
|
const desiredText = "\u200fWord\u202c השיר של נועה נועה קירל באירוויזיון";
|
|
56
52
|
|
|
57
53
|
expect(renderedText).toEqual(desiredText);
|
|
58
54
|
});
|
|
59
55
|
|
|
60
56
|
it("Hebrew text contains not first english word", () => {
|
|
61
|
-
const renderedText = getRenderedText(
|
|
57
|
+
const renderedText = getRenderedText(
|
|
58
|
+
textWithNotFirstEnglishWord,
|
|
59
|
+
storeConfig
|
|
60
|
+
);
|
|
61
|
+
|
|
62
62
|
expect(renderedText).toEqual(textWithNotFirstEnglishWord);
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
it("Hebrew text doesn't contain english word", () => {
|
|
66
|
-
const renderedText = getRenderedText(textWithoutEnglishWord,
|
|
66
|
+
const renderedText = getRenderedText(textWithoutEnglishWord, storeConfig);
|
|
67
67
|
expect(renderedText).toEqual(textWithoutEnglishWord);
|
|
68
68
|
});
|
|
69
69
|
});
|
|
@@ -77,16 +77,16 @@ describe("LTR app: English text", () => {
|
|
|
77
77
|
|
|
78
78
|
const englishText = "Test sentence";
|
|
79
79
|
|
|
80
|
-
const
|
|
80
|
+
const storeConfig = {
|
|
81
81
|
remoteConfigurations: { localizations: { en: {} } },
|
|
82
82
|
appData: {
|
|
83
83
|
languageCode: "en",
|
|
84
84
|
countryCode: "US",
|
|
85
85
|
},
|
|
86
|
-
}
|
|
86
|
+
};
|
|
87
87
|
|
|
88
88
|
it("English text", () => {
|
|
89
|
-
const renderedText = getRenderedText(englishText,
|
|
89
|
+
const renderedText = getRenderedText(englishText, storeConfig);
|
|
90
90
|
expect(renderedText).toEqual(englishText);
|
|
91
91
|
});
|
|
92
92
|
});
|
|
@@ -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
|
});
|
|
@@ -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
|
|
89
|
+
[state, item, entryIsSelected] // Assuming that item won't mutate
|
|
90
90
|
);
|
|
91
91
|
|
|
92
92
|
const wrapperRef = React.useRef(null);
|
|
@@ -1,28 +1,58 @@
|
|
|
1
1
|
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
|
|
2
|
-
import { StorageSingleValueProvider } from "@applicaster/zapp-react-native-
|
|
2
|
+
import { StorageSingleValueProvider } from "@applicaster/zapp-react-native-utils/storage/StorageSingleSelectProvider";
|
|
3
3
|
import { PushTopicManager } from "@applicaster/zapp-react-native-bridge/PushNotifications/PushTopicManager";
|
|
4
|
-
import { StorageMultiSelectProvider } from "@applicaster/zapp-react-native-
|
|
4
|
+
import { StorageMultiSelectProvider } from "@applicaster/zapp-react-native-utils/storage/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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
+
import { useScreenStateStore } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useScreenStateStore";
|
|
14
|
+
|
|
15
|
+
const parseContextKey = (
|
|
16
|
+
key: string,
|
|
17
|
+
context: string = "ctx"
|
|
18
|
+
): string | null => {
|
|
19
|
+
if (!key?.startsWith(`@{${context}/`)) return null;
|
|
20
|
+
|
|
21
|
+
return key.substring(`@{${context}/`.length, key.length - 1);
|
|
15
22
|
};
|
|
16
23
|
|
|
17
24
|
const getDataSourceProvider = (
|
|
18
|
-
behavior: Behavior
|
|
25
|
+
behavior: Behavior,
|
|
26
|
+
screenRoute: string,
|
|
27
|
+
screenStateStore: ReturnType<typeof useScreenStateStore>
|
|
19
28
|
): BehaviorSubject<string[] | string> | null => {
|
|
20
29
|
if (!behavior) return null;
|
|
21
30
|
|
|
22
31
|
const selection = String(behavior.current_selection);
|
|
32
|
+
const screenKey = parseContextKey(selection, "screen");
|
|
33
|
+
|
|
34
|
+
if (screenKey) {
|
|
35
|
+
if (behavior.select_mode === "multi") {
|
|
36
|
+
return ScreenMultiSelectProvider.getProvider(
|
|
37
|
+
screenKey,
|
|
38
|
+
screenRoute,
|
|
39
|
+
screenStateStore
|
|
40
|
+
).getObservable();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (behavior.select_mode === "single") {
|
|
44
|
+
return ScreenSingleValueProvider.getProvider(
|
|
45
|
+
screenKey,
|
|
46
|
+
screenRoute,
|
|
47
|
+
screenStateStore
|
|
48
|
+
).getObservable();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
23
52
|
const contextKey = parseContextKey(selection);
|
|
24
53
|
|
|
25
54
|
if (contextKey) {
|
|
55
|
+
// TODO: Add storage scope to behavior
|
|
26
56
|
if (behavior.select_mode === "multi") {
|
|
27
57
|
return StorageMultiSelectProvider.getProvider(contextKey).getObservable();
|
|
28
58
|
}
|
|
@@ -41,6 +71,8 @@ const getDataSourceProvider = (
|
|
|
41
71
|
|
|
42
72
|
export const useBehaviorUpdate = (behavior: Behavior) => {
|
|
43
73
|
const [lastUpdate, setLastUpdate] = React.useState<number | null>(null);
|
|
74
|
+
const screenRoute = useRoute()?.pathname || "";
|
|
75
|
+
const screenStateStore = useScreenStateStore();
|
|
44
76
|
const player = usePlayer();
|
|
45
77
|
|
|
46
78
|
const triggerUpdate = () => setLastUpdate(Date.now());
|
|
@@ -48,7 +80,11 @@ export const useBehaviorUpdate = (behavior: Behavior) => {
|
|
|
48
80
|
useEffect(() => {
|
|
49
81
|
if (!behavior) return;
|
|
50
82
|
|
|
51
|
-
const dataSource = getDataSourceProvider(
|
|
83
|
+
const dataSource = getDataSourceProvider(
|
|
84
|
+
behavior,
|
|
85
|
+
screenRoute,
|
|
86
|
+
screenStateStore
|
|
87
|
+
);
|
|
52
88
|
|
|
53
89
|
if (dataSource) {
|
|
54
90
|
const subscription = dataSource.subscribe(triggerUpdate);
|
|
@@ -72,10 +108,17 @@ export const useBehaviorUpdate = (behavior: Behavior) => {
|
|
|
72
108
|
|
|
73
109
|
// We cant use async in this function (its inside render),
|
|
74
110
|
// so we rely on useBehaviorUpdate to update current value and trigger re-render
|
|
75
|
-
export const isCellSelected = (
|
|
76
|
-
item
|
|
77
|
-
|
|
78
|
-
|
|
111
|
+
export const isCellSelected = ({
|
|
112
|
+
item,
|
|
113
|
+
screenRoute,
|
|
114
|
+
screenStateStore,
|
|
115
|
+
behavior,
|
|
116
|
+
}: {
|
|
117
|
+
item: ZappEntry;
|
|
118
|
+
screenRoute: string;
|
|
119
|
+
screenStateStore: ReturnType<typeof useScreenStateStore>;
|
|
120
|
+
behavior?: Behavior;
|
|
121
|
+
}): boolean => {
|
|
79
122
|
if (!behavior) return false;
|
|
80
123
|
|
|
81
124
|
const id = behavior.selector ? get(item, behavior.selector) : item.id;
|
|
@@ -99,7 +142,32 @@ export const isCellSelected = (
|
|
|
99
142
|
}
|
|
100
143
|
|
|
101
144
|
const selection = String(behavior.current_selection);
|
|
102
|
-
|
|
145
|
+
|
|
146
|
+
const screenKey = parseContextKey(selection, "screen");
|
|
147
|
+
|
|
148
|
+
if (screenKey) {
|
|
149
|
+
if (behavior.select_mode === "single") {
|
|
150
|
+
const selectedItem = ScreenSingleValueProvider.getProvider(
|
|
151
|
+
screenKey,
|
|
152
|
+
screenRoute,
|
|
153
|
+
screenStateStore
|
|
154
|
+
).getValue();
|
|
155
|
+
|
|
156
|
+
return selectedItem === String(id);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (behavior.select_mode === "multi") {
|
|
160
|
+
const selectedItems = ScreenMultiSelectProvider.getProvider(
|
|
161
|
+
screenKey,
|
|
162
|
+
screenRoute,
|
|
163
|
+
screenStateStore
|
|
164
|
+
).getSelectedItems();
|
|
165
|
+
|
|
166
|
+
return selectedItems?.includes(String(id));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const contextKey = parseContextKey(selection, "ctx");
|
|
103
171
|
|
|
104
172
|
if (contextKey) {
|
|
105
173
|
if (behavior.select_mode === "single") {
|
|
@@ -8,6 +8,8 @@ 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
|
+
import { useScreenStateStore } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useScreenStateStore";
|
|
11
13
|
|
|
12
14
|
const hasElementSpecificViewType = (viewType) => (element) => {
|
|
13
15
|
if (R.isNil(element)) {
|
|
@@ -190,10 +192,6 @@ export const getFocusedButtonId = (focusable) => {
|
|
|
190
192
|
});
|
|
191
193
|
};
|
|
192
194
|
|
|
193
|
-
export const isSelected = (item: ZappEntry, behavior?: Behavior) => {
|
|
194
|
-
return isCellSelected(item, behavior);
|
|
195
|
-
};
|
|
196
|
-
|
|
197
195
|
export const useCellState = ({
|
|
198
196
|
item,
|
|
199
197
|
behavior,
|
|
@@ -204,9 +202,17 @@ export const useCellState = ({
|
|
|
204
202
|
focused: boolean;
|
|
205
203
|
}): CellState => {
|
|
206
204
|
const lastUpdate = useBehaviorUpdate(behavior);
|
|
205
|
+
const router = useRoute();
|
|
206
|
+
const screenStateStore = useScreenStateStore();
|
|
207
207
|
|
|
208
208
|
const _isSelected = useMemo(
|
|
209
|
-
() =>
|
|
209
|
+
() =>
|
|
210
|
+
isCellSelected({
|
|
211
|
+
item,
|
|
212
|
+
screenRoute: router?.pathname,
|
|
213
|
+
screenStateStore,
|
|
214
|
+
behavior,
|
|
215
|
+
}),
|
|
210
216
|
[behavior, item, lastUpdate]
|
|
211
217
|
);
|
|
212
218
|
|
|
@@ -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
|
|
5
|
-
|
|
6
|
-
|
|
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 =
|
|
44
|
-
<NotificationView online dismiss={dismiss} />
|
|
45
|
-
);
|
|
40
|
+
const component = render(<NotificationView online dismiss={dismiss} />);
|
|
46
41
|
|
|
47
|
-
expect(component.
|
|
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 =
|
|
46
|
+
const component = render(
|
|
52
47
|
<NotificationView online={false} dismiss={dismiss} />
|
|
53
48
|
);
|
|
54
49
|
|
|
55
|
-
expect(component.
|
|
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 =
|
|
54
|
+
const component = render(
|
|
60
55
|
<NotificationView online={false} hidden={false} dismiss={dismiss} />
|
|
61
56
|
);
|
|
62
57
|
|
|
63
|
-
component.
|
|
58
|
+
component.rerender(
|
|
64
59
|
<NotificationView online={false} hidden={true} dismiss={dismiss} />
|
|
65
60
|
);
|
|
66
61
|
|
|
67
|
-
const animatedView = component.
|
|
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}
|
|
@@ -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
|
|
|
@@ -19,29 +18,27 @@ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/utils", () => {
|
|
|
19
18
|
};
|
|
20
19
|
});
|
|
21
20
|
|
|
22
|
-
jest.mock(
|
|
23
|
-
"@applicaster/zapp-react-native-redux/hooks
|
|
24
|
-
() => ({
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}),
|
|
39
|
-
},
|
|
21
|
+
jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
|
|
22
|
+
...jest.requireActual("@applicaster/zapp-react-native-redux/hooks"),
|
|
23
|
+
usePickFromState: () => ({
|
|
24
|
+
plugins: [
|
|
25
|
+
{
|
|
26
|
+
name: "offline experience",
|
|
27
|
+
identifier: "offline-experience",
|
|
28
|
+
type: "general",
|
|
29
|
+
module: {
|
|
30
|
+
useOfflineExperienceConfiguration: () => ({
|
|
31
|
+
configurationFields: {},
|
|
32
|
+
localizations: {
|
|
33
|
+
offline_toast_message: "No internet connection",
|
|
34
|
+
online_toast_message: "You are back online",
|
|
35
|
+
},
|
|
36
|
+
}),
|
|
40
37
|
},
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
})
|
|
44
|
-
);
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
}),
|
|
41
|
+
}));
|
|
45
42
|
|
|
46
43
|
jest.mock("react-native-safe-area-context", () => ({
|
|
47
44
|
useSafeAreaInsets: () => ({ top: 44 }),
|
|
@@ -51,24 +48,18 @@ describe("OfflineHandler", () => {
|
|
|
51
48
|
const { OfflineHandler, NotificationView } = require("../");
|
|
52
49
|
|
|
53
50
|
it("renders", () => {
|
|
54
|
-
const
|
|
55
|
-
expect(
|
|
51
|
+
const { toJSON } = render(<OfflineHandler />);
|
|
52
|
+
expect(toJSON()).toMatchSnapshot();
|
|
56
53
|
});
|
|
57
54
|
|
|
58
55
|
it("renders Notification mode if component was rendered while online", () => {
|
|
59
56
|
mockConnectionStatus = true;
|
|
60
57
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
act(() => {
|
|
64
|
-
instance = renderer.create(<OfflineHandler />);
|
|
65
|
-
});
|
|
58
|
+
const { rerender, UNSAFE_getByType } = render(<OfflineHandler />);
|
|
66
59
|
|
|
67
|
-
|
|
68
|
-
instance.update(<OfflineHandler />);
|
|
69
|
-
});
|
|
60
|
+
rerender(<OfflineHandler />);
|
|
70
61
|
|
|
71
|
-
const notificationsView =
|
|
62
|
+
const notificationsView = UNSAFE_getByType(NotificationView);
|
|
72
63
|
expect(notificationsView).toBeDefined();
|
|
73
64
|
});
|
|
74
65
|
});
|