@applicaster/zapp-react-native-ui-components 14.0.0-rc.9 → 14.0.0-rc.90
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 +68 -23
- 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/FocusableWrapper.tsx +44 -0
- package/Components/Cell/TvOSCellComponent.tsx +92 -17
- 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 +22 -21
- package/Components/HandlePlayable/HandlePlayable.tsx +39 -74
- package/Components/HandlePlayable/const.ts +3 -0
- package/Components/HandlePlayable/utils.ts +74 -0
- 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 +45 -47
- package/Components/PlayerContainer/ProgramInfo/index.tsx +1 -1
- package/Components/PlayerContainer/index.ts +1 -1
- package/Components/PlayerImageBackground/index.tsx +4 -23
- package/Components/River/ComponentsMap/ComponentsMap.tsx +49 -43
- package/Components/River/ComponentsMap/ContextProviders/ComponentsMapHeightContext.ts +8 -0
- package/Components/River/ComponentsMap/ContextProviders/ComponentsMapRefContext.ts +8 -0
- package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +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/TV/hooks/useInitialFocus.ts +14 -4
- package/Components/Screen/__tests__/Screen.test.tsx +28 -29
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +2 -0
- package/Components/Screen/__tests__/navigationHandler.test.ts +133 -22
- package/Components/Screen/index.tsx +22 -5
- package/Components/Screen/navigationHandler.ts +20 -2
- package/Components/ScreenRevealManager/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/utils/index.ts +23 -0
- package/Components/ScreenRevealManager/withScreenRevealManager.tsx +109 -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/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +1 -0
- package/Components/VideoLive/animationUtils.ts +3 -3
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +120 -133
- package/Components/VideoModal/ModalAnimation/index.ts +2 -13
- package/Components/VideoModal/ModalAnimation/utils.ts +1 -327
- package/Components/VideoModal/PlayerDetails.tsx +29 -7
- package/Components/VideoModal/PlayerWrapper.tsx +25 -215
- package/Components/VideoModal/VideoModal.tsx +4 -22
- package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +5 -5
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +2 -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 +23 -2
- package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +2 -2
- package/Components/VideoModal/hooks/utils/index.ts +4 -0
- package/Components/VideoModal/playerWrapperStyle.ts +70 -0
- package/Components/VideoModal/playerWrapperUtils.ts +91 -0
- package/Components/VideoModal/utils.ts +13 -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/getDatasourceUrl.ts +6 -10
- 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/ModalAnimation/AnimatedPlayerModalWrapper.tsx +0 -60
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +0 -421
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +0 -176
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +0 -500
- package/Components/VideoModal/ModalAnimation/__tests__/getMoveUpValue.test.ts +0 -108
- 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
|
@@ -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]
|
|
@@ -141,17 +142,15 @@ export const useCurationAPI = (
|
|
|
141
142
|
const url = path(SOURCE_PATH, component);
|
|
142
143
|
const mapping = path(MAPPING_PATH, component);
|
|
143
144
|
|
|
144
|
-
map[component.id] =
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
})
|
|
154
|
-
: url;
|
|
145
|
+
map[component.id] = getInflatedDataSourceUrl({
|
|
146
|
+
source: url,
|
|
147
|
+
contexts: {
|
|
148
|
+
entry: entryContext,
|
|
149
|
+
screen: screenContext,
|
|
150
|
+
search: getSearchContext(searchContext, mapping),
|
|
151
|
+
},
|
|
152
|
+
mapping,
|
|
153
|
+
});
|
|
155
154
|
});
|
|
156
155
|
|
|
157
156
|
return map;
|
|
@@ -159,19 +158,21 @@ export const useCurationAPI = (
|
|
|
159
158
|
|
|
160
159
|
const urls = useMemo<string[]>(() => Object.values(urlsMap), [urlsMap]);
|
|
161
160
|
|
|
161
|
+
const loadPipesDataDispatcher = useLoadPipesDataDispatch();
|
|
162
|
+
|
|
162
163
|
useEffect(() => {
|
|
163
164
|
urls.forEach((url, index) => {
|
|
164
165
|
if (url) {
|
|
165
|
-
|
|
166
|
+
loadPipesDataDispatcher(url, { clearCache: false });
|
|
166
167
|
} else {
|
|
167
168
|
logger.log_error("Curation url is empty", {
|
|
168
169
|
componentId: smartComponents?.[index]?.id,
|
|
169
170
|
});
|
|
170
171
|
}
|
|
171
172
|
});
|
|
172
|
-
}, [urls]);
|
|
173
|
+
}, [urls, loadPipesDataDispatcher]);
|
|
173
174
|
|
|
174
|
-
const feeds =
|
|
175
|
+
const feeds = useZappPipesFeed(urls);
|
|
175
176
|
const layoutPresets = useLayoutPresets();
|
|
176
177
|
|
|
177
178
|
const enrichedComponents = useMemo(() => {
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import * as R from "ramda";
|
|
3
|
-
import {
|
|
4
|
-
findPluginByType,
|
|
5
|
-
findPluginByIdentifier,
|
|
6
|
-
} from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
7
2
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
8
3
|
import {
|
|
9
4
|
useDimensions,
|
|
5
|
+
useIsTablet as isTablet,
|
|
10
6
|
useNavigation,
|
|
11
7
|
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
12
8
|
|
|
13
9
|
import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
|
|
14
10
|
import { PlayerContainer } from "../PlayerContainer";
|
|
15
11
|
import { useModalSize } from "../VideoModal/hooks";
|
|
12
|
+
import { ViewStyle } from "react-native";
|
|
13
|
+
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
14
|
+
import { findCastPlugin, getPlayer } from "./utils";
|
|
16
15
|
|
|
17
16
|
type Props = {
|
|
18
17
|
item: ZappEntry;
|
|
@@ -23,80 +22,40 @@ type Props = {
|
|
|
23
22
|
groupId?: string;
|
|
24
23
|
};
|
|
25
24
|
|
|
26
|
-
const YOUTUBE_PLUGIN_ID = "youtube-player-qb";
|
|
27
|
-
const CHROMECAST_PLUGIN_ID = "chromecast_qb";
|
|
28
|
-
|
|
29
|
-
const getPlayerWithModuleProperties = (
|
|
30
|
-
PlayerModule: ZappPlugin
|
|
31
|
-
): [ZappPlugin, PlayerModuleProperties] => {
|
|
32
|
-
const getPlayerModuleProperties = R.ifElse(
|
|
33
|
-
R.is(Object) && R.has("Component"),
|
|
34
|
-
R.omit(["Component"]),
|
|
35
|
-
() => ({})
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
return [
|
|
39
|
-
PlayerModule?.Component || PlayerModule,
|
|
40
|
-
getPlayerModuleProperties(PlayerModule),
|
|
41
|
-
];
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const getPlayer = (
|
|
45
|
-
item: ZappEntry,
|
|
46
|
-
state
|
|
47
|
-
): [ZappPlugin, PlayerModuleProperties] => {
|
|
48
|
-
const {
|
|
49
|
-
plugins,
|
|
50
|
-
contentTypes,
|
|
51
|
-
rivers,
|
|
52
|
-
appData: { layoutVersion },
|
|
53
|
-
} = state;
|
|
54
|
-
|
|
55
|
-
let PlayerModule;
|
|
56
|
-
|
|
57
|
-
if (layoutVersion === "v2") {
|
|
58
|
-
const { screen_id } = contentTypes?.[item?.type?.value] || {};
|
|
59
|
-
const { type } = rivers?.[screen_id] || {};
|
|
60
|
-
|
|
61
|
-
if (type) {
|
|
62
|
-
PlayerModule = findPluginByIdentifier(type, plugins)?.module;
|
|
63
|
-
|
|
64
|
-
return getPlayerWithModuleProperties(PlayerModule);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (item?.content?.type === "youtube-id") {
|
|
69
|
-
PlayerModule = findPluginByIdentifier(YOUTUBE_PLUGIN_ID, plugins)?.module;
|
|
70
|
-
|
|
71
|
-
return getPlayerWithModuleProperties(PlayerModule);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
PlayerModule = findPluginByType(
|
|
75
|
-
"playable",
|
|
76
|
-
plugins.filter(({ identifier }) => identifier !== YOUTUBE_PLUGIN_ID)
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
return getPlayerWithModuleProperties(PlayerModule);
|
|
80
|
-
};
|
|
81
|
-
|
|
82
25
|
type PlayableComponent = {
|
|
83
26
|
Component: React.ComponentType<any>;
|
|
84
27
|
};
|
|
85
28
|
|
|
29
|
+
const dimensionsContext: "window" | "screen" = platformSelect({
|
|
30
|
+
android_tv: "window",
|
|
31
|
+
amazon: "window",
|
|
32
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
33
|
+
default: isTablet() ? "window" : "screen", // on tablet, window represents correct values, on phone it's not as the screen could be rotated
|
|
34
|
+
});
|
|
35
|
+
|
|
86
36
|
export function HandlePlayable({
|
|
87
37
|
item,
|
|
88
38
|
isModal,
|
|
89
39
|
mode,
|
|
90
40
|
groupId,
|
|
91
41
|
}: Props): React.ReactElement | null {
|
|
92
|
-
const
|
|
42
|
+
const { plugins, contentTypes, rivers, appData } = usePickFromState([
|
|
43
|
+
"plugins",
|
|
44
|
+
"contentTypes",
|
|
45
|
+
"rivers",
|
|
46
|
+
"appData",
|
|
47
|
+
]);
|
|
93
48
|
|
|
94
49
|
const { closeVideoModal } = useNavigation();
|
|
95
50
|
|
|
96
|
-
const [Player, playerModuleProperties] = getPlayer(item,
|
|
51
|
+
const [Player, playerModuleProperties] = getPlayer(item, {
|
|
52
|
+
plugins,
|
|
53
|
+
contentTypes,
|
|
54
|
+
rivers,
|
|
55
|
+
appData,
|
|
56
|
+
});
|
|
97
57
|
|
|
98
|
-
const { module: CastPlugin } =
|
|
99
|
-
findPluginByIdentifier(CHROMECAST_PLUGIN_ID, state.plugins, true) || {};
|
|
58
|
+
const { module: CastPlugin } = findCastPlugin(plugins);
|
|
100
59
|
|
|
101
60
|
const [playable, setPlayable] =
|
|
102
61
|
React.useState<Nullable<PlayableComponent>>(null);
|
|
@@ -135,19 +94,25 @@ export function HandlePlayable({
|
|
|
135
94
|
});
|
|
136
95
|
}, [casting]);
|
|
137
96
|
|
|
138
|
-
const { width: screenWidth, height: screenHeight } =
|
|
97
|
+
const { width: screenWidth, height: screenHeight } =
|
|
98
|
+
useDimensions(dimensionsContext);
|
|
139
99
|
|
|
140
100
|
const modalSize = useModalSize();
|
|
141
101
|
|
|
142
102
|
const style = React.useMemo(
|
|
143
|
-
() =>
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
103
|
+
() =>
|
|
104
|
+
({
|
|
105
|
+
width: isModal
|
|
106
|
+
? modalSize.width
|
|
107
|
+
: mode === "PIP"
|
|
108
|
+
? "100%"
|
|
109
|
+
: screenWidth,
|
|
110
|
+
height: isModal
|
|
111
|
+
? modalSize.height
|
|
112
|
+
: mode === "PIP"
|
|
113
|
+
? "100%"
|
|
114
|
+
: screenHeight,
|
|
115
|
+
}) as ViewStyle,
|
|
151
116
|
[screenWidth, screenHeight, modalSize, isModal, mode]
|
|
152
117
|
);
|
|
153
118
|
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import {
|
|
2
|
+
findPluginByIdentifier,
|
|
3
|
+
findPluginByType,
|
|
4
|
+
} from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
5
|
+
|
|
6
|
+
import { CHROMECAST_PLUGIN_ID, YOUTUBE_PLUGIN_ID } from "./const";
|
|
7
|
+
import { omit } from "@applicaster/zapp-react-native-utils/utils";
|
|
8
|
+
|
|
9
|
+
const getPlayerModuleProperties = (PlayerModule: ZappPlugin) => {
|
|
10
|
+
if (PlayerModule?.Component && typeof PlayerModule.Component === "object") {
|
|
11
|
+
return omit(["Component"], PlayerModule);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return {};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const getPlayerWithModuleProperties = (
|
|
18
|
+
PlayerModule: ZappPlugin
|
|
19
|
+
): [ZappPlugin, PlayerModuleProperties] => {
|
|
20
|
+
return [
|
|
21
|
+
PlayerModule?.Component || PlayerModule,
|
|
22
|
+
getPlayerModuleProperties(PlayerModule),
|
|
23
|
+
];
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const findCastPlugin = (plugins: ZappPlugin[]) =>
|
|
27
|
+
findPluginByIdentifier(CHROMECAST_PLUGIN_ID, plugins, true) || {};
|
|
28
|
+
|
|
29
|
+
export const findYoutubePlugin = (plugins: ZappPlugin[]) =>
|
|
30
|
+
findPluginByIdentifier(YOUTUBE_PLUGIN_ID, plugins, true) || {};
|
|
31
|
+
|
|
32
|
+
export const getPlayer = (
|
|
33
|
+
item: ZappEntry,
|
|
34
|
+
{
|
|
35
|
+
plugins,
|
|
36
|
+
contentTypes,
|
|
37
|
+
rivers,
|
|
38
|
+
appData: { layoutVersion },
|
|
39
|
+
}: {
|
|
40
|
+
plugins: ZappPlugin[];
|
|
41
|
+
contentTypes: Record<string, any>;
|
|
42
|
+
rivers: Record<string, any>;
|
|
43
|
+
appData: { layoutVersion: string };
|
|
44
|
+
}
|
|
45
|
+
): [ZappPlugin, PlayerModuleProperties] => {
|
|
46
|
+
let PlayerModule;
|
|
47
|
+
|
|
48
|
+
if (layoutVersion === "v2") {
|
|
49
|
+
const screen_id = contentTypes?.[item?.type?.value]?.screen_id;
|
|
50
|
+
const type = rivers?.[screen_id]?.type;
|
|
51
|
+
|
|
52
|
+
if (type) {
|
|
53
|
+
PlayerModule = findPluginByIdentifier(type, plugins)?.module;
|
|
54
|
+
|
|
55
|
+
return getPlayerWithModuleProperties(PlayerModule);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (item?.content?.type === "youtube-id") {
|
|
60
|
+
PlayerModule = findYoutubePlugin(plugins)?.module;
|
|
61
|
+
|
|
62
|
+
return getPlayerWithModuleProperties(PlayerModule);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
PlayerModule = findPluginByType(
|
|
66
|
+
"playable",
|
|
67
|
+
(plugins as any[]).filter(
|
|
68
|
+
({ identifier }: { identifier: string }) =>
|
|
69
|
+
identifier !== YOUTUBE_PLUGIN_ID
|
|
70
|
+
)
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
return getPlayerWithModuleProperties(PlayerModule);
|
|
74
|
+
};
|
|
@@ -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",
|
|
@@ -23,6 +23,7 @@ type Props = {
|
|
|
23
23
|
style: ViewStyle;
|
|
24
24
|
testID?: string;
|
|
25
25
|
accessibilityLabel?: string;
|
|
26
|
+
accessibilityHint?: string;
|
|
26
27
|
cellUUID?: string;
|
|
27
28
|
extraProps?: Record<string, any>;
|
|
28
29
|
};
|
|
@@ -48,7 +49,9 @@ function getAssetValue(asset, flavour, fallbackAsset = null) {
|
|
|
48
49
|
return asset.src || fallbackAsset;
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
export
|
|
52
|
+
export const ActionButton = React.memo(function ActionButtonComponent(
|
|
53
|
+
props: Props
|
|
54
|
+
) {
|
|
52
55
|
const { item, action, asset, flavour = "flavour_1", cellUUID } = props;
|
|
53
56
|
const actionContext = useActions(action?.identifier);
|
|
54
57
|
|
|
@@ -98,6 +101,7 @@ export function ActionButton(props: Props) {
|
|
|
98
101
|
onPress={onPress}
|
|
99
102
|
testID={props?.testID || `${item?.id}`}
|
|
100
103
|
accessibilityLabel={props?.accessibilityLabel || `${item?.id}`}
|
|
104
|
+
accessibilityHint={props?.accessibilityHint}
|
|
101
105
|
accessible={!!(props?.testID || props?.accessibilityLabel)}
|
|
102
106
|
style={props?.style}
|
|
103
107
|
>
|
|
@@ -118,4 +122,4 @@ export function ActionButton(props: Props) {
|
|
|
118
122
|
)}
|
|
119
123
|
</TouchableOpacity>
|
|
120
124
|
);
|
|
121
|
-
}
|
|
125
|
+
});
|
|
@@ -4,7 +4,7 @@ import * as R from "ramda";
|
|
|
4
4
|
import { TouchableOpacity } from "react-native";
|
|
5
5
|
// import { SvgUri } from "react-native-svg";
|
|
6
6
|
|
|
7
|
-
import { connectToStore } from "@applicaster/zapp-react-native-redux";
|
|
7
|
+
import { connectToStore } from "@applicaster/zapp-react-native-redux/utils/connectToStore";
|
|
8
8
|
import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
|
|
9
9
|
|
|
10
10
|
import Image from "./Image";
|
|
@@ -2,10 +2,8 @@ import React, { useMemo } from "react";
|
|
|
2
2
|
import { ImageStyle } from "react-native";
|
|
3
3
|
import { Focusable } from "@applicaster/zapp-react-native-ui-components/Components/Focusable";
|
|
4
4
|
import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
|
|
5
|
-
import * as R from "ramda";
|
|
6
5
|
import { getXray } from "@applicaster/zapp-react-native-utils/logger";
|
|
7
6
|
import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
|
|
8
|
-
import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
|
|
9
7
|
|
|
10
8
|
const { Logger } = getXray();
|
|
11
9
|
|
|
@@ -45,11 +43,6 @@ export function FocusableView({ style, children, item, ...otherProps }: Props) {
|
|
|
45
43
|
|
|
46
44
|
const actionContext = useActions(pluginIdentifier);
|
|
47
45
|
|
|
48
|
-
const accessibilityManager = useAccessibilityManager({});
|
|
49
|
-
|
|
50
|
-
const { ttsLabel = "" } =
|
|
51
|
-
actionContext?.initialEntryState(item)?.getAccessibility?.(item) || {};
|
|
52
|
-
|
|
53
46
|
const onPress = (event) => {
|
|
54
47
|
event?.preventDefault?.();
|
|
55
48
|
|
|
@@ -67,39 +60,11 @@ export function FocusableView({ style, children, item, ...otherProps }: Props) {
|
|
|
67
60
|
const handleFocus = (focusable) => {
|
|
68
61
|
const focusedButtonId = getFocusedButtonId(focusable);
|
|
69
62
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const right = left + width;
|
|
75
|
-
|
|
76
|
-
const boundingRect = {
|
|
77
|
-
x,
|
|
78
|
-
y,
|
|
79
|
-
pageX,
|
|
80
|
-
pageY,
|
|
81
|
-
width,
|
|
82
|
-
height,
|
|
83
|
-
top,
|
|
84
|
-
bottom,
|
|
85
|
-
left,
|
|
86
|
-
right,
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
otherProps?.onToggleFocus?.({
|
|
90
|
-
focusable: {
|
|
91
|
-
getRect: R.always(boundingRect),
|
|
92
|
-
},
|
|
93
|
-
focusedButtonId,
|
|
94
|
-
mouse: focusable.mouse,
|
|
95
|
-
});
|
|
63
|
+
otherProps?.onToggleFocus?.({
|
|
64
|
+
focusable: wrapperRef.current,
|
|
65
|
+
focusedButtonId,
|
|
66
|
+
mouse: focusable.mouse,
|
|
96
67
|
});
|
|
97
|
-
|
|
98
|
-
if (ttsLabel) {
|
|
99
|
-
accessibilityManager.readText({
|
|
100
|
-
text: ttsLabel,
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
68
|
};
|
|
104
69
|
|
|
105
70
|
const handleBlur = (_focusable, _direction) => {
|
|
@@ -20,7 +20,7 @@ const withAppliedDimensions = (style: Style) => (source: Source) => ({
|
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
export const withDimensionsHOC = (Component) => {
|
|
23
|
-
return function WithDimensions(props:
|
|
23
|
+
return function WithDimensions(props: Record<string, unknown>) {
|
|
24
24
|
const theme = useTheme<BaseThemePropertiesMobile>();
|
|
25
25
|
|
|
26
26
|
const useDownScalingImages = toBooleanWithDefaultFalse(
|
|
@@ -13,7 +13,7 @@ export const ImageContainer = (props: Props) => {
|
|
|
13
13
|
const isActive = useIsScreenActive();
|
|
14
14
|
|
|
15
15
|
const Component =
|
|
16
|
-
isVideoPreviewEnabled(props) && isActive ? LiveImage : PureImage;
|
|
16
|
+
isVideoPreviewEnabled(props as Props) && isActive ? LiveImage : PureImage;
|
|
17
17
|
|
|
18
18
|
return <Component {...props} />;
|
|
19
19
|
};
|
|
@@ -28,17 +28,10 @@ interface Props {
|
|
|
28
28
|
onAsyncRender: () => void;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
displayMode,
|
|
36
|
-
imageSizing,
|
|
37
|
-
fitPosition,
|
|
38
|
-
fixedHeight,
|
|
39
|
-
fixedWidth,
|
|
40
|
-
onAsyncRender,
|
|
41
|
-
} = props;
|
|
31
|
+
/** Secondary Image Dynamic does not render until the image is loaded */
|
|
32
|
+
const SecondaryImageDynamic = (props: Props) => {
|
|
33
|
+
const { uri, style, displayMode, imageSizing, fitPosition, onAsyncRender } =
|
|
34
|
+
props;
|
|
42
35
|
|
|
43
36
|
const imageDimension = useGetImageDimensions(
|
|
44
37
|
uri,
|
|
@@ -46,13 +39,9 @@ const SecondaryImageComponent = (props: Props) => {
|
|
|
46
39
|
isImageSizingFit(imageSizing) ? undefined : (style.height as number)
|
|
47
40
|
);
|
|
48
41
|
|
|
49
|
-
const containerHeight =
|
|
50
|
-
? fixedHeight
|
|
51
|
-
: imageDimension?.height;
|
|
42
|
+
const containerHeight = imageDimension?.height;
|
|
52
43
|
|
|
53
|
-
const containerWidth =
|
|
54
|
-
? fixedWidth
|
|
55
|
-
: style?.width;
|
|
44
|
+
const containerWidth = style?.width;
|
|
56
45
|
|
|
57
46
|
if (isNil(imageDimension?.aspectRatio)) {
|
|
58
47
|
return null;
|
|
@@ -80,4 +69,63 @@ const SecondaryImageComponent = (props: Props) => {
|
|
|
80
69
|
);
|
|
81
70
|
};
|
|
82
71
|
|
|
72
|
+
/** Secondary Image Fixed does not render the image until the image is loaded, but keep container rendered */
|
|
73
|
+
const SecondaryImageFixed = (props: Props) => {
|
|
74
|
+
const {
|
|
75
|
+
uri,
|
|
76
|
+
style,
|
|
77
|
+
displayMode,
|
|
78
|
+
imageSizing,
|
|
79
|
+
fitPosition,
|
|
80
|
+
fixedHeight,
|
|
81
|
+
fixedWidth,
|
|
82
|
+
onAsyncRender,
|
|
83
|
+
} = props;
|
|
84
|
+
|
|
85
|
+
const imageDimension = useGetImageDimensions(
|
|
86
|
+
uri,
|
|
87
|
+
style.width as number,
|
|
88
|
+
isImageSizingFit(imageSizing) ? undefined : (style.height as number)
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<View style={style} onLayout={onAsyncRender}>
|
|
93
|
+
{isNil(imageDimension?.aspectRatio) ? null : (
|
|
94
|
+
<Image
|
|
95
|
+
{...props}
|
|
96
|
+
source={{ uri }}
|
|
97
|
+
style={{
|
|
98
|
+
...getStyle({
|
|
99
|
+
imageSizing,
|
|
100
|
+
fitPosition,
|
|
101
|
+
displayMode,
|
|
102
|
+
imageDimension,
|
|
103
|
+
containerHeight: fixedHeight,
|
|
104
|
+
containerWidth: fixedWidth,
|
|
105
|
+
}),
|
|
106
|
+
borderRadius: style.borderRadius,
|
|
107
|
+
aspectRatio: imageDimension.aspectRatio,
|
|
108
|
+
}}
|
|
109
|
+
/>
|
|
110
|
+
)}
|
|
111
|
+
</View>
|
|
112
|
+
);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const SecondaryImageComponent = (props: Props) => {
|
|
116
|
+
const { uri, displayMode } = props;
|
|
117
|
+
|
|
118
|
+
if (!uri) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const isFixed = isDisplayModeFixed(displayMode);
|
|
123
|
+
|
|
124
|
+
return isFixed ? (
|
|
125
|
+
<SecondaryImageFixed {...props} />
|
|
126
|
+
) : (
|
|
127
|
+
<SecondaryImageDynamic {...props} />
|
|
128
|
+
);
|
|
129
|
+
};
|
|
130
|
+
|
|
83
131
|
export const SecondaryImage = withAsyncRenderHOC(SecondaryImageComponent);
|
|
@@ -4,9 +4,26 @@ import { render } from "@testing-library/react-native";
|
|
|
4
4
|
import { SecondaryImage } from "../Image";
|
|
5
5
|
|
|
6
6
|
describe("SecondaryImage - Image", () => {
|
|
7
|
-
it("SecondaryImage should not render if no
|
|
7
|
+
it("SecondaryImage should not render if no uri", async () => {
|
|
8
8
|
const wrapper = await render(
|
|
9
|
-
<SecondaryImage
|
|
9
|
+
<SecondaryImage
|
|
10
|
+
displayMode="dynamic"
|
|
11
|
+
uri={undefined}
|
|
12
|
+
style={{ width: 100 }}
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
expect(wrapper.toJSON()).toEqual(null);
|
|
17
|
+
expect(wrapper.toJSON()).toMatchSnapshot();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("SecondaryImage should not render if no aspect ratio (dynamic)", async () => {
|
|
21
|
+
const wrapper = await render(
|
|
22
|
+
<SecondaryImage
|
|
23
|
+
displayMode="dynamic"
|
|
24
|
+
uri="someurl"
|
|
25
|
+
style={{ width: 100 }}
|
|
26
|
+
/>
|
|
10
27
|
);
|
|
11
28
|
|
|
12
29
|
expect(wrapper.toJSON()).toEqual(null);
|
|
@@ -16,7 +33,8 @@ describe("SecondaryImage - Image", () => {
|
|
|
16
33
|
it("SecondaryImage should render if known dimensions", async () => {
|
|
17
34
|
const wrapper = await render(
|
|
18
35
|
<SecondaryImage
|
|
19
|
-
uri=""
|
|
36
|
+
uri="someUrl"
|
|
37
|
+
displayMode="dynamic"
|
|
20
38
|
style={{ width: 100, height: 100, borderRadius: 10 }}
|
|
21
39
|
/>
|
|
22
40
|
);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
-
exports[`SecondaryImage - Image SecondaryImage should not render if no aspect ratio 1`] = `null`;
|
|
3
|
+
exports[`SecondaryImage - Image SecondaryImage should not render if no aspect ratio (dynamic) 1`] = `null`;
|
|
4
|
+
|
|
5
|
+
exports[`SecondaryImage - Image SecondaryImage should not render if no uri 1`] = `null`;
|
|
4
6
|
|
|
5
7
|
exports[`SecondaryImage - Image SecondaryImage should render if known dimensions 1`] = `
|
|
6
8
|
<View
|
|
@@ -14,10 +16,11 @@ exports[`SecondaryImage - Image SecondaryImage should render if known dimensions
|
|
|
14
16
|
}
|
|
15
17
|
>
|
|
16
18
|
<Image
|
|
19
|
+
displayMode="dynamic"
|
|
17
20
|
onAsyncRender={[Function]}
|
|
18
21
|
source={
|
|
19
22
|
{
|
|
20
|
-
"uri": "",
|
|
23
|
+
"uri": "someUrl",
|
|
21
24
|
}
|
|
22
25
|
}
|
|
23
26
|
style={
|
|
@@ -28,7 +31,7 @@ exports[`SecondaryImage - Image SecondaryImage should render if known dimensions
|
|
|
28
31
|
"width": 100,
|
|
29
32
|
}
|
|
30
33
|
}
|
|
31
|
-
uri=""
|
|
34
|
+
uri="someUrl"
|
|
32
35
|
/>
|
|
33
36
|
</View>
|
|
34
37
|
`;
|