@applicaster/zapp-react-native-ui-components 15.1.0-rc.8 → 16.0.0-alpha.1833861900
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/BackgroundImage/BackgroundImage.tsx +42 -0
- package/Components/BackgroundImage/BackgroundImage.tv.android.tsx +28 -0
- package/Components/BackgroundImage/BackgroundImage.tv.ios.tsx +24 -0
- package/Components/BackgroundImage/index.ts +1 -0
- package/Components/BaseFocusable/index.ios.ts +12 -2
- package/Components/Cell/FocusableWrapper.tsx +3 -0
- package/Components/Cell/TvOSCellComponent.tsx +6 -3
- package/Components/CellRendererResolver/index.ts +1 -1
- package/Components/ComponentResolver/__tests__/componentResolver.test.js +1 -1
- package/Components/Focusable/Focusable.tsx +4 -2
- package/Components/Focusable/FocusableTvOS.tsx +18 -1
- package/Components/Focusable/__tests__/__snapshots__/FocusableTvOS.test.tsx.snap +1 -0
- package/Components/FocusableGroup/FocusableTvOS.tsx +41 -8
- package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +1 -1
- package/Components/HandlePlayable/HandlePlayable.tsx +13 -8
- package/Components/Layout/TV/NavBarContainer.tsx +1 -10
- package/Components/Layout/TV/ScreenContainer.tsx +2 -6
- package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +7 -12
- package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +7 -12
- package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +0 -1
- package/Components/Layout/TV/index.tsx +5 -7
- package/Components/Layout/TV/index.web.tsx +5 -7
- package/Components/LinkHandler/LinkHandler.tsx +2 -2
- package/Components/MasterCell/CONFIG_BUILDER_TO_REACT_COMPONENT.md +144 -0
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +16 -5
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/model.test.ts +80 -0
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/placement.test.ts +187 -0
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/selectors.test.ts +45 -0
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/style.test.ts +49 -0
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/ActionButtonController.tsx +165 -0
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/__tests__/ActionButtonController.test.tsx +405 -0
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/index.ts +1 -0
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/model.ts +47 -0
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/placement.ts +170 -0
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/selectors.ts +26 -0
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/style.ts +29 -0
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/types.ts +37 -0
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +4 -10
- package/Components/MasterCell/DefaultComponents/Button.tsx +0 -15
- package/Components/MasterCell/DefaultComponents/ButtonContainerView/components/HorizontalSeparator.tsx +8 -0
- package/Components/MasterCell/DefaultComponents/ButtonContainerView/index.tsx +15 -0
- package/Components/MasterCell/DefaultComponents/ButtonContainerView/index.tv.android.tsx +58 -0
- package/Components/MasterCell/DefaultComponents/{tv/ButtonContainerView/index.tsx → ButtonContainerView/index.tv.tsx} +3 -11
- package/Components/MasterCell/DefaultComponents/ButtonContainerView/index.web.ts +1 -0
- package/Components/MasterCell/DefaultComponents/ButtonContainerView/types.ts +40 -0
- package/Components/MasterCell/DefaultComponents/DataProvider/index.tsx +163 -0
- package/Components/MasterCell/DefaultComponents/FocusableView/index.android.tsx +2 -23
- package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -22
- package/Components/MasterCell/DefaultComponents/Image/Image.android.tsx +8 -2
- package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +11 -3
- package/Components/MasterCell/DefaultComponents/Image/Image.web.tsx +9 -1
- package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +15 -14
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +1 -2
- package/Components/MasterCell/DefaultComponents/PressableView.tsx +34 -0
- package/Components/MasterCell/DefaultComponents/SecondaryImage/hooks/__tests__/useGetImageDimensions.test.ts +7 -6
- package/Components/MasterCell/DefaultComponents/Text/hooks/useText.ts +11 -0
- package/Components/MasterCell/DefaultComponents/__tests__/DataProvider.test.tsx +141 -0
- package/Components/MasterCell/DefaultComponents/index.ts +9 -3
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/ActionButton.tsx +135 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Asset.ts +33 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/AssetComponent.tsx +22 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Button.ts +125 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Spacer.ts +16 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabel.ts +67 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabelsContainer.ts +37 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/PressableView.test.tsx +393 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/builders.test.ts +141 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/index.test.ts +343 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/helpers.ts +105 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/index.ts +122 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/__tests__/insertButtons.test.ts +118 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/index.ts +238 -0
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/Asset.ts +4 -18
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/Button.ts +24 -73
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/TextLabelsContainer.ts +37 -18
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/TvActionButton.tsx +27 -0
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/__tests__/index.test.ts +89 -0
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/__tests__/renderedTree.test.tsx +231 -0
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +47 -48
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/getPluginIdentifier.test.ts +115 -29
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +101 -144
- package/Components/MasterCell/MappingFunctions/index.js +3 -2
- package/Components/MasterCell/README.md +4 -0
- package/Components/MasterCell/__tests__/__snapshots__/dataAdapter.test.js.snap +24 -0
- package/Components/MasterCell/__tests__/configInflater.test.js +1 -0
- package/Components/MasterCell/__tests__/elementMapper.test.js +46 -0
- package/Components/MasterCell/dataAdapter.ts +4 -1
- package/Components/MasterCell/elementMapper.tsx +52 -7
- package/Components/MasterCell/utils/__tests__/cloneChildrenWithIds.test.tsx +43 -0
- package/Components/MasterCell/utils/__tests__/useFilterChildren.test.tsx +80 -0
- package/Components/MasterCell/utils/index.ts +85 -15
- package/Components/OfflineHandler/NotificationView/NotificationView.tsx +2 -2
- package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +17 -18
- package/Components/OfflineHandler/__tests__/index.test.tsx +27 -18
- package/Components/PlayerContainer/PlayerContainer.tsx +15 -14
- package/Components/PlayerContainer/__tests__/PlayerContainer.test.tsx +284 -0
- package/Components/River/ComponentsMap/ComponentsMap.tsx +6 -19
- package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +1 -1
- package/Components/River/RefreshControl.tsx +19 -88
- package/Components/River/River.tsx +9 -82
- package/Components/River/TV/River.tsx +31 -14
- package/Components/River/TV/index.tsx +8 -4
- package/Components/River/TV/utils/__tests__/toStringOrEmpty.test.ts +30 -0
- package/Components/River/TV/utils/index.ts +4 -0
- package/Components/River/TV/withFocusableGroupForContent.tsx +71 -0
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +1 -0
- package/Components/River/__tests__/componentsMap.test.js +38 -0
- package/Components/River/hooks/__tests__/usePullToRefresh.test.ts +132 -0
- package/Components/River/hooks/index.ts +1 -0
- package/Components/River/hooks/usePullToRefresh.ts +51 -0
- package/Components/Screen/TV/index.web.tsx +4 -2
- package/Components/Screen/__tests__/Screen.test.tsx +65 -42
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +68 -44
- package/Components/Screen/hooks.ts +2 -3
- package/Components/Screen/index.tsx +2 -3
- package/Components/Screen/orientationHandler.ts +3 -3
- package/Components/ScreenResolver/index.tsx +9 -5
- package/Components/ScreenRevealManager/Overlay.tsx +34 -0
- package/Components/ScreenRevealManager/ScreenRevealManager.ts +40 -8
- package/Components/ScreenRevealManager/__tests__/Overlay.test.tsx +88 -0
- package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +86 -69
- package/Components/ScreenRevealManager/withScreenRevealManager.tsx +9 -20
- package/Components/Tabs/TabContent.tsx +7 -4
- package/Components/TopCutoffOverlay/__tests__/TopCutoffOverlay.test.tsx +201 -0
- package/Components/TopCutoffOverlay/hooks/__tests__/useMarginTop.test.ts +130 -0
- package/Components/TopCutoffOverlay/hooks/index.ts +1 -0
- package/Components/TopCutoffOverlay/hooks/useMarginTop.ts +59 -0
- package/Components/TopCutoffOverlay/index.tsx +55 -0
- package/Components/Transitioner/index.js +3 -3
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +5 -5
- package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +15 -7
- package/Components/VideoModal/utils.ts +18 -10
- package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +0 -2
- package/Components/Viewport/ViewportAware/index.tsx +16 -7
- package/Components/Viewport/ViewportEvents/__tests__/viewportEvents.test.js +1 -1
- package/Components/ZappFrameworkComponents/BarView/BarView.tsx +4 -6
- package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +2 -2
- package/Components/default-cell-renderer/viewTrees/mobile/index.ts +0 -3
- package/Contexts/ScreenContext/index.tsx +25 -18
- package/Contexts/ScreenTrackedViewPositionsContext/__tests__/index.test.tsx +1 -1
- package/Decorators/Analytics/index.tsx +6 -5
- package/Decorators/ConfigurationWrapper/__tests__/__snapshots__/withConfigurationProvider.test.tsx.snap +1 -0
- package/Decorators/ConfigurationWrapper/const.ts +1 -0
- package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +39 -21
- package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +1 -1
- package/Decorators/ZappPipesDataConnector/index.tsx +2 -2
- package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +1 -1
- package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +18 -7
- package/Helpers/DataSourceHelper/__tests__/itemLimitForData.test.ts +80 -0
- package/Helpers/DataSourceHelper/index.ts +19 -0
- package/Helpers/index.js +7 -1
- package/package.json +5 -5
- package/Components/Layout/TV/LayoutBackground.tsx +0 -28
- package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.android.tsx +0 -135
- package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/types.ts +0 -25
- package/Components/River/TV/withTVEventHandler.tsx +0 -36
- package/Helpers/DataSourceHelper/index.js +0 -19
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { DataProvider } from "../../DefaultComponents/DataProvider";
|
|
4
|
+
import { cloneChildrenWithIds } from "..";
|
|
5
|
+
|
|
6
|
+
const Probe = () => null;
|
|
7
|
+
|
|
8
|
+
describe("cloneChildrenWithIds", () => {
|
|
9
|
+
it("injects next focus props into plain children", () => {
|
|
10
|
+
const children = [
|
|
11
|
+
<Probe key="one" />,
|
|
12
|
+
<Probe key="two" />,
|
|
13
|
+
<Probe key="three" />,
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const result = cloneChildrenWithIds(["id-1", "id-2", "id-3"], children);
|
|
17
|
+
|
|
18
|
+
expect(result[0].props.nextFocusLeft).toBeUndefined();
|
|
19
|
+
expect(result[0].props.nextFocusRight).toBe("id-2");
|
|
20
|
+
expect(result[1].props.nextFocusLeft).toBe("id-1");
|
|
21
|
+
expect(result[1].props.nextFocusRight).toBe("id-3");
|
|
22
|
+
expect(result[2].props.nextFocusLeft).toBe("id-2");
|
|
23
|
+
expect(result[2].props.nextFocusRight).toBeUndefined();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("injects next focus props into DataProvider-wrapped children", () => {
|
|
27
|
+
const children = [
|
|
28
|
+
<DataProvider key="one" entry={{ id: "entry-1" }}>
|
|
29
|
+
<Probe suffixId="button_1" />
|
|
30
|
+
</DataProvider>,
|
|
31
|
+
<DataProvider key="two" entry={{ id: "entry-2" }}>
|
|
32
|
+
<Probe suffixId="button_2" />
|
|
33
|
+
</DataProvider>,
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
const result = cloneChildrenWithIds(["id-1", "id-2"], children);
|
|
37
|
+
|
|
38
|
+
expect(result[0].props.children.props.nextFocusLeft).toBeUndefined();
|
|
39
|
+
expect(result[0].props.children.props.nextFocusRight).toBe("id-2");
|
|
40
|
+
expect(result[1].props.children.props.nextFocusLeft).toBe("id-1");
|
|
41
|
+
expect(result[1].props.children.props.nextFocusRight).toBeUndefined();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { renderHook } from "@testing-library/react-native";
|
|
3
|
+
import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
|
|
4
|
+
|
|
5
|
+
import { DataProvider } from "../../DefaultComponents/DataProvider";
|
|
6
|
+
import { useFilterChildren } from "..";
|
|
7
|
+
|
|
8
|
+
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/actions", () => ({
|
|
9
|
+
useActions: jest.fn(),
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
const mockUseActions = useActions as jest.Mock;
|
|
13
|
+
const Probe = () => null;
|
|
14
|
+
|
|
15
|
+
describe("useFilterChildren", () => {
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
jest.clearAllMocks();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("filters DataProvider-wrapped button children using the wrapped button props", () => {
|
|
21
|
+
const available = jest.fn(() => true);
|
|
22
|
+
const unavailable = jest.fn(() => false);
|
|
23
|
+
|
|
24
|
+
mockUseActions.mockReturnValue({
|
|
25
|
+
actions: {
|
|
26
|
+
available_action: {
|
|
27
|
+
module: {
|
|
28
|
+
context: {
|
|
29
|
+
_currentValue: {
|
|
30
|
+
isActionAvailable: available,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
unavailable_action: {
|
|
36
|
+
module: {
|
|
37
|
+
context: {
|
|
38
|
+
_currentValue: {
|
|
39
|
+
isActionAvailable: unavailable,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const availableItem = { id: "entry-1" };
|
|
48
|
+
const unavailableItem = { id: "entry-2" };
|
|
49
|
+
|
|
50
|
+
const children = [
|
|
51
|
+
<DataProvider key="available" entry={availableItem}>
|
|
52
|
+
<Probe
|
|
53
|
+
entry={availableItem}
|
|
54
|
+
pluginIdentifier="available_action"
|
|
55
|
+
suffixId="button_1"
|
|
56
|
+
cellUUID="cell-1"
|
|
57
|
+
/>
|
|
58
|
+
</DataProvider>,
|
|
59
|
+
<DataProvider key="unavailable" entry={unavailableItem}>
|
|
60
|
+
<Probe
|
|
61
|
+
entry={unavailableItem}
|
|
62
|
+
pluginIdentifier="unavailable_action"
|
|
63
|
+
suffixId="button_2"
|
|
64
|
+
cellUUID="cell-1"
|
|
65
|
+
/>
|
|
66
|
+
</DataProvider>,
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
const { result } = renderHook(() => useFilterChildren(children));
|
|
70
|
+
|
|
71
|
+
expect(result.current).toHaveLength(1);
|
|
72
|
+
|
|
73
|
+
expect(result.current[0].props.children.props.pluginIdentifier).toBe(
|
|
74
|
+
"available_action"
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
expect(available).toHaveBeenCalledWith(availableItem);
|
|
78
|
+
expect(unavailable).toHaveBeenCalledWith(unavailableItem);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -13,6 +13,7 @@ import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
|
13
13
|
import { useScreenStateStore } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useScreenStateStore";
|
|
14
14
|
import memoizee from "memoizee";
|
|
15
15
|
import stringify from "fast-json-stable-stringify";
|
|
16
|
+
import { DataProvider } from "../DefaultComponents/DataProvider";
|
|
16
17
|
|
|
17
18
|
const hasElementSpecificViewType = (viewType) => (element) => {
|
|
18
19
|
if (R.isNil(element)) {
|
|
@@ -126,10 +127,50 @@ export function isVideoPreviewEnabled({
|
|
|
126
127
|
return enable_video_preview && !R.isEmpty(player_screen_id);
|
|
127
128
|
}
|
|
128
129
|
|
|
130
|
+
export const unwrapDataProviderChild = (
|
|
131
|
+
child: React.ReactElement
|
|
132
|
+
): React.ReactElement => {
|
|
133
|
+
if ((child as any)?.type !== DataProvider) {
|
|
134
|
+
return child;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const [wrappedChild] = React.Children.toArray((child as any).props.children);
|
|
138
|
+
|
|
139
|
+
return (
|
|
140
|
+
React.isValidElement(wrappedChild) ? wrappedChild : child
|
|
141
|
+
) as React.ReactElement;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Resolves the entry value passed by DataProvider.
|
|
146
|
+
* Prefer the direct `entry` prop and fall back to `dataProviderProps[_dataKey]`
|
|
147
|
+
* for older wrappers that still read from namespaced provider props.
|
|
148
|
+
*/
|
|
149
|
+
const getEntryFromProps = (props: {
|
|
150
|
+
dataProviderProps?: {
|
|
151
|
+
_dataKey: string;
|
|
152
|
+
[key: string]: unknown;
|
|
153
|
+
};
|
|
154
|
+
entry?: any;
|
|
155
|
+
}) => {
|
|
156
|
+
const dataProviderProps = props.dataProviderProps;
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
props.entry ??
|
|
160
|
+
(dataProviderProps?._dataKey
|
|
161
|
+
? dataProviderProps[dataProviderProps._dataKey]
|
|
162
|
+
: undefined)
|
|
163
|
+
);
|
|
164
|
+
};
|
|
165
|
+
|
|
129
166
|
export const useFilterChildren = <
|
|
130
167
|
T extends {
|
|
131
168
|
props: {
|
|
132
|
-
|
|
169
|
+
dataProviderProps?: {
|
|
170
|
+
_dataKey: string;
|
|
171
|
+
[key: string]: unknown;
|
|
172
|
+
};
|
|
173
|
+
entry?: any;
|
|
133
174
|
pluginIdentifier: string;
|
|
134
175
|
};
|
|
135
176
|
},
|
|
@@ -139,8 +180,13 @@ export const useFilterChildren = <
|
|
|
139
180
|
const actions = useActions("");
|
|
140
181
|
|
|
141
182
|
const filteredChildren = children.filter((child) => {
|
|
142
|
-
const
|
|
143
|
-
|
|
183
|
+
const wrappedChild = unwrapDataProviderChild(
|
|
184
|
+
child as unknown as React.ReactElement
|
|
185
|
+
) as unknown as T;
|
|
186
|
+
|
|
187
|
+
const item = getEntryFromProps(wrappedChild.props);
|
|
188
|
+
|
|
189
|
+
const actionIdentifier = wrappedChild.props.pluginIdentifier;
|
|
144
190
|
const action = actions.actions[actionIdentifier];
|
|
145
191
|
|
|
146
192
|
// context value of specific plugin
|
|
@@ -154,7 +200,7 @@ export const useFilterChildren = <
|
|
|
154
200
|
|
|
155
201
|
masterCellLogger.error({
|
|
156
202
|
message: `Action plugin for ${actionIdentifier} could not be found, check the configuration of your action button`,
|
|
157
|
-
data: { item, action:
|
|
203
|
+
data: { item, action: wrappedChild.props.pluginIdentifier },
|
|
158
204
|
});
|
|
159
205
|
|
|
160
206
|
return false;
|
|
@@ -202,17 +248,42 @@ export const recursiveCloneElementsWithState = (focused: boolean, children) => {
|
|
|
202
248
|
const next = (currentIndex, items) => items[currentIndex + 1];
|
|
203
249
|
const previous = (currentIndex, items) => items[currentIndex - 1];
|
|
204
250
|
|
|
205
|
-
export const
|
|
251
|
+
export const cloneChildrenWithIds = (
|
|
252
|
+
ids: string[],
|
|
253
|
+
children: React.ReactElement[]
|
|
254
|
+
) => {
|
|
206
255
|
if (R.isNil(children) || R.isEmpty(children)) {
|
|
207
256
|
return undefined;
|
|
208
257
|
}
|
|
209
258
|
|
|
210
|
-
return React.Children.map(children, (element, index) =>
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
259
|
+
return React.Children.map(children, (element, index) => {
|
|
260
|
+
const nextFocusLeft = previous(index, ids);
|
|
261
|
+
const nextFocusRight = next(index, ids);
|
|
262
|
+
|
|
263
|
+
if (element?.type !== DataProvider) {
|
|
264
|
+
return React.cloneElement(element, {
|
|
265
|
+
nextFocusLeft,
|
|
266
|
+
nextFocusRight,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const wrappedChild = unwrapDataProviderChild(element) as React.ReactElement<
|
|
271
|
+
Record<string, unknown>
|
|
272
|
+
>;
|
|
273
|
+
|
|
274
|
+
if (!React.isValidElement(wrappedChild)) {
|
|
275
|
+
return element;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const injectedWrappedChild = React.cloneElement(wrappedChild, {
|
|
279
|
+
nextFocusLeft,
|
|
280
|
+
nextFocusRight,
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
return React.cloneElement(element, {
|
|
284
|
+
children: injectedWrappedChild,
|
|
285
|
+
});
|
|
286
|
+
});
|
|
216
287
|
};
|
|
217
288
|
|
|
218
289
|
export const getFocusedButtonId = (focusable) => {
|
|
@@ -252,10 +323,9 @@ export const useCellState = ({
|
|
|
252
323
|
export const hasFocusableInsideBuilder = (elementsBuilder) => (item) => {
|
|
253
324
|
const elements = elementsBuilder({ entry: item });
|
|
254
325
|
|
|
255
|
-
return R.anyPass([
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
])(elements);
|
|
326
|
+
return R.anyPass([hasElementsSpecificViewType("ButtonContainerView")])(
|
|
327
|
+
elements
|
|
328
|
+
);
|
|
259
329
|
};
|
|
260
330
|
|
|
261
331
|
export function getEntryState(state, selected) {
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
TouchableWithoutFeedback,
|
|
9
9
|
} from "react-native";
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { usePlugins } from "@applicaster/zapp-react-native-redux";
|
|
12
12
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
13
13
|
import { textTransform } from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
14
14
|
import { useNotificationHeight } from "../utils";
|
|
@@ -46,7 +46,7 @@ export const NotificationView = ({
|
|
|
46
46
|
online = true,
|
|
47
47
|
dismiss,
|
|
48
48
|
}: Props) => {
|
|
49
|
-
const
|
|
49
|
+
const plugins = usePlugins();
|
|
50
50
|
const { statusHeight, notificationHeight } = useNotificationHeight();
|
|
51
51
|
|
|
52
52
|
const offlinePlugin = R.find(
|
|
@@ -8,25 +8,24 @@ import {
|
|
|
8
8
|
offlinePhrase,
|
|
9
9
|
} from "../NotificationView";
|
|
10
10
|
|
|
11
|
-
jest.mock("@applicaster/zapp-react-native-redux
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
},
|
|
11
|
+
jest.mock("@applicaster/zapp-react-native-redux", () => ({
|
|
12
|
+
...jest.requireActual("@applicaster/zapp-react-native-redux"),
|
|
13
|
+
usePlugins: () => [
|
|
14
|
+
{
|
|
15
|
+
name: "offline experience",
|
|
16
|
+
identifier: "offline-experience",
|
|
17
|
+
type: "general",
|
|
18
|
+
module: {
|
|
19
|
+
useOfflineExperienceConfiguration: () => ({
|
|
20
|
+
configurationFields: {},
|
|
21
|
+
localizations: {
|
|
22
|
+
offline_toast_message: "No internet connection",
|
|
23
|
+
online_toast_message: "You are back online",
|
|
24
|
+
},
|
|
25
|
+
}),
|
|
27
26
|
},
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
},
|
|
28
|
+
],
|
|
30
29
|
}));
|
|
31
30
|
|
|
32
31
|
jest.mock("react-native-safe-area-context", () => ({
|
|
@@ -8,36 +8,45 @@ const mockPreviousValue = null;
|
|
|
8
8
|
|
|
9
9
|
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/connection", () => {
|
|
10
10
|
return {
|
|
11
|
+
...jest.requireActual(
|
|
12
|
+
"@applicaster/zapp-react-native-utils/reactHooks/connection"
|
|
13
|
+
),
|
|
11
14
|
useConnectionInfo: jest.fn(() => mockConnectionStatus),
|
|
12
15
|
};
|
|
13
16
|
});
|
|
14
17
|
|
|
15
18
|
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/utils", () => {
|
|
16
19
|
return {
|
|
20
|
+
...jest.requireActual(
|
|
21
|
+
"@applicaster/zapp-react-native-utils/reactHooks/utils"
|
|
22
|
+
),
|
|
17
23
|
usePrevious: jest.fn(() => mockPreviousValue),
|
|
18
24
|
};
|
|
19
25
|
});
|
|
20
26
|
|
|
27
|
+
const mock_storeObj = {
|
|
28
|
+
plugins: [
|
|
29
|
+
{
|
|
30
|
+
name: "offline experience",
|
|
31
|
+
identifier: "offline-experience",
|
|
32
|
+
type: "general",
|
|
33
|
+
module: {
|
|
34
|
+
useOfflineExperienceConfiguration: () => ({
|
|
35
|
+
configurationFields: {},
|
|
36
|
+
localizations: {
|
|
37
|
+
offline_toast_message: "No internet connection",
|
|
38
|
+
online_toast_message: "You are back online",
|
|
39
|
+
},
|
|
40
|
+
}),
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
};
|
|
45
|
+
|
|
21
46
|
jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
|
|
22
47
|
...jest.requireActual("@applicaster/zapp-react-native-redux/hooks"),
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
}),
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
],
|
|
40
|
-
}),
|
|
48
|
+
usePlugins: () => mock_storeObj.plugins,
|
|
49
|
+
usePickFromState: () => ({}),
|
|
41
50
|
}));
|
|
42
51
|
|
|
43
52
|
jest.mock("react-native-safe-area-context", () => ({
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
|
|
18
18
|
import { TVEventHandlerComponent } from "@applicaster/zapp-react-native-tvos-ui-components/Components/TVEventHandlerComponent";
|
|
19
19
|
import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
import {
|
|
22
22
|
useBackHandler,
|
|
23
23
|
useNavigation,
|
|
@@ -59,6 +59,7 @@ import {
|
|
|
59
59
|
PlayerNativeCommandTypes,
|
|
60
60
|
PlayerNativeSendCommand,
|
|
61
61
|
} from "@applicaster/zapp-react-native-utils/appUtils/playerManager/playerNativeCommand";
|
|
62
|
+
import { useAppData } from "@applicaster/zapp-react-native-redux";
|
|
62
63
|
|
|
63
64
|
type Props = {
|
|
64
65
|
Player: React.ComponentType<any>;
|
|
@@ -237,7 +238,7 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
237
238
|
const [isLoadingNextVideo, setIsLoadingNextVideo] = React.useState(false);
|
|
238
239
|
|
|
239
240
|
const navigator = useNavigation();
|
|
240
|
-
const {
|
|
241
|
+
const { isTabletPortrait } = useAppData();
|
|
241
242
|
const prevItemId = usePrevious(item?.id);
|
|
242
243
|
const screenData = useTargetScreenData(item);
|
|
243
244
|
const { setVisible: showNavBar } = useSetNavbarState();
|
|
@@ -262,9 +263,14 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
262
263
|
|
|
263
264
|
showNavBar(true);
|
|
264
265
|
navigator.goBack();
|
|
265
|
-
}, [isModal,
|
|
266
|
+
}, [isModal, state.playerId, showNavBar, navigator]);
|
|
267
|
+
|
|
268
|
+
const pluginConfiguration = React.useMemo(
|
|
269
|
+
() => player?.getPluginConfiguration(),
|
|
270
|
+
[player]
|
|
271
|
+
);
|
|
266
272
|
|
|
267
|
-
const playEntry = (entry) => navigator.replaceTop(entry, { mode });
|
|
273
|
+
const playEntry = (entry: ZappEntry) => navigator.replaceTop(entry, { mode });
|
|
268
274
|
|
|
269
275
|
const onPlayNextPerformNextVideoPlay = React.useCallback(() => {
|
|
270
276
|
if (!playNextOverlayState.entry) {
|
|
@@ -448,13 +454,6 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
448
454
|
}
|
|
449
455
|
}, []);
|
|
450
456
|
|
|
451
|
-
const pluginConfiguration = React.useMemo(() => {
|
|
452
|
-
return (
|
|
453
|
-
playerManager.getPluginConfiguration() ||
|
|
454
|
-
R.prop("__plugin_configuration", Player)
|
|
455
|
-
);
|
|
456
|
-
}, [playerManager.isRegistered()]);
|
|
457
|
-
|
|
458
457
|
const disableMiniPlayer = React.useMemo(() => {
|
|
459
458
|
return pluginConfiguration?.disable_mini_player_when_inline;
|
|
460
459
|
}, [pluginConfiguration]);
|
|
@@ -467,6 +466,8 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
467
466
|
if (isModal && mode === VideoModalMode.MAXIMIZED) {
|
|
468
467
|
if (disableMiniPlayer) {
|
|
469
468
|
navigator.closeVideoModal();
|
|
469
|
+
} else {
|
|
470
|
+
navigator.minimiseVideoModal();
|
|
470
471
|
}
|
|
471
472
|
}
|
|
472
473
|
|
|
@@ -654,7 +655,7 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
654
655
|
<PlayerFocusableWrapperView
|
|
655
656
|
nextFocusDown={context.bottomFocusableId}
|
|
656
657
|
>
|
|
657
|
-
{Player ? (
|
|
658
|
+
{!Player ? null : (
|
|
658
659
|
<Player
|
|
659
660
|
source={{
|
|
660
661
|
uri,
|
|
@@ -669,7 +670,7 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
669
670
|
fullscreen={mode === VideoModalMode.FULLSCREEN}
|
|
670
671
|
inline={inline}
|
|
671
672
|
isModal={isModal}
|
|
672
|
-
isTabletPortrait={
|
|
673
|
+
isTabletPortrait={isTabletPortrait}
|
|
673
674
|
muted={false}
|
|
674
675
|
playableItem={item}
|
|
675
676
|
playerEvent={playerEvent}
|
|
@@ -685,7 +686,7 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
685
686
|
>
|
|
686
687
|
{renderApplePlayer(applePlayerProps)}
|
|
687
688
|
</Player>
|
|
688
|
-
)
|
|
689
|
+
)}
|
|
689
690
|
</PlayerFocusableWrapperView>
|
|
690
691
|
</View>
|
|
691
692
|
{/* Components container */}
|