@applicaster/zapp-react-native-ui-components 14.0.0-alpha.4517121861 → 14.0.0-alpha.4520122433
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/mobile/Layout.tsx +1 -1
- package/Components/AudioPlayer/tv/helpers.tsx +10 -3
- 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 +1 -1
- 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/index.android.tsx +8 -4
- 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 +17 -10
- 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/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 +45 -29
- package/Components/PlayerContainer/ProgramInfo/index.tsx +1 -1
- package/Components/PlayerContainer/index.ts +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/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/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/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/River/__tests__/__snapshots__/river.test.js.snap +0 -27
- package/Components/VideoModal/hooks/useBackgroundColor.ts +0 -10
|
@@ -4,7 +4,7 @@ import { FocusableiOS } from "./FocusableiOS";
|
|
|
4
4
|
|
|
5
5
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
6
6
|
|
|
7
|
-
export const Focusable = platformSelect({
|
|
7
|
+
export const Focusable: React.ComponentType<any> = platformSelect({
|
|
8
8
|
tvos: FocusableTvOS,
|
|
9
9
|
ios: FocusableiOS,
|
|
10
10
|
default: FocusableDefault,
|
|
@@ -10,7 +10,8 @@ type FocusableItemComponentProps = {
|
|
|
10
10
|
onFocus: (
|
|
11
11
|
element: FocusManager.FocusableRef,
|
|
12
12
|
renderArgs: { item: FocusableItemComponentProps["item"]; index: number },
|
|
13
|
-
|
|
13
|
+
options: FocusManager.Android.CallbackOptions,
|
|
14
|
+
context: Option<FocusManager.FocusContext>
|
|
14
15
|
) => void;
|
|
15
16
|
onListElementFocus?: (any, RenderItemProps, Direction) => void;
|
|
16
17
|
onListElementBlur?: (any, RenderItemProps, Direction) => void;
|
|
@@ -45,8 +46,8 @@ const FocusableItemComponent = ({
|
|
|
45
46
|
const renderArgs = { item, index };
|
|
46
47
|
|
|
47
48
|
const onFocusHandler = React.useCallback(
|
|
48
|
-
(element,
|
|
49
|
-
onFocus?.(element, renderArgs,
|
|
49
|
+
(element, options, context) => {
|
|
50
|
+
onFocus?.(element, renderArgs, options, context);
|
|
50
51
|
},
|
|
51
52
|
[item, onFocus]
|
|
52
53
|
);
|
|
@@ -17,7 +17,8 @@ type Props = {
|
|
|
17
17
|
onFocus: (
|
|
18
18
|
element: FocusManager.FocusableRef,
|
|
19
19
|
renderArgs: { item: Item; index: number },
|
|
20
|
-
|
|
20
|
+
options: FocusManager.Android.CallbackOptions,
|
|
21
|
+
context: FocusManager.FocusContext
|
|
21
22
|
) => void;
|
|
22
23
|
onListElementBlur?: (any, RenderItemProps, Direction) => void;
|
|
23
24
|
onListElementPress?: (any, RenderItemProps) => void;
|
|
@@ -10,15 +10,25 @@ export const useCellState = (id: string) => {
|
|
|
10
10
|
);
|
|
11
11
|
|
|
12
12
|
React.useEffect(() => {
|
|
13
|
-
const
|
|
13
|
+
const focusHandler = (focusable) => {
|
|
14
14
|
const isChildren = focusManager.isFocusableChildOf(focusable, id);
|
|
15
|
+
|
|
15
16
|
setCurrentCellFocused(isChildren);
|
|
16
17
|
};
|
|
17
18
|
|
|
18
|
-
focusManager.on(FOCUS_EVENTS.FOCUS,
|
|
19
|
+
focusManager.on(FOCUS_EVENTS.FOCUS, focusHandler);
|
|
20
|
+
|
|
21
|
+
const resetHandler = ({ focusedId }) => {
|
|
22
|
+
if (id === focusedId) {
|
|
23
|
+
setCurrentCellFocused(false);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
focusManager.on(FOCUS_EVENTS.RESET, resetHandler);
|
|
19
28
|
|
|
20
29
|
return () => {
|
|
21
|
-
focusManager.removeHandler(FOCUS_EVENTS.FOCUS,
|
|
30
|
+
focusManager.removeHandler(FOCUS_EVENTS.FOCUS, focusHandler);
|
|
31
|
+
focusManager.removeHandler(FOCUS_EVENTS.RESET, resetHandler);
|
|
22
32
|
};
|
|
23
33
|
}, [id]);
|
|
24
34
|
|
|
@@ -20,27 +20,34 @@ import { FocusableScrollView } from "../FocusableScrollView";
|
|
|
20
20
|
const mapIndexed = R.addIndex(R.map);
|
|
21
21
|
|
|
22
22
|
export type IListRenderItem<ItemT> = (
|
|
23
|
-
info:
|
|
23
|
+
info: {
|
|
24
24
|
focused: boolean;
|
|
25
25
|
onLoadFinished: () => void;
|
|
26
26
|
onLoadFailed: () => void;
|
|
27
|
-
}
|
|
27
|
+
} & IListRenderItemInfo<ItemT>
|
|
28
28
|
) => React.ReactElement | null;
|
|
29
29
|
|
|
30
30
|
export const getFocusableId = (parentId, index) =>
|
|
31
31
|
`${parentId}___index:${index}`;
|
|
32
32
|
|
|
33
|
+
type Item = ZappEntry | ZappUIComponent | any;
|
|
34
|
+
|
|
33
35
|
export type Props<ItemT> = FlatListProps<ItemT> & {
|
|
34
36
|
id?: number | string;
|
|
35
37
|
horizontal?: boolean;
|
|
36
38
|
loop?: boolean;
|
|
37
39
|
numColumns?: number;
|
|
38
40
|
data: ZappEntry[] | ZappUIComponent[] | any[];
|
|
39
|
-
onListElementFocus?: (
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
onListElementFocus?: (
|
|
42
|
+
element: FocusManager.FocusableRef,
|
|
43
|
+
renderItemProps: { item: Item; index: number },
|
|
44
|
+
options: FocusManager.Android.CallbackOptions,
|
|
45
|
+
context: FocusManager.FocusContext
|
|
46
|
+
) => void;
|
|
47
|
+
onListElementBlur?: (element, renderItemProps, direction) => void;
|
|
48
|
+
onListElementPress?: (element, renderItemProps) => void;
|
|
49
|
+
onListElementPressOut?: (element, renderItemProps) => void;
|
|
50
|
+
onListElementLongPress?: (element, renderItemProps) => void;
|
|
44
51
|
focusableItemProps?: any;
|
|
45
52
|
focused?: boolean;
|
|
46
53
|
initialScrollIndex?: number;
|
|
@@ -91,6 +98,7 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
|
|
|
91
98
|
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
92
99
|
omitPropsPropagation = [],
|
|
93
100
|
useScrollView = false,
|
|
101
|
+
onScrollToIndexFailed = noop,
|
|
94
102
|
} = props;
|
|
95
103
|
|
|
96
104
|
useCheckItemIdsForUnique({ componentId: props.id, items: data });
|
|
@@ -137,11 +145,11 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
|
|
|
137
145
|
);
|
|
138
146
|
|
|
139
147
|
const onFocus = React.useCallback(
|
|
140
|
-
(element, renderArgs,
|
|
148
|
+
(element, renderArgs, options, context) => {
|
|
141
149
|
const { index } = renderArgs;
|
|
142
150
|
|
|
143
151
|
updateFocusedIndex?.(index);
|
|
144
|
-
onListElementFocus?.(element, renderArgs,
|
|
152
|
+
onListElementFocus?.(element, renderArgs, options, context);
|
|
145
153
|
},
|
|
146
154
|
[onListElementFocus, updateFocusedIndex]
|
|
147
155
|
);
|
|
@@ -277,6 +285,7 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
|
|
|
277
285
|
"withStateMemory",
|
|
278
286
|
"useSequentialLoading",
|
|
279
287
|
"useScrollView",
|
|
288
|
+
"onScrollToIndexFailed",
|
|
280
289
|
...omitPropsPropagation,
|
|
281
290
|
],
|
|
282
291
|
R.__
|
|
@@ -305,6 +314,7 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
|
|
|
305
314
|
{...getFlatListProps(props)}
|
|
306
315
|
onEndReached={onEndReached}
|
|
307
316
|
initialNumToRender={initialNumToRender}
|
|
317
|
+
onScrollToIndexFailed={onScrollToIndexFailed}
|
|
308
318
|
renderItem={renderItem}
|
|
309
319
|
focused={focused}
|
|
310
320
|
data={data}
|
|
@@ -319,6 +329,7 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
|
|
|
319
329
|
renderItem={renderItem}
|
|
320
330
|
onEndReached={onEndReached}
|
|
321
331
|
initialNumToRender={initialNumToRender}
|
|
332
|
+
onScrollToIndexFailed={onScrollToIndexFailed}
|
|
322
333
|
/>
|
|
323
334
|
)}
|
|
324
335
|
</ChildrenFocusDeactivatorView>
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import React, { Dispatch, useEffect, useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
create,
|
|
5
|
-
ReactTestRenderer,
|
|
6
|
-
ReactTestRendererJSON,
|
|
7
|
-
} from "react-test-renderer";
|
|
2
|
+
import { act, render } from "@testing-library/react-native";
|
|
3
|
+
import { View } from "react-native";
|
|
8
4
|
import { FreezeWithCallback } from "../index";
|
|
9
5
|
|
|
10
|
-
const SimpleContent = () => <
|
|
6
|
+
const SimpleContent = () => <View testID="simple-content" />;
|
|
11
7
|
|
|
12
8
|
interface InnerProps {
|
|
13
9
|
value: number;
|
|
14
10
|
}
|
|
11
|
+
|
|
15
12
|
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
16
|
-
const Inner = ({ value }: InnerProps) =>
|
|
13
|
+
const Inner = ({ value }: InnerProps) => (
|
|
14
|
+
<View testID="inner-component" data-value={value} />
|
|
15
|
+
);
|
|
17
16
|
|
|
18
17
|
interface TestSubscriber {
|
|
19
18
|
renderCount: number;
|
|
@@ -51,24 +50,20 @@ const Container = ({ freeze, children }: ContainerProps) => (
|
|
|
51
50
|
);
|
|
52
51
|
|
|
53
52
|
function setupTest(initialFreeze: boolean = false) {
|
|
54
|
-
let testRenderer: ReactTestRenderer | undefined;
|
|
55
53
|
const [Subscriber, subscriberState] = createSubscriberComponent();
|
|
56
54
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
<
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
);
|
|
63
|
-
});
|
|
55
|
+
const renderResult = render(
|
|
56
|
+
<Container freeze={initialFreeze}>
|
|
57
|
+
<Subscriber />
|
|
58
|
+
</Container>
|
|
59
|
+
);
|
|
64
60
|
|
|
65
61
|
return {
|
|
66
|
-
|
|
67
|
-
testInstance: testRenderer?.root,
|
|
62
|
+
renderResult,
|
|
68
63
|
subscriberState,
|
|
69
64
|
updateFreeze: (freeze: boolean) => {
|
|
70
65
|
act(() =>
|
|
71
|
-
|
|
66
|
+
renderResult.rerender(
|
|
72
67
|
<Container freeze={freeze}>
|
|
73
68
|
<Subscriber />
|
|
74
69
|
</Container>
|
|
@@ -80,91 +75,120 @@ function setupTest(initialFreeze: boolean = false) {
|
|
|
80
75
|
|
|
81
76
|
describe("FreezeWithCallback", () => {
|
|
82
77
|
test("Renders stuff not frozen", () => {
|
|
83
|
-
const
|
|
78
|
+
const { getByTestId } = render(
|
|
84
79
|
<Container freeze={false}>
|
|
85
80
|
<SimpleContent />
|
|
86
81
|
</Container>
|
|
87
82
|
);
|
|
88
83
|
|
|
89
|
-
expect(
|
|
84
|
+
expect(getByTestId("simple-content")).toBeTruthy();
|
|
90
85
|
});
|
|
91
86
|
|
|
92
87
|
test("Does not render stuff when frozen", () => {
|
|
93
|
-
const
|
|
88
|
+
const { queryByTestId } = render(
|
|
94
89
|
<Container freeze>
|
|
95
90
|
<SimpleContent />
|
|
96
91
|
</Container>
|
|
97
92
|
);
|
|
98
93
|
|
|
99
|
-
expect(
|
|
94
|
+
expect(queryByTestId("simple-content")).toBe(null);
|
|
100
95
|
});
|
|
101
96
|
|
|
102
97
|
test("Stuff is gone after freeze", () => {
|
|
103
|
-
const
|
|
98
|
+
const { toJSON, getByTestId, rerender } = render(
|
|
104
99
|
<Container freeze={false}>
|
|
105
100
|
<SimpleContent />
|
|
106
101
|
</Container>
|
|
107
102
|
);
|
|
108
103
|
|
|
109
|
-
expect(
|
|
104
|
+
expect(getByTestId("simple-content")).toBeTruthy();
|
|
110
105
|
|
|
111
106
|
act(() =>
|
|
112
|
-
|
|
107
|
+
rerender(
|
|
113
108
|
<Container freeze>
|
|
114
109
|
<SimpleContent />
|
|
115
110
|
</Container>
|
|
116
111
|
)
|
|
117
112
|
);
|
|
118
113
|
|
|
119
|
-
expect(
|
|
114
|
+
expect(toJSON()).toBe(null);
|
|
120
115
|
});
|
|
121
116
|
|
|
122
117
|
test("Updates work when not frozen", () => {
|
|
123
|
-
const {
|
|
118
|
+
const { renderResult, subscriberState } = setupTest();
|
|
119
|
+
|
|
120
|
+
expect(
|
|
121
|
+
renderResult.getByTestId("inner-component").props["data-value"]
|
|
122
|
+
).toEqual(0);
|
|
124
123
|
|
|
125
|
-
expect(testInstance?.findByType(Inner).props.value).toEqual(0);
|
|
126
124
|
act(() => subscriberState.subscription(1));
|
|
127
|
-
|
|
125
|
+
|
|
126
|
+
expect(
|
|
127
|
+
renderResult.getByTestId("inner-component").props["data-value"]
|
|
128
|
+
).toEqual(1);
|
|
129
|
+
|
|
128
130
|
expect(subscriberState.renderCount).toBe(2);
|
|
129
131
|
});
|
|
130
132
|
|
|
131
133
|
test("Updates does not propagate when frozen", () => {
|
|
132
|
-
const {
|
|
134
|
+
const { renderResult, subscriberState, updateFreeze } = setupTest();
|
|
135
|
+
|
|
136
|
+
expect(
|
|
137
|
+
renderResult.getByTestId("inner-component").props["data-value"]
|
|
138
|
+
).toEqual(0);
|
|
133
139
|
|
|
134
|
-
expect(testInstance?.findByType(Inner).props.value).toEqual(0);
|
|
135
140
|
updateFreeze(true);
|
|
136
141
|
act(() => subscriberState.subscription(1));
|
|
137
|
-
|
|
142
|
+
|
|
143
|
+
expect(
|
|
144
|
+
renderResult.getByTestId("inner-component").props["data-value"]
|
|
145
|
+
).toEqual(0);
|
|
146
|
+
|
|
138
147
|
expect(subscriberState.renderCount).toBe(1);
|
|
139
148
|
});
|
|
140
149
|
|
|
141
150
|
test("State persists after defrost", () => {
|
|
142
|
-
const {
|
|
143
|
-
|
|
151
|
+
const { renderResult, subscriberState, updateFreeze } = setupTest();
|
|
152
|
+
|
|
153
|
+
expect(
|
|
154
|
+
renderResult.getByTestId("inner-component").props["data-value"]
|
|
155
|
+
).toEqual(0);
|
|
144
156
|
|
|
145
|
-
expect(testInstance?.findByType(Inner).props.value).toEqual(0);
|
|
146
157
|
act(() => subscriberState.subscription(1));
|
|
147
|
-
|
|
158
|
+
|
|
159
|
+
expect(
|
|
160
|
+
renderResult.getByTestId("inner-component").props["data-value"]
|
|
161
|
+
).toEqual(1);
|
|
148
162
|
|
|
149
163
|
updateFreeze(true);
|
|
150
|
-
expect(
|
|
164
|
+
expect(renderResult.toJSON()).toBe(null);
|
|
151
165
|
|
|
152
166
|
updateFreeze(false);
|
|
153
|
-
expect((
|
|
154
|
-
|
|
167
|
+
expect(renderResult.getByTestId("inner-component")).toBeTruthy();
|
|
168
|
+
|
|
169
|
+
expect(
|
|
170
|
+
renderResult.getByTestId("inner-component").props["data-value"]
|
|
171
|
+
).toEqual(1);
|
|
155
172
|
});
|
|
156
173
|
|
|
157
174
|
test("Update propagate after defrost", () => {
|
|
158
|
-
const {
|
|
175
|
+
const { renderResult, subscriberState, updateFreeze } = setupTest();
|
|
159
176
|
|
|
160
177
|
updateFreeze(true);
|
|
161
178
|
act(() => subscriberState.subscription(1));
|
|
162
179
|
act(() => subscriberState.subscription(2));
|
|
163
180
|
act(() => subscriberState.subscription(3));
|
|
164
|
-
|
|
181
|
+
|
|
182
|
+
expect(
|
|
183
|
+
renderResult.getByTestId("inner-component").props["data-value"]
|
|
184
|
+
).toEqual(0);
|
|
165
185
|
|
|
166
186
|
updateFreeze(false);
|
|
167
|
-
|
|
187
|
+
|
|
188
|
+
expect(
|
|
189
|
+
renderResult.getByTestId("inner-component").props["data-value"]
|
|
190
|
+
).toEqual(3);
|
|
191
|
+
|
|
168
192
|
expect(subscriberState.renderCount).toBe(2);
|
|
169
193
|
});
|
|
170
194
|
});
|
|
@@ -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 {
|
|
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
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
{
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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,16 @@
|
|
|
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 {
|
|
7
6
|
useLayoutPresets,
|
|
8
|
-
|
|
9
|
-
} from "@applicaster/zapp-react-native-redux
|
|
10
|
-
import { loadPipesData } from "@applicaster/zapp-react-native-redux/ZappPipes";
|
|
7
|
+
useZappPipesFeed,
|
|
8
|
+
} from "@applicaster/zapp-react-native-redux";
|
|
11
9
|
import { isEmptyOrNil } from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
12
10
|
import { Categories } from "./logger";
|
|
13
11
|
import { createLogger } from "@applicaster/zapp-react-native-utils/logger";
|
|
14
12
|
import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useRoute";
|
|
13
|
+
|
|
15
14
|
import {
|
|
16
15
|
ZappPipesEntryContext,
|
|
17
16
|
ZappPipesScreenContext,
|
|
@@ -24,9 +23,13 @@ import {
|
|
|
24
23
|
} from "@applicaster/zapp-react-native-utils/reactHooks/feed/useInflatedUrl";
|
|
25
24
|
|
|
26
25
|
import { produce } from "immer";
|
|
26
|
+
import { useLoadPipesDataDispatch } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
27
27
|
// types reference
|
|
28
28
|
|
|
29
|
-
declare
|
|
29
|
+
declare interface CurationEntry {
|
|
30
|
+
preset_name: string;
|
|
31
|
+
feed_url: string;
|
|
32
|
+
}
|
|
30
33
|
|
|
31
34
|
type Feeds = Record<string, ZappPipesData>;
|
|
32
35
|
|
|
@@ -122,8 +125,6 @@ export const getFinalComponents = (
|
|
|
122
125
|
export const useCurationAPI = (
|
|
123
126
|
components: Array<ZappUIComponent>
|
|
124
127
|
): ZappUIComponent[] => {
|
|
125
|
-
const dispatch = useDispatch();
|
|
126
|
-
|
|
127
128
|
const smartComponents = useMemo(
|
|
128
129
|
() => components?.filter?.(isSmartComponent) ?? [],
|
|
129
130
|
[components]
|
|
@@ -159,19 +160,21 @@ export const useCurationAPI = (
|
|
|
159
160
|
|
|
160
161
|
const urls = useMemo<string[]>(() => Object.values(urlsMap), [urlsMap]);
|
|
161
162
|
|
|
163
|
+
const loadPipesDataDispatcher = useLoadPipesDataDispatch();
|
|
164
|
+
|
|
162
165
|
useEffect(() => {
|
|
163
166
|
urls.forEach((url, index) => {
|
|
164
167
|
if (url) {
|
|
165
|
-
|
|
168
|
+
loadPipesDataDispatcher(url, { clearCache: false });
|
|
166
169
|
} else {
|
|
167
170
|
logger.log_error("Curation url is empty", {
|
|
168
171
|
componentId: smartComponents?.[index]?.id,
|
|
169
172
|
});
|
|
170
173
|
}
|
|
171
174
|
});
|
|
172
|
-
}, [urls]);
|
|
175
|
+
}, [urls, loadPipesDataDispatcher]);
|
|
173
176
|
|
|
174
|
-
const feeds =
|
|
177
|
+
const feeds = useZappPipesFeed(urls);
|
|
175
178
|
const layoutPresets = useLayoutPresets();
|
|
176
179
|
|
|
177
180
|
const enrichedComponents = useMemo(() => {
|
|
@@ -6,14 +6,15 @@ import {
|
|
|
6
6
|
} from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
7
7
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
8
8
|
import {
|
|
9
|
-
isTablet,
|
|
10
9
|
useDimensions,
|
|
10
|
+
useIsTablet as isTablet,
|
|
11
11
|
useNavigation,
|
|
12
12
|
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
13
13
|
|
|
14
14
|
import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
|
|
15
15
|
import { PlayerContainer } from "../PlayerContainer";
|
|
16
16
|
import { useModalSize } from "../VideoModal/hooks";
|
|
17
|
+
import { ViewStyle } from "react-native";
|
|
17
18
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
18
19
|
|
|
19
20
|
type Props = {
|
|
@@ -88,7 +89,8 @@ type PlayableComponent = {
|
|
|
88
89
|
const dimensionsContext: "window" | "screen" = platformSelect({
|
|
89
90
|
android_tv: "window",
|
|
90
91
|
amazon: "window",
|
|
91
|
-
|
|
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
|
|
92
94
|
});
|
|
93
95
|
|
|
94
96
|
export function HandlePlayable({
|
|
@@ -149,14 +151,19 @@ export function HandlePlayable({
|
|
|
149
151
|
const modalSize = useModalSize();
|
|
150
152
|
|
|
151
153
|
const style = React.useMemo(
|
|
152
|
-
() =>
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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,
|
|
160
167
|
[screenWidth, screenHeight, modalSize, isModal, mode]
|
|
161
168
|
);
|
|
162
169
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks
|
|
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
|
|
|
@@ -7,7 +7,6 @@ import { NavigationContext } from "@applicaster/zapp-react-native-ui-components/
|
|
|
7
7
|
import configureStore from "redux-mock-store";
|
|
8
8
|
import Layout from "../index.web";
|
|
9
9
|
|
|
10
|
-
// mock useTheme to provide app_background_color
|
|
11
10
|
jest.mock("@applicaster/zapp-react-native-utils/theme", () => ({
|
|
12
11
|
useTheme: () => ({
|
|
13
12
|
app_background_color: "#000000",
|