forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {View} from 'react-native'
2import {
3 FontAwesomeIcon,
4 type FontAwesomeIconStyle,
5} from '@fortawesome/react-native-fontawesome'
6import {msg} from '@lingui/core/macro'
7import {useLingui} from '@lingui/react'
8import {Trans} from '@lingui/react/macro'
9
10import {usePalette} from '#/lib/hooks/usePalette'
11import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons'
12import {atoms as a, useTheme} from '#/alf'
13import {Button, ButtonIcon, ButtonText} from '#/components/Button'
14import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as ArrowRotateCounterClockwiseIcon} from '#/components/icons/ArrowRotate'
15import * as Layout from '#/components/Layout'
16import {Text} from '#/components/Typography'
17
18export function ErrorScreen({
19 title,
20 message,
21 details,
22 onPressTryAgain,
23 testID,
24 showHeader,
25}: {
26 title: string
27 message: string
28 details?: string
29 onPressTryAgain?: () => void
30 testID?: string
31 showHeader?: boolean
32}) {
33 const t = useTheme()
34 const pal = usePalette('default')
35 const {_} = useLingui()
36 const enableSquareButtons = useEnableSquareButtons()
37
38 return (
39 <Layout.Center testID={testID}>
40 {showHeader && (
41 <Layout.Header.Outer>
42 <Layout.Header.BackButton />
43 <Layout.Header.Content>
44 <Layout.Header.TitleText>
45 <Trans>Error</Trans>
46 </Layout.Header.TitleText>
47 </Layout.Header.Content>
48 <Layout.Header.Slot />
49 </Layout.Header.Outer>
50 )}
51 <View style={[a.px_xl, a.py_2xl]}>
52 <View style={[a.mb_md, a.align_center]}>
53 <View
54 style={[
55 enableSquareButtons ? a.rounded_sm : a.rounded_full,
56 {width: 50, height: 50},
57 a.align_center,
58 a.justify_center,
59 {backgroundColor: t.palette.contrast_950},
60 ]}>
61 <FontAwesomeIcon
62 icon="exclamation"
63 style={pal.textInverted as FontAwesomeIconStyle}
64 size={24}
65 />
66 </View>
67 </View>
68 <Text style={[a.text_center, a.font_bold, a.text_2xl, a.mb_md]}>
69 {title}
70 </Text>
71 <Text style={[a.text_center, a.text_md, a.mb_xl]}>{message}</Text>
72 {details && (
73 <View
74 style={[
75 a.w_full,
76 a.border,
77 t.atoms.border_contrast_medium,
78 t.atoms.bg_contrast_25,
79 a.mb_xl,
80 a.py_sm,
81 a.px_lg,
82 a.rounded_xs,
83 a.overflow_hidden,
84 ]}>
85 <Text
86 testID={`${testID}-details`}
87 style={[a.text_center, a.text_md, t.atoms.text_contrast_high]}>
88 {details}
89 </Text>
90 </View>
91 )}
92 {onPressTryAgain && (
93 <View style={[a.align_center]}>
94 <Button
95 testID="errorScreenTryAgainButton"
96 onPress={onPressTryAgain}
97 variant="solid"
98 color="secondary_inverted"
99 size="small"
100 label={_(msg`Retry`)}
101 accessibilityHint={_(
102 msg`Retries the last action, which errored out`,
103 )}>
104 <ButtonIcon icon={ArrowRotateCounterClockwiseIcon} />
105 <ButtonText>
106 <Trans context="action">Try again</Trans>
107 </ButtonText>
108 </Button>
109 </View>
110 )}
111 </View>
112 </Layout.Center>
113 )
114}