forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {msg, Trans} from '@lingui/macro'
2import {useLingui} from '@lingui/react'
3import {type NativeStackScreenProps} from '@react-navigation/native-stack'
4
5import {type CommonNavigatorParams} from '#/lib/routes/types'
6import {useModalControls} from '#/state/modals'
7import {useSession} from '#/state/session'
8import * as SettingsList from '#/screens/Settings/components/SettingsList'
9import {atoms as a, useTheme} from '#/alf'
10import {AgeAssuranceAccountCard} from '#/components/ageAssurance/AgeAssuranceAccountCard'
11import {useDialogControl} from '#/components/Dialog'
12import {BirthDateSettingsDialog} from '#/components/dialogs/BirthDateSettings'
13import {
14 EmailDialogScreenID,
15 useEmailDialogControl,
16} from '#/components/dialogs/EmailDialog'
17import {At_Stroke2_Corner2_Rounded as AtIcon} from '#/components/icons/At'
18import {BirthdayCake_Stroke2_Corner2_Rounded as BirthdayCakeIcon} from '#/components/icons/BirthdayCake'
19import {Car_Stroke2_Corner2_Rounded as CarIcon} from '#/components/icons/Car'
20import {Envelope_Stroke2_Corner2_Rounded as EnvelopeIcon} from '#/components/icons/Envelope'
21import {Freeze_Stroke2_Corner2_Rounded as FreezeIcon} from '#/components/icons/Freeze'
22import {Lock_Stroke2_Corner2_Rounded as LockIcon} from '#/components/icons/Lock'
23import {PencilLine_Stroke2_Corner2_Rounded as PencilIcon} from '#/components/icons/Pencil'
24import {ShieldCheck_Stroke2_Corner0_Rounded as ShieldIcon} from '#/components/icons/Shield'
25import {Trash_Stroke2_Corner2_Rounded} from '#/components/icons/Trash'
26import * as Layout from '#/components/Layout'
27import {ChangeHandleDialog} from './components/ChangeHandleDialog'
28import {ChangePasswordDialog} from './components/ChangePasswordDialog'
29import {DeactivateAccountDialog} from './components/DeactivateAccountDialog'
30import {ExportCarDialog} from './components/ExportCarDialog'
31
32type Props = NativeStackScreenProps<CommonNavigatorParams, 'AccountSettings'>
33export function AccountSettingsScreen({}: Props) {
34 const t = useTheme()
35 const {_} = useLingui()
36 const {currentAccount} = useSession()
37 const {openModal} = useModalControls()
38 const emailDialogControl = useEmailDialogControl()
39 const birthdayControl = useDialogControl()
40 const changeHandleControl = useDialogControl()
41 const changePasswordControl = useDialogControl()
42 const exportCarControl = useDialogControl()
43 const deactivateAccountControl = useDialogControl()
44
45 return (
46 <Layout.Screen>
47 <Layout.Header.Outer>
48 <Layout.Header.BackButton />
49 <Layout.Header.Content>
50 <Layout.Header.TitleText>
51 <Trans>Account</Trans>
52 </Layout.Header.TitleText>
53 </Layout.Header.Content>
54 <Layout.Header.Slot />
55 </Layout.Header.Outer>
56 <Layout.Content>
57 <SettingsList.Container>
58 <SettingsList.Item>
59 <SettingsList.ItemIcon icon={EnvelopeIcon} />
60 {/* Tricky flexbox situation here: we want the email to truncate, but by default it will make the "Email" text wrap instead.
61 For numberOfLines to work, we need flex: 1 on the BadgeText, but that means it goes to width: 50% because the
62 ItemText is also flex: 1. So we need to set flex: 0 on the ItemText to prevent it from growing, but if we did that everywhere
63 it wouldn't push the BadgeText/Chevron/whatever to the right.
64 TODO: find a general solution for this. workaround in this case is to set the ItemText to flex: 1 and BadgeText to flex: 0 -sfn */}
65 <SettingsList.ItemText style={[a.flex_0]}>
66 <Trans>Email</Trans>
67 </SettingsList.ItemText>
68 {currentAccount && (
69 <>
70 <SettingsList.BadgeText style={[a.flex_1]}>
71 {currentAccount.email || <Trans>(no email)</Trans>}
72 </SettingsList.BadgeText>
73 {currentAccount.emailConfirmed && (
74 <ShieldIcon fill={t.palette.primary_500} size="md" />
75 )}
76 </>
77 )}
78 </SettingsList.Item>
79 {currentAccount && !currentAccount.emailConfirmed && (
80 <SettingsList.PressableItem
81 label={_(msg`Verify your email`)}
82 onPress={() =>
83 emailDialogControl.open({
84 id: EmailDialogScreenID.Verify,
85 })
86 }
87 style={[
88 a.my_xs,
89 a.mx_lg,
90 a.rounded_md,
91 {backgroundColor: t.palette.primary_50},
92 ]}
93 hoverStyle={[{backgroundColor: t.palette.primary_100}]}
94 contentContainerStyle={[a.rounded_md, a.px_lg]}>
95 <SettingsList.ItemIcon
96 icon={ShieldIcon}
97 color={t.palette.primary_500}
98 />
99 <SettingsList.ItemText
100 style={[{color: t.palette.primary_500}, a.font_semi_bold]}>
101 <Trans>Verify your email</Trans>
102 </SettingsList.ItemText>
103 <SettingsList.Chevron color={t.palette.primary_500} />
104 </SettingsList.PressableItem>
105 )}
106 <SettingsList.PressableItem
107 label={_(msg`Update email`)}
108 onPress={() =>
109 emailDialogControl.open({
110 id: EmailDialogScreenID.Update,
111 })
112 }>
113 <SettingsList.ItemIcon icon={PencilIcon} />
114 <SettingsList.ItemText>
115 <Trans>Update email</Trans>
116 </SettingsList.ItemText>
117 <SettingsList.Chevron />
118 </SettingsList.PressableItem>
119 <SettingsList.Divider />
120 <SettingsList.PressableItem
121 label={_(msg`Password`)}
122 onPress={() => changePasswordControl.open()}>
123 <SettingsList.ItemIcon icon={LockIcon} />
124 <SettingsList.ItemText>
125 <Trans>Password</Trans>
126 </SettingsList.ItemText>
127 <SettingsList.Chevron />
128 </SettingsList.PressableItem>
129 <SettingsList.PressableItem
130 label={_(msg`Handle`)}
131 accessibilityHint={_(msg`Opens change handle dialog`)}
132 onPress={() => changeHandleControl.open()}>
133 <SettingsList.ItemIcon icon={AtIcon} />
134 <SettingsList.ItemText>
135 <Trans>Handle</Trans>
136 </SettingsList.ItemText>
137 <SettingsList.Chevron />
138 </SettingsList.PressableItem>
139 <SettingsList.Item>
140 <SettingsList.ItemIcon icon={BirthdayCakeIcon} />
141 <SettingsList.ItemText>
142 <Trans>Birthday</Trans>
143 </SettingsList.ItemText>
144 <SettingsList.BadgeButton
145 label={_(msg`Edit`)}
146 onPress={() => birthdayControl.open()}
147 />
148 </SettingsList.Item>
149 <AgeAssuranceAccountCard style={[a.px_xl, a.pt_xs, a.pb_md]} />
150 <SettingsList.Divider />
151 <SettingsList.PressableItem
152 label={_(msg`Export my data`)}
153 onPress={() => exportCarControl.open()}>
154 <SettingsList.ItemIcon icon={CarIcon} />
155 <SettingsList.ItemText>
156 <Trans>Export my data</Trans>
157 </SettingsList.ItemText>
158 <SettingsList.Chevron />
159 </SettingsList.PressableItem>
160 <SettingsList.PressableItem
161 label={_(msg`Deactivate account`)}
162 onPress={() => deactivateAccountControl.open()}
163 destructive>
164 <SettingsList.ItemIcon icon={FreezeIcon} />
165 <SettingsList.ItemText>
166 <Trans>Deactivate account</Trans>
167 </SettingsList.ItemText>
168 <SettingsList.Chevron />
169 </SettingsList.PressableItem>
170 <SettingsList.PressableItem
171 label={_(msg`Delete account`)}
172 onPress={() => openModal({name: 'delete-account'})}
173 destructive>
174 <SettingsList.ItemIcon icon={Trash_Stroke2_Corner2_Rounded} />
175 <SettingsList.ItemText>
176 <Trans>Delete account</Trans>
177 </SettingsList.ItemText>
178 <SettingsList.Chevron />
179 </SettingsList.PressableItem>
180 </SettingsList.Container>
181 </Layout.Content>
182
183 <BirthDateSettingsDialog control={birthdayControl} />
184 <ChangeHandleDialog control={changeHandleControl} />
185 <ChangePasswordDialog control={changePasswordControl} />
186 <ExportCarDialog control={exportCarControl} />
187 <DeactivateAccountDialog control={deactivateAccountControl} />
188 </Layout.Screen>
189 )
190}