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