mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at samuel/exp-cli 386 lines 11 kB view raw
1import {useReducer} from 'react' 2import {View} from 'react-native' 3import {msg, Trans} from '@lingui/macro' 4import {useLingui} from '@lingui/react' 5 6import {wait} from '#/lib/async/wait' 7import {useCleanError} from '#/lib/hooks/useCleanError' 8import {logger} from '#/logger' 9import {useSession} from '#/state/session' 10import {atoms as a, useTheme} from '#/alf' 11import {Admonition} from '#/components/Admonition' 12import {Button, ButtonIcon, ButtonText} from '#/components/Button' 13import {ResendEmailText} from '#/components/dialogs/EmailDialog/components/ResendEmailText' 14import { 15 isValidCode, 16 TokenField, 17} from '#/components/dialogs/EmailDialog/components/TokenField' 18import {useConfirmEmail} from '#/components/dialogs/EmailDialog/data/useConfirmEmail' 19import {useRequestEmailVerification} from '#/components/dialogs/EmailDialog/data/useRequestEmailVerification' 20import {useOnEmailVerified} from '#/components/dialogs/EmailDialog/events' 21import { 22 ScreenID, 23 type ScreenProps, 24} from '#/components/dialogs/EmailDialog/types' 25import {Divider} from '#/components/Divider' 26import {CheckThick_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check' 27import {Envelope_Stroke2_Corner0_Rounded as Envelope} from '#/components/icons/Envelope' 28import {createStaticClick, InlineLinkText} from '#/components/Link' 29import {Loader} from '#/components/Loader' 30import {Span, Text} from '#/components/Typography' 31 32type State = { 33 step: 'email' | 'token' | 'success' 34 mutationStatus: 'pending' | 'success' | 'error' | 'default' 35 error: string 36 token: string 37} 38 39type Action = 40 | { 41 type: 'setStep' 42 step: State['step'] 43 } 44 | { 45 type: 'setError' 46 error: string 47 } 48 | { 49 type: 'setMutationStatus' 50 status: State['mutationStatus'] 51 } 52 | { 53 type: 'setToken' 54 value: string 55 } 56 57function reducer(state: State, action: Action): State { 58 switch (action.type) { 59 case 'setStep': { 60 return { 61 ...state, 62 error: '', 63 mutationStatus: 'default', 64 step: action.step, 65 } 66 } 67 case 'setError': { 68 return { 69 ...state, 70 error: action.error, 71 mutationStatus: 'error', 72 } 73 } 74 case 'setMutationStatus': { 75 return { 76 ...state, 77 error: '', 78 mutationStatus: action.status, 79 } 80 } 81 case 'setToken': { 82 return { 83 ...state, 84 error: '', 85 token: action.value, 86 } 87 } 88 } 89} 90 91export function Verify({config, showScreen}: ScreenProps<ScreenID.Verify>) { 92 const t = useTheme() 93 const {_} = useLingui() 94 const cleanError = useCleanError() 95 const {currentAccount} = useSession() 96 const [state, dispatch] = useReducer(reducer, { 97 step: 'email', 98 mutationStatus: 'default', 99 error: '', 100 token: '', 101 }) 102 103 const {mutateAsync: requestEmailVerification} = useRequestEmailVerification() 104 const {mutateAsync: confirmEmail} = useConfirmEmail() 105 106 useOnEmailVerified(() => { 107 if (config.onVerify) { 108 config.onVerify() 109 } else { 110 dispatch({ 111 type: 'setStep', 112 step: 'success', 113 }) 114 } 115 }) 116 117 const handleRequestEmailVerification = async () => { 118 dispatch({ 119 type: 'setMutationStatus', 120 status: 'pending', 121 }) 122 123 try { 124 await wait(1000, requestEmailVerification()) 125 dispatch({ 126 type: 'setMutationStatus', 127 status: 'success', 128 }) 129 } catch (e) { 130 logger.error('EmailDialog: sending verification email failed', { 131 safeMessage: e, 132 }) 133 const {clean} = cleanError(e) 134 dispatch({ 135 type: 'setError', 136 error: clean || _(msg`Failed to send email, please try again.`), 137 }) 138 } 139 } 140 141 const handleConfirmEmail = async () => { 142 if (!isValidCode(state.token)) { 143 dispatch({ 144 type: 'setError', 145 error: _(msg`Please enter a valid code.`), 146 }) 147 return 148 } 149 150 dispatch({ 151 type: 'setMutationStatus', 152 status: 'pending', 153 }) 154 155 try { 156 await wait(1000, confirmEmail({token: state.token})) 157 dispatch({ 158 type: 'setStep', 159 step: 'success', 160 }) 161 } catch (e) { 162 logger.error('EmailDialog: confirming email failed', { 163 safeMessage: e, 164 }) 165 const {clean} = cleanError(e) 166 dispatch({ 167 type: 'setError', 168 error: clean || _(msg`Failed to verify email, please try again.`), 169 }) 170 } 171 } 172 173 if (state.step === 'success') { 174 return ( 175 <View style={[a.gap_lg]}> 176 <View style={[a.gap_sm]}> 177 <Text style={[a.text_xl, a.font_heavy]}> 178 <Span style={{top: 1}}> 179 <Check size="sm" fill={t.palette.positive_600} /> 180 </Span> 181 {' '} 182 <Trans>Email verification complete!</Trans> 183 </Text> 184 185 <Text 186 style={[a.text_sm, a.leading_snug, t.atoms.text_contrast_medium]}> 187 <Trans> 188 You have successfully verified your email address. You can close 189 this dialog. 190 </Trans> 191 </Text> 192 </View> 193 </View> 194 ) 195 } 196 197 return ( 198 <View style={[a.gap_lg]}> 199 <View style={[a.gap_sm]}> 200 <Text style={[a.text_xl, a.font_heavy]}> 201 {state.step === 'email' ? ( 202 state.mutationStatus === 'success' ? ( 203 <> 204 <Span style={{top: 1}}> 205 <Check size="sm" fill={t.palette.positive_600} /> 206 </Span> 207 {' '} 208 <Trans>Email sent!</Trans> 209 </> 210 ) : ( 211 <Trans>Verify your email</Trans> 212 ) 213 ) : ( 214 <Trans>Verify email code</Trans> 215 )} 216 </Text> 217 218 {state.step === 'email' && state.mutationStatus !== 'success' && ( 219 <> 220 {config.instructions?.map((int, i) => ( 221 <Text 222 key={i} 223 style={[ 224 a.italic, 225 a.text_sm, 226 a.leading_snug, 227 t.atoms.text_contrast_medium, 228 ]}> 229 {int} 230 </Text> 231 ))} 232 </> 233 )} 234 235 <Text style={[a.text_sm, a.leading_snug, t.atoms.text_contrast_medium]}> 236 {state.step === 'email' ? ( 237 state.mutationStatus === 'success' ? ( 238 <Trans> 239 We sent an email to{' '} 240 <Span style={[a.font_bold, t.atoms.text]}> 241 {currentAccount!.email} 242 </Span>{' '} 243 containing a link. Please click on it to complete the email 244 verification process. 245 </Trans> 246 ) : ( 247 <Trans> 248 We'll send an email to{' '} 249 <Span style={[a.font_bold, t.atoms.text]}> 250 {currentAccount!.email} 251 </Span>{' '} 252 containing a link. Please click on it to complete the email 253 verification process. 254 </Trans> 255 ) 256 ) : ( 257 <Trans> 258 Please enter the code we sent to{' '} 259 <Span style={[a.font_bold, t.atoms.text]}> 260 {currentAccount!.email} 261 </Span>{' '} 262 below. 263 </Trans> 264 )} 265 </Text> 266 267 {state.step === 'email' && state.mutationStatus !== 'success' && ( 268 <Text 269 style={[a.text_sm, a.leading_snug, t.atoms.text_contrast_medium]}> 270 <Trans> 271 If you need to update your email,{' '} 272 <InlineLinkText 273 label={_(msg`Click here to update your email`)} 274 {...createStaticClick(() => { 275 showScreen({id: ScreenID.Update}) 276 })}> 277 click here 278 </InlineLinkText> 279 . 280 </Trans> 281 </Text> 282 )} 283 284 {state.step === 'email' && state.mutationStatus === 'success' && ( 285 <ResendEmailText onPress={requestEmailVerification} /> 286 )} 287 </View> 288 289 {state.step === 'email' && state.mutationStatus !== 'success' ? ( 290 <> 291 {state.error && <Admonition type="error">{state.error}</Admonition>} 292 <Button 293 label={_(msg`Send verification email`)} 294 size="large" 295 variant="solid" 296 color="primary" 297 onPress={handleRequestEmailVerification} 298 disabled={state.mutationStatus === 'pending'}> 299 <ButtonText> 300 <Trans>Send email</Trans> 301 </ButtonText> 302 <ButtonIcon 303 icon={state.mutationStatus === 'pending' ? Loader : Envelope} 304 /> 305 </Button> 306 </> 307 ) : null} 308 309 {state.step === 'email' && ( 310 <> 311 <Divider /> 312 313 <Text 314 style={[a.text_sm, a.leading_snug, t.atoms.text_contrast_medium]}> 315 <Trans> 316 Have a code?{' '} 317 <InlineLinkText 318 label={_(msg`Enter code`)} 319 {...createStaticClick(() => { 320 dispatch({ 321 type: 'setStep', 322 step: 'token', 323 }) 324 })}> 325 Click here. 326 </InlineLinkText> 327 </Trans> 328 </Text> 329 </> 330 )} 331 332 {state.step === 'token' ? ( 333 <> 334 <TokenField 335 value={state.token} 336 onChangeText={token => { 337 dispatch({ 338 type: 'setToken', 339 value: token, 340 }) 341 }} 342 onSubmitEditing={handleConfirmEmail} 343 /> 344 345 {state.error && <Admonition type="error">{state.error}</Admonition>} 346 347 <Button 348 label={_(msg`Verify code`)} 349 size="large" 350 variant="solid" 351 color="primary" 352 onPress={handleConfirmEmail} 353 disabled={ 354 !state.token || 355 state.token.length !== 11 || 356 state.mutationStatus === 'pending' 357 }> 358 <ButtonText> 359 <Trans>Verify code</Trans> 360 </ButtonText> 361 {state.mutationStatus === 'pending' && <ButtonIcon icon={Loader} />} 362 </Button> 363 364 <Divider /> 365 366 <Text 367 style={[a.text_sm, a.leading_snug, t.atoms.text_contrast_medium]}> 368 <Trans> 369 Don't have a code or need a new one?{' '} 370 <InlineLinkText 371 label={_(msg`Click here to restart the verification process.`)} 372 {...createStaticClick(() => { 373 dispatch({ 374 type: 'setStep', 375 step: 'email', 376 }) 377 })}> 378 Click here. 379 </InlineLinkText> 380 </Trans> 381 </Text> 382 </> 383 ) : null} 384 </View> 385 ) 386}