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