@applicaster/zapp-react-native-ui-components 12.0.0-rc.5 → 12.0.0-rc.51
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 +18 -10
- package/Components/AudioPlayer/AudioPlayer.tsx +9 -1
- package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +5 -0
- package/Components/AudioPlayer/helpers.tsx +1 -0
- package/Components/Cell/Cell.tsx +2 -2
- package/Components/Cell/CellWithFocusable.tsx +21 -14
- package/Components/Cell/TvOSCellComponent.tsx +2 -2
- package/Components/ErrorScreen/index.tsx +1 -1
- package/Components/FocusableCell/index.tsx +7 -7
- package/Components/FocusableList/FocusableChild.ts +24 -14
- package/Components/FocusableList/FocusableItem.tsx +1 -1
- package/Components/FocusableList/FocusableListItemWrapper.tsx +76 -0
- package/Components/FocusableList/hooks/useCellState.android.ts +3 -1
- package/Components/FocusableList/index.tsx +26 -25
- package/Components/GeneralContentScreen/GeneralContentScreen.tsx +11 -8
- package/Components/HandlePlayable/HandlePlayable.tsx +1 -1
- package/Components/HookRenderer/index.tsx +1 -6
- package/Components/Image/Image.android.tsx +3 -22
- package/Components/Image/Image.tsx +18 -2
- package/Components/Image/utils/index.ts +39 -0
- package/Components/Layout/TV/__tests__/index.test.tsx +1 -34
- package/Components/Layout/TV/index.tsx +20 -36
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +0 -1
- package/Components/MasterCell/DefaultComponents/CellBadge/index.tsx +21 -8
- package/Components/MasterCell/DefaultComponents/Image/Image.android.tsx +9 -26
- package/Components/MasterCell/DefaultComponents/Image/hooks/useImageSize.ts +65 -0
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +17 -2
- package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +3 -2
- package/Components/MasterCell/DefaultComponents/Toggle.tsx +5 -1
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +8 -10
- package/Components/MasterCell/utils/index.ts +16 -5
- package/Components/ModalComponent/BottomSheetModalContent.tsx +121 -0
- package/Components/ModalComponent/Button/Item.tsx +82 -0
- package/Components/ModalComponent/Button/ItemIcon.tsx +60 -0
- package/Components/ModalComponent/Button/ItemLabel.tsx +101 -0
- package/Components/ModalComponent/Button/assets.ts +4 -0
- package/Components/ModalComponent/Button/index.tsx +111 -0
- package/Components/ModalComponent/Header/CloseButton.tsx +59 -0
- package/Components/ModalComponent/Header/Title.tsx +70 -0
- package/Components/ModalComponent/Header/assets.ts +4 -0
- package/Components/ModalComponent/Header/index.tsx +71 -0
- package/Components/ModalComponent/Header/utils.ts +79 -0
- package/Components/ModalComponent/index.tsx +38 -0
- package/Components/ModalComponent/utils.ts +126 -0
- package/Components/PlayerContainer/ErrorDisplay/ErrorDisplay.tsx +4 -7
- package/Components/PlayerContainer/PlayerContainer.tsx +60 -30
- package/Components/PlayerContainer/ProgramInfo/index.tsx +3 -1
- package/Components/PlayerImageBackground/index.tsx +34 -8
- package/Components/River/ComponentsMap/ComponentsMap.tsx +25 -0
- package/Components/River/River.tsx +8 -5
- package/Components/River/TV/River.tsx +2 -2
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +1 -1
- package/Components/River/__tests__/componentsMap.test.js +7 -0
- package/Components/River/useScreenConfiguration.ts +5 -6
- package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +1 -0
- package/Components/RouteManager/__tests__/routeManager.test.js +9 -2
- package/Components/RouteManager/index.tsx +5 -3
- package/Components/Screen/__tests__/Screen.test.tsx +48 -36
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +20 -6
- package/Components/Screen/__tests__/navigationHandler.test.ts +1 -178
- package/Components/Screen/index.tsx +92 -44
- package/Components/Screen/navigationHandler.ts +0 -82
- package/Components/Screen/orientationHandler.ts +1 -1
- package/Components/ScreenResolver/index.tsx +1 -1
- package/Components/Tabs/TV/styles.ts +1 -1
- package/Components/TrackedView/index.tsx +6 -3
- package/Components/VideoLive/LiveImageManager.ts +42 -13
- package/Components/VideoLive/PlayerLiveImageComponent.tsx +81 -72
- package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +45 -3
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +22 -27
- package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +78 -0
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +342 -0
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +151 -0
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +438 -0
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +143 -0
- package/Components/VideoModal/ModalAnimation/index.ts +15 -0
- package/Components/VideoModal/ModalAnimation/utils.ts +299 -0
- package/Components/VideoModal/PlayerDetails.tsx +3 -0
- package/Components/VideoModal/PlayerWrapper.tsx +119 -95
- package/Components/VideoModal/VideoModal.tsx +8 -25
- package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +0 -2
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +8 -3
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +242 -166
- package/Components/VideoModal/hooks/useModalSize.ts +13 -4
- package/Components/VideoModal/utils.ts +3 -3
- package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +26 -21
- package/Components/Viewport/ViewportTracker/__tests__/viewportTracker.test.js +4 -5
- package/Components/ZappUIComponent/index.tsx +22 -12
- package/Components/index.js +2 -0
- package/Contexts/ScreenContext/index.tsx +1 -4
- package/Decorators/ComponentsMapWrapper/withComponentsMapProvider.tsx +7 -2
- package/Decorators/RiverResolver/index.tsx +0 -4
- package/Decorators/index.tsx +0 -4
- package/package.json +5 -6
- package/Components/VideoModal/hooks/usePosition.ts +0 -50
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
2
|
+
import { PluginConfiguration } from "./index";
|
|
3
|
+
|
|
4
|
+
export function defaultItemProps(
|
|
5
|
+
config: PluginConfiguration,
|
|
6
|
+
maxWidth: number
|
|
7
|
+
) {
|
|
8
|
+
const {
|
|
9
|
+
modal_bottom_sheet_item_background_color,
|
|
10
|
+
modal_bottom_sheet_item_focus_background_color,
|
|
11
|
+
modal_bottom_sheet_item_selected_background_color,
|
|
12
|
+
modal_bottom_sheet_item_focusected_background_color,
|
|
13
|
+
modal_bottom_sheet_item_corner_radius,
|
|
14
|
+
modal_bottom_sheet_item_margin_bottom,
|
|
15
|
+
modal_bottom_sheet_item_margin_left,
|
|
16
|
+
modal_bottom_sheet_item_margin_right,
|
|
17
|
+
modal_bottom_sheet_item_margin_top,
|
|
18
|
+
modal_bottom_sheet_item_padding_bottom,
|
|
19
|
+
modal_bottom_sheet_item_padding_left,
|
|
20
|
+
modal_bottom_sheet_item_padding_right,
|
|
21
|
+
modal_bottom_sheet_item_padding_top,
|
|
22
|
+
} = config;
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
backgroundColor: modal_bottom_sheet_item_background_color,
|
|
26
|
+
focusedBackgroundColor: modal_bottom_sheet_item_focus_background_color,
|
|
27
|
+
selectedBackgroundColor: modal_bottom_sheet_item_selected_background_color,
|
|
28
|
+
focusectedBackgroundColor:
|
|
29
|
+
modal_bottom_sheet_item_focusected_background_color,
|
|
30
|
+
borderRadius: modal_bottom_sheet_item_corner_radius,
|
|
31
|
+
marginBottom: modal_bottom_sheet_item_margin_bottom,
|
|
32
|
+
marginTop: modal_bottom_sheet_item_margin_top,
|
|
33
|
+
marginLeft: modal_bottom_sheet_item_margin_left,
|
|
34
|
+
marginRight: modal_bottom_sheet_item_margin_right,
|
|
35
|
+
paddingTop: modal_bottom_sheet_item_padding_top,
|
|
36
|
+
paddingBottom: modal_bottom_sheet_item_padding_bottom,
|
|
37
|
+
paddingRight: modal_bottom_sheet_item_padding_right,
|
|
38
|
+
paddingLeft: modal_bottom_sheet_item_padding_left,
|
|
39
|
+
maxWidth,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function defaultItemLabelProps(
|
|
44
|
+
config: PluginConfiguration,
|
|
45
|
+
sheetWidth: number
|
|
46
|
+
) {
|
|
47
|
+
const {
|
|
48
|
+
modal_bottom_sheet_item_label_android_letter_spacing,
|
|
49
|
+
modal_bottom_sheet_item_label_ios_letter_spacing,
|
|
50
|
+
modal_bottom_sheet_item_label_family_ios_font_selector,
|
|
51
|
+
modal_bottom_sheet_item_label_family_android_font_selector,
|
|
52
|
+
modal_bottom_sheet_item_label_focus_font_color,
|
|
53
|
+
modal_bottom_sheet_item_label_font_color,
|
|
54
|
+
modal_bottom_sheet_item_label_selected_font_color,
|
|
55
|
+
modal_bottom_sheet_item_label_hover_selected_font_color,
|
|
56
|
+
modal_bottom_sheet_item_label_font_size,
|
|
57
|
+
modal_bottom_sheet_item_label_line_height,
|
|
58
|
+
modal_bottom_sheet_item_label_margin_bottom,
|
|
59
|
+
modal_bottom_sheet_item_label_margin_top,
|
|
60
|
+
modal_bottom_sheet_item_label_margin_left,
|
|
61
|
+
modal_bottom_sheet_item_label_margin_right,
|
|
62
|
+
modal_bottom_sheet_item_label_transform,
|
|
63
|
+
modal_bottom_sheet_item_icon_width,
|
|
64
|
+
modal_bottom_sheet_item_icon_margin_left,
|
|
65
|
+
modal_bottom_sheet_item_icon_margin_right,
|
|
66
|
+
modal_bottom_sheet_item_margin_left,
|
|
67
|
+
modal_bottom_sheet_item_margin_right,
|
|
68
|
+
modal_bottom_sheet_item_padding_left,
|
|
69
|
+
modal_bottom_sheet_item_padding_right,
|
|
70
|
+
} = config;
|
|
71
|
+
|
|
72
|
+
const maxWidth =
|
|
73
|
+
sheetWidth -
|
|
74
|
+
(modal_bottom_sheet_item_icon_width +
|
|
75
|
+
modal_bottom_sheet_item_icon_margin_left +
|
|
76
|
+
modal_bottom_sheet_item_icon_margin_right +
|
|
77
|
+
modal_bottom_sheet_item_margin_left +
|
|
78
|
+
modal_bottom_sheet_item_margin_right +
|
|
79
|
+
modal_bottom_sheet_item_padding_left +
|
|
80
|
+
modal_bottom_sheet_item_padding_right);
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
fontFamily: platformSelect({
|
|
84
|
+
ios: modal_bottom_sheet_item_label_family_ios_font_selector,
|
|
85
|
+
android: modal_bottom_sheet_item_label_family_android_font_selector,
|
|
86
|
+
}),
|
|
87
|
+
letterSpacing: platformSelect({
|
|
88
|
+
ios: modal_bottom_sheet_item_label_ios_letter_spacing,
|
|
89
|
+
android: modal_bottom_sheet_item_label_android_letter_spacing,
|
|
90
|
+
}),
|
|
91
|
+
fontSize: modal_bottom_sheet_item_label_font_size,
|
|
92
|
+
color: modal_bottom_sheet_item_label_font_color,
|
|
93
|
+
focusColor: modal_bottom_sheet_item_label_focus_font_color,
|
|
94
|
+
hoverSelectedColor: modal_bottom_sheet_item_label_hover_selected_font_color,
|
|
95
|
+
selectedColor: modal_bottom_sheet_item_label_selected_font_color,
|
|
96
|
+
lineHeight: modal_bottom_sheet_item_label_line_height,
|
|
97
|
+
marginBottom: modal_bottom_sheet_item_label_margin_bottom,
|
|
98
|
+
marginTop: modal_bottom_sheet_item_label_margin_top,
|
|
99
|
+
marginLeft: modal_bottom_sheet_item_label_margin_left,
|
|
100
|
+
marginRight: modal_bottom_sheet_item_label_margin_right,
|
|
101
|
+
transform: modal_bottom_sheet_item_label_transform,
|
|
102
|
+
maxWidth,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function defaultItemIconProps(config: PluginConfiguration) {
|
|
107
|
+
const {
|
|
108
|
+
modal_bottom_sheet_item_icon_height,
|
|
109
|
+
modal_bottom_sheet_item_icon_width,
|
|
110
|
+
modal_bottom_sheet_item_icon_margin_bottom,
|
|
111
|
+
modal_bottom_sheet_item_icon_margin_left,
|
|
112
|
+
modal_bottom_sheet_item_icon_margin_right,
|
|
113
|
+
modal_bottom_sheet_item_icon_margin_top,
|
|
114
|
+
modal_bottom_sheet_item_icon_flavour,
|
|
115
|
+
} = config;
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
width: modal_bottom_sheet_item_icon_width,
|
|
119
|
+
height: modal_bottom_sheet_item_icon_height,
|
|
120
|
+
flavour: modal_bottom_sheet_item_icon_flavour,
|
|
121
|
+
marginTop: modal_bottom_sheet_item_icon_margin_top,
|
|
122
|
+
marginBottom: modal_bottom_sheet_item_icon_margin_bottom,
|
|
123
|
+
marginLeft: modal_bottom_sheet_item_icon_margin_left,
|
|
124
|
+
marginRight: modal_bottom_sheet_item_icon_margin_right,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
@@ -4,7 +4,6 @@ import { Text, TextStyle, View, ViewStyle } from "react-native";
|
|
|
4
4
|
|
|
5
5
|
import { getLocalizations } from "@applicaster/zapp-react-native-utils/localizationUtils";
|
|
6
6
|
import { getAppStylesColor } from "@applicaster/zapp-react-native-utils/stylesUtils";
|
|
7
|
-
import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks/layout";
|
|
8
7
|
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
9
8
|
import { styleKeys } from "@applicaster/zapp-react-native-utils/styleKeysUtils";
|
|
10
9
|
|
|
@@ -26,10 +25,10 @@ const textStyles = (appStyles = defaultAppStyles): TextStyle => ({
|
|
|
26
25
|
textAlign: "center",
|
|
27
26
|
});
|
|
28
27
|
|
|
29
|
-
const errorStyles = ({
|
|
28
|
+
const errorStyles = ({ backgroundColor }): ViewStyle => ({
|
|
30
29
|
flex: 1,
|
|
31
|
-
width,
|
|
32
|
-
height,
|
|
30
|
+
width: "100%",
|
|
31
|
+
height: "100%",
|
|
33
32
|
justifyContent: "center",
|
|
34
33
|
alignItems: "center",
|
|
35
34
|
position: "absolute",
|
|
@@ -41,8 +40,6 @@ export function ErrorDisplayComponent({
|
|
|
41
40
|
styles,
|
|
42
41
|
remoteConfigurations: { localizations },
|
|
43
42
|
}: Props) {
|
|
44
|
-
const { width, height } = useDimensions("window");
|
|
45
|
-
|
|
46
43
|
const theme = useTheme();
|
|
47
44
|
const backgroundColor = theme?.app_background_color;
|
|
48
45
|
|
|
@@ -53,7 +50,7 @@ export function ErrorDisplayComponent({
|
|
|
53
50
|
const appStyles = R.prop(styleKeys.style_namespace, styles);
|
|
54
51
|
|
|
55
52
|
return (
|
|
56
|
-
<View style={errorStyles({
|
|
53
|
+
<View style={errorStyles({ backgroundColor })}>
|
|
57
54
|
<Text style={textStyles(appStyles)}>{stream_error_message}</Text>
|
|
58
55
|
</View>
|
|
59
56
|
);
|
|
@@ -54,6 +54,11 @@ import { toNumber } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
|
54
54
|
import { usePlayNextOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayNextOverlay";
|
|
55
55
|
import { PlayNextState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/OverlayObserver/OverlaysObserver";
|
|
56
56
|
|
|
57
|
+
import {
|
|
58
|
+
useModalAnimationContext,
|
|
59
|
+
PlayerAnimationStateEnum,
|
|
60
|
+
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
61
|
+
|
|
57
62
|
type Props = {
|
|
58
63
|
Player: React.ComponentType<any>;
|
|
59
64
|
PlayerLoadingView?: React.ComponentType<any>; // 👀 we are not receiving this prop
|
|
@@ -145,34 +150,30 @@ const renderApplePlayer = ({
|
|
|
145
150
|
}) => {
|
|
146
151
|
const { title, summary } = item || {};
|
|
147
152
|
|
|
148
|
-
if (!
|
|
153
|
+
if (!isAppleTV() || !player) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (isAudioContent) {
|
|
158
|
+
return (
|
|
159
|
+
<AudioPlayer
|
|
160
|
+
audio_item={item}
|
|
161
|
+
plugin_configuration={pluginConfiguration}
|
|
162
|
+
/>
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (!playNextData && player.isPaused() && player.isAd() === false) {
|
|
149
167
|
return null;
|
|
150
168
|
}
|
|
151
169
|
|
|
152
170
|
return (
|
|
153
|
-
|
|
154
|
-
{
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
<ProgramInfo
|
|
160
|
-
title={title}
|
|
161
|
-
subtitle={summary}
|
|
162
|
-
plugin_configuration={pluginConfiguration}
|
|
163
|
-
videoStyle={videoStyle}
|
|
164
|
-
/>
|
|
165
|
-
)}
|
|
166
|
-
</>
|
|
167
|
-
)}
|
|
168
|
-
|
|
169
|
-
{isAudioContent && (
|
|
170
|
-
<AudioPlayer
|
|
171
|
-
audio_item={item}
|
|
172
|
-
plugin_configuration={pluginConfiguration}
|
|
173
|
-
/>
|
|
174
|
-
)}
|
|
175
|
-
</>
|
|
171
|
+
<ProgramInfo
|
|
172
|
+
title={title}
|
|
173
|
+
subtitle={summary}
|
|
174
|
+
plugin_configuration={pluginConfiguration}
|
|
175
|
+
videoStyle={videoStyle}
|
|
176
|
+
/>
|
|
176
177
|
);
|
|
177
178
|
};
|
|
178
179
|
|
|
@@ -233,6 +234,9 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
233
234
|
const screenData = useTargetScreenData(item);
|
|
234
235
|
const { setVisible: showNavBar } = useSetNavbarState();
|
|
235
236
|
|
|
237
|
+
const { isActiveGesture, startComponentsAnimation, setPlayerAnimationState } =
|
|
238
|
+
useModalAnimationContext();
|
|
239
|
+
|
|
236
240
|
const playerEvent = (event, ...args) => {
|
|
237
241
|
playerManager.invokeHandler(event, ...args);
|
|
238
242
|
};
|
|
@@ -339,6 +343,18 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
339
343
|
}
|
|
340
344
|
}, [item?.id, item?.extensions?.resumeTime, player]);
|
|
341
345
|
|
|
346
|
+
const onVideoFullscreenPlayerWillPresent = React.useCallback(() => {
|
|
347
|
+
playerManager.invokeHandler("toggleFullscreen", {
|
|
348
|
+
fullscreen: true,
|
|
349
|
+
});
|
|
350
|
+
}, []);
|
|
351
|
+
|
|
352
|
+
const onVideoFullscreenPlayerWillDismiss = React.useCallback(() => {
|
|
353
|
+
playerManager.invokeHandler("toggleFullscreen", {
|
|
354
|
+
fullscreen: false,
|
|
355
|
+
});
|
|
356
|
+
}, []);
|
|
357
|
+
|
|
342
358
|
// Util methods
|
|
343
359
|
const toggleFullscreen = (event) => {
|
|
344
360
|
const { fullscreen = false } = event || {};
|
|
@@ -381,17 +397,27 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
381
397
|
id: playerContainerId,
|
|
382
398
|
listener: {
|
|
383
399
|
onVideoEnd,
|
|
384
|
-
onError
|
|
385
|
-
onLoad
|
|
400
|
+
onError,
|
|
401
|
+
onLoad,
|
|
386
402
|
onPlayerClose: close,
|
|
387
403
|
onPlayerDetached: close,
|
|
404
|
+
onVideoFullscreenPlayerWillDismiss,
|
|
405
|
+
onVideoFullscreenPlayerWillPresent,
|
|
388
406
|
},
|
|
389
407
|
});
|
|
390
408
|
|
|
391
409
|
return () => {
|
|
392
410
|
player.removeListener(playerContainerId);
|
|
393
411
|
};
|
|
394
|
-
}, [
|
|
412
|
+
}, [
|
|
413
|
+
player,
|
|
414
|
+
onVideoEnd,
|
|
415
|
+
onError,
|
|
416
|
+
onLoad,
|
|
417
|
+
close,
|
|
418
|
+
onVideoFullscreenPlayerWillDismiss,
|
|
419
|
+
onVideoFullscreenPlayerWillPresent,
|
|
420
|
+
]);
|
|
395
421
|
|
|
396
422
|
useEffect(() => {
|
|
397
423
|
// TODO: We should not use playerManager here to connect buttons to player container
|
|
@@ -428,7 +454,7 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
428
454
|
if (disableMiniPlayer) {
|
|
429
455
|
navigator.closeVideoModal();
|
|
430
456
|
} else {
|
|
431
|
-
|
|
457
|
+
setPlayerAnimationState(PlayerAnimationStateEnum.minimize);
|
|
432
458
|
}
|
|
433
459
|
}
|
|
434
460
|
|
|
@@ -621,9 +647,13 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
621
647
|
}}
|
|
622
648
|
focused={isInlineTV ? true : undefined}
|
|
623
649
|
autoplay={true}
|
|
624
|
-
controls={
|
|
650
|
+
controls={false}
|
|
625
651
|
disableCastAction={disableCastAction}
|
|
626
|
-
docked={
|
|
652
|
+
docked={
|
|
653
|
+
navigator.isVideoModalDocked() &&
|
|
654
|
+
!startComponentsAnimation &&
|
|
655
|
+
!isActiveGesture
|
|
656
|
+
}
|
|
627
657
|
entry={item}
|
|
628
658
|
fullscreen={mode === VideoModalMode.FULLSCREEN}
|
|
629
659
|
inline={inline}
|
|
@@ -4,7 +4,9 @@ import { styleKeys } from "@applicaster/zapp-react-native-utils/styleKeysUtils";
|
|
|
4
4
|
import { transformColorCode as fixColorHexCode } from "@applicaster/zapp-react-native-utils/transform";
|
|
5
5
|
import * as R from "ramda";
|
|
6
6
|
import * as React from "react";
|
|
7
|
-
import {
|
|
7
|
+
import { Text, TextStyle, View, ViewStyle } from "react-native";
|
|
8
|
+
import { QBImage as Image } from "@applicaster/zapp-react-native-ui-components/Components/Image";
|
|
9
|
+
|
|
8
10
|
import * as programStyles from "./styles";
|
|
9
11
|
|
|
10
12
|
type Props = {
|
|
@@ -1,38 +1,64 @@
|
|
|
1
1
|
import React, { PropsWithChildren } from "react";
|
|
2
|
-
import { ImageBackground } from "react-native";
|
|
2
|
+
import { ImageBackground, View } from "react-native";
|
|
3
3
|
|
|
4
4
|
import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
|
|
5
|
+
import {
|
|
6
|
+
AnimationComponent,
|
|
7
|
+
ComponentAnimationType,
|
|
8
|
+
useModalAnimationContext,
|
|
9
|
+
PlayerAnimationStateEnum,
|
|
10
|
+
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
5
11
|
|
|
6
12
|
type Props = PropsWithChildren<{
|
|
7
13
|
entry: ZappEntry;
|
|
8
14
|
style?: { [K: string]: any };
|
|
9
15
|
imageStyle?: { [K: string]: any };
|
|
10
16
|
imageKey?: string;
|
|
17
|
+
defaultImageDimensions?: { [K: string]: any };
|
|
11
18
|
}>;
|
|
12
19
|
|
|
20
|
+
const imageSize = { width: "100%", height: "100%" };
|
|
21
|
+
|
|
13
22
|
const PlayerImageBackgroundComponent = ({
|
|
14
23
|
entry,
|
|
15
24
|
children,
|
|
16
25
|
style,
|
|
17
26
|
imageStyle,
|
|
18
27
|
imageKey,
|
|
28
|
+
defaultImageDimensions,
|
|
19
29
|
}: Props) => {
|
|
20
30
|
const source = React.useMemo(
|
|
21
31
|
() => ({ uri: imageSrcFromMediaItem(entry, imageKey) }),
|
|
22
32
|
[imageKey, entry]
|
|
23
33
|
);
|
|
24
34
|
|
|
35
|
+
const { playerAnimationState } = useModalAnimationContext();
|
|
36
|
+
|
|
25
37
|
if (!source) return <>{children}</>;
|
|
26
38
|
|
|
27
39
|
return (
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
<View
|
|
41
|
+
style={
|
|
42
|
+
playerAnimationState === PlayerAnimationStateEnum.maximaze
|
|
43
|
+
? defaultImageDimensions
|
|
44
|
+
: style
|
|
45
|
+
}
|
|
33
46
|
>
|
|
34
|
-
|
|
35
|
-
|
|
47
|
+
<AnimationComponent
|
|
48
|
+
style={style}
|
|
49
|
+
animationType={ComponentAnimationType.player}
|
|
50
|
+
additionalData={defaultImageDimensions}
|
|
51
|
+
>
|
|
52
|
+
<ImageBackground
|
|
53
|
+
resizeMode="cover"
|
|
54
|
+
style={imageSize}
|
|
55
|
+
imageStyle={imageStyle}
|
|
56
|
+
source={source}
|
|
57
|
+
>
|
|
58
|
+
{children}
|
|
59
|
+
</ImageBackground>
|
|
60
|
+
</AnimationComponent>
|
|
61
|
+
</View>
|
|
36
62
|
);
|
|
37
63
|
};
|
|
38
64
|
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
import { useScreenData } from "@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenData";
|
|
22
22
|
import { isLast } from "@applicaster/zapp-react-native-utils/arrayUtils";
|
|
23
23
|
import { withComponentsMapProvider } from "@applicaster/zapp-react-native-ui-components/Decorators/ComponentsMapWrapper";
|
|
24
|
+
import { useScreenScrollStore } from "@applicaster/zapp-react-native-utils/screenState";
|
|
24
25
|
|
|
25
26
|
type Props = {
|
|
26
27
|
feed: ZappFeed;
|
|
@@ -193,6 +194,27 @@ function ComponentsMapComponent(props: Props) {
|
|
|
193
194
|
[]
|
|
194
195
|
);
|
|
195
196
|
|
|
197
|
+
const onScrollFlatList = React.useCallback(
|
|
198
|
+
({ nativeEvent }, isScrollingDone = false) => {
|
|
199
|
+
const {
|
|
200
|
+
contentOffset: { y },
|
|
201
|
+
} = nativeEvent;
|
|
202
|
+
|
|
203
|
+
useScreenScrollStore.setState({
|
|
204
|
+
scrollingVelocity: isScrollingDone ? 0 : 1,
|
|
205
|
+
scrollPosition: y,
|
|
206
|
+
});
|
|
207
|
+
},
|
|
208
|
+
[]
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
const onMomentumScrollEnd = React.useCallback(
|
|
212
|
+
({ nativeEvent }) => {
|
|
213
|
+
onScrollFlatList({ nativeEvent }, true);
|
|
214
|
+
},
|
|
215
|
+
[onScrollFlatList]
|
|
216
|
+
);
|
|
217
|
+
|
|
196
218
|
if (shouldShowLoadingError) {
|
|
197
219
|
return <RiverError />;
|
|
198
220
|
}
|
|
@@ -227,6 +249,9 @@ function ComponentsMapComponent(props: Props) {
|
|
|
227
249
|
}
|
|
228
250
|
ListFooterComponent={renderFooter}
|
|
229
251
|
refreshControl={refreshControl}
|
|
252
|
+
onScroll={onScrollFlatList}
|
|
253
|
+
onMomentumScrollEnd={onMomentumScrollEnd}
|
|
254
|
+
scrollEventThrottle={16}
|
|
230
255
|
{...scrollViewExtraProps}
|
|
231
256
|
/>
|
|
232
257
|
</ViewportTracker>
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
|
+
import { GeneralContentScreen } from "@applicaster/zapp-react-native-ui-components/Components/GeneralContentScreen";
|
|
3
4
|
|
|
4
5
|
import { FeedLoader } from "../FeedLoader";
|
|
5
6
|
import { ScreenResolver } from "../ScreenResolver";
|
|
6
7
|
|
|
7
|
-
import type { ZappScreenProps } from "@applicaster/zapp-react-native-flow-types";
|
|
8
|
-
|
|
9
|
-
import { GeneralContentScreen } from "../GeneralContentScreen";
|
|
10
|
-
|
|
11
8
|
type Props = ZappScreenProps & {
|
|
12
9
|
feedUrl?: string;
|
|
13
10
|
isInsideContainer?: boolean;
|
|
@@ -18,6 +15,12 @@ type Props = ZappScreenProps & {
|
|
|
18
15
|
| import("react-native").FlatListProps<any>
|
|
19
16
|
) &
|
|
20
17
|
Record<string, any>;
|
|
18
|
+
appData: AppDataKeys;
|
|
19
|
+
screenTitle: string;
|
|
20
|
+
screenSummary: string;
|
|
21
|
+
setIsScreenWrappedInContainer: (isInsideContainer: boolean) => void;
|
|
22
|
+
screenContext: ZappRiver;
|
|
23
|
+
river: ZappRiver;
|
|
21
24
|
};
|
|
22
25
|
|
|
23
26
|
type State = {
|
|
@@ -27,7 +30,7 @@ type State = {
|
|
|
27
30
|
export class RiverComponent extends React.Component<Props, State> {
|
|
28
31
|
private currentScreenTitle: string;
|
|
29
32
|
private currentScreenSummary: string;
|
|
30
|
-
constructor(props) {
|
|
33
|
+
constructor(props: Props) {
|
|
31
34
|
super(props);
|
|
32
35
|
|
|
33
36
|
this.state = {
|
|
@@ -4,7 +4,6 @@ import * as React from "react";
|
|
|
4
4
|
import { Text } from "react-native";
|
|
5
5
|
import * as R from "ramda";
|
|
6
6
|
|
|
7
|
-
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
8
7
|
import {
|
|
9
8
|
useFeedLoader,
|
|
10
9
|
useLayoutVersion,
|
|
@@ -20,6 +19,7 @@ import {
|
|
|
20
19
|
useNavbarState,
|
|
21
20
|
useSetNavbarState,
|
|
22
21
|
} from "@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenContext";
|
|
22
|
+
import { useRivers } from "@applicaster/zapp-react-native-utils/reactHooks/state";
|
|
23
23
|
|
|
24
24
|
type Props = {
|
|
25
25
|
screenId: string;
|
|
@@ -53,7 +53,7 @@ export const River = (props: Props) => {
|
|
|
53
53
|
|
|
54
54
|
const navigationPluginData = useNavigationPluginData();
|
|
55
55
|
|
|
56
|
-
const
|
|
56
|
+
const rivers = useRivers();
|
|
57
57
|
const isV2 = useLayoutVersion({ isV2: true });
|
|
58
58
|
|
|
59
59
|
const river = React.useMemo(() => rivers?.[screenId], [screenId]);
|
|
@@ -64,7 +64,7 @@ exports[`componentsMap renders renders components map correctly 1`] = `
|
|
|
64
64
|
refreshControl={null}
|
|
65
65
|
removeClippedSubviews={true}
|
|
66
66
|
renderItem={[Function]}
|
|
67
|
-
scrollEventThrottle={
|
|
67
|
+
scrollEventThrottle={16}
|
|
68
68
|
scrollIndicatorInsets={
|
|
69
69
|
Object {
|
|
70
70
|
"right": 1,
|
|
@@ -6,6 +6,12 @@ import configureStore from "redux-mock-store";
|
|
|
6
6
|
|
|
7
7
|
import * as themeUtils from "@applicaster/zapp-react-native-utils/theme";
|
|
8
8
|
|
|
9
|
+
// silences the errors related to React-native-gesture-handler in tests
|
|
10
|
+
jest.mock(
|
|
11
|
+
"@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation",
|
|
12
|
+
() => () => null
|
|
13
|
+
);
|
|
14
|
+
|
|
9
15
|
jest.mock("react-native-safe-area-context", () => ({
|
|
10
16
|
useSafeAreaInsets: () => ({ top: 50 }),
|
|
11
17
|
}));
|
|
@@ -83,6 +89,7 @@ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
|
|
|
83
89
|
useNavigation: jest.fn(() => ({ currentRoute: "/river/A1234" })),
|
|
84
90
|
useRoute: jest.fn(() => ({ pathname: "/river/A1234", screenData })),
|
|
85
91
|
useProfilerLogging: jest.fn(),
|
|
92
|
+
useIsScreenActive: jest.fn().mockReturnValue(true),
|
|
86
93
|
}));
|
|
87
94
|
|
|
88
95
|
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/screen", () => ({
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as R from "ramda";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
3
|
+
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
5
4
|
import { toCamelCase } from "@applicaster/zapp-react-native-utils/stringUtils";
|
|
6
5
|
import { useMemo } from "react";
|
|
7
6
|
import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
|
|
7
|
+
import { useRivers } from "@applicaster/zapp-react-native-utils/reactHooks/state";
|
|
8
8
|
|
|
9
9
|
type GeneralContentScreen = ZappRiver & {
|
|
10
10
|
styles: {
|
|
@@ -46,8 +46,8 @@ const stylingKeys = [
|
|
|
46
46
|
];
|
|
47
47
|
|
|
48
48
|
export function useScreenConfiguration(screenId: string): ScreenConfiguration {
|
|
49
|
-
const
|
|
50
|
-
const
|
|
49
|
+
const rivers = useRivers();
|
|
50
|
+
const isTablet = useIsTablet();
|
|
51
51
|
|
|
52
52
|
return useMemo(() => {
|
|
53
53
|
const config = {} as ScreenConfiguration;
|
|
@@ -56,8 +56,7 @@ export function useScreenConfiguration(screenId: string): ScreenConfiguration {
|
|
|
56
56
|
if (screenData) {
|
|
57
57
|
const { styles } = screenData;
|
|
58
58
|
|
|
59
|
-
const keyPrefix =
|
|
60
|
-
deviceInfo?.isTablet && styles?.tablet_theme ? "tablet_" : "";
|
|
59
|
+
const keyPrefix = isTablet && styles?.tablet_theme ? "tablet_" : "";
|
|
61
60
|
|
|
62
61
|
stylingKeys.forEach(([key, castFn]) => {
|
|
63
62
|
const styleKey = `${keyPrefix}${key}`;
|
|
@@ -2,11 +2,17 @@ import React from "react";
|
|
|
2
2
|
import { shallow } from "enzyme";
|
|
3
3
|
import { shallowToJson } from "enzyme-to-json";
|
|
4
4
|
|
|
5
|
-
import { ScreenResolver } from "@applicaster/zapp-react-native-ui-components/Components/ScreenResolver";
|
|
6
|
-
|
|
7
5
|
const pathname = "/river/A1234";
|
|
8
6
|
const screenData = { id: "A1234" };
|
|
9
7
|
|
|
8
|
+
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
|
|
9
|
+
useRoute: jest.fn(() => ({ pathname: pathname, screenData: screenData })),
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
ScreenResolver,
|
|
14
|
+
} = require("@applicaster/zapp-react-native-ui-components/Components/ScreenResolver");
|
|
15
|
+
|
|
10
16
|
const { RouteManager } = require("../index");
|
|
11
17
|
|
|
12
18
|
describe("<RouteManager />", () => {
|
|
@@ -20,6 +26,7 @@ describe("<RouteManager />", () => {
|
|
|
20
26
|
|
|
21
27
|
it("passes the correct props to ScreenResolver", () => {
|
|
22
28
|
expect(wrapper.find(ScreenResolver).props()).toEqual({
|
|
29
|
+
pathname: "/river/A1234",
|
|
23
30
|
screenType: "river",
|
|
24
31
|
screenId: "A1234",
|
|
25
32
|
screenData: { id: "A1234" },
|
|
@@ -2,6 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import * as R from "ramda";
|
|
3
3
|
|
|
4
4
|
import { getPathAttributes } from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
5
|
+
import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
5
6
|
import { ScreenResolver } from "../ScreenResolver";
|
|
6
7
|
import { TestId } from "./TestId";
|
|
7
8
|
|
|
@@ -12,7 +13,8 @@ type Props = { pathname: string; screenData: Record<string, any> };
|
|
|
12
13
|
* and reconciles data returned from hook plugins if needed
|
|
13
14
|
* @param {Props}: see props above
|
|
14
15
|
*/
|
|
15
|
-
export function RouteManager(
|
|
16
|
+
export function RouteManager(props: Props) {
|
|
17
|
+
const { pathname, screenData: _screenData } = useRoute();
|
|
16
18
|
const pathAttributes = getPathAttributes({ pathname });
|
|
17
19
|
|
|
18
20
|
const { screenType, screenId } = R.last(pathAttributes);
|
|
@@ -22,8 +24,8 @@ export function RouteManager({ pathname, screenData, ...otherProps }: Props) {
|
|
|
22
24
|
<ScreenResolver
|
|
23
25
|
screenType={screenType}
|
|
24
26
|
screenId={screenId}
|
|
25
|
-
|
|
26
|
-
{
|
|
27
|
+
{...props}
|
|
28
|
+
screenData={props.screenData}
|
|
27
29
|
/>
|
|
28
30
|
</TestId>
|
|
29
31
|
);
|