@applicaster/zapp-react-native-ui-components 13.0.0-alpha.1240837114 → 13.0.0-alpha.1290120403
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/AudioPlayer/AudioPlayer.tsx +0 -4
- package/Components/AudioPlayer/helpers.tsx +0 -1
- package/Components/Cell/CellWithFocusable.tsx +4 -2
- package/Components/Cell/CellWrapper.tsx +18 -0
- package/Components/CellRendererResolver/index.ts +2 -1
- package/Components/GeneralContentScreen/GeneralContentScreen.tsx +3 -0
- package/Components/GeneralContentScreen/utils/useCurationAPI.ts +4 -2
- package/Components/GeneralContentScreen/utils/useEventAlerts.ts +30 -0
- package/Components/HandlePlayable/HandlePlayable.tsx +10 -3
- package/Components/Layout/TV/LayoutBackground.tsx +28 -0
- package/Components/Layout/TV/ScreenContainer.tsx +0 -1
- package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +15 -10
- package/Components/Layout/TV/__tests__/index.test.tsx +8 -2
- package/Components/Layout/TV/index.tsx +6 -20
- package/Components/Layout/TV/index.web.tsx +4 -1
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/const.ts +3 -0
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +6 -6
- package/Components/ModalComponent/BottomSheetModalContent.tsx +59 -43
- package/Components/ModalComponent/Button/Item.tsx +6 -5
- package/Components/ModalComponent/Button/index.tsx +45 -62
- package/Components/ModalComponent/Header/index.tsx +9 -8
- package/Components/ModalComponent/utils.ts +55 -7
- package/Components/PlayerContainer/PlayerContainer.tsx +25 -2
- package/Components/River/RiverItem.tsx +2 -1
- package/Components/Screen/TV/__tests__/index.web.test.tsx +26 -0
- package/Components/Screen/__tests__/Screen.test.tsx +22 -14
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +2 -2
- package/Components/TopMarginApplicator/TopMarginApplicator.tsx +2 -3
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +4 -2
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +21 -10
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +8 -1
- package/Components/VideoModal/ModalAnimation/__tests__/getMoveUpValue.test.ts +108 -0
- package/Components/VideoModal/ModalAnimation/const.ts +5 -0
- package/Components/VideoModal/ModalAnimation/index.ts +2 -0
- package/Components/VideoModal/ModalAnimation/utils.ts +30 -0
- package/Components/VideoModal/PlayerDetails.tsx +9 -4
- package/Components/VideoModal/PlayerWrapper.tsx +35 -22
- package/Components/VideoModal/VideoModal.tsx +19 -4
- package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -40
- package/Components/VideoModal/utils.ts +3 -4
- package/package.json +5 -5
- package/Components/Cell/CellWrapper.ts +0 -5
|
@@ -3,12 +3,10 @@ import { StyleSheet, TouchableOpacity, View } from "react-native";
|
|
|
3
3
|
import { Item, ItemProps } from "./Item";
|
|
4
4
|
import { ItemIcon, ItemIconProps } from "./ItemIcon";
|
|
5
5
|
import { ItemLabel, ItemLabelProps } from "./ItemLabel";
|
|
6
|
-
import * as assets from "./assets";
|
|
7
6
|
import { defaultSelectedAsset } from "./assets";
|
|
8
7
|
|
|
9
8
|
type ButtonProps = {
|
|
10
9
|
configuration: any;
|
|
11
|
-
width: number;
|
|
12
10
|
selectedItem?: any;
|
|
13
11
|
item: any; // Adjust type as needed
|
|
14
12
|
onPress: (item: any) => void; // Adjust type as needed
|
|
@@ -17,6 +15,9 @@ type ButtonProps = {
|
|
|
17
15
|
labelBaseProps?: ItemLabelProps;
|
|
18
16
|
disabled?: boolean;
|
|
19
17
|
label?: string | Record<string, string>;
|
|
18
|
+
iconPlacement?: "left" | "right";
|
|
19
|
+
selectedItemIcon?: ItemIconProps["asset"];
|
|
20
|
+
defaultItemIcon?: ItemIconProps["asset"];
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
const styles = StyleSheet.create({
|
|
@@ -31,81 +32,63 @@ export function Button({
|
|
|
31
32
|
item,
|
|
32
33
|
onPress,
|
|
33
34
|
configuration,
|
|
34
|
-
width,
|
|
35
35
|
iconBaseProps,
|
|
36
|
-
itemBaseProps,
|
|
36
|
+
itemBaseProps: itemProps,
|
|
37
37
|
labelBaseProps,
|
|
38
38
|
label,
|
|
39
|
+
iconPlacement = "left",
|
|
40
|
+
defaultItemIcon,
|
|
41
|
+
selectedItemIcon,
|
|
39
42
|
disabled = false,
|
|
40
43
|
}: ButtonProps) {
|
|
41
44
|
const [focused, setFocused] = useState(false);
|
|
42
45
|
|
|
43
|
-
const selected =
|
|
44
|
-
() => selectedItem && item.value === selectedItem?.value,
|
|
45
|
-
[selectedItem, selectedItem]
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
const itemProps = useMemo<ItemProps>(
|
|
49
|
-
() => ({
|
|
50
|
-
...itemBaseProps,
|
|
51
|
-
width,
|
|
52
|
-
}),
|
|
53
|
-
[configuration, width]
|
|
54
|
-
);
|
|
46
|
+
const selected = selectedItem && item.value === selectedItem?.value;
|
|
55
47
|
|
|
56
|
-
const
|
|
57
|
-
() =>
|
|
58
|
-
|
|
59
|
-
asset: configuration[item.asset] ?? assets[item.asset] ?? item.asset,
|
|
60
|
-
}),
|
|
61
|
-
[configuration, item.asset]
|
|
48
|
+
const itemIconPropsAssets = useMemo<ItemIconProps["asset"]>(
|
|
49
|
+
() => configuration[item.asset] ?? item.asset ?? defaultItemIcon,
|
|
50
|
+
[item.asset, defaultItemIcon]
|
|
62
51
|
);
|
|
63
52
|
|
|
64
|
-
const
|
|
65
|
-
() =>
|
|
66
|
-
|
|
67
|
-
asset:
|
|
68
|
-
configuration["modal_bottom_sheet_item_selected_icon"] ||
|
|
69
|
-
defaultSelectedAsset,
|
|
70
|
-
marginRight: 10,
|
|
71
|
-
}),
|
|
72
|
-
[configuration]
|
|
53
|
+
const selectedItemIconPropsAssets = useMemo<ItemIconProps["asset"]>(
|
|
54
|
+
() => selectedItemIcon || defaultSelectedAsset,
|
|
55
|
+
[selectedItemIcon]
|
|
73
56
|
);
|
|
74
57
|
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
...
|
|
78
|
-
|
|
79
|
-
}),
|
|
80
|
-
[configuration, item?.label]
|
|
81
|
-
);
|
|
58
|
+
const renderItemIcon =
|
|
59
|
+
itemIconPropsAssets && itemIconPropsAssets.length > 0 ? (
|
|
60
|
+
<ItemIcon {...iconBaseProps} asset={itemIconPropsAssets} />
|
|
61
|
+
) : null;
|
|
82
62
|
|
|
83
63
|
if (disabled) return null;
|
|
84
64
|
|
|
85
65
|
return (
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
>
|
|
93
|
-
<
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
66
|
+
<TouchableOpacity
|
|
67
|
+
activeOpacity={1}
|
|
68
|
+
onPress={() => onPress(item)}
|
|
69
|
+
onPressIn={() => setFocused(true)}
|
|
70
|
+
onPressOut={() => setFocused(false)}
|
|
71
|
+
>
|
|
72
|
+
<Item {...itemProps} focused={focused} selected={selected}>
|
|
73
|
+
<View style={styles.label_icon_container}>
|
|
74
|
+
{iconPlacement === "left" && renderItemIcon}
|
|
75
|
+
|
|
76
|
+
{label ? (
|
|
77
|
+
<ItemLabel
|
|
78
|
+
{...labelBaseProps}
|
|
79
|
+
label={label ?? null}
|
|
80
|
+
focused={focused}
|
|
81
|
+
selected={selected}
|
|
82
|
+
/>
|
|
83
|
+
) : null}
|
|
84
|
+
</View>
|
|
85
|
+
|
|
86
|
+
{selected ? (
|
|
87
|
+
<ItemIcon {...iconBaseProps} asset={selectedItemIconPropsAssets} />
|
|
88
|
+
) : (
|
|
89
|
+
iconPlacement === "right" && renderItemIcon
|
|
90
|
+
)}
|
|
91
|
+
</Item>
|
|
92
|
+
</TouchableOpacity>
|
|
110
93
|
);
|
|
111
94
|
}
|
|
@@ -8,13 +8,18 @@ import { PluginConfiguration } from "../index";
|
|
|
8
8
|
type Props = {
|
|
9
9
|
dismiss: () => void;
|
|
10
10
|
configuration: PluginConfiguration;
|
|
11
|
-
width: number;
|
|
12
11
|
onLayout?: (event: LayoutChangeEvent) => void;
|
|
13
12
|
summary?: string;
|
|
14
13
|
title?: string;
|
|
15
14
|
};
|
|
16
15
|
|
|
17
16
|
const styles = StyleSheet.create({
|
|
17
|
+
noFlex: {
|
|
18
|
+
flex: 0,
|
|
19
|
+
},
|
|
20
|
+
flex: {
|
|
21
|
+
flex: 1,
|
|
22
|
+
},
|
|
18
23
|
container: {
|
|
19
24
|
flexDirection: "row",
|
|
20
25
|
alignItems: "center",
|
|
@@ -22,7 +27,7 @@ const styles = StyleSheet.create({
|
|
|
22
27
|
});
|
|
23
28
|
|
|
24
29
|
export function ModalHeader(props: Props) {
|
|
25
|
-
const { configuration, dismiss,
|
|
30
|
+
const { configuration, dismiss, onLayout, summary, title } = props;
|
|
26
31
|
|
|
27
32
|
const closeButtonProps = useMemo<CloseButtonProps>(
|
|
28
33
|
() => ({
|
|
@@ -55,15 +60,11 @@ export function ModalHeader(props: Props) {
|
|
|
55
60
|
|
|
56
61
|
return (
|
|
57
62
|
<View onLayout={onLayout} style={styles.container}>
|
|
58
|
-
<View
|
|
59
|
-
style={{
|
|
60
|
-
width: width - buttonsContainerWidth,
|
|
61
|
-
}}
|
|
62
|
-
>
|
|
63
|
+
<View style={styles.flex}>
|
|
63
64
|
{title ? <Title {...titleProps} /> : null}
|
|
64
65
|
{summary ? <Title {...summaryProps} /> : null}
|
|
65
66
|
</View>
|
|
66
|
-
<View style={{ width: buttonsContainerWidth }}>
|
|
67
|
+
<View style={[styles.noFlex, { width: buttonsContainerWidth }]}>
|
|
67
68
|
<CloseButton {...closeButtonProps} />
|
|
68
69
|
</View>
|
|
69
70
|
</View>
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
2
|
-
import { PluginConfiguration } from "./
|
|
2
|
+
import { PluginConfiguration } from "./";
|
|
3
|
+
import { ItemIconProps } from "./Button/ItemIcon";
|
|
4
|
+
import { ItemLabelProps } from "./Button/ItemLabel";
|
|
5
|
+
import { ItemProps } from "./Button/Item";
|
|
3
6
|
|
|
4
7
|
export function defaultItemProps(
|
|
5
8
|
config: PluginConfiguration,
|
|
6
9
|
maxWidth: number
|
|
7
|
-
) {
|
|
10
|
+
): ItemProps {
|
|
8
11
|
const {
|
|
9
12
|
modal_bottom_sheet_item_background_color,
|
|
10
13
|
modal_bottom_sheet_item_focus_background_color,
|
|
11
14
|
modal_bottom_sheet_item_selected_background_color,
|
|
12
|
-
|
|
15
|
+
modal_bottom_sheet_item_focused_selected_background_color,
|
|
13
16
|
modal_bottom_sheet_item_corner_radius,
|
|
14
17
|
modal_bottom_sheet_item_margin_bottom,
|
|
15
18
|
modal_bottom_sheet_item_margin_left,
|
|
@@ -25,8 +28,8 @@ export function defaultItemProps(
|
|
|
25
28
|
backgroundColor: modal_bottom_sheet_item_background_color,
|
|
26
29
|
focusedBackgroundColor: modal_bottom_sheet_item_focus_background_color,
|
|
27
30
|
selectedBackgroundColor: modal_bottom_sheet_item_selected_background_color,
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
focusedSelectedBackgroundColor:
|
|
32
|
+
modal_bottom_sheet_item_focused_selected_background_color,
|
|
30
33
|
borderRadius: modal_bottom_sheet_item_corner_radius,
|
|
31
34
|
marginBottom: modal_bottom_sheet_item_margin_bottom,
|
|
32
35
|
marginTop: modal_bottom_sheet_item_margin_top,
|
|
@@ -43,7 +46,7 @@ export function defaultItemProps(
|
|
|
43
46
|
export function defaultItemLabelProps(
|
|
44
47
|
config: PluginConfiguration,
|
|
45
48
|
sheetWidth: number
|
|
46
|
-
) {
|
|
49
|
+
): ItemLabelProps {
|
|
47
50
|
const {
|
|
48
51
|
modal_bottom_sheet_item_label_android_letter_spacing,
|
|
49
52
|
modal_bottom_sheet_item_label_ios_letter_spacing,
|
|
@@ -103,7 +106,9 @@ export function defaultItemLabelProps(
|
|
|
103
106
|
};
|
|
104
107
|
}
|
|
105
108
|
|
|
106
|
-
export function defaultItemIconProps(
|
|
109
|
+
export function defaultItemIconProps(
|
|
110
|
+
config: PluginConfiguration
|
|
111
|
+
): ItemIconProps {
|
|
107
112
|
const {
|
|
108
113
|
modal_bottom_sheet_item_icon_height,
|
|
109
114
|
modal_bottom_sheet_item_icon_width,
|
|
@@ -124,3 +129,46 @@ export function defaultItemIconProps(config: PluginConfiguration) {
|
|
|
124
129
|
marginRight: modal_bottom_sheet_item_icon_margin_right,
|
|
125
130
|
};
|
|
126
131
|
}
|
|
132
|
+
|
|
133
|
+
export function getItemIconProps(
|
|
134
|
+
theme: PluginConfiguration,
|
|
135
|
+
iconProps?: ((theme: PluginConfiguration) => ItemIconProps) | ItemIconProps
|
|
136
|
+
) {
|
|
137
|
+
if (iconProps) {
|
|
138
|
+
return typeof iconProps === "function" ? iconProps(theme) : iconProps;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return defaultItemIconProps(theme);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function getItemLabelProps(
|
|
145
|
+
theme: PluginConfiguration,
|
|
146
|
+
width: number,
|
|
147
|
+
labelProps?:
|
|
148
|
+
| ((theme: PluginConfiguration, width: number) => ItemLabelProps)
|
|
149
|
+
| ItemLabelProps
|
|
150
|
+
) {
|
|
151
|
+
if (labelProps) {
|
|
152
|
+
return typeof labelProps === "function"
|
|
153
|
+
? labelProps(theme, width)
|
|
154
|
+
: labelProps;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return defaultItemLabelProps(theme, width);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export function getItemProps(
|
|
161
|
+
theme: PluginConfiguration,
|
|
162
|
+
width: number,
|
|
163
|
+
itemProps?:
|
|
164
|
+
| ((theme: PluginConfiguration, width: number) => ItemProps)
|
|
165
|
+
| ItemProps
|
|
166
|
+
) {
|
|
167
|
+
if (itemProps) {
|
|
168
|
+
return typeof itemProps === "function"
|
|
169
|
+
? itemProps(theme, width)
|
|
170
|
+
: itemProps;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return defaultItemProps(theme, width);
|
|
174
|
+
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
isApplePlatform,
|
|
10
10
|
isTV,
|
|
11
11
|
platformSelect,
|
|
12
|
+
isAndroidTVPlatform,
|
|
12
13
|
} from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
13
14
|
|
|
14
15
|
import { TVEventHandlerComponent } from "@applicaster/zapp-react-native-tvos-ui-components/Components/TVEventHandlerComponent";
|
|
@@ -93,6 +94,20 @@ export type PlayNextData = {
|
|
|
93
94
|
|
|
94
95
|
const focusableBottomContainerId = "player-container-bottom";
|
|
95
96
|
|
|
97
|
+
const isAndroidTV = isAndroidTVPlatform();
|
|
98
|
+
|
|
99
|
+
const withBorderHack = () => {
|
|
100
|
+
if (isAndroidTV) {
|
|
101
|
+
/* @HACK: see GH#7269 */
|
|
102
|
+
return {
|
|
103
|
+
borderWidth: 1,
|
|
104
|
+
borderColor: "transparent",
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return {};
|
|
109
|
+
};
|
|
110
|
+
|
|
96
111
|
// Styles
|
|
97
112
|
const webStyles = {
|
|
98
113
|
focusableGroup: {
|
|
@@ -582,7 +597,7 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
582
597
|
);
|
|
583
598
|
}
|
|
584
599
|
|
|
585
|
-
if (screen_background_color) {
|
|
600
|
+
if (screen_background_color && mode !== VideoModalMode.FULLSCREEN) {
|
|
586
601
|
updatedStyles.playerScreen.backgroundColor = screen_background_color;
|
|
587
602
|
}
|
|
588
603
|
|
|
@@ -600,6 +615,7 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
600
615
|
tv_component_container_height,
|
|
601
616
|
screen_background_color,
|
|
602
617
|
isInlineTV,
|
|
618
|
+
mode,
|
|
603
619
|
]);
|
|
604
620
|
|
|
605
621
|
const applePlayerProps = {
|
|
@@ -644,7 +660,14 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
644
660
|
testID={"player-screen-container"}
|
|
645
661
|
>
|
|
646
662
|
{/* Player container */}
|
|
647
|
-
<View
|
|
663
|
+
<View
|
|
664
|
+
style={[
|
|
665
|
+
styles.playerWrapper,
|
|
666
|
+
// eslint-disable-next-line react-native/no-inline-styles, react-native/no-color-literals
|
|
667
|
+
withBorderHack(),
|
|
668
|
+
]}
|
|
669
|
+
testID={"player-wrapper"}
|
|
670
|
+
>
|
|
648
671
|
<PlayerFocusableWrapperView
|
|
649
672
|
nextFocusDown={context.bottomFocusableId}
|
|
650
673
|
>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useEffect } from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
|
+
import { isGroup } from "@applicaster/zapp-react-native-utils/componentsUtils";
|
|
3
4
|
|
|
4
5
|
import { applyDecorators } from "../../Decorators";
|
|
5
6
|
|
|
@@ -112,7 +113,7 @@ function RiverItemComponent(props: RiverItemType) {
|
|
|
112
113
|
jsOnly: true,
|
|
113
114
|
});
|
|
114
115
|
|
|
115
|
-
if (!CellRenderer && item
|
|
116
|
+
if (!CellRenderer && !isGroup(item)) {
|
|
116
117
|
riverLogger.warning({
|
|
117
118
|
message: "Cell Renderer is null - will fallback to default cell",
|
|
118
119
|
data: { item, CellRenderer },
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const {
|
|
2
|
+
useScreenBackgroundColor,
|
|
3
|
+
} = require("@applicaster/zapp-react-native-utils/reactHooks/screen");
|
|
4
|
+
|
|
5
|
+
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/screen", () => ({
|
|
6
|
+
useScreenBackgroundColor: jest.fn(),
|
|
7
|
+
useNavbarState: jest.fn().mockReturnValue({ visible: true }),
|
|
8
|
+
}));
|
|
9
|
+
|
|
10
|
+
describe("TV Screen Component", () => {
|
|
11
|
+
it("uses the useScreenBackgroundColor hook with the correct screen ID", () => {
|
|
12
|
+
useScreenBackgroundColor.mockReturnValue("#FF0000");
|
|
13
|
+
|
|
14
|
+
expect(useScreenBackgroundColor("test-screen-id")).toBe("#FF0000");
|
|
15
|
+
|
|
16
|
+
// Verify the hook was called with the correct screen ID
|
|
17
|
+
expect(useScreenBackgroundColor).toHaveBeenCalledWith("test-screen-id");
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("returns 'transparent' when the screen background color is not defined", () => {
|
|
21
|
+
useScreenBackgroundColor.mockReturnValue("transparent");
|
|
22
|
+
|
|
23
|
+
// Verify the hook returns 'transparent'
|
|
24
|
+
expect(useScreenBackgroundColor("test-screen-id")).toBe("transparent");
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -68,21 +68,21 @@ jest.mock(
|
|
|
68
68
|
})
|
|
69
69
|
);
|
|
70
70
|
|
|
71
|
-
jest.mock(
|
|
72
|
-
"@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenData",
|
|
73
|
-
() => ({
|
|
74
|
-
useScreenData: jest.fn(() => ({
|
|
75
|
-
id: "testId",
|
|
76
|
-
navigations: [{ id: "testId", category: "nav_bar" }],
|
|
77
|
-
})),
|
|
78
|
-
})
|
|
79
|
-
);
|
|
80
|
-
|
|
81
71
|
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
|
|
82
72
|
isNavBarVisible: mockIsNavBarVisible,
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
73
|
+
useIsScreenActive: jest.fn().mockReturnValue(true),
|
|
74
|
+
}));
|
|
75
|
+
|
|
76
|
+
jest.mock("@applicaster/zapp-react-native-utils/reactHooks", () => ({
|
|
77
|
+
useCurrentScreenData: jest.fn(() => ({
|
|
78
|
+
id: "testId",
|
|
79
|
+
})),
|
|
80
|
+
useNavbarState: jest.fn(() => ({
|
|
81
|
+
title: "Test Title",
|
|
82
|
+
})),
|
|
83
|
+
useScreenData: jest.fn(() => ({
|
|
84
|
+
id: "testId",
|
|
85
|
+
navigations: [{ id: "testId", category: "nav_bar" }],
|
|
86
86
|
})),
|
|
87
87
|
useNavigation: jest.fn(() => ({
|
|
88
88
|
canGoBack: () => false,
|
|
@@ -91,7 +91,15 @@ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
|
|
|
91
91
|
screenData: { id: "testId" },
|
|
92
92
|
data: { screen: { id: "testId" } },
|
|
93
93
|
})),
|
|
94
|
-
|
|
94
|
+
useRoute: jest.fn(() => ({
|
|
95
|
+
pathname: "/river/testId",
|
|
96
|
+
screenData: { id: "testId" },
|
|
97
|
+
})),
|
|
98
|
+
useDimensions: jest.fn(() => ({
|
|
99
|
+
width: 1920,
|
|
100
|
+
height: 1080,
|
|
101
|
+
})),
|
|
102
|
+
useIsTablet: jest.fn(() => false),
|
|
95
103
|
}));
|
|
96
104
|
|
|
97
105
|
jest.mock("@applicaster/zapp-react-native-redux/hooks/usePickFromState", () => {
|
|
@@ -16,7 +16,7 @@ exports[`<Screen Component /> when the navbar should be hidden renders correctly
|
|
|
16
16
|
pathname="/river/testId"
|
|
17
17
|
selected="testId"
|
|
18
18
|
testID="navBar"
|
|
19
|
-
title=""
|
|
19
|
+
title="Test Title"
|
|
20
20
|
/>
|
|
21
21
|
<View>
|
|
22
22
|
<View
|
|
@@ -48,7 +48,7 @@ exports[`<Screen Component /> when the navbar should show renders correctly 1`]
|
|
|
48
48
|
pathname="/river/testId"
|
|
49
49
|
selected="testId"
|
|
50
50
|
testID="navBar"
|
|
51
|
-
title=""
|
|
51
|
+
title="Test Title"
|
|
52
52
|
/>
|
|
53
53
|
<View>
|
|
54
54
|
<View
|
|
@@ -2,6 +2,7 @@ import React from "react";
|
|
|
2
2
|
import { View, ViewProps, ViewStyle } from "react-native";
|
|
3
3
|
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
4
4
|
import { useCurrentScreenData } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
5
|
+
import { isFirstComponentScreenPicker } from "@applicaster/zapp-react-native-utils/componentsUtils";
|
|
5
6
|
|
|
6
7
|
interface IProps {
|
|
7
8
|
targetScreenId?: string;
|
|
@@ -31,11 +32,9 @@ export const useMarginTop = (targetScreenId: string): number => {
|
|
|
31
32
|
* ScreenPicker is a component but should really be a screen.
|
|
32
33
|
* We need to skip margin top for it as it's already applied to the target screen
|
|
33
34
|
**/
|
|
34
|
-
const isScreenPicker =
|
|
35
|
-
screenData?.ui_components?.[0]?.component_type === "screen-picker-qb-tv";
|
|
36
35
|
|
|
37
36
|
// ignore margin on screenPicker
|
|
38
|
-
if (
|
|
37
|
+
if (isFirstComponentScreenPicker(screenData?.ui_components)) {
|
|
39
38
|
return 0;
|
|
40
39
|
}
|
|
41
40
|
|
|
@@ -23,10 +23,12 @@ import {
|
|
|
23
23
|
setScrollModalAnimatedValue,
|
|
24
24
|
} from "./utils";
|
|
25
25
|
|
|
26
|
+
import { DURATION_TO_MINIMIZE } from "./const";
|
|
27
|
+
|
|
26
28
|
const getAnimatedConfig = (toValue) => {
|
|
27
29
|
return {
|
|
28
30
|
toValue,
|
|
29
|
-
duration:
|
|
31
|
+
duration: DURATION_TO_MINIMIZE,
|
|
30
32
|
useNativeDriver: true,
|
|
31
33
|
};
|
|
32
34
|
};
|
|
@@ -142,7 +144,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
142
144
|
|
|
143
145
|
setLastSnap(destSnapPoint);
|
|
144
146
|
|
|
145
|
-
if (destSnapPoint === modalSnapPoints[0]
|
|
147
|
+
if (destSnapPoint === modalSnapPoints[0]) {
|
|
146
148
|
translateYOffset.extractOffset();
|
|
147
149
|
translateYOffset.setValue(preparedTranslationY);
|
|
148
150
|
translateYOffset.flattenOffset();
|
|
@@ -24,8 +24,11 @@ import {
|
|
|
24
24
|
gestureListenerHelper,
|
|
25
25
|
getAnimationDefaultValue,
|
|
26
26
|
getAnimationStyle,
|
|
27
|
+
getMoveUpValue,
|
|
27
28
|
} from "./utils";
|
|
28
29
|
|
|
30
|
+
import { DURATION_TO_MINIMIZE, DEFAULT_DURATION_FOR_ANIMATION } from "./const";
|
|
31
|
+
|
|
29
32
|
type Props = {
|
|
30
33
|
animationType: string;
|
|
31
34
|
children: React.ReactNode;
|
|
@@ -91,20 +94,21 @@ export const AnimationView = ({
|
|
|
91
94
|
const isAudioItem = React.useMemo(
|
|
92
95
|
() =>
|
|
93
96
|
videoModalItem?.content?.type?.includes?.("audio") ||
|
|
94
|
-
videoModalItem?.type?.value
|
|
97
|
+
videoModalItem?.type?.value?.includes?.("audio"),
|
|
95
98
|
[videoModalItem]
|
|
96
99
|
);
|
|
97
100
|
|
|
98
101
|
const inlineAudioPlayer = additionalData.inlineAudioPlayer;
|
|
99
102
|
|
|
100
|
-
const moveUpValue =
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
const moveUpValue = getMoveUpValue({
|
|
104
|
+
additionalData,
|
|
105
|
+
insets,
|
|
106
|
+
isAudioItem,
|
|
107
|
+
progressBarHeight,
|
|
108
|
+
isTablet,
|
|
109
|
+
isTabletLandscape,
|
|
110
|
+
tabletLandscapePlayerTopPosition,
|
|
111
|
+
});
|
|
108
112
|
|
|
109
113
|
const moveComponentHorizontalValue = additionalData.moveValue
|
|
110
114
|
? isRTL
|
|
@@ -119,7 +123,10 @@ export const AnimationView = ({
|
|
|
119
123
|
(animationType, state) => {
|
|
120
124
|
const defaultConfig = {
|
|
121
125
|
toValue: 0,
|
|
122
|
-
duration:
|
|
126
|
+
duration:
|
|
127
|
+
state === PlayerAnimationStateEnum.minimize
|
|
128
|
+
? DURATION_TO_MINIMIZE
|
|
129
|
+
: DEFAULT_DURATION_FOR_ANIMATION,
|
|
123
130
|
useNativeDriver: true,
|
|
124
131
|
};
|
|
125
132
|
|
|
@@ -440,6 +447,10 @@ export const AnimationComponent = (props: Props) => {
|
|
|
440
447
|
videoModalState: { visible },
|
|
441
448
|
} = useNavigation();
|
|
442
449
|
|
|
450
|
+
if (additionalData?.disableAnimatedComponent) {
|
|
451
|
+
return <>{props.children}</>;
|
|
452
|
+
}
|
|
453
|
+
|
|
443
454
|
const useAnimation =
|
|
444
455
|
visible && !additionalData.disableAnimatedComponent && !isTV();
|
|
445
456
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
2
|
import { Animated } from "react-native";
|
|
3
3
|
|
|
4
4
|
import {
|
|
@@ -95,6 +95,13 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
|
|
|
95
95
|
setStartComponentsAnimation(false);
|
|
96
96
|
}, []);
|
|
97
97
|
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
// Reset player animation state when video modal is closed
|
|
100
|
+
if (!visible) {
|
|
101
|
+
resetPlayerAnimationState();
|
|
102
|
+
}
|
|
103
|
+
}, [visible, resetPlayerAnimationState]);
|
|
104
|
+
|
|
98
105
|
// Animated values
|
|
99
106
|
const lastScrollY = React.useRef(new Animated.Value(0)).current;
|
|
100
107
|
const dragScrollY = React.useRef(new Animated.Value(0)).current;
|