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 rm-open 231 lines 7.1 kB view raw
1import React from 'react' 2import {Modal, ScrollView, View} from 'react-native' 3import {useSafeAreaInsets} from 'react-native-safe-area-context' 4import {StatusBar} from 'expo-status-bar' 5import {msg, plural, Trans} from '@lingui/macro' 6import {useLingui} from '@lingui/react' 7 8import {logger} from '#/logger' 9import {isIOS, isWeb} from '#/platform/detection' 10import {isSignupQueued, useAgent, useSessionApi} from '#/state/session' 11import {useOnboardingDispatch} from '#/state/shell' 12import {Logo} from '#/view/icons/Logo' 13import {atoms as a, native, useBreakpoints, useTheme, web} from '#/alf' 14import {Button, ButtonIcon, ButtonText} from '#/components/Button' 15import {Loader} from '#/components/Loader' 16import {P, Text} from '#/components/Typography' 17 18const COL_WIDTH = 400 19 20export function SignupQueued() { 21 const {_} = useLingui() 22 const t = useTheme() 23 const insets = useSafeAreaInsets() 24 const {gtMobile} = useBreakpoints() 25 const onboardingDispatch = useOnboardingDispatch() 26 const {logoutCurrentAccount} = useSessionApi() 27 const agent = useAgent() 28 29 const [isProcessing, setProcessing] = React.useState(false) 30 const [estimatedTime, setEstimatedTime] = React.useState<string | undefined>( 31 undefined, 32 ) 33 const [placeInQueue, setPlaceInQueue] = React.useState<number | undefined>( 34 undefined, 35 ) 36 37 const checkStatus = React.useCallback(async () => { 38 setProcessing(true) 39 try { 40 const res = await agent.com.atproto.temp.checkSignupQueue() 41 if (res.data.activated) { 42 // ready to go, exchange the access token for a usable one and kick off onboarding 43 await agent.sessionManager.refreshSession() 44 if (!isSignupQueued(agent.session?.accessJwt)) { 45 onboardingDispatch({type: 'start'}) 46 } 47 } else { 48 // not ready, update UI 49 setEstimatedTime(msToString(res.data.estimatedTimeMs)) 50 if (typeof res.data.placeInQueue !== 'undefined') { 51 setPlaceInQueue(Math.max(res.data.placeInQueue, 1)) 52 } 53 } 54 } catch (e: any) { 55 logger.error('Failed to check signup queue', {err: e.toString()}) 56 } finally { 57 setProcessing(false) 58 } 59 }, [ 60 setProcessing, 61 setEstimatedTime, 62 setPlaceInQueue, 63 onboardingDispatch, 64 agent, 65 ]) 66 67 React.useEffect(() => { 68 checkStatus() 69 const interval = setInterval(checkStatus, 60e3) 70 return () => clearInterval(interval) 71 }, [checkStatus]) 72 73 const checkBtn = ( 74 <Button 75 variant="solid" 76 color="primary" 77 size="large" 78 label={_(msg`Check my status`)} 79 onPress={checkStatus} 80 disabled={isProcessing}> 81 <ButtonText> 82 <Trans>Check my status</Trans> 83 </ButtonText> 84 {isProcessing && <ButtonIcon icon={Loader} />} 85 </Button> 86 ) 87 88 return ( 89 <Modal 90 visible 91 animationType={native('slide')} 92 presentationStyle="formSheet" 93 style={[web(a.util_screen_outer)]}> 94 {isIOS && <StatusBar style="light" />} 95 <ScrollView 96 style={[a.flex_1, t.atoms.bg]} 97 contentContainerStyle={{borderWidth: 0}} 98 bounces={false}> 99 <View 100 style={[ 101 a.flex_row, 102 a.justify_center, 103 gtMobile ? a.pt_4xl : [a.px_xl, a.pt_xl], 104 ]}> 105 <View style={[a.flex_1, {maxWidth: COL_WIDTH}]}> 106 <View 107 style={[a.w_full, a.justify_center, a.align_center, a.my_4xl]}> 108 <Logo width={120} /> 109 </View> 110 111 <Text style={[a.text_4xl, a.font_bold, a.pb_sm]}> 112 <Trans>You're in line</Trans> 113 </Text> 114 <P style={[t.atoms.text_contrast_medium]}> 115 <Trans> 116 There's been a rush of new users to Bluesky! We'll activate your 117 account as soon as we can. 118 </Trans> 119 </P> 120 121 <View 122 style={[ 123 a.rounded_sm, 124 a.px_2xl, 125 a.py_4xl, 126 a.mt_2xl, 127 a.mb_md, 128 a.border, 129 t.atoms.bg_contrast_25, 130 t.atoms.border_contrast_medium, 131 ]}> 132 {typeof placeInQueue === 'number' && ( 133 <Text 134 style={[a.text_5xl, a.text_center, a.font_heavy, a.mb_2xl]}> 135 {placeInQueue} 136 </Text> 137 )} 138 <P style={[a.text_center]}> 139 {typeof placeInQueue === 'number' ? ( 140 <Trans>left to go.</Trans> 141 ) : ( 142 <Trans>You are in line.</Trans> 143 )}{' '} 144 {estimatedTime ? ( 145 <Trans> 146 We estimate {estimatedTime} until your account is ready. 147 </Trans> 148 ) : ( 149 <Trans> 150 We will let you know when your account is ready. 151 </Trans> 152 )} 153 </P> 154 </View> 155 156 {isWeb && gtMobile && ( 157 <View 158 style={[ 159 a.w_full, 160 a.flex_row, 161 a.justify_between, 162 a.pt_5xl, 163 {paddingBottom: 200}, 164 ]}> 165 <Button 166 variant="ghost" 167 size="large" 168 label={_(msg`Log out`)} 169 onPress={() => logoutCurrentAccount('SignupQueued')}> 170 <ButtonText style={[{color: t.palette.primary_500}]}> 171 <Trans>Log out</Trans> 172 </ButtonText> 173 </Button> 174 {checkBtn} 175 </View> 176 )} 177 </View> 178 </View> 179 </ScrollView> 180 181 {(!isWeb || !gtMobile) && ( 182 <View 183 style={[ 184 a.align_center, 185 t.atoms.bg, 186 gtMobile ? a.px_5xl : a.px_xl, 187 { 188 paddingBottom: Math.max(insets.bottom, a.pb_5xl.paddingBottom), 189 }, 190 ]}> 191 <View style={[a.w_full, a.gap_sm, {maxWidth: COL_WIDTH}]}> 192 {checkBtn} 193 <Button 194 variant="ghost" 195 size="large" 196 label={_(msg`Log out`)} 197 onPress={() => logoutCurrentAccount('SignupQueued')}> 198 <ButtonText style={[{color: t.palette.primary_500}]}> 199 <Trans>Log out</Trans> 200 </ButtonText> 201 </Button> 202 </View> 203 </View> 204 )} 205 </Modal> 206 ) 207} 208 209function msToString(ms: number | undefined): string | undefined { 210 if (ms && ms > 0) { 211 const estimatedTimeMins = Math.ceil(ms / 60e3) 212 if (estimatedTimeMins > 59) { 213 const estimatedTimeHrs = Math.round(estimatedTimeMins / 60) 214 if (estimatedTimeHrs > 6) { 215 // dont even bother 216 return undefined 217 } 218 // hours 219 return `${estimatedTimeHrs} ${plural(estimatedTimeHrs, { 220 one: 'hour', 221 other: 'hours', 222 })}` 223 } 224 // minutes 225 return `${estimatedTimeMins} ${plural(estimatedTimeMins, { 226 one: 'minute', 227 other: 'minutes', 228 })}` 229 } 230 return undefined 231}