-
Notifications
You must be signed in to change notification settings - Fork 3.1k
/
Copy pathindex.tsx
125 lines (118 loc) · 5.04 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import type {VideoReadyForDisplayEvent} from 'expo-av';
import React, {useMemo, useState} from 'react';
import {View} from 'react-native';
import Button from '@components/Button';
import ImageSVG from '@components/ImageSVG';
import Lottie from '@components/Lottie';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import VideoPlayer from '@components/VideoPlayer';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import CONST from '@src/CONST';
import type {EmptyStateComponentProps, VideoLoadedEventType} from './types';
const VIDEO_ASPECT_RATIO = 400 / 225;
function EmptyStateComponent({
SkeletonComponent,
headerMediaType,
headerMedia,
buttons,
containerStyles,
title,
titleStyles,
subtitle,
headerStyles,
headerContentStyles,
lottieWebViewStyles,
minModalHeight = 400,
}: EmptyStateComponentProps) {
const styles = useThemeStyles();
const [videoAspectRatio, setVideoAspectRatio] = useState(VIDEO_ASPECT_RATIO);
const {shouldUseNarrowLayout} = useResponsiveLayout();
const setAspectRatio = (event: VideoReadyForDisplayEvent | VideoLoadedEventType | undefined) => {
if (!event) {
return;
}
if ('naturalSize' in event) {
setVideoAspectRatio(event.naturalSize.width / event.naturalSize.height);
} else {
setVideoAspectRatio(event.srcElement.videoWidth / event.srcElement.videoHeight);
}
};
const HeaderComponent = useMemo(() => {
switch (headerMediaType) {
case CONST.EMPTY_STATE_MEDIA.VIDEO:
return (
<VideoPlayer
url={headerMedia}
videoPlayerStyle={[headerContentStyles, {aspectRatio: videoAspectRatio}]}
videoStyle={styles.emptyStateVideo}
onVideoLoaded={setAspectRatio}
controlsStatus={CONST.VIDEO_PLAYER.CONTROLS_STATUS.SHOW}
shouldUseControlsBottomMargin={false}
shouldPlay
isLooping
/>
);
case CONST.EMPTY_STATE_MEDIA.ANIMATION:
return (
<Lottie
source={headerMedia}
autoPlay
loop
style={headerContentStyles}
webStyle={lottieWebViewStyles}
/>
);
case CONST.EMPTY_STATE_MEDIA.ILLUSTRATION:
return (
<ImageSVG
style={headerContentStyles}
src={headerMedia}
/>
);
default:
return null;
}
}, [headerMedia, headerMediaType, headerContentStyles, videoAspectRatio, styles.emptyStateVideo, lottieWebViewStyles]);
return (
<ScrollView
contentContainerStyle={[{minHeight: minModalHeight}, styles.flexGrow1, styles.flexShrink0, containerStyles]}
style={styles.flex1}
>
<View style={styles.skeletonBackground}>
<SkeletonComponent
gradientOpacityEnabled
shouldAnimate={false}
/>
</View>
<View style={styles.emptyStateForeground}>
<View style={styles.emptyStateContent}>
<View style={[styles.emptyStateHeader(headerMediaType === CONST.EMPTY_STATE_MEDIA.ILLUSTRATION), headerStyles]}>{HeaderComponent}</View>
<View style={shouldUseNarrowLayout ? styles.p5 : styles.p8}>
<Text style={[styles.textAlignCenter, styles.textHeadlineH1, styles.mb2, titleStyles]}>{title}</Text>
{typeof subtitle === 'string' ? <Text style={[styles.textAlignCenter, styles.textSupporting, styles.textNormal]}>{subtitle}</Text> : subtitle}
<View style={[styles.gap2, styles.mt5, !shouldUseNarrowLayout ? styles.flexRow : undefined]}>
{buttons?.map(({buttonText, buttonAction, success}, index) => (
<View
// eslint-disable-next-line react/no-array-index-key
key={index}
style={styles.flex1}
>
<Button
success={success}
onPress={buttonAction}
text={buttonText}
large
/>
</View>
))}
</View>
</View>
</View>
</View>
</ScrollView>
);
}
EmptyStateComponent.displayName = 'EmptyStateComponent';
export default EmptyStateComponent;