Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

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

Merge branch 'main' of https://github.com/bluesky-social/social-app

+769 -1655
+4
.github/workflows/build-submit-android.yml
··· 52 52 distribution: 'temurin' 53 53 java-version: '17' 54 54 55 + - name: "Use upgraded MMKV for Fabric" 56 + run: | 57 + sed -i 's/"react-native-mmkv": "\^2\.12\.2"/"react-native-mmkv": "^3.3.0"/' package.json 58 + 55 59 - name: ⚙️ Install dependencies 56 60 run: yarn install 57 61
+4
.github/workflows/bundle-deploy-eas-update.yml
··· 275 275 distribution: 'temurin' 276 276 java-version: '17' 277 277 278 + - name: "Use upgraded MMKV for Fabric" 279 + run: | 280 + sed -i 's/"react-native-mmkv": "\^2\.12\.2"/"react-native-mmkv": "^3.3.0"/' package.json 281 + 278 282 - name: ⚙️ Install dependencies 279 283 run: yarn install 280 284
+2 -2
package.json
··· 69 69 "icons:optimize": "svgo -f ./assets/icons" 70 70 }, 71 71 "dependencies": { 72 - "@atproto/api": "^0.15.15", 72 + "@atproto/api": "^0.15.16", 73 73 "@bitdrift/react-native": "^0.6.8", 74 74 "@braintree/sanitize-url": "^6.0.2", 75 75 "@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet", ··· 218 218 "zod": "^3.20.2" 219 219 }, 220 220 "devDependencies": { 221 - "@atproto/dev-env": "^0.3.142", 221 + "@atproto/dev-env": "^0.3.144", 222 222 "@babel/core": "^7.26.0", 223 223 "@babel/preset-env": "^7.26.0", 224 224 "@babel/runtime": "^7.26.0",
-2
src/App.native.tsx
··· 64 64 import {ThemeProvider as Alf} from '#/alf' 65 65 import {useColorModeTheme} from '#/alf/util/useColorModeTheme' 66 66 import {Provider as ContextMenuProvider} from '#/components/ContextMenu' 67 - import {NuxDialogs} from '#/components/dialogs/nuxs' 68 67 import {useStarterPackEntry} from '#/components/hooks/useStarterPackEntry' 69 68 import {Provider as IntentDialogProvider} from '#/components/intents/IntentDialogs' 70 69 import {Provider as PortalProvider} from '#/components/Portal' ··· 157 156 <IntentDialogProvider> 158 157 <TestCtrls /> 159 158 <Shell /> 160 - <NuxDialogs /> 161 159 </IntentDialogProvider> 162 160 </GestureHandlerRootView> 163 161 </HideBottomBarBorderProvider>
-2
src/App.web.tsx
··· 54 54 import {ThemeProvider as Alf} from '#/alf' 55 55 import {useColorModeTheme} from '#/alf/util/useColorModeTheme' 56 56 import {Provider as ContextMenuProvider} from '#/components/ContextMenu' 57 - import {NuxDialogs} from '#/components/dialogs/nuxs' 58 57 import {useStarterPackEntry} from '#/components/hooks/useStarterPackEntry' 59 58 import {Provider as IntentDialogProvider} from '#/components/intents/IntentDialogs' 60 59 import {Provider as PortalProvider} from '#/components/Portal' ··· 135 134 <HideBottomBarBorderProvider> 136 135 <IntentDialogProvider> 137 136 <Shell /> 138 - <NuxDialogs /> 139 137 </IntentDialogProvider> 140 138 </HideBottomBarBorderProvider> 141 139 </ServiceConfigProvider>
+2 -2
src/Navigation.tsx
··· 456 456 name="LikesOnRepostsNotificationSettings" 457 457 getComponent={() => LikesOnRepostsNotificationSettingsScreen} 458 458 options={{ 459 - title: title(msg`Likes on your reposts notifications`), 459 + title: title(msg`Likes of your reposts notifications`), 460 460 requireAuth: true, 461 461 }} 462 462 /> ··· 464 464 name="RepostsOnRepostsNotificationSettings" 465 465 getComponent={() => RepostsOnRepostsNotificationSettingsScreen} 466 466 options={{ 467 - title: title(msg`Reposts on your reposts notifications`), 467 + title: title(msg`Reposts of your reposts notifications`), 468 468 requireAuth: true, 469 469 }} 470 470 />
+53 -18
src/components/Link.tsx
··· 9 9 import {BSKY_DOWNLOAD_URL} from '#/lib/constants' 10 10 import {useNavigationDeduped} from '#/lib/hooks/useNavigationDeduped' 11 11 import {useOpenLink} from '#/lib/hooks/useOpenLink' 12 - import {type AllNavigatorParams} from '#/lib/routes/types' 12 + import {type AllNavigatorParams, type RouteParams} from '#/lib/routes/types' 13 13 import {shareUrl} from '#/lib/sharing' 14 14 import { 15 15 convertBskyAppUrlIfNeeded, ··· 25 25 import {useInteractionState} from '#/components/hooks/useInteractionState' 26 26 import {Text, type TextProps} from '#/components/Typography' 27 27 import {router} from '#/routes' 28 + import {useGlobalDialogsControlContext} from './dialogs/Context' 28 29 29 30 /** 30 31 * Only available within a `Link`, since that inherits from `Button`. ··· 112 113 } 113 114 114 115 const isExternal = isExternalUrl(href) 115 - const {openModal, closeModal} = useModalControls() 116 + const {closeModal} = useModalControls() 117 + const {linkWarningDialogControl} = useGlobalDialogsControlContext() 116 118 const openLink = useOpenLink() 117 119 118 120 const goLinksEnabled = useGoLinksEnabled() ··· 135 137 } 136 138 137 139 if (requiresWarning) { 138 - openModal({ 139 - name: 'link-warning', 140 - text: displayText, 141 - href: href, 140 + linkWarningDialogControl.open({ 141 + displayText, 142 + href, 142 143 }) 143 144 } else { 144 145 if (isExternal) { ··· 158 159 } else { 159 160 closeModal() // close any active modals 160 161 162 + const [screen, params] = router.matchPath(href) as [ 163 + screen: keyof AllNavigatorParams, 164 + params?: RouteParams, 165 + ] 166 + 167 + // does not apply to web's flat navigator 168 + if (isNative && screen !== 'NotFound') { 169 + const state = navigation.getState() 170 + // if screen is not in the current navigator, it means it's 171 + // most likely a tab screen 172 + if (!state.routeNames.includes(screen)) { 173 + const parent = navigation.getParent() 174 + if ( 175 + parent && 176 + parent.getState().routeNames.includes(`${screen}Tab`) 177 + ) { 178 + // yep, it's a tab screen. i.e. SearchTab 179 + // thus we need to navigate to the child screen 180 + // via the parent navigator 181 + // see https://reactnavigation.org/docs/upgrading-from-6.x/#changes-to-the-navigate-action 182 + // TODO: can we support the other kinds of actions? push/replace -sfn 183 + 184 + // @ts-expect-error include does not narrow the type unfortunately 185 + parent.navigate(`${screen}Tab`, {screen, params}) 186 + return 187 + } else { 188 + // will probably fail, but let's try anyway 189 + } 190 + } 191 + } 192 + 161 193 if (action === 'push') { 162 - navigation.dispatch(StackActions.push(...router.matchPath(href))) 194 + navigation.dispatch(StackActions.push(screen, params)) 163 195 } else if (action === 'replace') { 164 - navigation.dispatch( 165 - StackActions.replace(...router.matchPath(href)), 166 - ) 196 + navigation.dispatch(StackActions.replace(screen, params)) 167 197 } else if (action === 'navigate') { 168 - // @ts-ignore 169 - navigation.navigate(...router.matchPath(href)) 198 + // @ts-expect-error not typed 199 + navigation.navigate(screen, params) 170 200 } else { 171 201 throw Error('Unsupported navigator action.') 172 202 } ··· 180 210 displayText, 181 211 isExternal, 182 212 href, 183 - openModal, 184 213 openLink, 185 214 closeModal, 186 215 action, ··· 188 217 overridePresentation, 189 218 shouldProxy, 190 219 goLinksEnabled, 220 + linkWarningDialogControl, 191 221 ], 192 222 ) 193 223 ··· 200 230 ) 201 231 202 232 if (requiresWarning) { 203 - openModal({ 204 - name: 'link-warning', 205 - text: displayText, 206 - href: href, 233 + linkWarningDialogControl.open({ 234 + displayText, 235 + href, 207 236 share: true, 208 237 }) 209 238 } else { 210 239 shareUrl(href) 211 240 } 212 - }, [disableMismatchWarning, displayText, href, isExternal, openModal]) 241 + }, [ 242 + disableMismatchWarning, 243 + displayText, 244 + href, 245 + isExternal, 246 + linkWarningDialogControl, 247 + ]) 213 248 214 249 const onLongPress = React.useCallback( 215 250 (e: GestureResponderEvent) => {
+1
src/components/Select/index.web.tsx
··· 244 244 onFocus={onFocus} 245 245 onBlur={onBlur} 246 246 style={flatten([ 247 + t.atoms.text, 247 248 a.relative, 248 249 a.flex, 249 250 {minHeight: 25, paddingLeft: 30, paddingRight: 35},
-259
src/components/dialogs/ChangeEmailDialog.tsx
··· 1 - import {useState} from 'react' 2 - import {View} from 'react-native' 3 - import {msg, Trans} from '@lingui/macro' 4 - import {useLingui} from '@lingui/react' 5 - 6 - import {cleanError} from '#/lib/strings/errors' 7 - import {useAgent, useSession} from '#/state/session' 8 - import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' 9 - import {atoms as a, useBreakpoints, web} from '#/alf' 10 - import {Button, ButtonText} from '#/components/Button' 11 - import * as Dialog from '#/components/Dialog' 12 - import * as TextField from '#/components/forms/TextField' 13 - import {Loader} from '#/components/Loader' 14 - import {Text} from '#/components/Typography' 15 - 16 - export function ChangeEmailDialog({ 17 - control, 18 - verifyEmailControl, 19 - }: { 20 - control: Dialog.DialogControlProps 21 - verifyEmailControl: Dialog.DialogControlProps 22 - }) { 23 - return ( 24 - <Dialog.Outer control={control}> 25 - <Dialog.Handle /> 26 - <Inner verifyEmailControl={verifyEmailControl} /> 27 - </Dialog.Outer> 28 - ) 29 - } 30 - 31 - export function Inner({ 32 - verifyEmailControl, 33 - }: { 34 - verifyEmailControl: Dialog.DialogControlProps 35 - }) { 36 - const {_} = useLingui() 37 - const {currentAccount} = useSession() 38 - const agent = useAgent() 39 - const control = Dialog.useDialogContext() 40 - const {gtMobile} = useBreakpoints() 41 - 42 - const [currentStep, setCurrentStep] = useState< 43 - 'StepOne' | 'StepTwo' | 'StepThree' 44 - >('StepOne') 45 - const [email, setEmail] = useState('') 46 - const [confirmationCode, setConfirmationCode] = useState('') 47 - const [isProcessing, setIsProcessing] = useState(false) 48 - const [error, setError] = useState('') 49 - 50 - const currentEmail = currentAccount?.email || '(no email)' 51 - const uiStrings = { 52 - StepOne: { 53 - title: _(msg`Change Your Email`), 54 - message: '', 55 - }, 56 - StepTwo: { 57 - title: _(msg`Security Step Required`), 58 - message: _( 59 - msg`An email has been sent to your previous address, ${currentEmail}. It includes a confirmation code which you can enter below.`, 60 - ), 61 - }, 62 - StepThree: { 63 - title: _(msg`Email Updated!`), 64 - message: _( 65 - msg`Your email address has been updated but it is not yet verified. As a next step, please verify your new email.`, 66 - ), 67 - }, 68 - } 69 - 70 - const onRequestChange = async () => { 71 - if (email === currentAccount?.email) { 72 - setError( 73 - _( 74 - msg`The email address you entered is the same as your current email address.`, 75 - ), 76 - ) 77 - return 78 - } 79 - setError('') 80 - setIsProcessing(true) 81 - try { 82 - const res = await agent.com.atproto.server.requestEmailUpdate() 83 - if (res.data.tokenRequired) { 84 - setCurrentStep('StepTwo') 85 - } else { 86 - await agent.com.atproto.server.updateEmail({email: email.trim()}) 87 - await agent.resumeSession(agent.session!) 88 - setCurrentStep('StepThree') 89 - } 90 - } catch (e) { 91 - setError(cleanError(String(e))) 92 - } finally { 93 - setIsProcessing(false) 94 - } 95 - } 96 - 97 - const onConfirm = async () => { 98 - setError('') 99 - setIsProcessing(true) 100 - try { 101 - await agent.com.atproto.server.updateEmail({ 102 - email: email.trim(), 103 - token: confirmationCode.trim(), 104 - }) 105 - await agent.resumeSession(agent.session!) 106 - setCurrentStep('StepThree') 107 - } catch (e) { 108 - setError(cleanError(String(e))) 109 - } finally { 110 - setIsProcessing(false) 111 - } 112 - } 113 - 114 - const onVerify = async () => { 115 - control.close(() => { 116 - verifyEmailControl.open() 117 - }) 118 - } 119 - 120 - return ( 121 - <Dialog.ScrollableInner 122 - label={_(msg`Verify email dialog`)} 123 - style={web({maxWidth: 450})}> 124 - <Dialog.Close /> 125 - <View style={[a.gap_xl]}> 126 - <View style={[a.gap_sm]}> 127 - <Text style={[a.font_heavy, a.text_2xl]}> 128 - {uiStrings[currentStep].title} 129 - </Text> 130 - {error ? ( 131 - <View style={[a.rounded_sm, a.overflow_hidden]}> 132 - <ErrorMessage message={error} /> 133 - </View> 134 - ) : null} 135 - {currentStep === 'StepOne' ? ( 136 - <View> 137 - <TextField.LabelText> 138 - <Trans>Enter your new email address below.</Trans> 139 - </TextField.LabelText> 140 - <TextField.Root> 141 - <TextField.Input 142 - label={_(msg`New email address`)} 143 - placeholder={_(msg`alice@example.com`)} 144 - defaultValue={email} 145 - onChangeText={setEmail} 146 - keyboardType="email-address" 147 - autoComplete="email" 148 - /> 149 - </TextField.Root> 150 - </View> 151 - ) : ( 152 - <Text style={[a.text_md, a.leading_snug]}> 153 - {uiStrings[currentStep].message} 154 - </Text> 155 - )} 156 - </View> 157 - {currentStep === 'StepTwo' ? ( 158 - <View> 159 - <TextField.LabelText> 160 - <Trans>Confirmation code</Trans> 161 - </TextField.LabelText> 162 - <TextField.Root> 163 - <TextField.Input 164 - label={_(msg`Confirmation code`)} 165 - placeholder="XXXXX-XXXXX" 166 - onChangeText={setConfirmationCode} 167 - /> 168 - </TextField.Root> 169 - </View> 170 - ) : null} 171 - <View style={[a.gap_sm, gtMobile && [a.flex_row_reverse, a.ml_auto]]}> 172 - {currentStep === 'StepOne' ? ( 173 - <> 174 - <Button 175 - label={_(msg`Request change`)} 176 - variant="solid" 177 - color="primary" 178 - size="large" 179 - disabled={isProcessing} 180 - onPress={onRequestChange}> 181 - <ButtonText> 182 - <Trans>Request change</Trans> 183 - </ButtonText> 184 - {isProcessing ? ( 185 - <Loader size="sm" style={[{color: 'white'}]} /> 186 - ) : null} 187 - </Button> 188 - <Button 189 - label={_(msg`I have a code`)} 190 - variant="solid" 191 - color="secondary" 192 - size="large" 193 - disabled={isProcessing} 194 - onPress={() => setCurrentStep('StepTwo')}> 195 - <ButtonText> 196 - <Trans>I have a code</Trans> 197 - </ButtonText> 198 - </Button> 199 - </> 200 - ) : currentStep === 'StepTwo' ? ( 201 - <> 202 - <Button 203 - label={_(msg`Confirm`)} 204 - variant="solid" 205 - color="primary" 206 - size="large" 207 - disabled={isProcessing} 208 - onPress={onConfirm}> 209 - <ButtonText> 210 - <Trans>Confirm</Trans> 211 - </ButtonText> 212 - {isProcessing ? ( 213 - <Loader size="sm" style={[{color: 'white'}]} /> 214 - ) : null} 215 - </Button> 216 - <Button 217 - label={_(msg`Resend email`)} 218 - variant="solid" 219 - color="secondary" 220 - size="large" 221 - disabled={isProcessing} 222 - onPress={() => { 223 - setConfirmationCode('') 224 - setCurrentStep('StepOne') 225 - }}> 226 - <ButtonText> 227 - <Trans>Resend email</Trans> 228 - </ButtonText> 229 - </Button> 230 - </> 231 - ) : currentStep === 'StepThree' ? ( 232 - <> 233 - <Button 234 - label={_(msg`Verify email`)} 235 - variant="solid" 236 - color="primary" 237 - size="large" 238 - onPress={onVerify}> 239 - <ButtonText> 240 - <Trans>Verify email</Trans> 241 - </ButtonText> 242 - </Button> 243 - <Button 244 - label={_(msg`Close`)} 245 - variant="solid" 246 - color="secondary" 247 - size="large" 248 - onPress={() => control.close()}> 249 - <ButtonText> 250 - <Trans>Close</Trans> 251 - </ButtonText> 252 - </Button> 253 - </> 254 - ) : null} 255 - </View> 256 - </View> 257 - </Dialog.ScrollableInner> 258 - ) 259 - }
+12
src/components/dialogs/Context.tsx
··· 17 17 signinDialogControl: Control 18 18 inAppBrowserConsentControl: StatefulControl<string> 19 19 emailDialogControl: StatefulControl<Screen> 20 + linkWarningDialogControl: StatefulControl<{ 21 + href: string 22 + displayText: string 23 + share?: boolean 24 + }> 20 25 } 21 26 22 27 const ControlsContext = createContext<ControlsContext | null>(null) ··· 36 41 const signinDialogControl = Dialog.useDialogControl() 37 42 const inAppBrowserConsentControl = useStatefulDialogControl<string>() 38 43 const emailDialogControl = useStatefulDialogControl<Screen>() 44 + const linkWarningDialogControl = useStatefulDialogControl<{ 45 + href: string 46 + displayText: string 47 + share?: boolean 48 + }>() 39 49 40 50 const ctx = useMemo<ControlsContext>( 41 51 () => ({ ··· 43 53 signinDialogControl, 44 54 inAppBrowserConsentControl, 45 55 emailDialogControl, 56 + linkWarningDialogControl, 46 57 }), 47 58 [ 48 59 mutedWordsDialogControl, 49 60 signinDialogControl, 50 61 inAppBrowserConsentControl, 51 62 emailDialogControl, 63 + linkWarningDialogControl, 52 64 ], 53 65 ) 54 66
+161
src/components/dialogs/LinkWarning.tsx
··· 1 + import {useCallback, useMemo} from 'react' 2 + import {View} from 'react-native' 3 + import {msg, Trans} from '@lingui/macro' 4 + import {useLingui} from '@lingui/react' 5 + 6 + import {useOpenLink} from '#/lib/hooks/useOpenLink' 7 + import {shareUrl} from '#/lib/sharing' 8 + import {isPossiblyAUrl, splitApexDomain} from '#/lib/strings/url-helpers' 9 + import {atoms as a, useBreakpoints, useTheme, web} from '#/alf' 10 + import {Button, ButtonText} from '#/components/Button' 11 + import * as Dialog from '#/components/Dialog' 12 + import {Text} from '#/components/Typography' 13 + import {useGlobalDialogsControlContext} from './Context' 14 + 15 + export function LinkWarningDialog() { 16 + const {linkWarningDialogControl} = useGlobalDialogsControlContext() 17 + 18 + return ( 19 + <Dialog.Outer 20 + control={linkWarningDialogControl.control} 21 + nativeOptions={{preventExpansion: true}} 22 + webOptions={{alignCenter: true}} 23 + onClose={linkWarningDialogControl.clear}> 24 + <Dialog.Handle /> 25 + <InAppBrowserConsentInner link={linkWarningDialogControl.value} /> 26 + </Dialog.Outer> 27 + ) 28 + } 29 + 30 + function InAppBrowserConsentInner({ 31 + link, 32 + }: { 33 + link?: {href: string; displayText: string; share?: boolean} 34 + }) { 35 + const control = Dialog.useDialogContext() 36 + const {_} = useLingui() 37 + const t = useTheme() 38 + const openLink = useOpenLink() 39 + const {gtMobile} = useBreakpoints() 40 + 41 + const potentiallyMisleading = useMemo( 42 + () => link && isPossiblyAUrl(link.displayText), 43 + [link], 44 + ) 45 + 46 + const onPressVisit = useCallback(() => { 47 + control.close(() => { 48 + if (!link) return 49 + if (link.share) { 50 + shareUrl(link.href) 51 + } else { 52 + openLink(link.href, undefined, true) 53 + } 54 + }) 55 + }, [control, link, openLink]) 56 + 57 + const onCancel = useCallback(() => { 58 + control.close() 59 + }, [control]) 60 + 61 + return ( 62 + <Dialog.ScrollableInner 63 + style={web({maxWidth: 450})} 64 + label={ 65 + potentiallyMisleading 66 + ? _(msg`Potentially misleading link warning`) 67 + : _(msg`Leaving Bluesky`) 68 + }> 69 + <View style={[a.gap_2xl]}> 70 + <View style={[a.gap_sm]}> 71 + <Text style={[a.font_heavy, a.text_2xl]}> 72 + {potentiallyMisleading ? ( 73 + <Trans>Potentially misleading link</Trans> 74 + ) : ( 75 + <Trans>Leaving Bluesky</Trans> 76 + )} 77 + </Text> 78 + <Text style={[t.atoms.text_contrast_high, a.text_md, a.leading_snug]}> 79 + <Trans>This link is taking you to the following website:</Trans> 80 + </Text> 81 + {link && <LinkBox href={link.href} />} 82 + {potentiallyMisleading && ( 83 + <Text 84 + style={[t.atoms.text_contrast_high, a.text_md, a.leading_snug]}> 85 + <Trans>Make sure this is where you intend to go!</Trans> 86 + </Text> 87 + )} 88 + </View> 89 + <View 90 + style={[ 91 + a.flex_1, 92 + a.gap_sm, 93 + gtMobile && [a.flex_row_reverse, a.justify_start], 94 + ]}> 95 + <Button 96 + label={link?.share ? _(msg`Share link`) : _(msg`Visit site`)} 97 + accessibilityHint={_(msg`Opens link ${link?.href ?? ''}`)} 98 + onPress={onPressVisit} 99 + size="large" 100 + variant="solid" 101 + color={potentiallyMisleading ? 'secondary_inverted' : 'primary'}> 102 + <ButtonText> 103 + {link?.share ? ( 104 + <Trans>Share link</Trans> 105 + ) : ( 106 + <Trans>Visit site</Trans> 107 + )} 108 + </ButtonText> 109 + </Button> 110 + <Button 111 + label={_(msg`Go back`)} 112 + onPress={onCancel} 113 + size="large" 114 + variant="ghost" 115 + color="secondary"> 116 + <ButtonText> 117 + <Trans>Go back</Trans> 118 + </ButtonText> 119 + </Button> 120 + </View> 121 + </View> 122 + <Dialog.Close /> 123 + </Dialog.ScrollableInner> 124 + ) 125 + } 126 + 127 + function LinkBox({href}: {href: string}) { 128 + const t = useTheme() 129 + const [scheme, hostname, rest] = useMemo(() => { 130 + try { 131 + const urlp = new URL(href) 132 + const [subdomain, apexdomain] = splitApexDomain(urlp.hostname) 133 + return [ 134 + urlp.protocol + '//' + subdomain, 135 + apexdomain, 136 + urlp.pathname.replace(/\/$/, '') + urlp.search + urlp.hash, 137 + ] 138 + } catch { 139 + return ['', href, ''] 140 + } 141 + }, [href]) 142 + return ( 143 + <View 144 + style={[ 145 + t.atoms.bg, 146 + t.atoms.border_contrast_medium, 147 + a.px_md, 148 + {paddingVertical: 10}, 149 + a.rounded_sm, 150 + a.border, 151 + ]}> 152 + <Text style={[a.text_md, a.leading_snug, t.atoms.text_contrast_medium]}> 153 + {scheme} 154 + <Text style={[a.text_md, a.leading_snug, t.atoms.text, a.font_bold]}> 155 + {hostname} 156 + </Text> 157 + {rest} 158 + </Text> 159 + </View> 160 + ) 161 + }
-360
src/components/dialogs/VerifyEmailDialog.tsx
··· 1 - import {useState} from 'react' 2 - import {View} from 'react-native' 3 - import {msg, Trans} from '@lingui/macro' 4 - import {useLingui} from '@lingui/react' 5 - 6 - import {cleanError} from '#/lib/strings/errors' 7 - import {logger} from '#/logger' 8 - import {useAgent, useSession} from '#/state/session' 9 - import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' 10 - import {atoms as a, useBreakpoints, useTheme, web} from '#/alf' 11 - import {Button, ButtonText} from '#/components/Button' 12 - import * as Dialog from '#/components/Dialog' 13 - import * as TextField from '#/components/forms/TextField' 14 - import {Envelope_Filled_Stroke2_Corner0_Rounded as EnvelopeIcon} from '#/components/icons/Envelope' 15 - import {InlineLinkText} from '#/components/Link' 16 - import {Loader} from '#/components/Loader' 17 - import {Text} from '#/components/Typography' 18 - import {ChangeEmailDialog} from './ChangeEmailDialog' 19 - 20 - export function VerifyEmailDialog({ 21 - control, 22 - onCloseWithoutVerifying, 23 - onCloseAfterVerifying, 24 - reasonText, 25 - changeEmailControl, 26 - reminder, 27 - }: { 28 - control: Dialog.DialogControlProps 29 - onCloseWithoutVerifying?: () => void 30 - onCloseAfterVerifying?: () => void 31 - reasonText?: string 32 - /** 33 - * if a changeEmailControl for a ChangeEmailDialog is not provided, 34 - * this component will create one for you. Using this prop 35 - * helps reduce duplication, since these dialogs are often used together. 36 - */ 37 - changeEmailControl?: Dialog.DialogControlProps 38 - reminder?: boolean 39 - }) { 40 - const agent = useAgent() 41 - const fallbackChangeEmailControl = Dialog.useDialogControl() 42 - 43 - const [didVerify, setDidVerify] = useState(false) 44 - 45 - return ( 46 - <> 47 - <Dialog.Outer 48 - control={control} 49 - onClose={async () => { 50 - if (!didVerify) { 51 - onCloseWithoutVerifying?.() 52 - return 53 - } 54 - 55 - try { 56 - await agent.resumeSession(agent.session!) 57 - onCloseAfterVerifying?.() 58 - } catch (e: unknown) { 59 - logger.error(String(e)) 60 - return 61 - } 62 - }}> 63 - <Dialog.Handle /> 64 - <Inner 65 - setDidVerify={setDidVerify} 66 - reasonText={reasonText} 67 - changeEmailControl={changeEmailControl ?? fallbackChangeEmailControl} 68 - reminder={reminder} 69 - /> 70 - </Dialog.Outer> 71 - {!changeEmailControl && ( 72 - <ChangeEmailDialog 73 - control={fallbackChangeEmailControl} 74 - verifyEmailControl={control} 75 - /> 76 - )} 77 - </> 78 - ) 79 - } 80 - 81 - export function Inner({ 82 - setDidVerify, 83 - reasonText, 84 - changeEmailControl, 85 - reminder, 86 - }: { 87 - setDidVerify: (value: boolean) => void 88 - reasonText?: string 89 - changeEmailControl: Dialog.DialogControlProps 90 - reminder?: boolean 91 - }) { 92 - const control = Dialog.useDialogContext() 93 - const {_} = useLingui() 94 - const {currentAccount} = useSession() 95 - const agent = useAgent() 96 - const {gtMobile} = useBreakpoints() 97 - const t = useTheme() 98 - 99 - const [currentStep, setCurrentStep] = useState< 100 - 'Reminder' | 'StepOne' | 'StepTwo' | 'StepThree' 101 - >(reminder ? 'Reminder' : 'StepOne') 102 - const [confirmationCode, setConfirmationCode] = useState('') 103 - const [isProcessing, setIsProcessing] = useState(false) 104 - const [error, setError] = useState('') 105 - 106 - const uiStrings = { 107 - Reminder: { 108 - title: _(msg`Please Verify Your Email`), 109 - message: _( 110 - msg`Your email has not yet been verified. This is an important security step which we recommend.`, 111 - ), 112 - }, 113 - StepOne: { 114 - title: _(msg`Verify Your Email`), 115 - message: '', 116 - }, 117 - StepTwo: { 118 - title: _(msg`Enter Code`), 119 - message: _( 120 - msg`An email has been sent! Please enter the confirmation code included in the email below.`, 121 - ), 122 - }, 123 - StepThree: { 124 - title: _(msg`Success!`), 125 - message: _(msg`Thank you! Your email has been successfully verified.`), 126 - }, 127 - } 128 - 129 - const onSendEmail = async () => { 130 - setError('') 131 - setIsProcessing(true) 132 - try { 133 - await agent.com.atproto.server.requestEmailConfirmation() 134 - setCurrentStep('StepTwo') 135 - } catch (e: unknown) { 136 - setError(cleanError(e)) 137 - } finally { 138 - setIsProcessing(false) 139 - } 140 - } 141 - 142 - const onVerifyEmail = async () => { 143 - setError('') 144 - setIsProcessing(true) 145 - try { 146 - await agent.com.atproto.server.confirmEmail({ 147 - email: (currentAccount?.email || '').trim(), 148 - token: confirmationCode.trim(), 149 - }) 150 - } catch (e: unknown) { 151 - setError(cleanError(String(e))) 152 - setIsProcessing(false) 153 - return 154 - } 155 - 156 - setIsProcessing(false) 157 - setDidVerify(true) 158 - setCurrentStep('StepThree') 159 - } 160 - 161 - return ( 162 - <Dialog.ScrollableInner 163 - label={_(msg`Verify email dialog`)} 164 - style={web({maxWidth: 450})}> 165 - <View style={[a.gap_xl]}> 166 - {currentStep === 'Reminder' && ( 167 - <View 168 - style={[ 169 - a.rounded_sm, 170 - a.align_center, 171 - a.justify_center, 172 - {height: 150}, 173 - t.atoms.bg_contrast_100, 174 - ]}> 175 - <EnvelopeIcon width={64} fill="white" /> 176 - </View> 177 - )} 178 - <View style={[a.gap_sm]}> 179 - <Text style={[a.font_heavy, a.text_2xl]}> 180 - {uiStrings[currentStep].title} 181 - </Text> 182 - {error ? ( 183 - <View style={[a.rounded_sm, a.overflow_hidden]}> 184 - <ErrorMessage message={error} /> 185 - </View> 186 - ) : null} 187 - {currentStep === 'StepOne' ? ( 188 - <View> 189 - {reasonText ? ( 190 - <View style={[a.gap_sm]}> 191 - <Text style={[a.text_md, a.leading_snug]}>{reasonText}</Text> 192 - <Text style={[a.text_md, a.leading_snug]}> 193 - Don't have access to{' '} 194 - <Text style={[a.text_md, a.leading_snug, a.font_bold]}> 195 - {currentAccount?.email} 196 - </Text> 197 - ?{' '} 198 - <InlineLinkText 199 - to="#" 200 - label={_(msg`Change email address`)} 201 - style={[a.text_md, a.leading_snug]} 202 - onPress={e => { 203 - e.preventDefault() 204 - control.close(() => { 205 - changeEmailControl.open() 206 - }) 207 - return false 208 - }}> 209 - <Trans>Change your email address</Trans> 210 - </InlineLinkText> 211 - . 212 - </Text> 213 - </View> 214 - ) : ( 215 - <Text style={[a.text_md, a.leading_snug]}> 216 - <Trans> 217 - You'll receive an email at{' '} 218 - <Text style={[a.text_md, a.leading_snug, a.font_bold]}> 219 - {currentAccount?.email} 220 - </Text>{' '} 221 - to verify it's you. 222 - </Trans>{' '} 223 - <InlineLinkText 224 - to="#" 225 - label={_(msg`Change email address`)} 226 - style={[a.text_md, a.leading_snug]} 227 - onPress={e => { 228 - e.preventDefault() 229 - control.close(() => { 230 - changeEmailControl.open() 231 - }) 232 - return false 233 - }}> 234 - <Trans>Need to change it?</Trans> 235 - </InlineLinkText> 236 - </Text> 237 - )} 238 - </View> 239 - ) : ( 240 - <Text style={[a.text_md, a.leading_snug]}> 241 - {uiStrings[currentStep].message} 242 - </Text> 243 - )} 244 - </View> 245 - {currentStep === 'StepTwo' ? ( 246 - <View> 247 - <TextField.LabelText> 248 - <Trans>Confirmation Code</Trans> 249 - </TextField.LabelText> 250 - <TextField.Root> 251 - <TextField.Input 252 - label={_(msg`Confirmation code`)} 253 - placeholder="XXXXX-XXXXX" 254 - onChangeText={setConfirmationCode} 255 - /> 256 - </TextField.Root> 257 - </View> 258 - ) : null} 259 - <View style={[a.gap_sm, gtMobile && [a.flex_row_reverse, a.ml_auto]]}> 260 - {currentStep === 'Reminder' ? ( 261 - <> 262 - <Button 263 - label={_(msg`Get started`)} 264 - variant="solid" 265 - color="primary" 266 - size="large" 267 - onPress={() => setCurrentStep('StepOne')}> 268 - <ButtonText> 269 - <Trans>Get started</Trans> 270 - </ButtonText> 271 - </Button> 272 - <Button 273 - label={_(msg`Maybe later`)} 274 - accessibilityHint={_(msg`Snoozes the reminder`)} 275 - variant="ghost" 276 - color="secondary" 277 - size="large" 278 - disabled={isProcessing} 279 - onPress={() => control.close()}> 280 - <ButtonText> 281 - <Trans>Maybe later</Trans> 282 - </ButtonText> 283 - </Button> 284 - </> 285 - ) : currentStep === 'StepOne' ? ( 286 - <> 287 - <Button 288 - label={_(msg`Send confirmation email`)} 289 - variant="solid" 290 - color="primary" 291 - size="large" 292 - disabled={isProcessing} 293 - onPress={onSendEmail}> 294 - <ButtonText> 295 - <Trans>Send confirmation</Trans> 296 - </ButtonText> 297 - {isProcessing ? ( 298 - <Loader size="sm" style={[{color: 'white'}]} /> 299 - ) : null} 300 - </Button> 301 - <Button 302 - label={_(msg`I have a code`)} 303 - variant="solid" 304 - color="secondary" 305 - size="large" 306 - disabled={isProcessing} 307 - onPress={() => setCurrentStep('StepTwo')}> 308 - <ButtonText> 309 - <Trans>I have a code</Trans> 310 - </ButtonText> 311 - </Button> 312 - </> 313 - ) : currentStep === 'StepTwo' ? ( 314 - <> 315 - <Button 316 - label={_(msg`Confirm`)} 317 - variant="solid" 318 - color="primary" 319 - size="large" 320 - disabled={isProcessing} 321 - onPress={onVerifyEmail}> 322 - <ButtonText> 323 - <Trans>Confirm</Trans> 324 - </ButtonText> 325 - {isProcessing ? ( 326 - <Loader size="sm" style={[{color: 'white'}]} /> 327 - ) : null} 328 - </Button> 329 - <Button 330 - label={_(msg`Resend email`)} 331 - variant="solid" 332 - color="secondary" 333 - size="large" 334 - disabled={isProcessing} 335 - onPress={() => { 336 - setConfirmationCode('') 337 - setCurrentStep('StepOne') 338 - }}> 339 - <ButtonText> 340 - <Trans>Resend email</Trans> 341 - </ButtonText> 342 - </Button> 343 - </> 344 - ) : currentStep === 'StepThree' ? ( 345 - <Button 346 - label={_(msg`Close`)} 347 - variant="solid" 348 - color="primary" 349 - size="large" 350 - onPress={() => control.close()}> 351 - <ButtonText> 352 - <Trans>Close</Trans> 353 - </ButtonText> 354 - </Button> 355 - ) : null} 356 - </View> 357 - </View> 358 - </Dialog.ScrollableInner> 359 - ) 360 - }
+4
src/lib/hooks/useNavigationDeduped.ts
··· 14 14 | 'dispatch' 15 15 | 'goBack' 16 16 | 'getState' 17 + | 'getParent' 17 18 > 18 19 19 20 export function useNavigationDeduped() { ··· 45 46 }, 46 47 getState: () => { 47 48 return navigation.getState() 49 + }, 50 + getParent: (...args: Parameters<typeof navigation.getParent>) => { 51 + return navigation.getParent(...args) 48 52 }, 49 53 }), 50 54 [dedupe, navigation],
+5
src/lib/strings/url-helpers.ts
··· 198 198 return startUriToStarterPackUri(urlp.pathname) 199 199 } 200 200 201 + // special-case search links 202 + if (urlp.pathname === '/search') { 203 + return `/search?q=${urlp.searchParams.get('q')}` 204 + } 205 + 201 206 return urlp.pathname 202 207 } catch (e) { 203 208 console.error('Unexpected error in convertBskyAppUrlIfNeeded()', e)
+357 -317
src/locale/locales/en/messages.po
··· 464 464 msgid "<0>{date}</0> at {time}" 465 465 msgstr "" 466 466 467 - #: src/screens/Settings/NotificationSettings.tsx:85 468 - msgid "<0>Experimental:</0> When this preference is enabled, you'll only receive reply and quote notifications from users you follow. We'll continue to add more controls here over time." 469 - msgstr "" 470 - 471 467 #: src/screens/StarterPack/Wizard/index.tsx:440 472 468 msgid "<0>You</0> and<1> </1><2>{0} </2>are included in your starter pack" 473 469 msgstr "" ··· 501 497 msgid "A new form of verification" 502 498 msgstr "" 503 499 504 - #: src/Navigation.tsx:403 500 + #: src/Navigation.tsx:490 505 501 #: src/screens/Settings/AboutSettings.tsx:75 506 - #: src/screens/Settings/Settings.tsx:225 507 - #: src/screens/Settings/Settings.tsx:228 502 + #: src/screens/Settings/Settings.tsx:234 503 + #: src/screens/Settings/Settings.tsx:237 508 504 msgid "About" 509 505 msgstr "" 510 506 ··· 523 519 msgstr "" 524 520 525 521 #: src/screens/Settings/AccessibilitySettings.tsx:46 526 - #: src/screens/Settings/Settings.tsx:201 527 - #: src/screens/Settings/Settings.tsx:204 522 + #: src/screens/Settings/Settings.tsx:210 523 + #: src/screens/Settings/Settings.tsx:213 528 524 msgid "Accessibility" 529 525 msgstr "" 530 526 531 - #: src/Navigation.tsx:355 527 + #: src/Navigation.tsx:365 532 528 msgid "Accessibility Settings" 533 529 msgstr "" 534 530 535 - #: src/Navigation.tsx:371 531 + #: src/Navigation.tsx:381 536 532 #: src/screens/Login/LoginForm.tsx:194 537 533 #: src/screens/Settings/AccountSettings.tsx:48 538 - #: src/screens/Settings/Settings.tsx:163 539 - #: src/screens/Settings/Settings.tsx:166 534 + #: src/screens/Settings/Settings.tsx:164 535 + #: src/screens/Settings/Settings.tsx:167 540 536 msgid "Account" 541 537 msgstr "" 542 538 ··· 567 563 msgid "Account Muted by List" 568 564 msgstr "" 569 565 570 - #: src/screens/Settings/Settings.tsx:505 566 + #: src/screens/Settings/Settings.tsx:514 571 567 msgid "Account options" 572 568 msgstr "" 573 569 574 - #: src/screens/Settings/Settings.tsx:541 570 + #: src/screens/Settings/Settings.tsx:550 575 571 msgid "Account removed from quick access" 576 572 msgstr "" 577 573 ··· 643 639 msgid "Add alt text (optional)" 644 640 msgstr "" 645 641 646 - #: src/screens/Settings/Settings.tsx:445 647 - #: src/screens/Settings/Settings.tsx:448 642 + #: src/screens/Settings/Settings.tsx:454 643 + #: src/screens/Settings/Settings.tsx:457 648 644 #: src/view/shell/desktop/LeftNav.tsx:260 649 645 #: src/view/shell/desktop/LeftNav.tsx:264 650 646 msgid "Add another account" ··· 772 768 msgid "Advanced" 773 769 msgstr "" 774 770 775 - #: src/components/dialogs/ChangeEmailDialog.tsx:143 776 771 #: src/components/dialogs/EmailDialog/screens/Update.tsx:223 777 772 msgid "alice@example.com" 778 773 msgstr "" ··· 859 854 msgid "An email has been sent to {0}. It includes a confirmation code which you can enter below." 860 855 msgstr "" 861 856 862 - #: src/components/dialogs/ChangeEmailDialog.tsx:59 863 - msgid "An email has been sent to your previous address, {currentEmail}. It includes a confirmation code which you can enter below." 864 - msgstr "" 865 - 866 - #: src/components/dialogs/VerifyEmailDialog.tsx:120 867 - msgid "An email has been sent! Please enter the confirmation code included in the email below." 868 - msgstr "" 869 - 870 857 #: src/components/dialogs/GifSelect.tsx:265 871 858 msgid "An error has occurred" 872 859 msgstr "" ··· 978 965 msgid "Anybody can interact" 979 966 msgstr "" 980 967 981 - #: src/Navigation.tsx:411 968 + #: src/Navigation.tsx:498 982 969 #: src/screens/Settings/AppIconSettings/index.tsx:67 983 970 #: src/screens/Settings/AppIconSettings/SettingsListItem.tsx:18 984 971 #: src/screens/Settings/AppIconSettings/SettingsListItem.tsx:23 ··· 1015 1002 msgid "App passwords" 1016 1003 msgstr "" 1017 1004 1018 - #: src/Navigation.tsx:323 1005 + #: src/Navigation.tsx:333 1019 1006 #: src/screens/Settings/AppPasswords.tsx:51 1020 1007 msgid "App Passwords" 1021 1008 msgstr "" ··· 1051 1038 msgid "Appeal this decision" 1052 1039 msgstr "" 1053 1040 1054 - #: src/Navigation.tsx:363 1041 + #: src/Navigation.tsx:373 1055 1042 #: src/screens/Settings/AppearanceSettings.tsx:85 1056 - #: src/screens/Settings/Settings.tsx:193 1057 - #: src/screens/Settings/Settings.tsx:196 1043 + #: src/screens/Settings/Settings.tsx:202 1044 + #: src/screens/Settings/Settings.tsx:205 1058 1045 msgid "Appearance" 1059 1046 msgstr "" 1060 1047 ··· 1271 1258 msgid "Blocked accounts" 1272 1259 msgstr "" 1273 1260 1274 - #: src/Navigation.tsx:164 1261 + #: src/Navigation.tsx:174 1275 1262 #: src/view/screens/ModerationBlockedAccounts.tsx:104 1276 1263 msgid "Blocked Accounts" 1277 1264 msgstr "" ··· 1468 1455 #: src/screens/Settings/AppIconSettings/index.tsx:225 1469 1456 #: src/screens/Settings/components/ChangeHandleDialog.tsx:78 1470 1457 #: src/screens/Settings/components/ChangeHandleDialog.tsx:85 1471 - #: src/screens/Settings/Settings.tsx:270 1458 + #: src/screens/Settings/Settings.tsx:279 1472 1459 #: src/screens/Takendown.tsx:99 1473 1460 #: src/screens/Takendown.tsx:102 1474 1461 #: src/view/com/composer/Composer.tsx:960 ··· 1479 1466 #: src/view/com/modals/ChangePassword.tsx:282 1480 1467 #: src/view/com/modals/CreateOrEditList.tsx:333 1481 1468 #: src/view/com/modals/CropImage.web.tsx:97 1482 - #: src/view/com/modals/EditProfile.tsx:269 1483 1469 #: src/view/com/modals/LinkWarning.tsx:105 1484 1470 #: src/view/com/modals/LinkWarning.tsx:107 1485 1471 #: src/view/shell/desktop/LeftNav.tsx:213 ··· 1502 1488 msgid "Cancel image crop" 1503 1489 msgstr "" 1504 1490 1505 - #: src/view/com/modals/EditProfile.tsx:264 1506 - msgid "Cancel profile editing" 1507 - msgstr "" 1508 - 1509 1491 #: src/components/PostControls/RepostButton.tsx:203 1510 1492 msgid "Cancel quote post" 1511 1493 msgstr "" ··· 1555 1537 msgid "Change app language" 1556 1538 msgstr "" 1557 1539 1558 - #: src/components/dialogs/VerifyEmailDialog.tsx:200 1559 - #: src/components/dialogs/VerifyEmailDialog.tsx:225 1560 - msgid "Change email address" 1561 - msgstr "" 1562 - 1563 1540 #: src/screens/Settings/components/ChangeHandleDialog.tsx:94 1564 1541 #: src/screens/Settings/components/ChangeHandleDialog.tsx:98 1565 1542 msgid "Change Handle" ··· 1581 1558 msgid "Change report reason" 1582 1559 msgstr "" 1583 1560 1584 - #: src/components/dialogs/ChangeEmailDialog.tsx:53 1585 - msgid "Change Your Email" 1586 - msgstr "" 1587 - 1588 - #: src/components/dialogs/VerifyEmailDialog.tsx:209 1589 - msgid "Change your email address" 1590 - msgstr "" 1591 - 1592 1561 #: src/screens/Settings/AppIconSettings/index.tsx:216 1593 1562 msgid "Changes app icon" 1594 1563 msgstr "" ··· 1598 1567 msgid "Changes hosting provider" 1599 1568 msgstr "" 1600 1569 1601 - #: src/Navigation.tsx:428 1570 + #: src/Navigation.tsx:515 1602 1571 #: src/view/shell/bottom-bar/BottomBar.tsx:221 1603 1572 #: src/view/shell/desktop/LeftNav.tsx:553 1604 1573 #: src/view/shell/Drawer.tsx:455 ··· 1616 1585 msgid "Chat muted" 1617 1586 msgstr "" 1618 1587 1619 - #: src/Navigation.tsx:438 1588 + #: src/Navigation.tsx:525 1620 1589 #: src/screens/Messages/components/InboxPreview.tsx:24 1621 1590 msgid "Chat request inbox" 1622 1591 msgstr "" ··· 1627 1596 msgstr "" 1628 1597 1629 1598 #: src/components/dms/ConvoMenu.tsx:75 1630 - #: src/Navigation.tsx:433 1599 + #: src/Navigation.tsx:520 1631 1600 #: src/screens/Messages/ChatList.tsx:341 1632 1601 msgid "Chat settings" 1633 1602 msgstr "" ··· 1699 1668 msgid "Choose your username" 1700 1669 msgstr "" 1701 1670 1702 - #: src/screens/Settings/Settings.tsx:423 1671 + #: src/screens/Settings/Settings.tsx:432 1703 1672 msgid "Clear all storage data" 1704 1673 msgstr "" 1705 1674 1706 - #: src/screens/Settings/Settings.tsx:425 1675 + #: src/screens/Settings/Settings.tsx:434 1707 1676 msgid "Clear all storage data (restart after this)" 1708 1677 msgstr "" 1709 1678 ··· 1752 1721 msgid "Clip 🐴 clop 🐴" 1753 1722 msgstr "" 1754 1723 1755 - #: src/components/dialogs/ChangeEmailDialog.tsx:244 1756 - #: src/components/dialogs/ChangeEmailDialog.tsx:250 1757 1724 #: src/components/dialogs/GifSelect.tsx:281 1758 1725 #: src/components/dialogs/nuxs/InitialVerificationAnnouncement.tsx:178 1759 1726 #: src/components/dialogs/nuxs/InitialVerificationAnnouncement.tsx:187 1760 1727 #: src/components/dialogs/SearchablePeopleList.tsx:295 1761 - #: src/components/dialogs/VerifyEmailDialog.tsx:346 1762 - #: src/components/dialogs/VerifyEmailDialog.tsx:352 1763 1728 #: src/components/dms/EmojiPopup.android.tsx:58 1764 1729 #: src/components/dms/ReportDialog.tsx:381 1765 1730 #: src/components/dms/ReportDialog.tsx:390 ··· 1872 1837 msgid "Comics" 1873 1838 msgstr "" 1874 1839 1875 - #: src/Navigation.tsx:313 1840 + #: src/Navigation.tsx:323 1876 1841 #: src/view/screens/CommunityGuidelines.tsx:34 1877 1842 msgid "Community Guidelines" 1878 1843 msgstr "" ··· 1909 1874 msgid "Configured in <0>moderation settings</0>." 1910 1875 msgstr "" 1911 1876 1912 - #: src/components/dialogs/ChangeEmailDialog.tsx:203 1913 - #: src/components/dialogs/ChangeEmailDialog.tsx:210 1914 - #: src/components/dialogs/VerifyEmailDialog.tsx:316 1915 - #: src/components/dialogs/VerifyEmailDialog.tsx:323 1916 1877 #: src/components/Prompt.tsx:186 1917 1878 #: src/components/Prompt.tsx:189 1918 1879 #: src/screens/Settings/components/DisableEmail2FADialog.tsx:185 ··· 1936 1897 msgid "Confirm your birthdate" 1937 1898 msgstr "" 1938 1899 1939 - #: src/components/dialogs/ChangeEmailDialog.tsx:160 1940 - #: src/components/dialogs/ChangeEmailDialog.tsx:164 1941 1900 #: src/components/dialogs/EmailDialog/components/TokenField.tsx:36 1942 - #: src/components/dialogs/VerifyEmailDialog.tsx:252 1943 1901 #: src/screens/Login/LoginForm.tsx:274 1944 1902 #: src/screens/Settings/components/DisableEmail2FADialog.tsx:144 1945 1903 #: src/screens/Settings/components/DisableEmail2FADialog.tsx:150 ··· 1948 1906 msgid "Confirmation code" 1949 1907 msgstr "" 1950 1908 1951 - #: src/components/dialogs/VerifyEmailDialog.tsx:248 1952 - msgid "Confirmation Code" 1953 - msgstr "" 1954 - 1955 1909 #: src/screens/Login/LoginForm.tsx:337 1956 1910 msgid "Connecting..." 1957 1911 msgstr "" ··· 1966 1920 msgstr "" 1967 1921 1968 1922 #: src/screens/Settings/AccessibilitySettings.tsx:109 1969 - #: src/screens/Settings/Settings.tsx:185 1970 - #: src/screens/Settings/Settings.tsx:188 1923 + #: src/screens/Settings/Settings.tsx:194 1924 + #: src/screens/Settings/Settings.tsx:197 1971 1925 msgid "Content and media" 1972 1926 msgstr "" 1973 1927 1974 - #: src/Navigation.tsx:387 1928 + #: src/Navigation.tsx:474 1975 1929 msgid "Content and Media" 1976 1930 msgstr "" 1977 1931 ··· 2162 2116 msgid "Copy TXT record value" 2163 2117 msgstr "" 2164 2118 2165 - #: src/Navigation.tsx:318 2119 + #: src/Navigation.tsx:328 2166 2120 #: src/view/screens/CopyrightPolicy.tsx:31 2167 2121 msgid "Copyright Policy" 2168 2122 msgstr "" ··· 2188 2142 msgid "Could not process your video" 2189 2143 msgstr "" 2190 2144 2145 + #: src/state/queries/notifications/settings.ts:47 2146 + msgid "Could not update notification settings" 2147 + msgstr "" 2148 + 2191 2149 #: src/components/StarterPack/ProfileStarterPacks.tsx:300 2192 2150 msgid "Create" 2193 2151 msgstr "" ··· 2198 2156 2199 2157 #: src/components/StarterPack/ProfileStarterPacks.tsx:178 2200 2158 #: src/components/StarterPack/ProfileStarterPacks.tsx:287 2201 - #: src/Navigation.tsx:463 2159 + #: src/Navigation.tsx:550 2202 2160 msgid "Create a starter pack" 2203 2161 msgstr "" 2204 2162 ··· 2309 2267 msgid "Deactivate account" 2310 2268 msgstr "" 2311 2269 2312 - #: src/screens/Settings/Settings.tsx:397 2270 + #: src/screens/Settings/Settings.tsx:406 2313 2271 msgid "Debug Moderation" 2314 2272 msgstr "" 2315 2273 ··· 2358 2316 msgid "Delete chat" 2359 2317 msgstr "" 2360 2318 2361 - #: src/screens/Settings/Settings.tsx:404 2319 + #: src/screens/Settings/Settings.tsx:413 2362 2320 msgid "Delete chat declaration record" 2363 2321 msgstr "" 2364 2322 ··· 2432 2390 #: src/screens/Profile/Header/EditProfileDialog.tsx:369 2433 2391 #: src/view/com/modals/CreateOrEditList.tsx:278 2434 2392 #: src/view/com/modals/CreateOrEditList.tsx:299 2435 - #: src/view/com/modals/EditProfile.tsx:218 2436 - #: src/view/com/modals/EditProfile.tsx:230 2437 2393 msgid "Description" 2438 2394 msgstr "" 2439 2395 ··· 2469 2425 msgid "Developer mode enabled" 2470 2426 msgstr "" 2471 2427 2472 - #: src/screens/Settings/Settings.tsx:252 2473 - #: src/screens/Settings/Settings.tsx:255 2428 + #: src/screens/Settings/Settings.tsx:261 2429 + #: src/screens/Settings/Settings.tsx:264 2474 2430 msgid "Developer options" 2475 2431 msgstr "" 2476 2432 ··· 2577 2533 #: src/screens/Profile/Header/EditProfileDialog.tsx:320 2578 2534 #: src/screens/Profile/Header/EditProfileDialog.tsx:326 2579 2535 #: src/screens/Profile/Header/EditProfileDialog.tsx:376 2580 - #: src/view/com/modals/EditProfile.tsx:194 2581 2536 msgid "Display name" 2582 - msgstr "" 2583 - 2584 - #: src/view/com/modals/EditProfile.tsx:182 2585 - msgid "Display Name" 2586 2537 msgstr "" 2587 2538 2588 2539 #: src/screens/Profile/Header/EditProfileDialog.tsx:339 ··· 2692 2643 msgid "e.g. Alice Lastname" 2693 2644 msgstr "" 2694 2645 2695 - #: src/view/com/modals/EditProfile.tsx:187 2696 - msgid "e.g. Alice Roberts" 2697 - msgstr "" 2698 - 2699 2646 #: src/screens/Settings/components/ChangeHandleDialog.tsx:376 2700 2647 msgid "e.g. alice.com" 2701 - msgstr "" 2702 - 2703 - #: src/view/com/modals/EditProfile.tsx:223 2704 - msgid "e.g. Artist, dog-lover, and avid reader." 2705 2648 msgstr "" 2706 2649 2707 2650 #: src/lib/moderation/useGlobalLabelStrings.ts:43 ··· 2779 2722 msgid "Edit Moderation List" 2780 2723 msgstr "" 2781 2724 2782 - #: src/Navigation.tsx:328 2725 + #: src/Navigation.tsx:338 2783 2726 #: src/view/screens/Feeds.tsx:518 2784 2727 msgid "Edit My Feeds" 2785 - msgstr "" 2786 - 2787 - #: src/view/com/modals/EditProfile.tsx:154 2788 - msgid "Edit my profile" 2789 2728 msgstr "" 2790 2729 2791 2730 #: src/components/StarterPack/Wizard/WizardEditListDialog.tsx:109 ··· 2821 2760 msgid "Edit who can reply" 2822 2761 msgstr "" 2823 2762 2824 - #: src/view/com/modals/EditProfile.tsx:195 2825 - msgid "Edit your display name" 2826 - msgstr "" 2827 - 2828 - #: src/view/com/modals/EditProfile.tsx:231 2829 - msgid "Edit your profile description" 2830 - msgstr "" 2831 - 2832 - #: src/Navigation.tsx:468 2763 + #: src/Navigation.tsx:555 2833 2764 msgid "Edit your starter pack" 2834 2765 msgstr "" 2835 2766 ··· 2866 2797 2867 2798 #: src/components/dialogs/EmailDialog/screens/Verify.tsx:208 2868 2799 msgid "Email sent!" 2869 - msgstr "" 2870 - 2871 - #: src/components/dialogs/ChangeEmailDialog.tsx:63 2872 - msgid "Email Updated!" 2873 2800 msgstr "" 2874 2801 2875 2802 #: src/components/dialogs/EmailDialog/screens/Verify.tsx:182 ··· 2926 2853 msgid "Enable media players for" 2927 2854 msgstr "" 2928 2855 2929 - #: src/screens/Settings/NotificationSettings.tsx:74 2930 - #: src/screens/Settings/NotificationSettings.tsx:77 2931 - msgid "Enable priority notifications" 2856 + #: src/screens/Settings/NotificationSettings/index.tsx:102 2857 + #: src/screens/Settings/NotificationSettings/index.tsx:106 2858 + msgid "Enable push notifications" 2932 2859 msgstr "" 2933 2860 2934 2861 #: src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.tsx:387 ··· 2980 2907 msgid "Enter code" 2981 2908 msgstr "" 2982 2909 2983 - #: src/components/dialogs/VerifyEmailDialog.tsx:118 2984 - msgid "Enter Code" 2985 - msgstr "" 2986 - 2987 2910 #: src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.tsx:405 2988 2911 msgid "Enter fullscreen" 2989 2912 msgstr "" ··· 3011 2934 #: src/screens/Login/ForgotPasswordForm.tsx:99 3012 2935 #: src/screens/Signup/StepInfo/index.tsx:213 3013 2936 msgid "Enter your email address" 3014 - msgstr "" 3015 - 3016 - #: src/components/dialogs/ChangeEmailDialog.tsx:138 3017 - msgid "Enter your new email address below." 3018 2937 msgstr "" 3019 2938 3020 2939 #: src/screens/Login/LoginForm.tsx:243 ··· 3072 2991 3073 2992 #: src/screens/Messages/Settings.tsx:83 3074 2993 #: src/screens/Messages/Settings.tsx:86 2994 + #: src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx:153 2995 + #: src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx:167 3075 2996 msgid "Everyone" 2997 + msgstr "" 2998 + 2999 + #: src/screens/Settings/NotificationSettings/index.tsx:236 3000 + #: src/screens/Settings/NotificationSettings/MiscellaneousNotificationSettings.tsx:41 3001 + msgid "Everything else" 3076 3002 msgstr "" 3077 3003 3078 3004 #: src/components/moderation/ReportDialog/utils/useReportOptions.ts:73 ··· 3164 3090 msgid "Explicit sexual images." 3165 3091 msgstr "" 3166 3092 3167 - #: src/Navigation.tsx:625 3093 + #: src/Navigation.tsx:712 3168 3094 #: src/screens/Search/Shell.tsx:307 3169 3095 #: src/view/shell/desktop/LeftNav.tsx:635 3170 3096 #: src/view/shell/Drawer.tsx:403 ··· 3195 3121 msgid "External media may allow websites to collect information about you and your device. No information is sent or requested until you press the \"play\" button." 3196 3122 msgstr "" 3197 3123 3198 - #: src/Navigation.tsx:347 3124 + #: src/Navigation.tsx:357 3199 3125 #: src/screens/Settings/ExternalMediaPreferences.tsx:31 3200 3126 msgid "External Media Preferences" 3201 3127 msgstr "" ··· 3265 3191 msgid "Failed to load GIFs" 3266 3192 msgstr "" 3267 3193 3194 + #: src/screens/Settings/NotificationSettings/index.tsx:115 3195 + #: src/screens/Settings/NotificationSettings/LikeNotificationSettings.tsx:50 3196 + #: src/screens/Settings/NotificationSettings/LikesOnRepostsNotificationSettings.tsx:52 3197 + #: src/screens/Settings/NotificationSettings/MentionNotificationSettings.tsx:50 3198 + #: src/screens/Settings/NotificationSettings/MiscellaneousNotificationSettings.tsx:53 3199 + #: src/screens/Settings/NotificationSettings/NewFollowerNotificationSettings.tsx:50 3200 + #: src/screens/Settings/NotificationSettings/QuoteNotificationSettings.tsx:50 3201 + #: src/screens/Settings/NotificationSettings/ReplyNotificationSettings.tsx:52 3202 + #: src/screens/Settings/NotificationSettings/RepostNotificationSettings.tsx:50 3203 + #: src/screens/Settings/NotificationSettings/RepostsOnRepostsNotificationSettings.tsx:53 3204 + msgid "Failed to load notification settings." 3205 + msgstr "" 3206 + 3268 3207 #: src/screens/Messages/components/MessageListError.tsx:23 3269 3208 msgid "Failed to load past messages" 3270 3209 msgstr "" ··· 3302 3241 msgid "Failed to save image: {0}" 3303 3242 msgstr "" 3304 3243 3305 - #: src/state/queries/notifications/settings.ts:39 3306 - msgid "Failed to save notification preferences, please try again" 3307 - msgstr "" 3308 - 3309 3244 #: src/screens/ModerationInteractionSettings/index.tsx:108 3310 3245 msgid "Failed to save settings. Please try again." 3311 3246 msgstr "" 3312 3247 3313 - #: src/screens/Settings/SettingsInterests.tsx:133 3248 + #: src/screens/Settings/InterestsSettings.tsx:136 3314 3249 msgctxt "toast" 3315 3250 msgid "Failed to save your interests." 3316 3251 msgstr "" ··· 3365 3300 msgid "Failed to verify handle. Please try again." 3366 3301 msgstr "" 3367 3302 3368 - #: src/Navigation.tsx:263 3303 + #: src/Navigation.tsx:273 3369 3304 msgid "Feed" 3370 3305 msgstr "" 3371 3306 ··· 3394 3329 msgid "Feedback sent!" 3395 3330 msgstr "" 3396 3331 3397 - #: src/Navigation.tsx:448 3332 + #: src/Navigation.tsx:535 3398 3333 #: src/screens/Search/SearchResults.tsx:68 3399 3334 #: src/screens/StarterPack/StarterPackScreen.tsx:190 3400 3335 #: src/view/screens/Feeds.tsx:511 ··· 3555 3490 msgid "Followed by <0>{0}</0>, <1>{1}</1>, and {2, plural, one {# other} other {# others}}" 3556 3491 msgstr "" 3557 3492 3558 - #: src/Navigation.tsx:217 3493 + #: src/Navigation.tsx:227 3559 3494 msgid "Followers of @{0} that you know" 3560 3495 msgstr "" 3561 3496 ··· 3590 3525 msgid "Following feed preferences" 3591 3526 msgstr "" 3592 3527 3593 - #: src/Navigation.tsx:334 3528 + #: src/Navigation.tsx:344 3594 3529 #: src/screens/Settings/FollowingFeedPreferences.tsx:53 3595 3530 msgid "Following Feed Preferences" 3596 3531 msgstr "" ··· 3675 3610 msgid "Get help" 3676 3611 msgstr "" 3677 3612 3613 + #: src/screens/Settings/NotificationSettings/NewFollowerNotificationSettings.tsx:43 3614 + msgid "Get notifications when people follow you." 3615 + msgstr "" 3616 + 3617 + #: src/screens/Settings/NotificationSettings/LikesOnRepostsNotificationSettings.tsx:43 3618 + msgid "Get notifications when people like posts that you've reposted." 3619 + msgstr "" 3620 + 3621 + #: src/screens/Settings/NotificationSettings/LikeNotificationSettings.tsx:43 3622 + msgid "Get notifications when people like your posts." 3623 + msgstr "" 3624 + 3625 + #: src/screens/Settings/NotificationSettings/MentionNotificationSettings.tsx:43 3626 + msgid "Get notifications when people mention you." 3627 + msgstr "" 3628 + 3629 + #: src/screens/Settings/NotificationSettings/QuoteNotificationSettings.tsx:43 3630 + msgid "Get notifications when people quote your posts." 3631 + msgstr "" 3632 + 3633 + #: src/screens/Settings/NotificationSettings/ReplyNotificationSettings.tsx:43 3634 + msgid "Get notifications when people reply to your posts." 3635 + msgstr "" 3636 + 3637 + #: src/screens/Settings/NotificationSettings/RepostsOnRepostsNotificationSettings.tsx:43 3638 + msgid "Get notifications when people repost posts that you've reposted." 3639 + msgstr "" 3640 + 3641 + #: src/screens/Settings/NotificationSettings/RepostNotificationSettings.tsx:43 3642 + msgid "Get notifications when people repost your posts." 3643 + msgstr "" 3644 + 3678 3645 #: src/components/dialogs/EmailDialog/screens/VerificationReminder.tsx:76 3679 3646 #: src/components/dialogs/EmailDialog/screens/VerificationReminder.tsx:86 3680 - #: src/components/dialogs/VerifyEmailDialog.tsx:263 3681 - #: src/components/dialogs/VerifyEmailDialog.tsx:269 3682 3647 msgid "Get started" 3683 3648 msgstr "" 3684 3649 ··· 3817 3782 msgid "Harassment, trolling, or intolerance" 3818 3783 msgstr "" 3819 3784 3820 - #: src/Navigation.tsx:418 3785 + #: src/Navigation.tsx:505 3821 3786 msgid "Hashtag" 3822 3787 msgstr "" 3823 3788 ··· 3834 3799 msgid "Having trouble?" 3835 3800 msgstr "" 3836 3801 3837 - #: src/screens/Settings/Settings.tsx:217 3838 - #: src/screens/Settings/Settings.tsx:221 3802 + #: src/screens/Settings/Settings.tsx:226 3803 + #: src/screens/Settings/Settings.tsx:230 3839 3804 #: src/view/shell/desktop/RightNav.tsx:120 3840 3805 #: src/view/shell/desktop/RightNav.tsx:121 3841 3806 #: src/view/shell/Drawer.tsx:370 ··· 3974 3939 msgid "Hold up! We’re gradually giving access to video, and you’re still waiting in line. Check back soon!" 3975 3940 msgstr "" 3976 3941 3977 - #: src/Navigation.tsx:620 3978 - #: src/Navigation.tsx:640 3942 + #: src/Navigation.tsx:707 3943 + #: src/Navigation.tsx:727 3979 3944 #: src/view/shell/bottom-bar/BottomBar.tsx:178 3980 3945 #: src/view/shell/desktop/LeftNav.tsx:617 3981 3946 #: src/view/shell/Drawer.tsx:429 ··· 4007 3972 msgid "How should we open this link?" 4008 3973 msgstr "" 4009 3974 4010 - #: src/components/dialogs/ChangeEmailDialog.tsx:189 4011 - #: src/components/dialogs/ChangeEmailDialog.tsx:196 4012 - #: src/components/dialogs/VerifyEmailDialog.tsx:302 4013 - #: src/components/dialogs/VerifyEmailDialog.tsx:309 4014 3975 #: src/screens/Settings/components/DisableEmail2FADialog.tsx:133 4015 3976 #: src/screens/Settings/components/DisableEmail2FADialog.tsx:136 4016 3977 msgid "I have a code" ··· 4102 4063 msgid "Impersonation, misinformation, or false claims" 4103 4064 msgstr "" 4104 4065 4066 + #: src/screens/Settings/NotificationSettings/index.tsx:285 4067 + msgid "In-app" 4068 + msgstr "" 4069 + 4070 + #: src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx:134 4071 + msgid "In-app notifications" 4072 + msgstr "" 4073 + 4074 + #: src/screens/Settings/NotificationSettings/index.tsx:268 4075 + msgid "In-app, Everyone" 4076 + msgstr "" 4077 + 4078 + #: src/screens/Settings/NotificationSettings/index.tsx:276 4079 + msgid "In-app, People you follow" 4080 + msgstr "" 4081 + 4082 + #: src/screens/Settings/NotificationSettings/index.tsx:283 4083 + msgid "In-app, Push" 4084 + msgstr "" 4085 + 4086 + #: src/screens/Settings/NotificationSettings/index.tsx:266 4087 + msgid "In-app, Push, Everyone" 4088 + msgstr "" 4089 + 4090 + #: src/screens/Settings/NotificationSettings/index.tsx:274 4091 + msgid "In-app, Push, People you follow" 4092 + msgstr "" 4093 + 4105 4094 #: src/components/moderation/ReportDialog/utils/useReportOptions.ts:91 4106 4095 #: src/lib/moderation/useReportOptions.ts:91 4107 4096 msgid "Inappropriate messages or explicit links" ··· 4264 4253 msgid "Language selection" 4265 4254 msgstr "" 4266 4255 4267 - #: src/Navigation.tsx:190 4256 + #: src/Navigation.tsx:200 4268 4257 msgid "Language Settings" 4269 4258 msgstr "" 4270 4259 4271 4260 #: src/screens/Settings/LanguageSettings.tsx:78 4272 - #: src/screens/Settings/Settings.tsx:209 4273 - #: src/screens/Settings/Settings.tsx:212 4261 + #: src/screens/Settings/Settings.tsx:218 4262 + #: src/screens/Settings/Settings.tsx:221 4274 4263 msgid "Languages" 4275 4264 msgstr "" 4276 4265 ··· 4293 4282 #: src/screens/Moderation/VerificationSettings.tsx:47 4294 4283 #: src/screens/Profile/Header/EditProfileDialog.tsx:359 4295 4284 #: src/screens/Settings/components/ChangeHandleDialog.tsx:212 4296 - #: src/view/com/modals/EditProfile.tsx:207 4297 4285 msgid "Learn more" 4298 4286 msgstr "" 4299 4287 ··· 4408 4396 msgid "Like 10 posts to train the Discover feed" 4409 4397 msgstr "" 4410 4398 4399 + #: src/Navigation.tsx:426 4400 + msgid "Like notifications" 4401 + msgstr "" 4402 + 4411 4403 #: src/screens/Profile/components/ProfileFeedHeader.tsx:505 4412 4404 msgid "Like this feed" 4413 4405 msgstr "" ··· 4416 4408 msgid "Like this labeler" 4417 4409 msgstr "" 4418 4410 4419 - #: src/Navigation.tsx:268 4420 - #: src/Navigation.tsx:273 4411 + #: src/Navigation.tsx:278 4412 + #: src/Navigation.tsx:283 4421 4413 msgid "Liked by" 4422 4414 msgstr "" 4423 4415 ··· 4439 4431 msgid "Liked by {likeCount, plural, one {# user} other {# users}}" 4440 4432 msgstr "" 4441 4433 4434 + #: src/screens/Settings/NotificationSettings/index.tsx:159 4435 + #: src/screens/Settings/NotificationSettings/LikeNotificationSettings.tsx:41 4442 4436 #: src/view/screens/Profile.tsx:229 4443 4437 msgid "Likes" 4444 4438 msgstr "" 4445 4439 4440 + #: src/screens/Settings/NotificationSettings/index.tsx:208 4441 + #: src/screens/Settings/NotificationSettings/LikesOnRepostsNotificationSettings.tsx:41 4442 + msgid "Likes of your reposts" 4443 + msgstr "" 4444 + 4445 + #: src/Navigation.tsx:450 4446 + msgid "Likes of your reposts notifications" 4447 + msgstr "" 4448 + 4446 4449 #: src/screens/PostThread/components/ThreadItemAnchor.tsx:467 4447 4450 #: src/view/com/post-thread/PostThreadItem.tsx:243 4448 4451 msgid "Likes on this post" ··· 4455 4458 msgid "Linear" 4456 4459 msgstr "" 4457 4460 4458 - #: src/Navigation.tsx:223 4461 + #: src/Navigation.tsx:233 4459 4462 msgid "List" 4460 4463 msgstr "" 4461 4464 ··· 4513 4516 msgid "List unmuted" 4514 4517 msgstr "" 4515 4518 4516 - #: src/Navigation.tsx:144 4519 + #: src/Navigation.tsx:154 4517 4520 #: src/view/screens/Lists.tsx:65 4518 4521 #: src/view/screens/Profile.tsx:224 4519 4522 #: src/view/screens/Profile.tsx:232 ··· 4566 4569 msgid "Loading..." 4567 4570 msgstr "" 4568 4571 4569 - #: src/Navigation.tsx:293 4572 + #: src/Navigation.tsx:303 4570 4573 msgid "Log" 4571 4574 msgstr "" 4572 4575 ··· 4646 4649 4647 4650 #: src/components/dialogs/EmailDialog/screens/VerificationReminder.tsx:90 4648 4651 #: src/components/dialogs/EmailDialog/screens/VerificationReminder.tsx:97 4649 - #: src/components/dialogs/VerifyEmailDialog.tsx:273 4650 - #: src/components/dialogs/VerifyEmailDialog.tsx:281 4651 4652 msgid "Maybe later" 4652 4653 msgstr "" 4653 4654 ··· 4659 4660 msgid "Media that may be disturbing or inappropriate for some audiences." 4660 4661 msgstr "" 4661 4662 4663 + #: src/Navigation.tsx:410 4664 + msgid "Mention notifications" 4665 + msgstr "" 4666 + 4662 4667 #: src/components/WhoCanReply.tsx:263 4663 4668 msgid "mentioned users" 4664 4669 msgstr "" ··· 4667 4672 msgid "Mentioned users" 4668 4673 msgstr "" 4669 4674 4675 + #: src/screens/Settings/NotificationSettings/index.tsx:137 4676 + #: src/screens/Settings/NotificationSettings/MentionNotificationSettings.tsx:41 4670 4677 #: src/view/screens/Notifications.tsx:99 4671 4678 msgid "Mentions" 4672 4679 msgstr "" ··· 4709 4716 msgid "Message options" 4710 4717 msgstr "" 4711 4718 4712 - #: src/Navigation.tsx:635 4719 + #: src/Navigation.tsx:722 4713 4720 msgid "Messages" 4714 4721 msgstr "" 4715 4722 ··· 4718 4725 msgid "Midnight" 4719 4726 msgstr "" 4720 4727 4728 + #: src/Navigation.tsx:466 4729 + msgid "Miscellaneous notifications" 4730 + msgstr "" 4731 + 4721 4732 #: src/components/moderation/ReportDialog/utils/useReportOptions.ts:47 4722 4733 #: src/lib/moderation/useReportOptions.ts:47 4723 4734 msgid "Misleading Account" ··· 4728 4739 msgid "Misleading Post" 4729 4740 msgstr "" 4730 4741 4731 - #: src/Navigation.tsx:149 4742 + #: src/Navigation.tsx:159 4732 4743 #: src/screens/Moderation/index.tsx:93 4733 - #: src/screens/Settings/Settings.tsx:177 4734 - #: src/screens/Settings/Settings.tsx:180 4744 + #: src/screens/Settings/Settings.tsx:178 4745 + #: src/screens/Settings/Settings.tsx:181 4735 4746 msgid "Moderation" 4736 4747 msgstr "" 4737 4748 ··· 4767 4778 msgid "Moderation lists" 4768 4779 msgstr "" 4769 4780 4770 - #: src/Navigation.tsx:154 4781 + #: src/Navigation.tsx:164 4771 4782 #: src/view/screens/ModerationModlists.tsx:65 4772 4783 msgid "Moderation Lists" 4773 4784 msgstr "" ··· 4776 4787 msgid "moderation settings" 4777 4788 msgstr "" 4778 4789 4779 - #: src/Navigation.tsx:283 4790 + #: src/Navigation.tsx:293 4780 4791 msgid "Moderation states" 4781 4792 msgstr "" 4782 4793 ··· 4899 4910 msgid "Muted accounts" 4900 4911 msgstr "" 4901 4912 4902 - #: src/Navigation.tsx:159 4913 + #: src/Navigation.tsx:169 4903 4914 #: src/view/screens/ModerationMutedAccounts.tsx:118 4904 4915 msgid "Muted Accounts" 4905 4916 msgstr "" ··· 4972 4983 msgid "Navigates to your profile" 4973 4984 msgstr "" 4974 4985 4975 - #: src/components/dialogs/VerifyEmailDialog.tsx:234 4976 - msgid "Need to change it?" 4977 - msgstr "" 4978 - 4979 4986 #: src/components/moderation/ReportDialog/index.tsx:288 4980 4987 #: src/components/ReportDialog/SelectReportOptionView.tsx:128 4981 4988 msgid "Need to report a copyright violation?" ··· 5005 5012 msgid "New chat" 5006 5013 msgstr "" 5007 5014 5008 - #: src/components/dialogs/ChangeEmailDialog.tsx:142 5009 5015 #: src/components/dialogs/EmailDialog/screens/Update.tsx:222 5010 5016 msgid "New email address" 5011 5017 msgstr "" ··· 5014 5020 msgid "New Feature" 5015 5021 msgstr "" 5016 5022 5023 + #: src/Navigation.tsx:442 5024 + msgid "New follower notifications" 5025 + msgstr "" 5026 + 5027 + #: src/screens/Settings/NotificationSettings/index.tsx:181 5028 + #: src/screens/Settings/NotificationSettings/NewFollowerNotificationSettings.tsx:41 5029 + msgid "New followers" 5030 + msgstr "" 5031 + 5017 5032 #: src/screens/Settings/components/ChangeHandleDialog.tsx:221 5018 5033 #: src/screens/Settings/components/ChangeHandleDialog.tsx:229 5019 5034 #: src/screens/Settings/components/ChangeHandleDialog.tsx:375 ··· 5246 5261 msgid "Not followed by anyone you're following" 5247 5262 msgstr "" 5248 5263 5249 - #: src/Navigation.tsx:139 5264 + #: src/Navigation.tsx:149 5250 5265 #: src/view/screens/Profile.tsx:125 5251 5266 msgid "Not Found" 5252 5267 msgstr "" ··· 5267 5282 msgid "Nothing here" 5268 5283 msgstr "" 5269 5284 5270 - #: src/screens/Settings/NotificationSettings.tsx:64 5271 - msgid "Notification filters" 5272 - msgstr "" 5273 - 5274 - #: src/Navigation.tsx:443 5285 + #: src/Navigation.tsx:396 5286 + #: src/Navigation.tsx:530 5275 5287 #: src/view/screens/Notifications.tsx:134 5276 5288 msgid "Notification settings" 5277 5289 msgstr "" 5278 5290 5279 - #: src/screens/Settings/NotificationSettings.tsx:46 5280 - msgid "Notification Settings" 5281 - msgstr "" 5282 - 5283 5291 #: src/screens/Messages/Settings.tsx:123 5284 5292 msgid "Notification sounds" 5285 5293 msgstr "" ··· 5288 5296 msgid "Notification Sounds" 5289 5297 msgstr "" 5290 5298 5291 - #: src/Navigation.tsx:630 5299 + #: src/Navigation.tsx:717 5300 + #: src/screens/Settings/NotificationSettings/index.tsx:92 5301 + #: src/screens/Settings/NotificationSettings/LikeNotificationSettings.tsx:30 5302 + #: src/screens/Settings/NotificationSettings/LikesOnRepostsNotificationSettings.tsx:30 5303 + #: src/screens/Settings/NotificationSettings/MentionNotificationSettings.tsx:30 5304 + #: src/screens/Settings/NotificationSettings/MiscellaneousNotificationSettings.tsx:30 5305 + #: src/screens/Settings/NotificationSettings/NewFollowerNotificationSettings.tsx:30 5306 + #: src/screens/Settings/NotificationSettings/QuoteNotificationSettings.tsx:30 5307 + #: src/screens/Settings/NotificationSettings/ReplyNotificationSettings.tsx:30 5308 + #: src/screens/Settings/NotificationSettings/RepostNotificationSettings.tsx:30 5309 + #: src/screens/Settings/NotificationSettings/RepostsOnRepostsNotificationSettings.tsx:30 5310 + #: src/screens/Settings/Settings.tsx:186 5311 + #: src/screens/Settings/Settings.tsx:189 5292 5312 #: src/view/screens/Notifications.tsx:128 5293 5313 #: src/view/shell/bottom-bar/BottomBar.tsx:252 5294 5314 #: src/view/shell/desktop/LeftNav.tsx:654 5295 5315 #: src/view/shell/Drawer.tsx:482 5296 5316 msgid "Notifications" 5317 + msgstr "" 5318 + 5319 + #: src/screens/Settings/NotificationSettings/MiscellaneousNotificationSettings.tsx:43 5320 + msgid "Notifications for everything else, such as when someone joins via one of your starter packs." 5297 5321 msgstr "" 5298 5322 5299 5323 #: src/lib/hooks/useTimeAgo.ts:135 ··· 5315 5339 msgstr "" 5316 5340 5317 5341 #: src/lib/moderation/useLabelBehaviorDescription.ts:11 5342 + #: src/screens/Settings/NotificationSettings/index.tsx:292 5318 5343 msgid "Off" 5319 5344 msgstr "" 5320 5345 ··· 5356 5381 msgid "on<0><1/><2><3/></2></0>" 5357 5382 msgstr "" 5358 5383 5359 - #: src/screens/Settings/Settings.tsx:358 5384 + #: src/screens/Settings/Settings.tsx:367 5360 5385 msgid "Onboarding reset" 5361 5386 msgstr "" 5362 5387 ··· 5401 5426 #: src/components/StarterPack/ProfileStarterPacks.tsx:341 5402 5427 #: src/screens/Settings/AppPasswords.tsx:59 5403 5428 #: src/screens/Settings/components/ChangeHandleDialog.tsx:106 5404 - #: src/screens/Settings/NotificationSettings.tsx:54 5405 5429 #: src/view/screens/Profile.tsx:125 5406 5430 msgid "Oops!" 5407 5431 msgstr "" ··· 5449 5473 msgid "Open message options" 5450 5474 msgstr "" 5451 5475 5452 - #: src/screens/Settings/Settings.tsx:395 5476 + #: src/screens/Settings/Settings.tsx:404 5453 5477 msgid "Open moderation debug page" 5454 5478 msgstr "" 5455 5479 ··· 5478 5502 msgid "Open starter pack menu" 5479 5503 msgstr "" 5480 5504 5481 - #: src/screens/Settings/Settings.tsx:388 5482 - #: src/screens/Settings/Settings.tsx:402 5505 + #: src/screens/Settings/Settings.tsx:397 5506 + #: src/screens/Settings/Settings.tsx:411 5483 5507 msgid "Open storybook page" 5484 5508 msgstr "" 5485 5509 5486 - #: src/screens/Settings/Settings.tsx:381 5510 + #: src/screens/Settings/Settings.tsx:390 5487 5511 msgid "Open system log" 5488 5512 msgstr "" 5489 5513 ··· 5545 5569 msgid "Opens GIF select dialog" 5546 5570 msgstr "" 5547 5571 5548 - #: src/screens/Settings/Settings.tsx:218 5572 + #: src/screens/Settings/Settings.tsx:227 5549 5573 msgid "Opens helpdesk in browser" 5550 5574 msgstr "" 5551 5575 ··· 5683 5707 msgid "People" 5684 5708 msgstr "" 5685 5709 5686 - #: src/Navigation.tsx:210 5710 + #: src/Navigation.tsx:220 5687 5711 msgid "People followed by @{0}" 5688 5712 msgstr "" 5689 5713 5690 - #: src/Navigation.tsx:203 5714 + #: src/Navigation.tsx:213 5691 5715 msgid "People following @{0}" 5716 + msgstr "" 5717 + 5718 + #: src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx:171 5719 + #: src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx:185 5720 + msgid "People I follow" 5692 5721 msgstr "" 5693 5722 5694 5723 #: src/lib/media/save-image.ts:51 ··· 5895 5924 msgid "Please verify your email" 5896 5925 msgstr "" 5897 5926 5898 - #: src/components/dialogs/VerifyEmailDialog.tsx:108 5899 - msgid "Please Verify Your Email" 5900 - msgstr "" 5901 - 5902 5927 #: src/screens/Onboarding/index.tsx:34 5903 5928 #: src/screens/Onboarding/state.ts:111 5904 5929 #: src/screens/Search/modules/ExploreTrendingTopics.tsx:235 ··· 5933 5958 msgid "Post by {0}" 5934 5959 msgstr "" 5935 5960 5936 - #: src/Navigation.tsx:236 5937 - #: src/Navigation.tsx:243 5938 - #: src/Navigation.tsx:250 5939 - #: src/Navigation.tsx:257 5961 + #: src/Navigation.tsx:246 5962 + #: src/Navigation.tsx:253 5963 + #: src/Navigation.tsx:260 5964 + #: src/Navigation.tsx:267 5940 5965 msgid "Post by @{0}" 5941 5966 msgstr "" 5942 5967 ··· 5974 5999 msgid "Post interaction settings" 5975 6000 msgstr "" 5976 6001 5977 - #: src/Navigation.tsx:170 6002 + #: src/Navigation.tsx:180 5978 6003 #: src/screens/ModerationInteractionSettings/index.tsx:34 5979 6004 msgid "Post Interaction Settings" 5980 6005 msgstr "" ··· 6022 6047 msgid "Potentially Misleading Link" 6023 6048 msgstr "" 6024 6049 6025 - #: src/state/queries/notifications/settings.ts:44 6026 - msgctxt "toast" 6027 - msgid "Preference saved" 6028 - msgstr "" 6029 - 6030 6050 #: src/screens/Messages/components/MessageListError.tsx:19 6031 6051 msgid "Press to attempt reconnection" 6032 6052 msgstr "" ··· 6057 6077 msgid "Prioritize your Follows" 6058 6078 msgstr "" 6059 6079 6060 - #: src/screens/Settings/NotificationSettings.tsx:67 6061 - msgid "Priority notifications" 6062 - msgstr "" 6063 - 6064 6080 #: src/view/shell/desktop/RightNav.tsx:110 6065 6081 #: src/view/shell/desktop/RightNav.tsx:111 6066 6082 msgid "Privacy" 6067 6083 msgstr "" 6068 6084 6069 - #: src/screens/Settings/Settings.tsx:171 6070 - #: src/screens/Settings/Settings.tsx:174 6085 + #: src/screens/Settings/Settings.tsx:172 6086 + #: src/screens/Settings/Settings.tsx:175 6071 6087 msgid "Privacy and security" 6072 6088 msgstr "" 6073 6089 6074 - #: src/Navigation.tsx:379 6090 + #: src/Navigation.tsx:389 6075 6091 #: src/screens/Settings/PrivacyAndSecuritySettings.tsx:36 6076 6092 msgid "Privacy and Security" 6077 6093 msgstr "" 6078 6094 6079 - #: src/Navigation.tsx:303 6095 + #: src/Navigation.tsx:313 6080 6096 #: src/screens/Settings/AboutSettings.tsx:92 6081 6097 #: src/screens/Settings/AboutSettings.tsx:95 6082 6098 #: src/view/screens/PrivacyPolicy.tsx:31 ··· 6107 6123 msgstr "" 6108 6124 6109 6125 #: src/screens/Profile/Header/EditProfileDialog.tsx:196 6110 - #: src/view/com/modals/EditProfile.tsx:128 6111 6126 msgctxt "toast" 6112 6127 msgid "Profile updated" 6113 6128 msgstr "" ··· 6144 6159 msgid "Publish reply" 6145 6160 msgstr "" 6146 6161 6162 + #: src/screens/Settings/NotificationSettings/index.tsx:287 6163 + msgid "Push" 6164 + msgstr "" 6165 + 6166 + #: src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx:117 6167 + msgid "Push notifications" 6168 + msgstr "" 6169 + 6170 + #: src/screens/Settings/NotificationSettings/index.tsx:270 6171 + msgid "Push, Everyone" 6172 + msgstr "" 6173 + 6174 + #: src/screens/Settings/NotificationSettings/index.tsx:278 6175 + msgid "Push, People you follow" 6176 + msgstr "" 6177 + 6147 6178 #: src/components/StarterPack/QrCodeDialog.tsx:134 6148 6179 msgid "QR code copied to your clipboard!" 6149 6180 msgstr "" ··· 6154 6185 6155 6186 #: src/components/StarterPack/QrCodeDialog.tsx:113 6156 6187 msgid "QR code saved to your camera roll!" 6188 + msgstr "" 6189 + 6190 + #: src/Navigation.tsx:418 6191 + msgid "Quote notifications" 6157 6192 msgstr "" 6158 6193 6159 6194 #: src/components/PostControls/RepostButton.tsx:174 ··· 6183 6218 msgstr "" 6184 6219 6185 6220 #: src/screens/Post/PostQuotes.tsx:38 6221 + #: src/screens/Settings/NotificationSettings/index.tsx:148 6222 + #: src/screens/Settings/NotificationSettings/QuoteNotificationSettings.tsx:41 6186 6223 msgid "Quotes" 6187 6224 msgstr "" 6188 6225 ··· 6259 6296 msgid "Reason:" 6260 6297 msgstr "" 6261 6298 6299 + #: src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx:123 6300 + msgid "Receive in-app notifications" 6301 + msgstr "" 6302 + 6303 + #: src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx:106 6304 + msgid "Receive push notifications" 6305 + msgstr "" 6306 + 6262 6307 #: src/screens/Search/components/SearchHistory.tsx:49 6263 6308 msgid "Recent Searches" 6264 6309 msgstr "" ··· 6290 6335 #: src/components/FeedCard.tsx:343 6291 6336 #: src/components/StarterPack/Wizard/WizardListCard.tsx:102 6292 6337 #: src/components/StarterPack/Wizard/WizardListCard.tsx:109 6293 - #: src/screens/Settings/Settings.tsx:543 6338 + #: src/screens/Settings/Settings.tsx:552 6294 6339 #: src/view/com/feeds/FeedSourceCard.tsx:322 6295 6340 #: src/view/com/modals/UserAddRemoveLists.tsx:235 6296 6341 #: src/view/com/posts/PostFeedErrorMessage.tsx:213 ··· 6305 6350 msgid "Remove {historyItem}" 6306 6351 msgstr "" 6307 6352 6308 - #: src/screens/Settings/Settings.tsx:522 6309 - #: src/screens/Settings/Settings.tsx:525 6353 + #: src/screens/Settings/Settings.tsx:531 6354 + #: src/screens/Settings/Settings.tsx:534 6310 6355 msgid "Remove account" 6311 6356 msgstr "" 6312 6357 ··· 6347 6392 msgid "Remove from my feeds" 6348 6393 msgstr "" 6349 6394 6350 - #: src/screens/Settings/Settings.tsx:535 6395 + #: src/screens/Settings/Settings.tsx:544 6351 6396 msgid "Remove from quick access?" 6352 6397 msgstr "" 6353 6398 ··· 6442 6487 msgid "Replace with Discover" 6443 6488 msgstr "" 6444 6489 6490 + #: src/screens/Settings/NotificationSettings/index.tsx:126 6491 + #: src/screens/Settings/NotificationSettings/ReplyNotificationSettings.tsx:41 6445 6492 #: src/view/screens/Profile.tsx:226 6446 6493 msgid "Replies" 6447 6494 msgstr "" ··· 6472 6519 #: src/components/moderation/ModerationDetailsDialog.tsx:115 6473 6520 #: src/lib/moderation/useModerationCauseDescription.ts:124 6474 6521 msgid "Reply Hidden by You" 6522 + msgstr "" 6523 + 6524 + #: src/Navigation.tsx:402 6525 + msgid "Reply notifications" 6475 6526 msgstr "" 6476 6527 6477 6528 #: src/components/dialogs/PostInteractionSettingsDialog.tsx:385 ··· 6622 6673 msgid "Repost ({0, plural, one {# repost} other {# reposts}})" 6623 6674 msgstr "" 6624 6675 6676 + #: src/Navigation.tsx:434 6677 + msgid "Repost notifications" 6678 + msgstr "" 6679 + 6625 6680 #: src/components/PostControls/RepostButton.tsx:144 6626 6681 #: src/components/PostControls/RepostButton.web.tsx:43 6627 6682 #: src/components/PostControls/RepostButton.web.tsx:97 ··· 6646 6701 msgid "Reposted by you" 6647 6702 msgstr "" 6648 6703 6704 + #: src/screens/Settings/NotificationSettings/index.tsx:170 6705 + #: src/screens/Settings/NotificationSettings/RepostNotificationSettings.tsx:41 6706 + msgid "Reposts" 6707 + msgstr "" 6708 + 6649 6709 #: src/screens/PostThread/components/ThreadItemAnchor.tsx:433 6650 6710 #: src/view/com/post-thread/PostThreadItem.tsx:248 6651 6711 msgid "Reposts of this post" 6652 6712 msgstr "" 6653 6713 6654 - #: src/components/dialogs/ChangeEmailDialog.tsx:175 6655 - #: src/components/dialogs/ChangeEmailDialog.tsx:182 6656 - msgid "Request change" 6714 + #: src/screens/Settings/NotificationSettings/index.tsx:223 6715 + #: src/screens/Settings/NotificationSettings/RepostsOnRepostsNotificationSettings.tsx:41 6716 + msgid "Reposts of your reposts" 6717 + msgstr "" 6718 + 6719 + #: src/Navigation.tsx:458 6720 + msgid "Reposts of your reposts notifications" 6657 6721 msgstr "" 6658 6722 6659 6723 #: src/view/com/modals/ChangePassword.tsx:253 ··· 6682 6746 msgid "Resend" 6683 6747 msgstr "" 6684 6748 6685 - #: src/components/dialogs/ChangeEmailDialog.tsx:217 6686 - #: src/components/dialogs/ChangeEmailDialog.tsx:227 6687 - #: src/components/dialogs/VerifyEmailDialog.tsx:330 6688 - #: src/components/dialogs/VerifyEmailDialog.tsx:340 6689 6749 #: src/screens/Settings/components/DisableEmail2FADialog.tsx:173 6690 6750 #: src/screens/Settings/components/DisableEmail2FADialog.tsx:176 6691 6751 msgid "Resend email" ··· 6708 6768 msgid "Reset Code" 6709 6769 msgstr "" 6710 6770 6711 - #: src/screens/Settings/Settings.tsx:409 6712 - #: src/screens/Settings/Settings.tsx:411 6771 + #: src/screens/Settings/Settings.tsx:418 6772 + #: src/screens/Settings/Settings.tsx:420 6713 6773 msgid "Reset onboarding state" 6714 6774 msgstr "" 6715 6775 ··· 6790 6850 #: src/view/com/composer/photos/ImageAltTextDialog.tsx:153 6791 6851 #: src/view/com/composer/photos/ImageAltTextDialog.tsx:163 6792 6852 #: src/view/com/modals/CreateOrEditList.tsx:315 6793 - #: src/view/com/modals/EditProfile.tsx:244 6794 6853 #: src/view/screens/SavedFeeds.tsx:109 6795 6854 msgid "Save" 6796 6855 msgstr "" ··· 6808 6867 #: src/view/screens/SavedFeeds.tsx:105 6809 6868 #: src/view/screens/SavedFeeds.tsx:109 6810 6869 msgid "Save changes" 6811 - msgstr "" 6812 - 6813 - #: src/view/com/modals/EditProfile.tsx:252 6814 - msgid "Save Changes" 6815 6870 msgstr "" 6816 6871 6817 6872 #: src/components/StarterPack/ShareDialog.tsx:131 ··· 6845 6900 msgid "Saved to your feeds" 6846 6901 msgstr "" 6847 6902 6848 - #: src/view/com/modals/EditProfile.tsx:245 6849 - msgid "Saves any changes to your profile" 6850 - msgstr "" 6851 - 6852 6903 #: src/view/com/modals/CropImage.web.tsx:105 6853 6904 msgid "Saves image crop settings" 6854 6905 msgstr "" ··· 6878 6929 msgid "Search" 6879 6930 msgstr "" 6880 6931 6881 - #: src/Navigation.tsx:229 6932 + #: src/Navigation.tsx:239 6882 6933 #: src/screens/Profile/ProfileSearch.tsx:37 6883 6934 msgid "Search @{0}'s posts" 6884 6935 msgstr "" ··· 6953 7004 6954 7005 #: src/components/dialogs/EmailDialog/screens/Update.tsx:243 6955 7006 msgid "Security step required" 6956 - msgstr "" 6957 - 6958 - #: src/components/dialogs/ChangeEmailDialog.tsx:57 6959 - msgid "Security Step Required" 6960 7007 msgstr "" 6961 7008 6962 7009 #: src/components/RichTextTag.tsx:111 ··· 7093 7140 msgstr "" 7094 7141 7095 7142 #: src/screens/Onboarding/StepInterests/index.tsx:192 7096 - #: src/screens/Settings/SettingsInterests.tsx:162 7143 + #: src/screens/Settings/InterestsSettings.tsx:165 7097 7144 msgid "Select your interests from the options below" 7098 7145 msgstr "" 7099 7146 ··· 7107 7154 7108 7155 #: src/components/dms/ChatEmptyPill.tsx:38 7109 7156 msgid "Send a neat website!" 7110 - msgstr "" 7111 - 7112 - #: src/components/dialogs/VerifyEmailDialog.tsx:295 7113 - msgid "Send confirmation" 7114 - msgstr "" 7115 - 7116 - #: src/components/dialogs/VerifyEmailDialog.tsx:288 7117 - msgid "Send confirmation email" 7118 7157 msgstr "" 7119 7158 7120 7159 #: src/components/dialogs/EmailDialog/screens/Manage2FA/Disable.tsx:174 ··· 7202 7241 msgid "Sets email for password reset" 7203 7242 msgstr "" 7204 7243 7205 - #: src/Navigation.tsx:185 7206 - #: src/screens/Settings/Settings.tsx:90 7244 + #: src/Navigation.tsx:195 7245 + #: src/screens/Settings/Settings.tsx:91 7207 7246 #: src/view/shell/desktop/LeftNav.tsx:727 7208 7247 #: src/view/shell/Drawer.tsx:572 7209 7248 msgid "Settings" 7210 7249 msgstr "" 7211 7250 7251 + #: src/screens/Settings/NotificationSettings/index.tsx:154 7252 + msgid "Settings for like notifications" 7253 + msgstr "" 7254 + 7255 + #: src/screens/Settings/NotificationSettings/index.tsx:132 7256 + msgid "Settings for mention notifications" 7257 + msgstr "" 7258 + 7259 + #: src/screens/Settings/NotificationSettings/index.tsx:176 7260 + msgid "Settings for new follower notifications" 7261 + msgstr "" 7262 + 7263 + #: src/screens/Settings/NotificationSettings/index.tsx:231 7264 + msgid "Settings for notifications for everything else" 7265 + msgstr "" 7266 + 7267 + #: src/screens/Settings/NotificationSettings/index.tsx:202 7268 + msgid "Settings for notifications for likes of your reposts" 7269 + msgstr "" 7270 + 7271 + #: src/screens/Settings/NotificationSettings/index.tsx:217 7272 + msgid "Settings for notifications for reposts of your reposts" 7273 + msgstr "" 7274 + 7275 + #: src/screens/Settings/NotificationSettings/index.tsx:143 7276 + msgid "Settings for quote notifications" 7277 + msgstr "" 7278 + 7279 + #: src/screens/Settings/NotificationSettings/index.tsx:121 7280 + msgid "Settings for reply notifications" 7281 + msgstr "" 7282 + 7283 + #: src/screens/Settings/NotificationSettings/index.tsx:165 7284 + msgid "Settings for repost notifications" 7285 + msgstr "" 7286 + 7212 7287 #: src/screens/ModerationInteractionSettings/index.tsx:102 7213 7288 msgctxt "toast" 7214 7289 msgid "Settings saved" ··· 7301 7376 msgid "Share your favorite feed!" 7302 7377 msgstr "" 7303 7378 7304 - #: src/Navigation.tsx:288 7379 + #: src/Navigation.tsx:298 7305 7380 msgid "Shared Preferences Tester" 7306 7381 msgstr "" 7307 7382 ··· 7426 7501 msgid "Shows information about when this post was created" 7427 7502 msgstr "" 7428 7503 7429 - #: src/screens/Settings/Settings.tsx:114 7504 + #: src/screens/Settings/Settings.tsx:115 7430 7505 msgid "Shows other accounts you can switch to" 7431 7506 msgstr "" 7432 7507 ··· 7483 7558 msgid "Sign in to view post" 7484 7559 msgstr "" 7485 7560 7486 - #: src/screens/Settings/Settings.tsx:235 7487 - #: src/screens/Settings/Settings.tsx:237 7488 - #: src/screens/Settings/Settings.tsx:269 7561 + #: src/screens/Settings/Settings.tsx:244 7562 + #: src/screens/Settings/Settings.tsx:246 7563 + #: src/screens/Settings/Settings.tsx:278 7489 7564 #: src/screens/SignupQueued.tsx:93 7490 7565 #: src/screens/SignupQueued.tsx:96 7491 7566 #: src/screens/Takendown.tsx:85 ··· 7499 7574 msgid "Sign Out" 7500 7575 msgstr "" 7501 7576 7502 - #: src/screens/Settings/Settings.tsx:266 7577 + #: src/screens/Settings/Settings.tsx:275 7503 7578 #: src/view/shell/desktop/LeftNav.tsx:209 7504 7579 msgid "Sign out?" 7505 7580 msgstr "" ··· 7532 7607 msgstr "" 7533 7608 7534 7609 #: src/components/dialogs/EmailDialog/screens/VerificationReminder.tsx:91 7535 - #: src/components/dialogs/VerifyEmailDialog.tsx:274 7536 7610 msgid "Snoozes the reminder" 7537 7611 msgstr "" 7538 7612 ··· 7582 7656 msgstr "" 7583 7657 7584 7658 #: src/components/Lists.tsx:174 7585 - #: src/screens/Settings/NotificationSettings.tsx:55 7586 7659 msgid "Something went wrong!" 7587 7660 msgstr "" 7588 7661 ··· 7663 7736 msgid "Start chat with {displayName}" 7664 7737 msgstr "" 7665 7738 7666 - #: src/Navigation.tsx:453 7667 - #: src/Navigation.tsx:458 7739 + #: src/Navigation.tsx:540 7740 + #: src/Navigation.tsx:545 7668 7741 #: src/screens/StarterPack/Wizard/index.tsx:186 7669 7742 msgid "Starter Pack" 7670 7743 msgstr "" ··· 7704 7777 msgid "Step {0} of {1}" 7705 7778 msgstr "" 7706 7779 7707 - #: src/screens/Settings/Settings.tsx:363 7780 + #: src/screens/Settings/Settings.tsx:372 7708 7781 msgid "Storage cleared, you need to restart the app now." 7709 7782 msgstr "" 7710 7783 7711 - #: src/Navigation.tsx:278 7712 - #: src/screens/Settings/Settings.tsx:390 7784 + #: src/Navigation.tsx:288 7785 + #: src/screens/Settings/Settings.tsx:399 7713 7786 msgid "Storybook" 7714 7787 msgstr "" 7715 7788 ··· 7755 7828 msgstr "" 7756 7829 7757 7830 #: src/components/dialogs/EmailDialog/screens/Update.tsx:286 7758 - #: src/components/dialogs/VerifyEmailDialog.tsx:124 7759 7831 msgid "Success!" 7760 7832 msgstr "" 7761 7833 ··· 7786 7858 msgid "Sunset" 7787 7859 msgstr "" 7788 7860 7789 - #: src/Navigation.tsx:298 7861 + #: src/Navigation.tsx:308 7790 7862 #: src/view/screens/Support.tsx:31 7791 7863 #: src/view/screens/Support.tsx:34 7792 7864 msgid "Support" 7793 7865 msgstr "" 7794 7866 7795 - #: src/screens/Settings/Settings.tsx:112 7796 - #: src/screens/Settings/Settings.tsx:126 7797 - #: src/screens/Settings/Settings.tsx:485 7867 + #: src/screens/Settings/Settings.tsx:113 7868 + #: src/screens/Settings/Settings.tsx:127 7869 + #: src/screens/Settings/Settings.tsx:494 7798 7870 #: src/view/shell/desktop/LeftNav.tsx:246 7799 7871 msgid "Switch account" 7800 7872 msgstr "" ··· 7821 7893 7822 7894 #: src/screens/Settings/AboutSettings.tsx:107 7823 7895 #: src/screens/Settings/AboutSettings.tsx:110 7824 - #: src/screens/Settings/Settings.tsx:383 7896 + #: src/screens/Settings/Settings.tsx:392 7825 7897 msgid "System log" 7826 7898 msgstr "" 7827 7899 ··· 7873 7945 msgid "Terms" 7874 7946 msgstr "" 7875 7947 7876 - #: src/Navigation.tsx:308 7948 + #: src/Navigation.tsx:318 7877 7949 #: src/screens/Settings/AboutSettings.tsx:84 7878 7950 #: src/screens/Settings/AboutSettings.tsx:87 7879 7951 #: src/view/screens/TermsOfService.tsx:31 ··· 7910 7982 msgid "Thank you for your feedback! It has been sent to the feed operator." 7911 7983 msgstr "" 7912 7984 7913 - #: src/components/dialogs/VerifyEmailDialog.tsx:125 7914 - msgid "Thank you! Your email has been successfully verified." 7915 - msgstr "" 7916 - 7917 7985 #: src/components/ReportDialog/SubmitView.tsx:83 7918 7986 msgid "Thank you. Your report has been sent." 7919 7987 msgstr "" ··· 7980 8048 7981 8049 #: src/state/shell/progress-guide.tsx:224 7982 8050 msgid "The Discover feed now knows what you like" 7983 - msgstr "" 7984 - 7985 - #: src/components/dialogs/ChangeEmailDialog.tsx:74 7986 - msgid "The email address you entered is the same as your current email address." 7987 8051 msgstr "" 7988 8052 7989 8053 #: src/screens/StarterPack/StarterPackLandingScreen.tsx:324 ··· 8377 8441 msgid "This will delete \"{0}\" from your muted words. You can always add it back later." 8378 8442 msgstr "" 8379 8443 8380 - #: src/screens/Settings/Settings.tsx:537 8444 + #: src/screens/Settings/Settings.tsx:546 8381 8445 msgid "This will remove @{0} from the quick access list." 8382 8446 msgstr "" 8383 8447 ··· 8413 8477 msgid "Threaded mode" 8414 8478 msgstr "" 8415 8479 8416 - #: src/Navigation.tsx:341 8480 + #: src/Navigation.tsx:351 8417 8481 msgid "Threads Preferences" 8418 8482 msgstr "" 8419 8483 ··· 8467 8531 msgid "Top replies first" 8468 8532 msgstr "" 8469 8533 8470 - #: src/Navigation.tsx:423 8534 + #: src/Navigation.tsx:510 8471 8535 msgid "Topic" 8472 8536 msgstr "" 8473 8537 ··· 8694 8758 msgid "Unpinned from your feeds" 8695 8759 msgstr "" 8696 8760 8697 - #: src/screens/Settings/Settings.tsx:416 8698 - #: src/screens/Settings/Settings.tsx:418 8761 + #: src/screens/Settings/Settings.tsx:425 8762 + #: src/screens/Settings/Settings.tsx:427 8699 8763 msgid "Unsnooze email reminder" 8700 8764 msgstr "" 8701 8765 ··· 8930 8994 msgid "Verification settings" 8931 8995 msgstr "" 8932 8996 8933 - #: src/Navigation.tsx:178 8997 + #: src/Navigation.tsx:188 8934 8998 #: src/screens/Moderation/VerificationSettings.tsx:32 8935 8999 msgid "Verification Settings" 8936 9000 msgstr "" ··· 8960 9024 msgid "Verify DNS Record" 8961 9025 msgstr "" 8962 9026 8963 - #: src/components/dialogs/ChangeEmailDialog.tsx:234 8964 - #: src/components/dialogs/ChangeEmailDialog.tsx:240 8965 - msgid "Verify email" 8966 - msgstr "" 8967 - 8968 9027 #: src/components/dialogs/EmailDialog/screens/Verify.tsx:214 8969 9028 msgid "Verify email code" 8970 9029 msgstr "" 8971 9030 8972 - #: src/components/dialogs/ChangeEmailDialog.tsx:122 8973 - #: src/components/dialogs/VerifyEmailDialog.tsx:163 8974 9031 #: src/components/intents/VerifyEmailIntentDialog.tsx:67 8975 9032 msgid "Verify email dialog" 8976 9033 msgstr "" ··· 8990 9047 msgid "Verify your email" 8991 9048 msgstr "" 8992 9049 8993 - #: src/components/dialogs/VerifyEmailDialog.tsx:114 8994 - msgid "Verify Your Email" 8995 - msgstr "" 8996 - 8997 9050 #: src/screens/Settings/AboutSettings.tsx:126 8998 9051 #: src/screens/Settings/AboutSettings.tsx:155 8999 9052 msgid "Version {appVersion}" ··· 9008 9061 msgid "Video failed to process" 9009 9062 msgstr "" 9010 9063 9011 - #: src/Navigation.tsx:474 9064 + #: src/Navigation.tsx:561 9012 9065 msgid "Video Feed" 9013 9066 msgstr "" 9014 9067 ··· 9228 9281 msgid "We ran out of posts from your follows. Here's the latest from <0/>." 9229 9282 msgstr "" 9230 9283 9231 - #: src/screens/Settings/SettingsInterests.tsx:155 9284 + #: src/screens/Settings/InterestsSettings.tsx:158 9232 9285 msgid "We recommend selecting at least two interests." 9233 9286 msgstr "" 9234 9287 ··· 9500 9553 msgstr "" 9501 9554 9502 9555 #: src/screens/Profile/Header/EditProfileDialog.tsx:355 9503 - #: src/view/com/modals/EditProfile.tsx:203 9504 9556 msgid "You are verified. You will lose your verification status if you change your display name. <0>Learn more.</0>" 9505 9557 msgstr "" 9506 9558 ··· 9701 9753 msgid "You previously deactivated @{0}." 9702 9754 msgstr "" 9703 9755 9704 - #: src/screens/Settings/Settings.tsx:374 9756 + #: src/screens/Settings/Settings.tsx:383 9705 9757 msgid "You probably want to restart the app now." 9706 9758 msgstr "" 9707 9759 ··· 9713 9765 msgid "You reacted {0} to {1}" 9714 9766 msgstr "" 9715 9767 9716 - #: src/screens/Settings/Settings.tsx:267 9768 + #: src/screens/Settings/Settings.tsx:276 9717 9769 #: src/view/shell/desktop/LeftNav.tsx:210 9718 9770 msgid "You will be signed out of all your accounts." 9719 9771 msgstr "" ··· 9756 9808 9757 9809 #: src/screens/StarterPack/StarterPackLandingScreen.tsx:234 9758 9810 msgid "You'll follow these people right away" 9759 - msgstr "" 9760 - 9761 - #: src/components/dialogs/VerifyEmailDialog.tsx:216 9762 - msgid "You'll receive an email at <0>{0}</0> to verify it's you." 9763 9811 msgstr "" 9764 9812 9765 9813 #: src/screens/StarterPack/StarterPackLandingScreen.tsx:274 ··· 9856 9904 msgid "Your current handle <0>{0}</0> will automatically remain reserved for you. You can switch back to it at any time from this account." 9857 9905 msgstr "" 9858 9906 9859 - #: src/components/dialogs/ChangeEmailDialog.tsx:65 9860 - msgid "Your email address has been updated but it is not yet verified. As a next step, please verify your new email." 9861 - msgstr "" 9862 - 9863 9907 #: src/screens/Login/ForgotPasswordForm.tsx:51 9864 9908 #: src/screens/Signup/state.ts:270 9865 9909 #: src/screens/Signup/StepInfo/index.tsx:98 ··· 9871 9915 msgid "Your email has not yet been verified. Please verify your email in order to enjoy all the features of Bluesky." 9872 9916 msgstr "" 9873 9917 9874 - #: src/components/dialogs/VerifyEmailDialog.tsx:110 9875 - msgid "Your email has not yet been verified. This is an important security step which we recommend." 9876 - msgstr "" 9877 - 9878 9918 #: src/state/shell/progress-guide.tsx:213 9879 9919 msgid "Your first like!" 9880 9920 msgstr "" ··· 9895 9935 msgid "Your full username will be <0>@{0}</0>" 9896 9936 msgstr "" 9897 9937 9898 - #: src/Navigation.tsx:395 9938 + #: src/Navigation.tsx:482 9899 9939 #: src/screens/Search/modules/ExploreInterestsCard.tsx:67 9900 9940 #: src/screens/Settings/ContentAndMediaSettings.tsx:92 9901 9941 #: src/screens/Settings/ContentAndMediaSettings.tsx:95 9902 - #: src/screens/Settings/SettingsInterests.tsx:39 9942 + #: src/screens/Settings/InterestsSettings.tsx:42 9903 9943 msgid "Your interests" 9904 9944 msgstr "" 9905 9945 9906 - #: src/screens/Settings/SettingsInterests.tsx:124 9946 + #: src/screens/Settings/InterestsSettings.tsx:127 9907 9947 msgctxt "toast" 9908 9948 msgid "Your interests have been updated!" 9909 9949 msgstr "" ··· 9952 9992 msgid "Your report will be sent to the Bluesky Moderation Service" 9953 9993 msgstr "" 9954 9994 9955 - #: src/screens/Settings/SettingsInterests.tsx:53 9995 + #: src/screens/Settings/InterestsSettings.tsx:56 9956 9996 msgid "Your selected interests help us serve you content you care about." 9957 9997 msgstr "" 9958 9998
+46 -44
src/screens/PostThread/components/ThreadItemAnchor.tsx
··· 319 319 live={live} 320 320 onBeforePress={onOpenAuthor} 321 321 /> 322 - <ProfileHoverCard did={post.author.did}> 323 - <View style={[a.flex_1]}> 324 - <View style={[a.flex_row, a.align_center]}> 325 - <Link 326 - to={authorHref} 327 - style={[a.flex_shrink]} 328 - label={sanitizeDisplayName( 329 - post.author.displayName || 330 - sanitizeHandle(post.author.handle), 331 - moderation.ui('displayName'), 332 - )} 333 - onPress={onOpenAuthor}> 334 - <Text 335 - emoji 336 - style={[ 337 - a.text_lg, 338 - a.font_bold, 339 - a.leading_snug, 340 - a.self_start, 341 - ]} 342 - numberOfLines={1}> 343 - {sanitizeDisplayName( 322 + <View style={[a.flex_1, a.align_start]}> 323 + <ProfileHoverCard did={post.author.did}> 324 + <View style={[a.flex_1]}> 325 + <View style={[a.flex_row, a.align_center]}> 326 + <Link 327 + to={authorHref} 328 + style={[a.flex_shrink]} 329 + label={sanitizeDisplayName( 344 330 post.author.displayName || 345 331 sanitizeHandle(post.author.handle), 346 332 moderation.ui('displayName'), 347 333 )} 348 - </Text> 349 - </Link> 334 + onPress={onOpenAuthor}> 335 + <Text 336 + emoji 337 + style={[ 338 + a.text_lg, 339 + a.font_bold, 340 + a.leading_snug, 341 + a.self_start, 342 + ]} 343 + numberOfLines={1}> 344 + {sanitizeDisplayName( 345 + post.author.displayName || 346 + sanitizeHandle(post.author.handle), 347 + moderation.ui('displayName'), 348 + )} 349 + </Text> 350 + </Link> 350 351 351 - <View style={[{paddingLeft: 3, top: -1}]}> 352 - <VerificationCheckButton profile={authorShadow} size="md" /> 352 + <View style={[{paddingLeft: 3, top: -1}]}> 353 + <VerificationCheckButton profile={authorShadow} size="md" /> 354 + </View> 355 + </View> 356 + <View style={[a.align_start]}> 357 + <Link 358 + style={[a.flex_shrink]} 359 + to={authorHref} 360 + label={sanitizeHandle(post.author.handle, '@')}> 361 + <Text 362 + style={[ 363 + a.text_md, 364 + a.leading_snug, 365 + t.atoms.text_contrast_medium, 366 + ]} 367 + numberOfLines={1}> 368 + {sanitizeHandle(post.author.handle, '@')} 369 + </Text> 370 + </Link> 353 371 </View> 354 372 </View> 355 - <View style={[a.align_start]}> 356 - <Link 357 - style={[a.flex_shrink]} 358 - to={authorHref} 359 - label={sanitizeHandle(post.author.handle, '@')}> 360 - <Text 361 - style={[ 362 - a.text_md, 363 - a.leading_snug, 364 - t.atoms.text_contrast_medium, 365 - ]} 366 - numberOfLines={1}> 367 - {sanitizeHandle(post.author.handle, '@')} 368 - </Text> 369 - </Link> 370 - </View> 371 - </View> 372 - </ProfileHoverCard> 373 + </ProfileHoverCard> 374 + </View> 373 375 {showFollowButton && ( 374 376 <View> 375 377 <PostThreadFollowBtn did={post.author.did} />
+3 -7
src/screens/Settings/InterestsSettings.tsx
··· 113 113 }, 114 114 ) 115 115 await Promise.all([ 116 - await qc.resetQueries({ 117 - queryKey: createSuggestedStarterPacksQueryKey(), 118 - }), 119 - await qc.resetQueries({queryKey: createGetSuggestedFeedsQueryKey()}), 120 - await qc.resetQueries({ 121 - queryKey: createGetSuggestedUsersQueryKey({}), 122 - }), 116 + qc.resetQueries({queryKey: createSuggestedStarterPacksQueryKey()}), 117 + qc.resetQueries({queryKey: createGetSuggestedFeedsQueryKey()}), 118 + qc.resetQueries({queryKey: createGetSuggestedUsersQueryKey({})}), 123 119 ]) 124 120 125 121 Toast.show(
+1 -1
src/screens/Settings/NotificationSettings/LikesOnRepostsNotificationSettings.tsx
··· 38 38 <SettingsList.ItemIcon icon={LikeRepostIcon} /> 39 39 <ItemTextWithSubtitle 40 40 bold 41 - titleText={<Trans>Likes on your reposts</Trans>} 41 + titleText={<Trans>Likes of your reposts</Trans>} 42 42 subtitleText={ 43 43 <Trans> 44 44 Get notifications when people like posts that you've reposted.
+8 -6
src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx
··· 85 85 86 86 const newPreference = { 87 87 ...preference, 88 - filter: change, 88 + include: change, 89 89 } satisfies typeof preference 90 90 91 91 mutate({ ··· 98 98 <View style={[a.px_xl, a.pt_md, a.gap_sm]}> 99 99 <Toggle.Group 100 100 type="checkbox" 101 - label={_(`Select your preferred notification channels`)} 101 + label={_(msg`Select your preferred notification channels`)} 102 102 values={channels} 103 103 onChange={onChangeChannels}> 104 104 <View style={[a.gap_sm]}> ··· 138 138 )} 139 139 </View> 140 140 </Toggle.Group> 141 - {'filter' in preference && ( 141 + {'include' in preference && ( 142 142 <> 143 143 <Divider /> 144 - <Text style={[a.font_bold, a.text_md]}>From</Text> 144 + <Text style={[a.font_bold, a.text_md]}> 145 + <Trans>From</Trans> 146 + </Text> 145 147 <Toggle.Group 146 148 type="radio" 147 - label={_('Filter who you receive notifications from')} 148 - values={[preference.filter]} 149 + label={_(msg`Filter who you receive notifications from`)} 150 + values={[preference.include]} 149 151 onChange={onChangeFilter} 150 152 disabled={channels.length === 0}> 151 153 <View style={[a.gap_sm]}>
+27 -27
src/screens/Settings/NotificationSettings/index.tsx
··· 118 118 )} 119 119 <View style={[a.gap_sm]}> 120 120 <SettingsList.LinkItem 121 + label={_(msg`Settings for like notifications`)} 122 + to={{screen: 'LikeNotificationSettings'}} 123 + contentContainerStyle={[a.align_start]}> 124 + <SettingsList.ItemIcon icon={HeartIcon} /> 125 + <ItemTextWithSubtitle 126 + titleText={<Trans>Likes</Trans>} 127 + subtitleText={<SettingPreview preference={settings?.like} />} 128 + showSkeleton={!settings} 129 + /> 130 + </SettingsList.LinkItem> 131 + <SettingsList.LinkItem 132 + label={_(msg`Settings for new follower notifications`)} 133 + to={{screen: 'NewFollowerNotificationSettings'}} 134 + contentContainerStyle={[a.align_start]}> 135 + <SettingsList.ItemIcon icon={PersonPlusIcon} /> 136 + <ItemTextWithSubtitle 137 + titleText={<Trans>New followers</Trans>} 138 + subtitleText={<SettingPreview preference={settings?.follow} />} 139 + showSkeleton={!settings} 140 + /> 141 + </SettingsList.LinkItem> 142 + <SettingsList.LinkItem 121 143 label={_(msg`Settings for reply notifications`)} 122 144 to={{screen: 'ReplyNotificationSettings'}} 123 145 contentContainerStyle={[a.align_start]}> ··· 151 173 /> 152 174 </SettingsList.LinkItem> 153 175 <SettingsList.LinkItem 154 - label={_(msg`Settings for like notifications`)} 155 - to={{screen: 'LikeNotificationSettings'}} 156 - contentContainerStyle={[a.align_start]}> 157 - <SettingsList.ItemIcon icon={HeartIcon} /> 158 - <ItemTextWithSubtitle 159 - titleText={<Trans>Likes</Trans>} 160 - subtitleText={<SettingPreview preference={settings?.like} />} 161 - showSkeleton={!settings} 162 - /> 163 - </SettingsList.LinkItem> 164 - <SettingsList.LinkItem 165 176 label={_(msg`Settings for repost notifications`)} 166 177 to={{screen: 'RepostNotificationSettings'}} 167 178 contentContainerStyle={[a.align_start]}> ··· 172 183 showSkeleton={!settings} 173 184 /> 174 185 </SettingsList.LinkItem> 175 - <SettingsList.LinkItem 176 - label={_(msg`Settings for new follower notifications`)} 177 - to={{screen: 'NewFollowerNotificationSettings'}} 178 - contentContainerStyle={[a.align_start]}> 179 - <SettingsList.ItemIcon icon={PersonPlusIcon} /> 180 - <ItemTextWithSubtitle 181 - titleText={<Trans>New followers</Trans>} 182 - subtitleText={<SettingPreview preference={settings?.follow} />} 183 - showSkeleton={!settings} 184 - /> 185 - </SettingsList.LinkItem> 186 186 {/* <SettingsList.LinkItem 187 187 label={_(msg`Settings for activity alerts`)} 188 188 to={{screen: 'ActivityNotificationSettings'}} ··· 199 199 </SettingsList.LinkItem> */} 200 200 <SettingsList.LinkItem 201 201 label={_( 202 - msg`Settings for notifications for likes on your reposts`, 202 + msg`Settings for notifications for likes of your reposts`, 203 203 )} 204 204 to={{screen: 'LikesOnRepostsNotificationSettings'}} 205 205 contentContainerStyle={[a.align_start]}> 206 206 <SettingsList.ItemIcon icon={LikeRepostIcon} /> 207 207 <ItemTextWithSubtitle 208 - titleText={<Trans>Likes on your reposts</Trans>} 208 + titleText={<Trans>Likes of your reposts</Trans>} 209 209 subtitleText={ 210 210 <SettingPreview preference={settings?.likeViaRepost} /> 211 211 } ··· 260 260 if (!preference) { 261 261 return null 262 262 } else { 263 - if ('filter' in preference) { 264 - if (preference.filter === 'all') { 263 + if ('include' in preference) { 264 + if (preference.include === 'all') { 265 265 if (preference.list && preference.push) { 266 266 return _(msg`In-app, Push, Everyone`) 267 267 } else if (preference.list) { ··· 269 269 } else if (preference.push) { 270 270 return _(msg`Push, Everyone`) 271 271 } 272 - } else if (preference.filter === 'follows') { 272 + } else if (preference.include === 'follows') { 273 273 if (preference.list && preference.push) { 274 274 return _(msg`In-app, Push, People you follow`) 275 275 } else if (preference.list) {
-10
src/state/modals/index.tsx
··· 43 43 name: 'change-password' 44 44 } 45 45 46 - export interface LinkWarningModal { 47 - name: 'link-warning' 48 - text: string 49 - href: string 50 - share?: boolean 51 - } 52 - 53 46 export type Modal = 54 47 // Account 55 48 | DeleteAccountModal ··· 66 59 // Bluesky access 67 60 | WaitlistModal 68 61 | InviteCodesModal 69 - 70 - // Generic 71 - | LinkWarningModal 72 62 73 63 const ModalContext = React.createContext<{ 74 64 isModalActive: boolean
-335
src/view/com/modals/EditProfile.tsx
··· 1 - import {useCallback, useState} from 'react' 2 - import { 3 - ActivityIndicator, 4 - KeyboardAvoidingView, 5 - ScrollView, 6 - StyleSheet, 7 - TextInput, 8 - TouchableOpacity, 9 - View, 10 - } from 'react-native' 11 - import Animated, {FadeOut} from 'react-native-reanimated' 12 - import {LinearGradient} from 'expo-linear-gradient' 13 - import {type AppBskyActorDefs} from '@atproto/api' 14 - import {msg, Trans} from '@lingui/macro' 15 - import {useLingui} from '@lingui/react' 16 - 17 - import {MAX_DESCRIPTION, MAX_DISPLAY_NAME, urls} from '#/lib/constants' 18 - import {usePalette} from '#/lib/hooks/usePalette' 19 - import {compressIfNeeded} from '#/lib/media/manip' 20 - import {type PickerImage} from '#/lib/media/picker.shared' 21 - import {cleanError} from '#/lib/strings/errors' 22 - import {enforceLen} from '#/lib/strings/helpers' 23 - import {colors, gradients, s} from '#/lib/styles' 24 - import {useTheme} from '#/lib/ThemeContext' 25 - import {logger} from '#/logger' 26 - import {isWeb} from '#/platform/detection' 27 - import {useModalControls} from '#/state/modals' 28 - import {useProfileUpdateMutation} from '#/state/queries/profile' 29 - import {Text} from '#/view/com/util/text/Text' 30 - import * as Toast from '#/view/com/util/Toast' 31 - import {EditableUserAvatar} from '#/view/com/util/UserAvatar' 32 - import {UserBanner} from '#/view/com/util/UserBanner' 33 - import {Admonition} from '#/components/Admonition' 34 - import {InlineLinkText} from '#/components/Link' 35 - import {useSimpleVerificationState} from '#/components/verification' 36 - import {ErrorMessage} from '../util/error/ErrorMessage' 37 - 38 - const AnimatedTouchableOpacity = 39 - Animated.createAnimatedComponent(TouchableOpacity) 40 - 41 - export const snapPoints = ['fullscreen'] 42 - 43 - export function Component({ 44 - profile, 45 - onUpdate, 46 - }: { 47 - profile: AppBskyActorDefs.ProfileViewDetailed 48 - onUpdate?: () => void 49 - }) { 50 - const pal = usePalette('default') 51 - const theme = useTheme() 52 - const {_} = useLingui() 53 - const {closeModal} = useModalControls() 54 - const updateMutation = useProfileUpdateMutation() 55 - const [imageError, setImageError] = useState<string>('') 56 - const initialDisplayName = profile.displayName || '' 57 - const [displayName, setDisplayName] = useState<string>( 58 - profile.displayName || '', 59 - ) 60 - const [description, setDescription] = useState<string>( 61 - profile.description || '', 62 - ) 63 - const [userBanner, setUserBanner] = useState<string | undefined | null>( 64 - profile.banner, 65 - ) 66 - const [userAvatar, setUserAvatar] = useState<string | undefined | null>( 67 - profile.avatar, 68 - ) 69 - const [newUserBanner, setNewUserBanner] = useState< 70 - PickerImage | undefined | null 71 - >() 72 - const [newUserAvatar, setNewUserAvatar] = useState< 73 - PickerImage | undefined | null 74 - >() 75 - const onPressCancel = () => { 76 - closeModal() 77 - } 78 - const onSelectNewAvatar = useCallback( 79 - async (img: PickerImage | null) => { 80 - setImageError('') 81 - if (img === null) { 82 - setNewUserAvatar(null) 83 - setUserAvatar(null) 84 - return 85 - } 86 - try { 87 - const finalImg = await compressIfNeeded(img, 1000000) 88 - setNewUserAvatar(finalImg) 89 - setUserAvatar(finalImg.path) 90 - } catch (e: any) { 91 - setImageError(cleanError(e)) 92 - } 93 - }, 94 - [setNewUserAvatar, setUserAvatar, setImageError], 95 - ) 96 - 97 - const onSelectNewBanner = useCallback( 98 - async (img: PickerImage | null) => { 99 - setImageError('') 100 - if (!img) { 101 - setNewUserBanner(null) 102 - setUserBanner(null) 103 - return 104 - } 105 - try { 106 - const finalImg = await compressIfNeeded(img, 1000000) 107 - setNewUserBanner(finalImg) 108 - setUserBanner(finalImg.path) 109 - } catch (e: any) { 110 - setImageError(cleanError(e)) 111 - } 112 - }, 113 - [setNewUserBanner, setUserBanner, setImageError], 114 - ) 115 - 116 - const onPressSave = useCallback(async () => { 117 - setImageError('') 118 - try { 119 - await updateMutation.mutateAsync({ 120 - profile, 121 - updates: { 122 - displayName, 123 - description, 124 - }, 125 - newUserAvatar, 126 - newUserBanner, 127 - }) 128 - Toast.show(_(msg({message: 'Profile updated', context: 'toast'}))) 129 - onUpdate?.() 130 - closeModal() 131 - } catch (e: any) { 132 - logger.error('Failed to update user profile', {message: String(e)}) 133 - } 134 - }, [ 135 - updateMutation, 136 - profile, 137 - onUpdate, 138 - closeModal, 139 - displayName, 140 - description, 141 - newUserAvatar, 142 - newUserBanner, 143 - setImageError, 144 - _, 145 - ]) 146 - const verification = useSimpleVerificationState({ 147 - profile, 148 - }) 149 - 150 - return ( 151 - <KeyboardAvoidingView style={s.flex1} behavior="height"> 152 - <ScrollView style={[pal.view]} testID="editProfileModal"> 153 - <Text style={[styles.title, pal.text]}> 154 - <Trans>Edit my profile</Trans> 155 - </Text> 156 - <View style={styles.photos}> 157 - <UserBanner 158 - banner={userBanner} 159 - onSelectNewBanner={onSelectNewBanner} 160 - /> 161 - <View style={[styles.avi, {borderColor: pal.colors.background}]}> 162 - <EditableUserAvatar 163 - size={80} 164 - avatar={userAvatar} 165 - onSelectNewAvatar={onSelectNewAvatar} 166 - /> 167 - </View> 168 - </View> 169 - {updateMutation.isError && ( 170 - <View style={styles.errorContainer}> 171 - <ErrorMessage message={cleanError(updateMutation.error)} /> 172 - </View> 173 - )} 174 - {imageError !== '' && ( 175 - <View style={styles.errorContainer}> 176 - <ErrorMessage message={imageError} /> 177 - </View> 178 - )} 179 - <View style={styles.form}> 180 - <View> 181 - <Text style={[styles.label, pal.text]}> 182 - <Trans>Display Name</Trans> 183 - </Text> 184 - <TextInput 185 - testID="editProfileDisplayNameInput" 186 - style={[styles.textInput, pal.border, pal.text]} 187 - placeholder={_(msg`e.g. Alice Roberts`)} 188 - placeholderTextColor={colors.gray4} 189 - value={displayName} 190 - onChangeText={v => 191 - setDisplayName(enforceLen(v, MAX_DISPLAY_NAME)) 192 - } 193 - accessible={true} 194 - accessibilityLabel={_(msg`Display name`)} 195 - accessibilityHint={_(msg`Edit your display name`)} 196 - /> 197 - 198 - {verification.isVerified && 199 - verification.role === 'default' && 200 - displayName !== initialDisplayName && ( 201 - <View style={{paddingTop: 8}}> 202 - <Admonition type="error"> 203 - <Trans> 204 - You are verified. You will lose your verification status 205 - if you change your display name.{' '} 206 - <InlineLinkText 207 - label={_(msg`Learn more`)} 208 - to={urls.website.blog.initialVerificationAnnouncement}> 209 - <Trans>Learn more.</Trans> 210 - </InlineLinkText> 211 - </Trans> 212 - </Admonition> 213 - </View> 214 - )} 215 - </View> 216 - <View style={s.pb10}> 217 - <Text style={[styles.label, pal.text]}> 218 - <Trans>Description</Trans> 219 - </Text> 220 - <TextInput 221 - testID="editProfileDescriptionInput" 222 - style={[styles.textArea, pal.border, pal.text]} 223 - placeholder={_(msg`e.g. Artist, dog-lover, and avid reader.`)} 224 - placeholderTextColor={colors.gray4} 225 - keyboardAppearance={theme.colorScheme} 226 - multiline 227 - value={description} 228 - onChangeText={v => setDescription(enforceLen(v, MAX_DESCRIPTION))} 229 - accessible={true} 230 - accessibilityLabel={_(msg`Description`)} 231 - accessibilityHint={_(msg`Edit your profile description`)} 232 - /> 233 - </View> 234 - {updateMutation.isPending ? ( 235 - <View style={[styles.btn, s.mt10, {backgroundColor: colors.gray2}]}> 236 - <ActivityIndicator /> 237 - </View> 238 - ) : ( 239 - <TouchableOpacity 240 - testID="editProfileSaveBtn" 241 - style={s.mt10} 242 - onPress={onPressSave} 243 - accessibilityRole="button" 244 - accessibilityLabel={_(msg`Save`)} 245 - accessibilityHint={_(msg`Saves any changes to your profile`)}> 246 - <LinearGradient 247 - colors={[gradients.blueLight.start, gradients.blueLight.end]} 248 - start={{x: 0, y: 0}} 249 - end={{x: 1, y: 1}} 250 - style={[styles.btn]}> 251 - <Text style={[s.white, s.bold]}> 252 - <Trans>Save Changes</Trans> 253 - </Text> 254 - </LinearGradient> 255 - </TouchableOpacity> 256 - )} 257 - {!updateMutation.isPending && ( 258 - <AnimatedTouchableOpacity 259 - exiting={!isWeb ? FadeOut : undefined} 260 - testID="editProfileCancelBtn" 261 - style={s.mt5} 262 - onPress={onPressCancel} 263 - accessibilityRole="button" 264 - accessibilityLabel={_(msg`Cancel profile editing`)} 265 - accessibilityHint="" 266 - onAccessibilityEscape={onPressCancel}> 267 - <View style={[styles.btn]}> 268 - <Text style={[s.black, s.bold, pal.text]}> 269 - <Trans>Cancel</Trans> 270 - </Text> 271 - </View> 272 - </AnimatedTouchableOpacity> 273 - )} 274 - </View> 275 - </ScrollView> 276 - </KeyboardAvoidingView> 277 - ) 278 - } 279 - 280 - const styles = StyleSheet.create({ 281 - title: { 282 - textAlign: 'center', 283 - fontWeight: '600', 284 - fontSize: 24, 285 - marginBottom: 18, 286 - }, 287 - label: { 288 - fontWeight: '600', 289 - paddingHorizontal: 4, 290 - paddingBottom: 4, 291 - marginTop: 20, 292 - }, 293 - form: { 294 - paddingHorizontal: 14, 295 - }, 296 - textInput: { 297 - borderWidth: 1, 298 - borderRadius: 6, 299 - paddingHorizontal: 14, 300 - paddingVertical: 10, 301 - fontSize: 16, 302 - }, 303 - textArea: { 304 - borderWidth: 1, 305 - borderRadius: 6, 306 - paddingHorizontal: 12, 307 - paddingTop: 10, 308 - fontSize: 16, 309 - height: 120, 310 - textAlignVertical: 'top', 311 - }, 312 - btn: { 313 - flexDirection: 'row', 314 - alignItems: 'center', 315 - justifyContent: 'center', 316 - width: '100%', 317 - borderRadius: 32, 318 - padding: 10, 319 - marginBottom: 10, 320 - }, 321 - avi: { 322 - position: 'absolute', 323 - top: 80, 324 - left: 24, 325 - width: 84, 326 - height: 84, 327 - borderWidth: 2, 328 - borderRadius: 42, 329 - }, 330 - photos: { 331 - marginBottom: 36, 332 - marginHorizontal: -14, 333 - }, 334 - errorContainer: {marginTop: 20}, 335 - })
-180
src/view/com/modals/LinkWarning.tsx
··· 1 - import React from 'react' 2 - import {SafeAreaView, StyleSheet, View} from 'react-native' 3 - import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 4 - import {msg, Trans} from '@lingui/macro' 5 - import {useLingui} from '@lingui/react' 6 - 7 - import {useOpenLink} from '#/lib/hooks/useOpenLink' 8 - import {usePalette} from '#/lib/hooks/usePalette' 9 - import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' 10 - import {shareUrl} from '#/lib/sharing' 11 - import {isPossiblyAUrl, splitApexDomain} from '#/lib/strings/url-helpers' 12 - import {colors, s} from '#/lib/styles' 13 - import {isWeb} from '#/platform/detection' 14 - import {useModalControls} from '#/state/modals' 15 - import {Button} from '#/view/com/util/forms/Button' 16 - import {Text} from '#/view/com/util/text/Text' 17 - import {ScrollView} from './util' 18 - 19 - export const snapPoints = ['50%'] 20 - 21 - export function Component({ 22 - text, 23 - href, 24 - share, 25 - }: { 26 - text: string 27 - href: string 28 - share?: boolean 29 - }) { 30 - const pal = usePalette('default') 31 - const {closeModal} = useModalControls() 32 - const {isMobile} = useWebMediaQueries() 33 - const {_} = useLingui() 34 - const potentiallyMisleading = isPossiblyAUrl(text) 35 - const openLink = useOpenLink() 36 - 37 - const onPressVisit = () => { 38 - closeModal() 39 - if (share) { 40 - shareUrl(href) 41 - } else { 42 - openLink(href, false, true) 43 - } 44 - } 45 - 46 - return ( 47 - <SafeAreaView style={[s.flex1, pal.view]}> 48 - <ScrollView 49 - testID="linkWarningModal" 50 - style={[s.flex1, isMobile && {paddingHorizontal: 18}]}> 51 - <View style={styles.titleSection}> 52 - {potentiallyMisleading ? ( 53 - <> 54 - <FontAwesomeIcon 55 - icon="circle-exclamation" 56 - color={pal.colors.text} 57 - size={18} 58 - /> 59 - <Text type="title-lg" style={[pal.text, styles.title]}> 60 - <Trans>Potentially Misleading Link</Trans> 61 - </Text> 62 - </> 63 - ) : ( 64 - <Text type="title-lg" style={[pal.text, styles.title]}> 65 - <Trans>Leaving Bluesky</Trans> 66 - </Text> 67 - )} 68 - </View> 69 - 70 - <View style={{gap: 10}}> 71 - <Text type="lg" style={pal.text}> 72 - <Trans>This link is taking you to the following website:</Trans> 73 - </Text> 74 - 75 - <LinkBox href={href} /> 76 - 77 - {potentiallyMisleading && ( 78 - <Text type="lg" style={pal.text}> 79 - <Trans>Make sure this is where you intend to go!</Trans> 80 - </Text> 81 - )} 82 - </View> 83 - 84 - <View style={[styles.btnContainer, isMobile && {paddingBottom: 40}]}> 85 - <Button 86 - testID="confirmBtn" 87 - type="primary" 88 - onPress={onPressVisit} 89 - accessibilityLabel={share ? _(msg`Share Link`) : _(msg`Visit Site`)} 90 - accessibilityHint={ 91 - share 92 - ? _(msg`Shares the linked website`) 93 - : _(msg`Opens the linked website`) 94 - } 95 - label={share ? _(msg`Share Link`) : _(msg`Visit Site`)} 96 - labelContainerStyle={{justifyContent: 'center', padding: 4}} 97 - labelStyle={[s.f18]} 98 - /> 99 - <Button 100 - testID="cancelBtn" 101 - type="default" 102 - onPress={() => { 103 - closeModal() 104 - }} 105 - accessibilityLabel={_(msg`Cancel`)} 106 - accessibilityHint={_(msg`Cancels opening the linked website`)} 107 - label={_(msg`Cancel`)} 108 - labelContainerStyle={{justifyContent: 'center', padding: 4}} 109 - labelStyle={[s.f18]} 110 - /> 111 - </View> 112 - </ScrollView> 113 - </SafeAreaView> 114 - ) 115 - } 116 - 117 - function LinkBox({href}: {href: string}) { 118 - const pal = usePalette('default') 119 - const [scheme, hostname, rest] = React.useMemo(() => { 120 - try { 121 - const urlp = new URL(href) 122 - const [subdomain, apexdomain] = splitApexDomain(urlp.hostname) 123 - return [ 124 - urlp.protocol + '//' + subdomain, 125 - apexdomain, 126 - urlp.pathname + urlp.search + urlp.hash, 127 - ] 128 - } catch { 129 - return ['', href, ''] 130 - } 131 - }, [href]) 132 - return ( 133 - <View style={[pal.view, pal.border, styles.linkBox]}> 134 - <Text type="lg" style={pal.textLight}> 135 - {scheme} 136 - <Text type="lg-bold" style={pal.text}> 137 - {hostname} 138 - </Text> 139 - {rest} 140 - </Text> 141 - </View> 142 - ) 143 - } 144 - 145 - const styles = StyleSheet.create({ 146 - container: { 147 - flex: 1, 148 - paddingBottom: isWeb ? 0 : 40, 149 - }, 150 - titleSection: { 151 - flexDirection: 'row', 152 - justifyContent: 'center', 153 - alignItems: 'center', 154 - gap: 6, 155 - paddingTop: isWeb ? 0 : 4, 156 - paddingBottom: isWeb ? 14 : 10, 157 - }, 158 - title: { 159 - textAlign: 'center', 160 - fontWeight: '600', 161 - }, 162 - linkBox: { 163 - paddingHorizontal: 12, 164 - paddingVertical: 10, 165 - borderRadius: 6, 166 - borderWidth: 1, 167 - }, 168 - btn: { 169 - flexDirection: 'row', 170 - alignItems: 'center', 171 - justifyContent: 'center', 172 - borderRadius: 32, 173 - padding: 14, 174 - backgroundColor: colors.blue3, 175 - }, 176 - btnContainer: { 177 - paddingTop: 20, 178 - gap: 6, 179 - }, 180 - })
-4
src/view/com/modals/Modal.tsx
··· 13 13 import * as InviteCodesModal from './InviteCodes' 14 14 import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings' 15 15 import * as PostLanguagesSettingsModal from './lang-settings/PostLanguagesSettings' 16 - import * as LinkWarningModal from './LinkWarning' 17 16 import * as UserAddRemoveListsModal from './UserAddRemoveLists' 18 17 19 18 const DEFAULT_SNAPPOINTS = ['90%'] ··· 68 67 } else if (activeModal?.name === 'change-password') { 69 68 snapPoints = ChangePasswordModal.snapPoints 70 69 element = <ChangePasswordModal.Component /> 71 - } else if (activeModal?.name === 'link-warning') { 72 - snapPoints = LinkWarningModal.snapPoints 73 - element = <LinkWarningModal.Component {...activeModal} /> 74 70 } else { 75 71 return null 76 72 }
-3
src/view/com/modals/Modal.web.tsx
··· 12 12 import * as InviteCodesModal from './InviteCodes' 13 13 import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings' 14 14 import * as PostLanguagesSettingsModal from './lang-settings/PostLanguagesSettings' 15 - import * as LinkWarningModal from './LinkWarning' 16 15 import * as UserAddRemoveLists from './UserAddRemoveLists' 17 16 18 17 export function ModalsContainer() { ··· 65 64 element = <PostLanguagesSettingsModal.Component /> 66 65 } else if (modal.name === 'change-password') { 67 66 element = <ChangePasswordModal.Component /> 68 - } else if (modal.name === 'link-warning') { 69 - element = <LinkWarningModal.Component {...modal} /> 70 67 } else { 71 68 return null 72 69 }
+6 -5
src/view/com/util/Link.tsx
··· 30 30 import {useModalControls} from '#/state/modals' 31 31 import {WebAuxClickWrapper} from '#/view/com/util/WebAuxClickWrapper' 32 32 import {useTheme} from '#/alf' 33 + import {useGlobalDialogsControlContext} from '#/components/dialogs/Context' 33 34 import {router} from '../../../routes' 34 35 import {PressableWithHover} from './PressableWithHover' 35 36 import {Text} from './text/Text' ··· 189 190 onBeforePress?: () => void 190 191 } & TextProps) { 191 192 const navigation = useNavigationDeduped() 192 - const {openModal, closeModal} = useModalControls() 193 + const {closeModal} = useModalControls() 194 + const {linkWarningDialogControl} = useGlobalDialogsControlContext() 193 195 const openLink = useOpenLink() 194 196 195 197 if (!disableMismatchWarning && typeof text !== 'string') { ··· 211 213 linkRequiresWarning(href, typeof text === 'string' ? text : '') 212 214 if (requiresWarning) { 213 215 e?.preventDefault?.() 214 - openModal({ 215 - name: 'link-warning', 216 - text: typeof text === 'string' ? text : '', 216 + linkWarningDialogControl.open({ 217 + displayText: typeof text === 'string' ? text : '', 217 218 href, 218 219 }) 219 220 } ··· 245 246 onBeforePress, 246 247 onPressProp, 247 248 closeModal, 248 - openModal, 249 249 navigation, 250 250 href, 251 251 text, 252 252 disableMismatchWarning, 253 253 navigationAction, 254 254 openLink, 255 + linkWarningDialogControl, 255 256 ], 256 257 ) 257 258 const hrefAttrs = useMemo(() => {
+22
src/view/shell/createNativeStackNavigatorWithAuth.tsx
··· 40 40 import {SignupQueued} from '#/screens/SignupQueued' 41 41 import {Takendown} from '#/screens/Takendown' 42 42 import {atoms as a, useLayoutBreakpoints} from '#/alf' 43 + import {EmailDialog} from '#/components/dialogs/EmailDialog' 44 + import {InAppBrowserConsentDialog} from '#/components/dialogs/InAppBrowserConsent' 45 + import {LinkWarningDialog} from '#/components/dialogs/LinkWarning' 46 + import {MutedWordsDialog} from '#/components/dialogs/MutedWords' 47 + import {NuxDialogs} from '#/components/dialogs/nuxs' 48 + import {SigninDialog} from '#/components/dialogs/Signin' 49 + import {Outlet as PortalOutlet} from '#/components/Portal' 50 + import {BottomSheetOutlet} from '#/../modules/bottom-sheet' 43 51 import {BottomBarWeb} from './bottom-bar/BottomBarWeb' 44 52 import {DesktopLeftNav} from './desktop/LeftNav' 45 53 import {DesktopRightNav} from './desktop/RightNav' ··· 167 175 {!isMobile && <DesktopRightNav routeName={activeRoute.name} />} 168 176 </> 169 177 )} 178 + 179 + {/* Start: individual dialogs and outlets */} 180 + <MutedWordsDialog /> 181 + <SigninDialog /> 182 + <EmailDialog /> 183 + <LinkWarningDialog /> 184 + {!isWeb && <InAppBrowserConsentDialog />} 185 + <PortalOutlet /> 186 + <BottomSheetOutlet /> 187 + {/* End: individual dialogs and outlets */} 188 + 189 + {/* Start: dialog controllers */} 190 + <NuxDialogs /> 191 + {/* End: dialog controllers */} 170 192 </NavigationContent> 171 193 ) 172 194 }
-12
src/view/shell/index.tsx
··· 25 25 import {ErrorBoundary} from '#/view/com/util/ErrorBoundary' 26 26 import {atoms as a, select, useTheme} from '#/alf' 27 27 import {setSystemUITheme} from '#/alf/util/systemUI' 28 - import {EmailDialog} from '#/components/dialogs/EmailDialog' 29 - import {InAppBrowserConsentDialog} from '#/components/dialogs/InAppBrowserConsent' 30 - import {MutedWordsDialog} from '#/components/dialogs/MutedWords' 31 - import {SigninDialog} from '#/components/dialogs/Signin' 32 - import {Outlet as PortalOutlet} from '#/components/Portal' 33 28 import {RoutesContainer, TabsNavigator} from '#/Navigation' 34 - import {BottomSheetOutlet} from '../../../modules/bottom-sheet' 35 29 import {updateActiveViewAsync} from '../../../modules/expo-bluesky-swiss-army/src/VisibilityView' 36 30 import {Composer} from './Composer' 37 31 import {DrawerContent} from './Drawer' ··· 151 145 </View> 152 146 <Composer winHeight={winDim.height} /> 153 147 <ModalsContainer /> 154 - <MutedWordsDialog /> 155 - <SigninDialog /> 156 - <EmailDialog /> 157 - <InAppBrowserConsentDialog /> 158 148 <Lightbox /> 159 - <PortalOutlet /> 160 - <BottomSheetOutlet /> 161 149 </> 162 150 ) 163 151 }
-8
src/view/shell/index.web.tsx
··· 17 17 import {ModalsContainer} from '#/view/com/modals/Modal' 18 18 import {ErrorBoundary} from '#/view/com/util/ErrorBoundary' 19 19 import {atoms as a, select, useTheme} from '#/alf' 20 - import {EmailDialog} from '#/components/dialogs/EmailDialog' 21 - import {MutedWordsDialog} from '#/components/dialogs/MutedWords' 22 - import {SigninDialog} from '#/components/dialogs/Signin' 23 - import {Outlet as PortalOutlet} from '#/components/Portal' 24 20 import {FlatNavigator, RoutesContainer} from '#/Navigation' 25 21 import {Composer} from './Composer.web' 26 22 import {DrawerContent} from './Drawer' ··· 66 62 </ErrorBoundary> 67 63 <Composer winHeight={0} /> 68 64 <ModalsContainer /> 69 - <MutedWordsDialog /> 70 - <SigninDialog /> 71 - <EmailDialog /> 72 65 <Lightbox /> 73 - <PortalOutlet /> 74 66 75 67 {showDrawerDelayedExit && ( 76 68 <>
+51 -51
yarn.lock
··· 63 63 "@atproto/xrpc" "^0.7.0" 64 64 "@atproto/xrpc-server" "^0.8.0" 65 65 66 - "@atproto/api@^0.15.15": 67 - version "0.15.15" 68 - resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.15.15.tgz#a506a1a26f3dfef9adb77234f451c0e784b071e7" 69 - integrity sha512-Wn8jv76pCvffnkNj68w0CGZ3PT4DJGM8DUZnYq9kEW2im6jbRBYI0yYrHNhSiE92A5Ox0HjL2jMhalsI2p9VlQ== 66 + "@atproto/api@^0.15.16": 67 + version "0.15.16" 68 + resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.15.16.tgz#1962e7067e03a661e17c3164874596ef1e7ed7ad" 69 + integrity sha512-ZNBrzBg2l0lHreKik1lJn8lrhAktwlY8NUPBU/hO9dwjAnDHQTiSzNFZt65dp9djmqZ75sX/VJ+heNuaJBvnhQ== 70 70 dependencies: 71 71 "@atproto/common-web" "^0.4.2" 72 72 "@atproto/lexicon" "^0.4.11" ··· 77 77 tlds "^1.234.0" 78 78 zod "^3.23.8" 79 79 80 - "@atproto/aws@^0.2.21": 81 - version "0.2.21" 82 - resolved "https://registry.yarnpkg.com/@atproto/aws/-/aws-0.2.21.tgz#06006a101c8004db11384a19366296cd87468326" 83 - integrity sha512-bosExZ3YdFjOehNBcNWsC2mZBrAVLO8Ut/JquypXSahFeeXZP/9rd9F1VGf+vAmjFEKagHXQCb6CRFfJyN+I7A== 80 + "@atproto/aws@^0.2.22": 81 + version "0.2.22" 82 + resolved "https://registry.yarnpkg.com/@atproto/aws/-/aws-0.2.22.tgz#14a664c06e3569945e4ab143d3a8a03400c7d1de" 83 + integrity sha512-xZ+0/zHHmpgzdLJGTDkFl5Wd39Wm5MyyMLdGYSzyt0wGTBmH6Ktp7ZgR8rmQVNYN1+VkMcdClAiNhg+BSH3mRw== 84 84 dependencies: 85 85 "@atproto/common" "^0.4.11" 86 86 "@atproto/crypto" "^0.4.4" 87 - "@atproto/repo" "^0.8.1" 87 + "@atproto/repo" "^0.8.2" 88 88 "@aws-sdk/client-cloudfront" "^3.261.0" 89 89 "@aws-sdk/client-kms" "^3.196.0" 90 90 "@aws-sdk/client-s3" "^3.224.0" ··· 94 94 multiformats "^9.9.0" 95 95 uint8arrays "3.0.0" 96 96 97 - "@atproto/bsky@^0.0.159": 98 - version "0.0.159" 99 - resolved "https://registry.yarnpkg.com/@atproto/bsky/-/bsky-0.0.159.tgz#6fcfd7d6c73e4041c5abc9ac3b99dbe0e1e6cf76" 100 - integrity sha512-kRjDCW6FbByeafrEoUD5YMhhjuKTvSqrE2/QJ5xe9CP8UIhl8BShm2PcBh9gJtYc7lO83aJPqDSqb5gJwNAJUg== 97 + "@atproto/bsky@^0.0.161": 98 + version "0.0.161" 99 + resolved "https://registry.yarnpkg.com/@atproto/bsky/-/bsky-0.0.161.tgz#671280c1d40f5c4eb0cc31d338a9e950acbf0ce0" 100 + integrity sha512-L4uzadjt+oyVq3+W7rc1A+X2DyZDsTfeSD15w7k6+6JzICp32qavDuVjut3CIBqXCt7ykvSDujApyLsB/lcWJQ== 101 101 dependencies: 102 102 "@atproto-labs/fetch-node" "0.1.9" 103 103 "@atproto-labs/xrpc-utils" "0.0.16" 104 - "@atproto/api" "^0.15.15" 104 + "@atproto/api" "^0.15.16" 105 105 "@atproto/common" "^0.4.11" 106 106 "@atproto/crypto" "^0.4.4" 107 107 "@atproto/did" "^0.1.5" 108 108 "@atproto/identity" "^0.4.8" 109 109 "@atproto/lexicon" "^0.4.11" 110 - "@atproto/repo" "^0.8.1" 111 - "@atproto/sync" "^0.1.25" 110 + "@atproto/repo" "^0.8.2" 111 + "@atproto/sync" "^0.1.26" 112 112 "@atproto/syntax" "^0.4.0" 113 113 "@atproto/xrpc-server" "^0.8.0" 114 114 "@bufbuild/protobuf" "^1.5.0" ··· 218 218 "@noble/hashes" "^1.6.1" 219 219 uint8arrays "3.0.0" 220 220 221 - "@atproto/dev-env@^0.3.142": 222 - version "0.3.142" 223 - resolved "https://registry.yarnpkg.com/@atproto/dev-env/-/dev-env-0.3.142.tgz#466cff00c92d53ad148709ae50bcca816fcee1bc" 224 - integrity sha512-NiNb3Pdj93goEmKBIF5rIlLSmkfZiwnYmo7U6cGvGXoopRNG5e4Vm2PXb1n7uVdzuvEtiPtpswQxaf0x6jJsWA== 221 + "@atproto/dev-env@^0.3.144": 222 + version "0.3.144" 223 + resolved "https://registry.yarnpkg.com/@atproto/dev-env/-/dev-env-0.3.144.tgz#cd2949ff870ca4cde23b4c377b08740a2e64151f" 224 + integrity sha512-ND0oGp7itSnXxlAHlFxYjGFyCcu0f4eSucImVtKRxTcW8UeyyTtJcQP8OyNvtC8j13YjbW124r0g25Wlm0j9XQ== 225 225 dependencies: 226 - "@atproto/api" "^0.15.15" 227 - "@atproto/bsky" "^0.0.159" 226 + "@atproto/api" "^0.15.16" 227 + "@atproto/bsky" "^0.0.161" 228 228 "@atproto/bsync" "^0.0.20" 229 229 "@atproto/common-web" "^0.4.2" 230 230 "@atproto/crypto" "^0.4.4" 231 231 "@atproto/identity" "^0.4.8" 232 232 "@atproto/lexicon" "^0.4.11" 233 - "@atproto/ozone" "^0.1.120" 234 - "@atproto/pds" "^0.4.148" 235 - "@atproto/sync" "^0.1.25" 233 + "@atproto/ozone" "^0.1.121" 234 + "@atproto/pds" "^0.4.150" 235 + "@atproto/sync" "^0.1.26" 236 236 "@atproto/syntax" "^0.4.0" 237 237 "@atproto/xrpc-server" "^0.8.0" 238 238 "@did-plc/lib" "^0.0.1" ··· 308 308 optionalDependencies: 309 309 "@atproto/oauth-provider-api" "0.1.4" 310 310 311 - "@atproto/oauth-provider@^0.9.0": 312 - version "0.9.0" 313 - resolved "https://registry.yarnpkg.com/@atproto/oauth-provider/-/oauth-provider-0.9.0.tgz#3598924978c2e3d5fdf62bced54574156d15cf92" 314 - integrity sha512-LbZS9rbR5l9gVO97wJ3ls+ENXwv6BakmArRyjc5EfaQ4Xc3eLbvE629hpu9LV8LyCkBpseum0l+D+rYXsemNUw== 311 + "@atproto/oauth-provider@^0.9.1": 312 + version "0.9.1" 313 + resolved "https://registry.yarnpkg.com/@atproto/oauth-provider/-/oauth-provider-0.9.1.tgz#0147b75d1ad444455159f0a687ce87b3b49a2894" 314 + integrity sha512-2Gm3jv45cGLmUQV0C4/orCJBsHu4wajy+JTN9f/ATX3vvjnFtAd/1GRvAMKDGXtdF7VIjNFlD+4lqhoDxYJpng== 315 315 dependencies: 316 316 "@atproto-labs/fetch" "0.2.3" 317 317 "@atproto-labs/fetch-node" "0.1.9" ··· 347 347 "@atproto/jwk" "0.3.0" 348 348 zod "^3.23.8" 349 349 350 - "@atproto/ozone@^0.1.120": 351 - version "0.1.120" 352 - resolved "https://registry.yarnpkg.com/@atproto/ozone/-/ozone-0.1.120.tgz#b5c431a538558179de0465cfbfea512d65e092bf" 353 - integrity sha512-zu2f16K/z/3r4mC4z/8qISPt0j+Y0GwtjmSE+VOJvVT363iOd9a834K+QHJqnD6B3iTBHR1VPlZ/4fsZ3+4UaA== 350 + "@atproto/ozone@^0.1.121": 351 + version "0.1.121" 352 + resolved "https://registry.yarnpkg.com/@atproto/ozone/-/ozone-0.1.121.tgz#309b7e876f3b598ed4e79bb5a79e2346931588fe" 353 + integrity sha512-kc3NxiXSPqQmWz8yXlV5cFnZ469ViQd0AexEMw467AcB8ikK1WSxhLsa1EiNAQuLOOpyeXSmAKGAUFHzSOIMpw== 354 354 dependencies: 355 - "@atproto/api" "^0.15.15" 355 + "@atproto/api" "^0.15.16" 356 356 "@atproto/common" "^0.4.11" 357 357 "@atproto/crypto" "^0.4.4" 358 358 "@atproto/identity" "^0.4.8" ··· 377 377 undici "^6.14.1" 378 378 ws "^8.12.0" 379 379 380 - "@atproto/pds@^0.4.148": 381 - version "0.4.148" 382 - resolved "https://registry.yarnpkg.com/@atproto/pds/-/pds-0.4.148.tgz#7af82480e42174ea1c284f5975bf0aff3bd4da24" 383 - integrity sha512-PbxTpxRAcsdu3zANjwNH+Pfbu0pfj5z6UDmcnc3eaEP11xsExu3+B84jOYKAkIN/PbM1A9EbiBjKb95yBQxGAw== 380 + "@atproto/pds@^0.4.150": 381 + version "0.4.150" 382 + resolved "https://registry.yarnpkg.com/@atproto/pds/-/pds-0.4.150.tgz#45686b05b8ed46e265efa5231ab16e6eda72a8e8" 383 + integrity sha512-CPT6H2uDTe4ZAyxQbws2dIlmdFFf6GQGwMc0OE3kI1wBBaLHprpexjM2Gd4ObtYNxGOOV0fwoCDAth8qqZ4XVw== 384 384 dependencies: 385 385 "@atproto-labs/fetch-node" "0.1.9" 386 386 "@atproto-labs/xrpc-utils" "0.0.16" 387 - "@atproto/api" "^0.15.15" 388 - "@atproto/aws" "^0.2.21" 387 + "@atproto/api" "^0.15.16" 388 + "@atproto/aws" "^0.2.22" 389 389 "@atproto/common" "^0.4.11" 390 390 "@atproto/crypto" "^0.4.4" 391 391 "@atproto/identity" "^0.4.8" 392 392 "@atproto/lexicon" "^0.4.11" 393 - "@atproto/oauth-provider" "^0.9.0" 394 - "@atproto/repo" "^0.8.1" 393 + "@atproto/oauth-provider" "^0.9.1" 394 + "@atproto/repo" "^0.8.2" 395 395 "@atproto/syntax" "^0.4.0" 396 396 "@atproto/xrpc" "^0.7.0" 397 397 "@atproto/xrpc-server" "^0.8.0" ··· 424 424 undici "^6.19.8" 425 425 zod "^3.23.8" 426 426 427 - "@atproto/repo@^0.8.1": 428 - version "0.8.1" 429 - resolved "https://registry.yarnpkg.com/@atproto/repo/-/repo-0.8.1.tgz#be8c6b93c000944b81aaa1026d6c50d82c025d74" 430 - integrity sha512-d1NtHhXYJVJlFVI6mbVOUnpB0rnhqxPnZcALkJoYJjaDPVr4NNqRFAtrwb+GHzxT6DhijoXYQf24pKGfEFDd4g== 427 + "@atproto/repo@^0.8.2": 428 + version "0.8.2" 429 + resolved "https://registry.yarnpkg.com/@atproto/repo/-/repo-0.8.2.tgz#7953cb2c637c94505da76f74a784b2aae050c204" 430 + integrity sha512-lP0g5Uw3TUC2Tc7te8YKCpRoIhBYI+Uvn11fupGEaMcMjgLdYtB0Kc0AiqWXF42KqlBG9dAEoJITi2GRzDNHUg== 431 431 dependencies: 432 432 "@atproto/common" "^0.4.11" 433 433 "@atproto/common-web" "^0.4.2" ··· 439 439 varint "^6.0.0" 440 440 zod "^3.23.8" 441 441 442 - "@atproto/sync@^0.1.25": 443 - version "0.1.25" 444 - resolved "https://registry.yarnpkg.com/@atproto/sync/-/sync-0.1.25.tgz#66b3453e3cf0ba6a155dbbf207ea46d632c2d6b0" 445 - integrity sha512-4UsQgQsUK+hKFAEDi10Ops6n2W/kfk2JYP8AU6FSHAzOadB1hKRDJbGF5vLiLP9ACBhCzoJerZ31DCnhjzRzfw== 442 + "@atproto/sync@^0.1.26": 443 + version "0.1.26" 444 + resolved "https://registry.yarnpkg.com/@atproto/sync/-/sync-0.1.26.tgz#6be2876be612d9cd704452598ee679b2e912cfe3" 445 + integrity sha512-bpUIajtPrE3RgFW8mIfrI4EM/LJ4JjQhI5fsqc78zCHZawuflpllf1aH70roDWWiskMWoiLWnVRxdYXdeEgbXA== 446 446 dependencies: 447 447 "@atproto/common" "^0.4.11" 448 448 "@atproto/identity" "^0.4.8" 449 449 "@atproto/lexicon" "^0.4.11" 450 - "@atproto/repo" "^0.8.1" 450 + "@atproto/repo" "^0.8.2" 451 451 "@atproto/syntax" "^0.4.0" 452 452 "@atproto/xrpc-server" "^0.8.0" 453 453 multiformats "^9.9.0"