@applicaster/zapp-react-native-ui-components 14.0.0-alpha.4748018412 → 14.0.0-alpha.5114565431
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Components/AnimatedInOut/index.tsx +5 -3
- package/Components/AudioPlayer/index.tsx +15 -0
- package/Components/AudioPlayer/mobile/Layout.tsx +66 -0
- package/Components/AudioPlayer/{__tests__/__snapshots__/audioPlayer.test.js.snap → mobile/__tests__/__snapshots__/audioPlayerMobileLayout.test.js.snap} +2 -2
- package/Components/AudioPlayer/mobile/__tests__/audioPlayerMobileLayout.test.js +18 -0
- package/Components/AudioPlayer/mobile/index.tsx +18 -0
- package/Components/AudioPlayer/{Artwork.tsx → tv/Artwork.tsx} +3 -2
- package/Components/AudioPlayer/{Channel.tsx → tv/Channel.tsx} +7 -7
- package/Components/AudioPlayer/tv/Layout.tsx +168 -0
- package/Components/AudioPlayer/{Runtime.tsx → tv/Runtime.tsx} +7 -1
- package/Components/AudioPlayer/{Summary.tsx → tv/Summary.tsx} +6 -2
- package/Components/AudioPlayer/{Title.tsx → tv/Title.tsx} +6 -2
- package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/Runtime.test.js.snap +2 -2
- package/Components/AudioPlayer/tv/__tests__/__snapshots__/audioPlayer.test.js.snap +164 -0
- package/Components/AudioPlayer/tv/__tests__/__snapshots__/channel.test.js.snap +19 -0
- package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/summary.test.js.snap +1 -2
- package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/title.test.js.snap +1 -2
- package/Components/AudioPlayer/{__tests__ → tv/__tests__}/audioPlayer.test.js +7 -3
- package/Components/AudioPlayer/{helpers.tsx → tv/helpers.tsx} +11 -5
- package/Components/AudioPlayer/{AudioPlayer.tsx → tv/index.tsx} +17 -58
- package/Components/AudioPlayer/types.ts +40 -0
- package/Components/Cell/index.js +6 -2
- package/Components/Focusable/Focusable.tsx +5 -3
- package/Components/Focusable/FocusableTvOS.tsx +3 -3
- package/Components/Focusable/FocusableiOS.tsx +2 -2
- package/Components/Focusable/__tests__/index.android.test.tsx +3 -0
- package/Components/Focusable/index.android.tsx +12 -8
- package/Components/Focusable/index.tsx +1 -1
- package/Components/FocusableList/index.tsx +4 -0
- package/Components/GeneralContentScreen/GeneralContentScreen.tsx +0 -2
- package/Components/HandlePlayable/HandlePlayable.tsx +25 -9
- package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -27
- package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +1 -1
- package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +2 -2
- package/Components/MasterCell/DefaultComponents/Text/index.tsx +1 -0
- package/Components/MasterCell/elementMapper.tsx +1 -2
- package/Components/MasterCell/index.tsx +1 -1
- package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +13 -18
- package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +9 -0
- package/Components/PlayerContainer/PlayerContainer.tsx +43 -30
- package/Components/PlayerImageBackground/index.tsx +1 -1
- package/Components/River/ComponentsMap/ComponentsMap.tsx +0 -1
- package/Components/River/TV/River.tsx +2 -20
- 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/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 +0 -2
- package/Components/TopMarginApplicator/TopMarginApplicator.tsx +16 -15
- package/Components/Touchable/__tests__/__snapshots__/touchable.test.tsx.snap +34 -0
- package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +15 -9
- package/Components/VideoLive/animationUtils.ts +3 -3
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +32 -8
- 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__/PlayerWrapper.test.tsx +1 -7
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +44 -180
- package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +17 -55
- package/Components/VideoModal/hooks/index.ts +0 -2
- package/Components/VideoModal/hooks/useModalSize.ts +18 -2
- package/Components/VideoModal/utils.ts +6 -0
- package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -16
- package/Components/Viewport/ViewportTracker/__tests__/viewportTracker.test.js +84 -24
- package/Components/Viewport/VisibilitySensor/VisibilitySensor.tsx +3 -3
- package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/index.ts +3 -3
- package/Decorators/ConfigurationWrapper/withConfigurationProvider.tsx +2 -2
- 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 +241 -0
- package/Decorators/ZappPipesDataConnector/types.ts +29 -0
- package/index.d.ts +0 -1
- package/package.json +5 -9
- 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/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,7 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { render } from "@testing-library/react-native";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { AudioPlayerTV } from "..";
|
|
5
|
+
|
|
6
|
+
jest.mock("@applicaster/zapp-react-native-utils/audioPlayerUtils", () => ({
|
|
7
|
+
useArtworkImage: jest.fn(() => "artwork_url"),
|
|
8
|
+
}));
|
|
5
9
|
|
|
6
10
|
const audioPlayerProps = {
|
|
7
11
|
audio_item: {
|
|
@@ -45,9 +49,9 @@ const audioPlayerProps = {
|
|
|
45
49
|
styles: {},
|
|
46
50
|
};
|
|
47
51
|
|
|
48
|
-
describe("<
|
|
52
|
+
describe("<AudioPlayerTV />", () => {
|
|
49
53
|
it("renders correctly", () => {
|
|
50
|
-
const { toJSON } = render(<
|
|
54
|
+
const { toJSON } = render(<AudioPlayerTV {...audioPlayerProps} />);
|
|
51
55
|
expect(toJSON()).toMatchSnapshot();
|
|
52
56
|
});
|
|
53
57
|
});
|
|
@@ -2,9 +2,8 @@ const defaults = {
|
|
|
2
2
|
audio_player_title_color: "white",
|
|
3
3
|
audio_player_summary_color: "white",
|
|
4
4
|
audio_player_background_color: "black",
|
|
5
|
-
|
|
5
|
+
audio_player_background_image: undefined,
|
|
6
6
|
audio_player_rtl: false,
|
|
7
|
-
audio_player_background_image_default_color: "",
|
|
8
7
|
};
|
|
9
8
|
|
|
10
9
|
export function getPropertyFromEntryOrConfig({ entry, plugin_configuration }) {
|
|
@@ -28,13 +27,20 @@ const LTR = {
|
|
|
28
27
|
justifyContent: "flex-start",
|
|
29
28
|
textAlign: "left",
|
|
30
29
|
alignItems: "flex-end",
|
|
31
|
-
};
|
|
30
|
+
} as const;
|
|
32
31
|
|
|
33
32
|
const RTL = {
|
|
34
33
|
flexDirection: "row-reverse",
|
|
35
34
|
justifyContent: "flex-end",
|
|
36
35
|
textAlign: "right",
|
|
37
36
|
alignItems: "flex-start",
|
|
38
|
-
};
|
|
37
|
+
} as const;
|
|
39
38
|
|
|
40
|
-
export const directionStyles = (
|
|
39
|
+
export const directionStyles = (
|
|
40
|
+
isRTL: boolean
|
|
41
|
+
): {
|
|
42
|
+
flexDirection: "row" | "row-reverse";
|
|
43
|
+
justifyContent: "flex-start" | "flex-end";
|
|
44
|
+
textAlign: "left" | "right";
|
|
45
|
+
alignItems: "flex-end" | "flex-start";
|
|
46
|
+
} => (isRTL ? RTL : LTR);
|
|
@@ -1,60 +1,24 @@
|
|
|
1
1
|
import React, { useCallback, useMemo } from "react";
|
|
2
2
|
|
|
3
3
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
4
|
+
import { useArtworkImage } from "@applicaster/zapp-react-native-utils/audioPlayerUtils";
|
|
4
5
|
|
|
5
|
-
import {
|
|
6
|
+
import { AudioPlayerTVLayout } from "./Layout";
|
|
6
7
|
|
|
7
|
-
import { AudioPlayerLayout } from "./AudioPlayerLayout";
|
|
8
8
|
import { Channel } from "./Channel";
|
|
9
9
|
import { Title } from "./Title";
|
|
10
10
|
import { Summary } from "./Summary";
|
|
11
11
|
import { Runtime } from "./Runtime";
|
|
12
12
|
import { getPropertyFromEntryOrConfig } from "./helpers";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
audio_player_artwork_aspect_ratio?: string;
|
|
19
|
-
audio_player_background_image?: string;
|
|
20
|
-
audio_player_background_color?: string;
|
|
21
|
-
audio_player_channel_icon?: string;
|
|
22
|
-
audio_player_title_color?: string;
|
|
23
|
-
audio_player_summary_color?: string;
|
|
24
|
-
audio_player_rtl?: boolean;
|
|
25
|
-
audio_player_background_image_default_color?: string;
|
|
26
|
-
start_time?: string;
|
|
27
|
-
end_time?: string;
|
|
28
|
-
};
|
|
29
|
-
};
|
|
30
|
-
plugin_configuration: {
|
|
31
|
-
audio_player_background_color?: string;
|
|
32
|
-
audio_player_title_color?: string;
|
|
33
|
-
audio_player_summary_color?: string;
|
|
34
|
-
audio_player_rtl?: string;
|
|
35
|
-
audio_player_background_image_default_color?: string;
|
|
36
|
-
audio_player_background_image?: string;
|
|
37
|
-
audio_player_artwork_aspect_ratio?: string;
|
|
38
|
-
lg_tv_audio_player_title_font_family?: string;
|
|
39
|
-
lg_tv_audio_player_title_font_size?: number;
|
|
40
|
-
lg_tv_audio_player_summary_font_family?: string;
|
|
41
|
-
lg_tv_audio_player_summary_font_size?: number;
|
|
42
|
-
samsung_tv_audio_player_title_font_family?: string;
|
|
43
|
-
samsung_tv_audio_player_title_font_size?: number;
|
|
44
|
-
samsung_tv_audio_player_summary_font_family?: string;
|
|
45
|
-
samsung_tv_audio_player_summary_font_size?: number;
|
|
46
|
-
tv_os_audio_player_title_font_family?: string;
|
|
47
|
-
tv_os_audio_player_title_font_size?: number;
|
|
48
|
-
tv_os_audio_player_summary_font_family?: string;
|
|
49
|
-
tv_os_audio_player_summary_font_size?: number;
|
|
50
|
-
};
|
|
51
|
-
style?: ViewStyle;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export function AudioPlayer(props: Props) {
|
|
55
|
-
const { audio_item, plugin_configuration, style } = props;
|
|
13
|
+
|
|
14
|
+
import { Props } from "../types";
|
|
15
|
+
|
|
16
|
+
export function AudioPlayerTV(props: Props) {
|
|
17
|
+
const { audio_item, plugin_configuration, style = {} } = props;
|
|
56
18
|
const { extensions, title, summary } = audio_item;
|
|
57
19
|
|
|
20
|
+
const artwork = useArtworkImage(audio_item);
|
|
21
|
+
|
|
58
22
|
const getProp = useCallback(
|
|
59
23
|
getPropertyFromEntryOrConfig({
|
|
60
24
|
entry: audio_item,
|
|
@@ -64,20 +28,20 @@ export function AudioPlayer(props: Props) {
|
|
|
64
28
|
);
|
|
65
29
|
|
|
66
30
|
const config = useMemo(() => {
|
|
67
|
-
// Checking if we are
|
|
31
|
+
// Checking if we are receiving items from the DSP
|
|
68
32
|
const titleColor = getProp("audio_player_title_color");
|
|
69
33
|
const summaryColor = getProp("audio_player_summary_color");
|
|
70
34
|
const backgroundColor = getProp("audio_player_background_color");
|
|
71
35
|
const backgroundImage = getProp("audio_player_background_image");
|
|
72
|
-
const artworkAspectRatio = getProp("audio_player_artwork_aspect_ratio");
|
|
73
36
|
const channelIcon = getProp("audio_player_channel_icon");
|
|
74
37
|
const rtlFlag = getProp("audio_player_rtl");
|
|
75
|
-
const artworkBorderRadius = getProp("audio_player_artwork_border_radius");
|
|
76
38
|
|
|
77
|
-
const
|
|
78
|
-
"
|
|
39
|
+
const backgroundImageOverlay = getProp(
|
|
40
|
+
"audio_player_background_image_overlay"
|
|
79
41
|
);
|
|
80
42
|
|
|
43
|
+
const artworkBorderRadius = getProp("audio_player_artwork_border_radius");
|
|
44
|
+
|
|
81
45
|
const isRTL = rtlFlag === "1" || rtlFlag === "true" || rtlFlag === true;
|
|
82
46
|
|
|
83
47
|
const titleFontFamily = getProp(
|
|
@@ -152,23 +116,18 @@ export function AudioPlayer(props: Props) {
|
|
|
152
116
|
summaryFontSize,
|
|
153
117
|
runTimeFontFamily,
|
|
154
118
|
runTimeFontSize,
|
|
155
|
-
artworkAspectRatio,
|
|
156
119
|
channelIcon,
|
|
157
|
-
audioPlayerBackgroundImageDefaultColor,
|
|
158
120
|
artworkBorderRadius,
|
|
121
|
+
backgroundImageOverlay,
|
|
159
122
|
};
|
|
160
123
|
}, [getProp]);
|
|
161
124
|
|
|
162
|
-
const artwork = imageSrcFromMediaItem(audio_item, [
|
|
163
|
-
config?.artworkAspectRatio,
|
|
164
|
-
]);
|
|
165
|
-
|
|
166
125
|
return (
|
|
167
|
-
<
|
|
126
|
+
<AudioPlayerTVLayout artwork={artwork} config={config} style={style}>
|
|
168
127
|
<Channel srcImage={config?.channelIcon} config={config} />
|
|
169
128
|
<Title title={title} config={config} />
|
|
170
129
|
<Summary summary={summary} config={config} />
|
|
171
130
|
<Runtime {...extensions} config={config} />
|
|
172
|
-
</
|
|
131
|
+
</AudioPlayerTVLayout>
|
|
173
132
|
);
|
|
174
133
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ViewStyle } from "react-native";
|
|
2
|
+
|
|
3
|
+
export type Props = {
|
|
4
|
+
audio_item: ZappEntry & {
|
|
5
|
+
extensions?: {
|
|
6
|
+
audio_player_artwork_aspect_ratio?: string;
|
|
7
|
+
audio_player_background_image?: string;
|
|
8
|
+
audio_player_background_color?: string;
|
|
9
|
+
audio_player_channel_icon?: string;
|
|
10
|
+
audio_player_title_color?: string;
|
|
11
|
+
audio_player_summary_color?: string;
|
|
12
|
+
audio_player_rtl?: boolean;
|
|
13
|
+
audio_player_background_image_default_color?: string;
|
|
14
|
+
start_time?: string;
|
|
15
|
+
end_time?: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
plugin_configuration: {
|
|
19
|
+
audio_player_background_color?: string;
|
|
20
|
+
audio_player_title_color?: string;
|
|
21
|
+
audio_player_summary_color?: string;
|
|
22
|
+
audio_player_rtl?: string;
|
|
23
|
+
audio_player_background_image_default_color?: string;
|
|
24
|
+
audio_player_background_image?: string;
|
|
25
|
+
audio_player_artwork_aspect_ratio?: string;
|
|
26
|
+
lg_tv_audio_player_title_font_family?: string;
|
|
27
|
+
lg_tv_audio_player_title_font_size?: number;
|
|
28
|
+
lg_tv_audio_player_summary_font_family?: string;
|
|
29
|
+
lg_tv_audio_player_summary_font_size?: number;
|
|
30
|
+
samsung_tv_audio_player_title_font_family?: string;
|
|
31
|
+
samsung_tv_audio_player_title_font_size?: number;
|
|
32
|
+
samsung_tv_audio_player_summary_font_family?: string;
|
|
33
|
+
samsung_tv_audio_player_summary_font_size?: number;
|
|
34
|
+
tv_os_audio_player_title_font_family?: string;
|
|
35
|
+
tv_os_audio_player_title_font_size?: number;
|
|
36
|
+
tv_os_audio_player_summary_font_family?: string;
|
|
37
|
+
tv_os_audio_player_summary_font_size?: number;
|
|
38
|
+
};
|
|
39
|
+
style?: ViewStyle;
|
|
40
|
+
};
|
package/Components/Cell/index.js
CHANGED
|
@@ -3,11 +3,15 @@ import * as R from "ramda";
|
|
|
3
3
|
import { connectToStore } from "@applicaster/zapp-react-native-redux";
|
|
4
4
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
HorizontalScrollContext,
|
|
8
|
+
RiverOffsetContext,
|
|
9
|
+
ScreenScrollingContext,
|
|
10
|
+
} from "../../Contexts";
|
|
11
|
+
|
|
7
12
|
import { CellComponent } from "./Cell";
|
|
8
13
|
import { TvOSCellComponent } from "./TvOSCellComponent";
|
|
9
14
|
import { withConsumer } from "../../Contexts/HeaderOffsetContext";
|
|
10
|
-
import { ScreenScrollingContext } from "../../Contexts/ScreenScrollingContext";
|
|
11
15
|
|
|
12
16
|
import { ScreenLayoutContextConsumer } from "../../Contexts/ScreenLayoutContext";
|
|
13
17
|
import { createContext } from "@applicaster/zapp-react-native-utils/reactUtils/createContext";
|
|
@@ -5,6 +5,7 @@ import { BaseFocusable } from "../BaseFocusable";
|
|
|
5
5
|
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
|
|
6
6
|
import { LONG_KEY_PRESS_TIMEOUT } from "@applicaster/quick-brick-core/const";
|
|
7
7
|
import { withFocusableContext } from "../../Contexts/FocusableGroupContext/withFocusableContext";
|
|
8
|
+
import { StyleSheet, ViewStyle } from "react-native";
|
|
8
9
|
|
|
9
10
|
type Props = {
|
|
10
11
|
initialFocus?: boolean;
|
|
@@ -21,7 +22,7 @@ type Props = {
|
|
|
21
22
|
handleFocus?: ({ mouse }: { mouse: boolean }) => void;
|
|
22
23
|
children: (boolean, string) => React.ComponentType<any>;
|
|
23
24
|
selected?: boolean;
|
|
24
|
-
style?:
|
|
25
|
+
style?: ViewStyle[] | ViewStyle;
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
class Focusable extends BaseFocusable<Props> {
|
|
@@ -122,7 +123,7 @@ class Focusable extends BaseFocusable<Props> {
|
|
|
122
123
|
}
|
|
123
124
|
|
|
124
125
|
render() {
|
|
125
|
-
const { children, style } = this.props;
|
|
126
|
+
const { children, style, ...otherProps } = this.props;
|
|
126
127
|
const { focused } = this.state;
|
|
127
128
|
|
|
128
129
|
const id = this.getId();
|
|
@@ -139,7 +140,8 @@ class Focusable extends BaseFocusable<Props> {
|
|
|
139
140
|
onMouseUp={this.pressOut}
|
|
140
141
|
data-testid={focusableId}
|
|
141
142
|
focused-teststate={focused ? "focused" : "default"}
|
|
142
|
-
style={style}
|
|
143
|
+
style={StyleSheet.flatten(style) as any as React.CSSProperties}
|
|
144
|
+
{...otherProps}
|
|
143
145
|
>
|
|
144
146
|
{children(focused, { mouse: this.mouse })}
|
|
145
147
|
</div>
|
|
@@ -16,9 +16,9 @@ function noop() {}
|
|
|
16
16
|
type Props = {
|
|
17
17
|
id: string;
|
|
18
18
|
groupId: string;
|
|
19
|
-
onPress?: (nativeEvent:
|
|
20
|
-
onFocus?: (nativeEvent:
|
|
21
|
-
onBlur?: (nativeEvent:
|
|
19
|
+
onPress?: (nativeEvent: any) => void;
|
|
20
|
+
onFocus?: (nativeEvent: any) => void;
|
|
21
|
+
onBlur?: (nativeEvent: any) => void;
|
|
22
22
|
children: (focused?: boolean) => React.ReactNode;
|
|
23
23
|
isParallaxDisabled: boolean;
|
|
24
24
|
preferredFocus?: boolean;
|
|
@@ -2,7 +2,7 @@ import React from "react";
|
|
|
2
2
|
|
|
3
3
|
type Props = {
|
|
4
4
|
children: () => React.ReactNode;
|
|
5
|
-
}
|
|
5
|
+
} & Record<string, any>;
|
|
6
6
|
|
|
7
7
|
function FocusableiOSComponent({ children }: Props) {
|
|
8
8
|
if (typeof children === "function") {
|
|
@@ -12,4 +12,4 @@ function FocusableiOSComponent({ children }: Props) {
|
|
|
12
12
|
return children;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export const FocusableiOS =
|
|
15
|
+
export const FocusableiOS = FocusableiOSComponent;
|
|
@@ -38,6 +38,9 @@ describe("Focusable", () => {
|
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
it("updates disableFocus state when disableFocus prop changes", () => {
|
|
41
|
+
const unregister = jest.fn();
|
|
42
|
+
mockFocusManager.registerFocusable.mockReturnValue(unregister);
|
|
43
|
+
|
|
41
44
|
const { rerender } = render(
|
|
42
45
|
<Focusable id="test-id" disableFocus={false}>
|
|
43
46
|
<Touchable testID="touchable" />
|
|
@@ -43,11 +43,13 @@ export const FocusableContext = React.createContext<
|
|
|
43
43
|
// eslint-disable-next-line
|
|
44
44
|
setIsFocusable: (enableFocus: boolean) => void;
|
|
45
45
|
ref: FocusManager.FocusableRef;
|
|
46
|
+
parentFocusableId: Option<string>;
|
|
46
47
|
} & ParentFocus
|
|
47
48
|
>({
|
|
48
49
|
focused: false,
|
|
49
50
|
setIsFocusable: () => {},
|
|
50
51
|
ref: { current: null },
|
|
52
|
+
parentFocusableId: undefined,
|
|
51
53
|
});
|
|
52
54
|
|
|
53
55
|
export const useFocusable = () => React.useContext(FocusableContext);
|
|
@@ -74,7 +76,7 @@ function FocusableComponent(props: Props, forwardedRef) {
|
|
|
74
76
|
|
|
75
77
|
const isRTL = useIsRTL();
|
|
76
78
|
const focusManager = useFocusManager();
|
|
77
|
-
const { ref:
|
|
79
|
+
const { ref: parentFocusableRef, parentFocusableId } = useFocusable();
|
|
78
80
|
const touchableRef = React.useRef(null);
|
|
79
81
|
|
|
80
82
|
const [focused, setFocused] = React.useState(() =>
|
|
@@ -98,13 +100,14 @@ function FocusableComponent(props: Props, forwardedRef) {
|
|
|
98
100
|
}
|
|
99
101
|
}, [disableFocus]);
|
|
100
102
|
|
|
101
|
-
React.
|
|
103
|
+
React.useLayoutEffect(() => {
|
|
102
104
|
if (id) {
|
|
103
|
-
const unregister = focusManager.registerFocusable(
|
|
105
|
+
const unregister = focusManager.registerFocusable({
|
|
104
106
|
touchableRef,
|
|
105
|
-
|
|
106
|
-
isFocusableCell
|
|
107
|
-
|
|
107
|
+
parentFocusableRef,
|
|
108
|
+
isFocusableCell,
|
|
109
|
+
parentFocusableId,
|
|
110
|
+
});
|
|
108
111
|
|
|
109
112
|
onRegister();
|
|
110
113
|
|
|
@@ -112,7 +115,7 @@ function FocusableComponent(props: Props, forwardedRef) {
|
|
|
112
115
|
unregister();
|
|
113
116
|
};
|
|
114
117
|
}
|
|
115
|
-
}, [id, onRegister, isFocusableCell]);
|
|
118
|
+
}, [id, onRegister, isFocusableCell, parentFocusableId]);
|
|
116
119
|
|
|
117
120
|
if (R.isNil(id)) {
|
|
118
121
|
// eslint-disable-next-line no-console
|
|
@@ -164,8 +167,9 @@ function FocusableComponent(props: Props, forwardedRef) {
|
|
|
164
167
|
...parentFocus,
|
|
165
168
|
ref: touchableRef,
|
|
166
169
|
setIsFocusable,
|
|
170
|
+
parentFocusableId: id,
|
|
167
171
|
};
|
|
168
|
-
}, [parentFocus, focused]);
|
|
172
|
+
}, [parentFocus, focused, id]);
|
|
169
173
|
|
|
170
174
|
return (
|
|
171
175
|
<Touchable
|
|
@@ -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,
|
|
@@ -91,6 +91,7 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
|
|
|
91
91
|
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
92
92
|
omitPropsPropagation = [],
|
|
93
93
|
useScrollView = false,
|
|
94
|
+
onScrollToIndexFailed = noop,
|
|
94
95
|
} = props;
|
|
95
96
|
|
|
96
97
|
useCheckItemIdsForUnique({ componentId: props.id, items: data });
|
|
@@ -277,6 +278,7 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
|
|
|
277
278
|
"withStateMemory",
|
|
278
279
|
"useSequentialLoading",
|
|
279
280
|
"useScrollView",
|
|
281
|
+
"onScrollToIndexFailed",
|
|
280
282
|
...omitPropsPropagation,
|
|
281
283
|
],
|
|
282
284
|
R.__
|
|
@@ -305,6 +307,7 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
|
|
|
305
307
|
{...getFlatListProps(props)}
|
|
306
308
|
onEndReached={onEndReached}
|
|
307
309
|
initialNumToRender={initialNumToRender}
|
|
310
|
+
onScrollToIndexFailed={onScrollToIndexFailed}
|
|
308
311
|
renderItem={renderItem}
|
|
309
312
|
focused={focused}
|
|
310
313
|
data={data}
|
|
@@ -319,6 +322,7 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
|
|
|
319
322
|
renderItem={renderItem}
|
|
320
323
|
onEndReached={onEndReached}
|
|
321
324
|
initialNumToRender={initialNumToRender}
|
|
325
|
+
onScrollToIndexFailed={onScrollToIndexFailed}
|
|
322
326
|
/>
|
|
323
327
|
)}
|
|
324
328
|
</ChildrenFocusDeactivatorView>
|
|
@@ -30,7 +30,6 @@ export const GeneralContentScreen = ({
|
|
|
30
30
|
isScreenWrappedInContainer,
|
|
31
31
|
componentsMapExtraProps = {},
|
|
32
32
|
focused,
|
|
33
|
-
extraOffset,
|
|
34
33
|
parentFocus,
|
|
35
34
|
containerHeight,
|
|
36
35
|
preferredFocus = false,
|
|
@@ -122,7 +121,6 @@ export const GeneralContentScreen = ({
|
|
|
122
121
|
isScreenWrappedInContainer={isScreenWrappedInContainer}
|
|
123
122
|
parentFocus={parentFocus}
|
|
124
123
|
focused={focused}
|
|
125
|
-
extraOffset={extraOffset}
|
|
126
124
|
containerHeight={containerHeight}
|
|
127
125
|
preferredFocus={preferredFocus}
|
|
128
126
|
{...componentsMapExtraProps}
|
|
@@ -7,12 +7,15 @@ import {
|
|
|
7
7
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
8
8
|
import {
|
|
9
9
|
useDimensions,
|
|
10
|
+
useIsTablet as isTablet,
|
|
10
11
|
useNavigation,
|
|
11
12
|
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
12
13
|
|
|
13
14
|
import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
|
|
14
15
|
import { PlayerContainer } from "../PlayerContainer";
|
|
15
16
|
import { useModalSize } from "../VideoModal/hooks";
|
|
17
|
+
import { ViewStyle } from "react-native";
|
|
18
|
+
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
16
19
|
|
|
17
20
|
type Props = {
|
|
18
21
|
item: ZappEntry;
|
|
@@ -83,6 +86,13 @@ type PlayableComponent = {
|
|
|
83
86
|
Component: React.ComponentType<any>;
|
|
84
87
|
};
|
|
85
88
|
|
|
89
|
+
const dimensionsContext: "window" | "screen" = platformSelect({
|
|
90
|
+
android_tv: "window",
|
|
91
|
+
amazon: "window",
|
|
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
|
|
94
|
+
});
|
|
95
|
+
|
|
86
96
|
export function HandlePlayable({
|
|
87
97
|
item,
|
|
88
98
|
isModal,
|
|
@@ -135,19 +145,25 @@ export function HandlePlayable({
|
|
|
135
145
|
});
|
|
136
146
|
}, [casting]);
|
|
137
147
|
|
|
138
|
-
const { width: screenWidth, height: screenHeight } =
|
|
148
|
+
const { width: screenWidth, height: screenHeight } =
|
|
149
|
+
useDimensions(dimensionsContext);
|
|
139
150
|
|
|
140
151
|
const modalSize = useModalSize();
|
|
141
152
|
|
|
142
153
|
const style = React.useMemo(
|
|
143
|
-
() =>
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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,
|
|
151
167
|
[screenWidth, screenHeight, modalSize, isModal, mode]
|
|
152
168
|
);
|
|
153
169
|
|
|
@@ -2,7 +2,6 @@ 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
7
|
import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
|
|
@@ -67,32 +66,10 @@ export function FocusableView({ style, children, item, ...otherProps }: Props) {
|
|
|
67
66
|
const handleFocus = (focusable) => {
|
|
68
67
|
const focusedButtonId = getFocusedButtonId(focusable);
|
|
69
68
|
|
|
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
|
-
});
|
|
69
|
+
otherProps?.onToggleFocus?.({
|
|
70
|
+
focusable: wrapperRef.current,
|
|
71
|
+
focusedButtonId,
|
|
72
|
+
mouse: focusable.mouse,
|
|
96
73
|
});
|
|
97
74
|
|
|
98
75
|
if (ttsLabel) {
|
|
@@ -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(
|
|
@@ -9,11 +9,11 @@ type Props = {
|
|
|
9
9
|
player_screen_id: string;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
export const ImageContainer = (props:
|
|
12
|
+
export const ImageContainer = (props: any) => {
|
|
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
|
};
|
|
@@ -73,7 +73,6 @@ export function elementMapper(
|
|
|
73
73
|
: {};
|
|
74
74
|
|
|
75
75
|
const componentProps = {
|
|
76
|
-
key,
|
|
77
76
|
style,
|
|
78
77
|
skipButtons: otherProps?.skipButtons,
|
|
79
78
|
emitAsyncElementRegistrate: otherProps?.emitAsyncElementRegistrate,
|
|
@@ -91,7 +90,7 @@ export function elementMapper(
|
|
|
91
90
|
const fn = mapElementWithKey(elementMapper(components, otherProps));
|
|
92
91
|
|
|
93
92
|
return (
|
|
94
|
-
<Component {...componentProps}>
|
|
93
|
+
<Component key={key} {...componentProps}>
|
|
95
94
|
{focusableTypes.has(type) && elements.length > 0
|
|
96
95
|
? elements.map(fn)
|
|
97
96
|
: null}
|
|
@@ -86,7 +86,7 @@ export function masterCellBuilder({
|
|
|
86
86
|
entry: item,
|
|
87
87
|
state: getEntryState(state, entryIsSelected),
|
|
88
88
|
}),
|
|
89
|
-
[state, item
|
|
89
|
+
[state, item, entryIsSelected] // Assuming that item won't mutate
|
|
90
90
|
);
|
|
91
91
|
|
|
92
92
|
const wrapperRef = React.useRef(null);
|