mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import React, {memo} from 'react'
2import {StyleProp, View, ViewStyle} from 'react-native'
3import {msg, Trans} from '@lingui/macro'
4import {useLingui} from '@lingui/react'
5
6import {cleanError} from '#/lib/strings/errors'
7import {CenteredView} from '#/view/com/util/Views'
8import {atoms as a, flatten, useBreakpoints, useTheme} from '#/alf'
9import {Button, ButtonText} from '#/components/Button'
10import {Error} from '#/components/Error'
11import {Loader} from '#/components/Loader'
12import {Text} from '#/components/Typography'
13
14export function ListFooter({
15 isFetchingNextPage,
16 hasNextPage,
17 error,
18 onRetry,
19 height,
20 style,
21 showEndMessage = false,
22 endMessageText,
23 renderEndMessage,
24}: {
25 isFetchingNextPage?: boolean
26 hasNextPage?: boolean
27 error?: string
28 onRetry?: () => Promise<unknown>
29 height?: number
30 style?: StyleProp<ViewStyle>
31 showEndMessage?: boolean
32 endMessageText?: string
33 renderEndMessage?: () => React.ReactNode
34}) {
35 const t = useTheme()
36
37 return (
38 <View
39 style={[
40 a.w_full,
41 a.align_center,
42 a.border_t,
43 a.pb_lg,
44 t.atoms.border_contrast_low,
45 {height: height ?? 180, paddingTop: 30},
46 flatten(style),
47 ]}>
48 {isFetchingNextPage ? (
49 <Loader size="xl" />
50 ) : error ? (
51 <ListFooterMaybeError error={error} onRetry={onRetry} />
52 ) : !hasNextPage && showEndMessage ? (
53 renderEndMessage ? (
54 renderEndMessage()
55 ) : (
56 <Text style={[a.text_sm, t.atoms.text_contrast_low]}>
57 {endMessageText ?? <Trans>You have reached the end</Trans>}
58 </Text>
59 )
60 ) : null}
61 </View>
62 )
63}
64
65function ListFooterMaybeError({
66 error,
67 onRetry,
68}: {
69 error?: string
70 onRetry?: () => Promise<unknown>
71}) {
72 const t = useTheme()
73 const {_} = useLingui()
74
75 if (!error) return null
76
77 return (
78 <View style={[a.w_full, a.px_lg]}>
79 <View
80 style={[
81 a.flex_row,
82 a.gap_md,
83 a.p_md,
84 a.rounded_sm,
85 a.align_center,
86 t.atoms.bg_contrast_25,
87 ]}>
88 <Text
89 style={[a.flex_1, a.text_sm, t.atoms.text_contrast_medium]}
90 numberOfLines={2}>
91 {error ? (
92 cleanError(error)
93 ) : (
94 <Trans>Oops, something went wrong!</Trans>
95 )}
96 </Text>
97 <Button
98 variant="gradient"
99 label={_(msg`Press to retry`)}
100 style={[
101 a.align_center,
102 a.justify_center,
103 a.rounded_sm,
104 a.overflow_hidden,
105 a.px_md,
106 a.py_sm,
107 ]}
108 onPress={onRetry}>
109 <ButtonText>
110 <Trans>Retry</Trans>
111 </ButtonText>
112 </Button>
113 </View>
114 </View>
115 )
116}
117
118let ListMaybePlaceholder = ({
119 isLoading,
120 noEmpty,
121 isError,
122 emptyTitle,
123 emptyMessage,
124 errorTitle,
125 errorMessage,
126 emptyType = 'page',
127 onRetry,
128 onGoBack,
129 hideBackButton,
130 sideBorders,
131 topBorder = false,
132}: {
133 isLoading: boolean
134 noEmpty?: boolean
135 isError?: boolean
136 emptyTitle?: string
137 emptyMessage?: string
138 errorTitle?: string
139 errorMessage?: string
140 emptyType?: 'page' | 'results'
141 onRetry?: () => Promise<unknown>
142 onGoBack?: () => void
143 hideBackButton?: boolean
144 sideBorders?: boolean
145 topBorder?: boolean
146}): React.ReactNode => {
147 const t = useTheme()
148 const {_} = useLingui()
149 const {gtMobile, gtTablet} = useBreakpoints()
150
151 if (isLoading) {
152 return (
153 <CenteredView
154 style={[
155 a.h_full_vh,
156 a.align_center,
157 !gtMobile ? a.justify_between : a.gap_5xl,
158 t.atoms.border_contrast_low,
159 {paddingTop: 175, paddingBottom: 110},
160 ]}
161 sideBorders={sideBorders ?? gtMobile}
162 topBorder={topBorder && !gtTablet}>
163 <View style={[a.w_full, a.align_center, {top: 100}]}>
164 <Loader size="xl" />
165 </View>
166 </CenteredView>
167 )
168 }
169
170 if (isError) {
171 return (
172 <Error
173 title={errorTitle ?? _(msg`Oops!`)}
174 message={errorMessage ?? _(msg`Something went wrong!`)}
175 onRetry={onRetry}
176 onGoBack={onGoBack}
177 sideBorders={sideBorders}
178 hideBackButton={hideBackButton}
179 />
180 )
181 }
182
183 if (!noEmpty) {
184 return (
185 <Error
186 title={
187 emptyTitle ??
188 (emptyType === 'results'
189 ? _(msg`No results found`)
190 : _(msg`Page not found`))
191 }
192 message={
193 emptyMessage ??
194 _(msg`We're sorry! We can't find the page you were looking for.`)
195 }
196 onRetry={onRetry}
197 onGoBack={onGoBack}
198 hideBackButton={hideBackButton}
199 sideBorders={sideBorders}
200 />
201 )
202 }
203
204 return null
205}
206ListMaybePlaceholder = memo(ListMaybePlaceholder)
207export {ListMaybePlaceholder}