Bluesky app fork with some witchin' additions 💫

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

Changed files
+224 -553
src
components
lib
locale
locales
screens
Login
Messages
components
Profile
Header
Search
Settings
components
VideoFeed
state
queries
session
view
+58 -24
src/components/AccountList.tsx
··· 5 import {useLingui} from '@lingui/react' 6 7 import {useActorStatus} from '#/lib/actor-status' 8 import {sanitizeDisplayName} from '#/lib/strings/display-names' 9 import {sanitizeHandle} from '#/lib/strings/handles' 10 import {useProfilesQuery} from '#/state/queries/profile' 11 import {type SessionAccount, useSession} from '#/state/session' 12 import {UserAvatar} from '#/view/com/util/UserAvatar' 13 import {atoms as a, useTheme} from '#/alf' 14 - import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check' 15 - import {ChevronRight_Stroke2_Corner0_Rounded as Chevron} from '#/components/icons/Chevron' 16 import {useSimpleVerificationState} from '#/components/verification' 17 import {VerificationCheck} from '#/components/verification/VerificationCheck' 18 - import {Button} from './Button' 19 - import {Text} from './Typography' 20 21 export function AccountList({ 22 onSelectAccount, ··· 44 <View 45 pointerEvents={pendingDid ? 'none' : 'auto'} 46 style={[ 47 - a.rounded_md, 48 a.overflow_hidden, 49 - {borderWidth: 1}, 50 t.atoms.border_contrast_low, 51 ]}> 52 {accounts.map(account => ( ··· 58 isCurrentAccount={account.did === currentAccount?.did} 59 isPendingAccount={account.did === pendingDid} 60 /> 61 - <View style={[{borderBottomWidth: 1}, t.atoms.border_contrast_low]} /> 62 </React.Fragment> 63 ))} 64 <Button ··· 72 a.flex_1, 73 a.flex_row, 74 a.align_center, 75 - {height: 48}, 76 (hovered || pressed) && t.atoms.bg_contrast_25, 77 ]}> 78 - <Text 79 style={[ 80 - a.font_semi_bold, 81 - a.flex_1, 82 - a.flex_row, 83 - a.py_sm, 84 - a.leading_tight, 85 - t.atoms.text_contrast_medium, 86 - {paddingLeft: 56}, 87 ]}> 88 {otherLabel ?? <Trans>Other account</Trans>} 89 </Text> 90 - <Chevron size="sm" style={[t.atoms.text, a.mr_md]} /> 91 </View> 92 )} 93 </Button> ··· 116 const onPress = useCallback(() => { 117 onSelect(account) 118 }, [account, onSelect]) 119 120 return ( 121 <Button ··· 134 a.flex_1, 135 a.flex_row, 136 a.align_center, 137 - a.px_md, 138 a.gap_sm, 139 - {height: 56}, 140 (hovered || pressed || isPendingAccount) && t.atoms.bg_contrast_25, 141 ]}> 142 <UserAvatar 143 avatar={profile?.avatar} 144 - size={36} 145 type={profile?.associated?.labeler ? 'labeler' : 'user'} 146 live={live} 147 hideLiveBadge ··· 151 <View style={[a.flex_row, a.align_center, a.gap_xs]}> 152 <Text 153 emoji 154 - style={[a.font_semi_bold, a.leading_tight]} 155 numberOfLines={1}> 156 {sanitizeDisplayName( 157 profile?.displayName || profile?.handle || account.handle, ··· 166 </View> 167 )} 168 </View> 169 - <Text style={[a.leading_tight, t.atoms.text_contrast_medium]}> 170 {sanitizeHandle(account.handle, '@')} 171 </Text> 172 </View> 173 174 {isCurrentAccount ? ( 175 - <Check size="sm" style={[{color: t.palette.positive_500}]} /> 176 ) : ( 177 - <Chevron size="sm" style={[t.atoms.text]} /> 178 )} 179 </View> 180 )}
··· 5 import {useLingui} from '@lingui/react' 6 7 import {useActorStatus} from '#/lib/actor-status' 8 + import {isJwtExpired} from '#/lib/jwt' 9 import {sanitizeDisplayName} from '#/lib/strings/display-names' 10 import {sanitizeHandle} from '#/lib/strings/handles' 11 import {useProfilesQuery} from '#/state/queries/profile' 12 import {type SessionAccount, useSession} from '#/state/session' 13 import {UserAvatar} from '#/view/com/util/UserAvatar' 14 import {atoms as a, useTheme} from '#/alf' 15 + import {Button} from '#/components/Button' 16 + import {CheckThick_Stroke2_Corner0_Rounded as CheckIcon} from '#/components/icons/Check' 17 + import {ChevronRight_Stroke2_Corner0_Rounded as ChevronIcon} from '#/components/icons/Chevron' 18 + import {PlusLarge_Stroke2_Corner0_Rounded as PlusIcon} from '#/components/icons/Plus' 19 + import {Text} from '#/components/Typography' 20 import {useSimpleVerificationState} from '#/components/verification' 21 import {VerificationCheck} from '#/components/verification/VerificationCheck' 22 23 export function AccountList({ 24 onSelectAccount, ··· 46 <View 47 pointerEvents={pendingDid ? 'none' : 'auto'} 48 style={[ 49 + a.rounded_lg, 50 a.overflow_hidden, 51 + a.border, 52 t.atoms.border_contrast_low, 53 ]}> 54 {accounts.map(account => ( ··· 60 isCurrentAccount={account.did === currentAccount?.did} 61 isPendingAccount={account.did === pendingDid} 62 /> 63 + <View style={[a.border_b, t.atoms.border_contrast_low]} /> 64 </React.Fragment> 65 ))} 66 <Button ··· 74 a.flex_1, 75 a.flex_row, 76 a.align_center, 77 + a.p_lg, 78 + a.gap_sm, 79 (hovered || pressed) && t.atoms.bg_contrast_25, 80 ]}> 81 + <View 82 style={[ 83 + t.atoms.bg_contrast_25, 84 + a.rounded_full, 85 + {width: 48, height: 48}, 86 + a.justify_center, 87 + a.align_center, 88 + (hovered || pressed) && t.atoms.bg_contrast_50, 89 ]}> 90 + <PlusIcon style={[t.atoms.text_contrast_low]} size="md" /> 91 + </View> 92 + <Text style={[a.flex_1, a.leading_tight, a.text_md, a.font_medium]}> 93 {otherLabel ?? <Trans>Other account</Trans>} 94 </Text> 95 + <ChevronIcon size="md" style={[t.atoms.text_contrast_low]} /> 96 </View> 97 )} 98 </Button> ··· 121 const onPress = useCallback(() => { 122 onSelect(account) 123 }, [account, onSelect]) 124 + 125 + const isLoggedOut = !account.refreshJwt || isJwtExpired(account.refreshJwt) 126 127 return ( 128 <Button ··· 141 a.flex_1, 142 a.flex_row, 143 a.align_center, 144 + a.p_lg, 145 a.gap_sm, 146 (hovered || pressed || isPendingAccount) && t.atoms.bg_contrast_25, 147 ]}> 148 <UserAvatar 149 avatar={profile?.avatar} 150 + size={48} 151 type={profile?.associated?.labeler ? 'labeler' : 'user'} 152 live={live} 153 hideLiveBadge ··· 157 <View style={[a.flex_row, a.align_center, a.gap_xs]}> 158 <Text 159 emoji 160 + style={[a.font_medium, a.leading_tight, a.text_md]} 161 numberOfLines={1}> 162 {sanitizeDisplayName( 163 profile?.displayName || profile?.handle || account.handle, ··· 172 </View> 173 )} 174 </View> 175 + <Text 176 + style={[ 177 + a.leading_tight, 178 + t.atoms.text_contrast_medium, 179 + a.text_sm, 180 + ]}> 181 {sanitizeHandle(account.handle, '@')} 182 </Text> 183 + {isLoggedOut && ( 184 + <Text 185 + style={[ 186 + a.leading_tight, 187 + a.text_xs, 188 + a.italic, 189 + t.atoms.text_contrast_medium, 190 + ]}> 191 + <Trans>Logged out</Trans> 192 + </Text> 193 + )} 194 </View> 195 196 {isCurrentAccount ? ( 197 + <View 198 + style={[ 199 + { 200 + width: 20, 201 + height: 20, 202 + backgroundColor: t.palette.positive_500, 203 + }, 204 + a.rounded_full, 205 + a.justify_center, 206 + a.align_center, 207 + ]}> 208 + <CheckIcon size="xs" style={[{color: t.palette.white}]} /> 209 + </View> 210 ) : ( 211 + <ChevronIcon size="md" style={[t.atoms.text_contrast_low]} /> 212 )} 213 </View> 214 )}
+3 -6
src/components/Button.tsx
··· 435 436 if (shape === 'default') { 437 if (size === 'large') { 438 - baseStyles.push({ 439 paddingVertical: 12, 440 paddingHorizontal: 25, 441 - borderRadius: 10, 442 gap: 3, 443 }) 444 } else if (size === 'small') { 445 - baseStyles.push({ 446 paddingVertical: 8, 447 paddingHorizontal: 13, 448 - borderRadius: 8, 449 gap: 3, 450 }) 451 } else if (size === 'tiny') { 452 - baseStyles.push({ 453 paddingVertical: 5, 454 paddingHorizontal: 9, 455 - borderRadius: 6, 456 gap: 2, 457 }) 458 }
··· 435 436 if (shape === 'default') { 437 if (size === 'large') { 438 + baseStyles.push(a.rounded_full, { 439 paddingVertical: 12, 440 paddingHorizontal: 25, 441 gap: 3, 442 }) 443 } else if (size === 'small') { 444 + baseStyles.push(a.rounded_full, { 445 paddingVertical: 8, 446 paddingHorizontal: 13, 447 gap: 3, 448 }) 449 } else if (size === 'tiny') { 450 + baseStyles.push(a.rounded_full, { 451 paddingVertical: 5, 452 paddingHorizontal: 9, 453 gap: 2, 454 }) 455 }
-1
src/components/Layout/Header/index.tsx
··· 129 size="small" 130 variant="ghost" 131 color="secondary" 132 - shape="square" 133 onPress={onPressBack} 134 hitSlop={HITSLOP_30} 135 style={[
··· 129 size="small" 130 variant="ghost" 131 color="secondary" 132 onPress={onPressBack} 133 hitSlop={HITSLOP_30} 134 style={[
+1 -2
src/components/PostControls/RepostButton.tsx
··· 204 label={_(msg`Cancel quote post`)} 205 onPress={onPressClose} 206 size="large" 207 - variant="outline" 208 - color="primary"> 209 <ButtonText> 210 <Trans>Cancel</Trans> 211 </ButtonText>
··· 204 label={_(msg`Cancel quote post`)} 205 onPress={onPressClose} 206 size="large" 207 + color="secondary"> 208 <ButtonText> 209 <Trans>Cancel</Trans> 210 </ButtonText>
+2 -2
src/components/ageAssurance/AgeAssuranceAppealDialog.tsx
··· 1 import React from 'react' 2 import {View} from 'react-native' 3 - import {ComAtprotoModerationDefs} from '@atproto/api' 4 import {msg, Trans} from '@lingui/macro' 5 import {useLingui} from '@lingui/react' 6 import {useMutation} from '@tanstack/react-query' ··· 50 51 await agent.createModerationReport( 52 { 53 - reasonType: ComAtprotoModerationDefs.REASONAPPEAL, 54 subject: { 55 $type: 'com.atproto.admin.defs#repoRef', 56 did: currentAccount?.did,
··· 1 import React from 'react' 2 import {View} from 'react-native' 3 + import {ToolsOzoneReportDefs} from '@atproto/api' 4 import {msg, Trans} from '@lingui/macro' 5 import {useLingui} from '@lingui/react' 6 import {useMutation} from '@tanstack/react-query' ··· 50 51 await agent.createModerationReport( 52 { 53 + reasonType: ToolsOzoneReportDefs.REASONAPPEAL, 54 subject: { 55 $type: 'com.atproto.admin.defs#repoRef', 56 did: currentAccount?.did,
+1 -1
src/components/dialogs/SwitchAccount.tsx
··· 41 }, [setShowLoggedOut, control]) 42 43 return ( 44 - <Dialog.Outer control={control}> 45 <Dialog.Handle /> 46 <Dialog.ScrollableInner label={_(msg`Switch Account`)}> 47 <View style={[a.gap_lg]}>
··· 41 }, [setShowLoggedOut, control]) 42 43 return ( 44 + <Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}> 45 <Dialog.Handle /> 46 <Dialog.ScrollableInner label={_(msg`Switch Account`)}> 47 <View style={[a.gap_lg]}>
+2 -2
src/components/dms/AfterReportDialog.tsx
··· 46 <Dialog.Handle /> 47 <Dialog.ScrollableInner 48 label={_( 49 - msg`Would you like to block this account or delete this conversation?`, 50 )} 51 style={[web({maxWidth: 400})]}> 52 <DialogInner params={params} currentScreen={currentScreen} /> ··· 177 </Text> 178 </View> 179 <Toggle.Group 180 - label={_(msg`Block and/or delete this conversation`)} 181 values={actions} 182 onChange={setActions}> 183 <View style={[a.gap_md]}>
··· 46 <Dialog.Handle /> 47 <Dialog.ScrollableInner 48 label={_( 49 + msg`Would you like to block this user and/or delete this conversation?`, 50 )} 51 style={[web({maxWidth: 400})]}> 52 <DialogInner params={params} currentScreen={currentScreen} /> ··· 177 </Text> 178 </View> 179 <Toggle.Group 180 + label={_(msg`Block user and/or delete this conversation`)} 181 values={actions} 182 onChange={setActions}> 183 <View style={[a.gap_md]}>
+2 -2
src/components/moderation/LabelsOnMeDialog.tsx
··· 1 import React, {useState} from 'react' 2 import {View} from 'react-native' 3 - import {type ComAtprotoLabelDefs, ComAtprotoModerationDefs} from '@atproto/api' 4 import {XRPCError} from '@atproto/xrpc' 5 import {msg, Trans} from '@lingui/macro' 6 import {useLingui} from '@lingui/react' ··· 239 : 'com.atproto.admin.defs#repoRef' 240 await agent.createModerationReport( 241 { 242 - reasonType: ComAtprotoModerationDefs.REASONAPPEAL, 243 subject: { 244 $type, 245 ...subject,
··· 1 import React, {useState} from 'react' 2 import {View} from 'react-native' 3 + import {type ComAtprotoLabelDefs, ToolsOzoneReportDefs} from '@atproto/api' 4 import {XRPCError} from '@atproto/xrpc' 5 import {msg, Trans} from '@lingui/macro' 6 import {useLingui} from '@lingui/react' ··· 239 : 'com.atproto.admin.defs#repoRef' 240 await agent.createModerationReport( 241 { 242 + reasonType: ToolsOzoneReportDefs.REASONAPPEAL, 243 subject: { 244 $type, 245 ...subject,
+23
src/lib/jwt.ts
···
··· 1 + import {jwtDecode} from 'jwt-decode' 2 + 3 + import {logger} from '#/logger' 4 + 5 + /** 6 + * Simple check if a JWT token has expired. Does *not* validate the token or check for revocation status, 7 + * just checks the expiration time. 8 + * 9 + * @param token The JWT token to check. 10 + * @returns `true` if the token has expired, `false` otherwise. 11 + */ 12 + export function isJwtExpired(token: string) { 13 + try { 14 + const payload = jwtDecode(token) 15 + 16 + if (!payload.exp) return true 17 + const now = Math.floor(Date.now() / 1000) 18 + return now >= payload.exp 19 + } catch { 20 + logger.error(`session: could not decode jwt`) 21 + return true // invalid token or parse error 22 + } 23 + }
-122
src/lib/moderation/useReportOptions.ts
··· 1 - import {useMemo} from 'react' 2 - import {ComAtprotoModerationDefs} from '@atproto/api' 3 - import {msg} from '@lingui/macro' 4 - import {useLingui} from '@lingui/react' 5 - 6 - export interface ReportOption { 7 - reason: string 8 - title: string 9 - description: string 10 - } 11 - 12 - interface ReportOptions { 13 - account: ReportOption[] 14 - post: ReportOption[] 15 - list: ReportOption[] 16 - starterpack: ReportOption[] 17 - feedgen: ReportOption[] 18 - other: ReportOption[] 19 - convoMessage: ReportOption[] 20 - } 21 - 22 - export function useReportOptions(): ReportOptions { 23 - const {_} = useLingui() 24 - return useMemo(() => { 25 - const other = { 26 - reason: ComAtprotoModerationDefs.REASONOTHER, 27 - title: _(msg`Other`), 28 - description: _(msg`An issue not included in these options`), 29 - } 30 - const common = [ 31 - { 32 - reason: ComAtprotoModerationDefs.REASONRUDE, 33 - title: _(msg`Anti-Social Behavior`), 34 - description: _(msg`Harassment, trolling, or intolerance`), 35 - }, 36 - { 37 - reason: ComAtprotoModerationDefs.REASONVIOLATION, 38 - title: _(msg`Illegal and Urgent`), 39 - description: _(msg`Glaring violations of law or terms of service`), 40 - }, 41 - other, 42 - ] 43 - return { 44 - account: [ 45 - { 46 - reason: ComAtprotoModerationDefs.REASONMISLEADING, 47 - title: _(msg`Misleading Account`), 48 - description: _( 49 - msg`Impersonation or false claims about identity or affiliation`, 50 - ), 51 - }, 52 - { 53 - reason: ComAtprotoModerationDefs.REASONSPAM, 54 - title: _(msg`Frequently Posts Unwanted Content`), 55 - description: _(msg`Spam; excessive mentions or replies`), 56 - }, 57 - { 58 - reason: ComAtprotoModerationDefs.REASONVIOLATION, 59 - title: _(msg`Name or Description Violates Community Standards`), 60 - description: _(msg`Terms used violate community standards`), 61 - }, 62 - other, 63 - ], 64 - post: [ 65 - { 66 - reason: ComAtprotoModerationDefs.REASONMISLEADING, 67 - title: _(msg`Misleading Post`), 68 - description: _(msg`Impersonation, misinformation, or false claims`), 69 - }, 70 - { 71 - reason: ComAtprotoModerationDefs.REASONSPAM, 72 - title: _(msg`Spam`), 73 - description: _(msg`Excessive mentions or replies`), 74 - }, 75 - { 76 - reason: ComAtprotoModerationDefs.REASONSEXUAL, 77 - title: _(msg`Unwanted Sexual Content`), 78 - description: _(msg`Nudity or adult content not labeled as such`), 79 - }, 80 - ...common, 81 - ], 82 - convoMessage: [ 83 - { 84 - reason: ComAtprotoModerationDefs.REASONSPAM, 85 - title: _(msg`Spam`), 86 - description: _(msg`Excessive or unwanted messages`), 87 - }, 88 - { 89 - reason: ComAtprotoModerationDefs.REASONSEXUAL, 90 - title: _(msg`Unwanted Sexual Content`), 91 - description: _(msg`Inappropriate messages or explicit links`), 92 - }, 93 - ...common, 94 - ], 95 - list: [ 96 - { 97 - reason: ComAtprotoModerationDefs.REASONVIOLATION, 98 - title: _(msg`Name or Description Violates Community Standards`), 99 - description: _(msg`Terms used violate community standards`), 100 - }, 101 - ...common, 102 - ], 103 - starterpack: [ 104 - { 105 - reason: ComAtprotoModerationDefs.REASONVIOLATION, 106 - title: _(msg`Name or Description Violates Community Standards`), 107 - description: _(msg`Terms used violate community standards`), 108 - }, 109 - ...common, 110 - ], 111 - feedgen: [ 112 - { 113 - reason: ComAtprotoModerationDefs.REASONVIOLATION, 114 - title: _(msg`Name or Description Violates Community Standards`), 115 - description: _(msg`Terms used violate community standards`), 116 - }, 117 - ...common, 118 - ], 119 - other: common, 120 - } 121 - }, [_]) 122 - }
···
+89 -181
src/locale/locales/en/messages.po
··· 1047 msgstr "" 1048 1049 #: src/components/moderation/ReportDialog/utils/useReportOptions.ts:239 1050 - #: src/lib/moderation/useReportOptions.ts:28 1051 msgid "An issue not included in these options" 1052 msgstr "" 1053 ··· 1063 #: src/components/hooks/useFollowMethods.ts:50 1064 #: src/components/ProfileCard.tsx:484 1065 #: src/components/ProfileCard.tsx:505 1066 - #: src/view/com/profile/FollowButton.tsx:38 1067 - #: src/view/com/profile/FollowButton.tsx:48 1068 msgid "An issue occurred, please try again." 1069 msgstr "" 1070 ··· 1105 1106 #: src/components/dialogs/nuxs/InitialVerificationAnnouncement.tsx:37 1107 msgid "Announcing verification on Bluesky" 1108 - msgstr "" 1109 - 1110 - #: src/lib/moderation/useReportOptions.ts:33 1111 - msgid "Anti-Social Behavior" 1112 msgstr "" 1113 1114 #: src/view/com/composer/threadgate/ThreadgateBtn.tsx:48 ··· 1304 1305 #: src/components/moderation/LabelsOnMeDialog.tsx:333 1306 #: src/components/moderation/LabelsOnMeDialog.tsx:334 1307 - #: src/screens/Login/ChooseAccountForm.tsx:90 1308 - #: src/screens/Login/ChooseAccountForm.tsx:95 1309 #: src/screens/Login/ForgotPasswordForm.tsx:123 1310 #: src/screens/Login/ForgotPasswordForm.tsx:129 1311 #: src/screens/Login/LoginForm.tsx:310 ··· 1412 msgid "Block and Delete" 1413 msgstr "" 1414 1415 - #: src/components/dms/AfterReportDialog.tsx:180 1416 - msgid "Block and/or delete this conversation" 1417 - msgstr "" 1418 - 1419 #: src/screens/ProfileList/components/SubscribeMenu.tsx:125 1420 msgid "Block list" 1421 msgstr "" ··· 1437 msgid "Block User" 1438 msgstr "" 1439 1440 #: src/components/Post/Embed/index.tsx:186 1441 msgid "Blocked" 1442 msgstr "" ··· 1592 #: src/components/LabelingServiceCard/index.tsx:62 1593 #: src/components/moderation/ReportDialog/index.tsx:834 1594 #: src/screens/Search/components/StarterPackCard.tsx:106 1595 - #: src/screens/Search/Explore.tsx:937 1596 msgid "By {0}" 1597 msgstr "" 1598 1599 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:451 1600 msgid "By <0>{0}</0>" 1601 msgstr "" 1602 ··· 1642 #: src/components/live/GoLiveDialog.tsx:244 1643 #: src/components/live/GoLiveDialog.tsx:250 1644 #: src/components/Menu/index.tsx:350 1645 - #: src/components/PostControls/RepostButton.tsx:210 1646 #: src/components/Prompt.tsx:144 1647 #: src/components/Prompt.tsx:146 1648 #: src/screens/Deactivated.tsx:158 ··· 2260 msgid "Continue" 2261 msgstr "" 2262 2263 - #: src/components/AccountList.tsx:128 2264 msgid "Continue as {0} (currently signed in)" 2265 msgstr "" 2266 ··· 2839 msgid "Discover new custom feeds" 2840 msgstr "" 2841 2842 - #: src/screens/Search/Explore.tsx:432 2843 #: src/view/screens/Feeds.tsx:730 2844 msgid "Discover New Feeds" 2845 msgstr "" ··· 2951 msgid "Double tap to close the dialog" 2952 msgstr "" 2953 2954 - #: src/screens/VideoFeed/index.tsx:1087 2955 msgid "Double tap to like" 2956 msgstr "" 2957 ··· 3351 msgid "Everything else" 3352 msgstr "" 3353 3354 - #: src/lib/moderation/useReportOptions.ts:73 3355 - msgid "Excessive mentions or replies" 3356 - msgstr "" 3357 - 3358 - #: src/lib/moderation/useReportOptions.ts:86 3359 - msgid "Excessive or unwanted messages" 3360 - msgstr "" 3361 - 3362 #: src/components/dialogs/MutedWords.tsx:316 3363 msgid "Exclude users you follow" 3364 msgstr "" ··· 3395 msgid "Expand post text" 3396 msgstr "" 3397 3398 - #: src/screens/VideoFeed/index.tsx:972 3399 msgid "Expands or collapses post text" 3400 msgstr "" 3401 ··· 3536 msgid "Failed to load conversations" 3537 msgstr "" 3538 3539 - #: src/screens/Search/Explore.tsx:468 3540 - #: src/screens/Search/Explore.tsx:520 3541 - #: src/screens/Search/Explore.tsx:558 3542 - #: src/screens/Search/Explore.tsx:597 3543 msgid "Failed to load feeds preferences" 3544 msgstr "" 3545 ··· 3569 msgid "Failed to load preference." 3570 msgstr "" 3571 3572 - #: src/screens/Search/Explore.tsx:461 3573 - #: src/screens/Search/Explore.tsx:513 3574 - #: src/screens/Search/Explore.tsx:551 3575 - #: src/screens/Search/Explore.tsx:590 3576 msgid "Failed to load suggested feeds" 3577 msgstr "" 3578 3579 - #: src/screens/Search/Explore.tsx:371 3580 msgid "Failed to load suggested follows" 3581 msgstr "" 3582 ··· 3703 msgid "Feed identifier" 3704 msgstr "" 3705 3706 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:354 3707 msgid "Feed menu" 3708 msgstr "" 3709 ··· 3846 #: src/components/ProfileHoverCard/index.web.tsx:507 3847 #: src/screens/PostThread/components/ThreadItemAnchorFollowButton.tsx:131 3848 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:258 3849 - #: src/screens/VideoFeed/index.tsx:856 3850 - msgid "Follow" 3851 - msgstr "" 3852 - 3853 - #: src/view/com/profile/FollowButton.tsx:72 3854 - msgctxt "action" 3855 msgid "Follow" 3856 msgstr "" 3857 ··· 3860 msgid "Follow {0}" 3861 msgstr "" 3862 3863 - #: src/screens/VideoFeed/index.tsx:833 3864 msgid "Follow {handle}" 3865 msgstr "" 3866 ··· 3897 msgid "Follow back" 3898 msgstr "" 3899 3900 - #: src/view/com/profile/FollowButton.tsx:81 3901 - msgctxt "action" 3902 - msgid "Follow back" 3903 - msgstr "" 3904 - 3905 #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:113 3906 msgid "Followed all accounts!" 3907 msgstr "" ··· 3937 #: src/components/ProfileHoverCard/index.web.tsx:506 3938 #: src/screens/PostThread/components/ThreadItemAnchorFollowButton.tsx:134 3939 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:254 3940 - #: src/screens/VideoFeed/index.tsx:854 3941 msgid "Following" 3942 msgstr "" 3943 ··· 3952 msgid "Following {0}" 3953 msgstr "" 3954 3955 - #: src/screens/VideoFeed/index.tsx:832 3956 msgid "Following {handle}" 3957 msgstr "" 3958 ··· 4031 4032 #: src/screens/Onboarding/StepFinished/ValuePropositionPager.shared.tsx:12 4033 msgid "Free your feed" 4034 - msgstr "" 4035 - 4036 - #: src/lib/moderation/useReportOptions.ts:54 4037 - msgid "Frequently Posts Unwanted Content" 4038 msgstr "" 4039 4040 #: src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx:157 ··· 4131 msgid "Give your profile a face" 4132 msgstr "" 4133 4134 - #: src/lib/moderation/useReportOptions.ts:39 4135 - msgid "Glaring violations of law or terms of service" 4136 - msgstr "" 4137 - 4138 #: src/components/moderation/ReportDialog/utils/useReportOptions.ts:142 4139 msgid "Glorification of violence" 4140 msgstr "" ··· 4149 #: src/screens/ProfileList/components/ErrorScreen.tsx:34 4150 #: src/screens/ProfileList/components/ErrorScreen.tsx:40 4151 #: src/screens/VideoFeed/components/Header.tsx:163 4152 - #: src/screens/VideoFeed/index.tsx:1148 4153 - #: src/screens/VideoFeed/index.tsx:1152 4154 #: src/view/com/auth/LoggedOut.tsx:72 4155 #: src/view/screens/NotFound.tsx:57 4156 msgid "Go back" ··· 4285 msgid "Harassment or hate" 4286 msgstr "" 4287 4288 - #: src/lib/moderation/useReportOptions.ts:34 4289 - msgid "Harassment, trolling, or intolerance" 4290 - msgstr "" 4291 - 4292 #: src/components/moderation/ReportDialog/utils/useReportOptions.ts:189 4293 msgid "Harmful or high-risk activities" 4294 msgstr "" ··· 4344 msgid "Hidden" 4345 msgstr "" 4346 4347 - #: src/screens/VideoFeed/index.tsx:630 4348 msgid "Hidden by your moderation settings." 4349 msgstr "" 4350 ··· 4553 msgid "If you're trying to change your handle or email, do so before you deactivate." 4554 msgstr "" 4555 4556 - #: src/lib/moderation/useReportOptions.ts:38 4557 - msgid "Illegal and Urgent" 4558 - msgstr "" 4559 - 4560 #: src/view/com/util/images/Gallery.tsx:75 4561 msgid "Image" 4562 msgstr "" ··· 4583 msgid "Impersonation" 4584 msgstr "" 4585 4586 - #: src/lib/moderation/useReportOptions.ts:49 4587 - msgid "Impersonation or false claims about identity or affiliation" 4588 - msgstr "" 4589 - 4590 - #: src/lib/moderation/useReportOptions.ts:68 4591 - msgid "Impersonation, misinformation, or false claims" 4592 - msgstr "" 4593 - 4594 #: src/screens/Settings/NotificationSettings/index.tsx:284 4595 msgid "In-app" 4596 msgstr "" ··· 4617 4618 #: src/screens/Settings/NotificationSettings/index.tsx:273 4619 msgid "In-app, Push, People you follow" 4620 - msgstr "" 4621 - 4622 - #: src/lib/moderation/useReportOptions.ts:91 4623 - msgid "Inappropriate messages or explicit links" 4624 msgstr "" 4625 4626 #. Title message shown in chat requests inbox when it's empty ··· 4944 msgid "Light" 4945 msgstr "" 4946 4947 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:518 4948 msgid "Like" 4949 msgstr "" 4950 ··· 4966 msgid "Like notifications" 4967 msgstr "" 4968 4969 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:505 4970 msgid "Like this feed" 4971 msgstr "" 4972 ··· 4991 msgstr "" 4992 4993 #: src/components/LabelingServiceCard/index.tsx:96 4994 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:493 4995 #: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:290 4996 #: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:304 4997 msgid "Liked by {likeCount, plural, one {# user} other {# users}}" ··· 5132 msgid "Live link" 5133 msgstr "" 5134 5135 - #: src/screens/Search/Explore.tsx:84 5136 msgid "Load more" 5137 msgstr "" 5138 5139 - #: src/screens/Search/Explore.tsx:502 5140 - #: src/screens/Search/Explore.tsx:579 5141 msgid "Load more suggested feeds" 5142 msgstr "" 5143 ··· 5158 5159 #: src/Navigation.tsx:321 5160 msgid "Log" 5161 msgstr "" 5162 5163 #: src/screens/Settings/PrivacyAndSecuritySettings.tsx:106 ··· 5325 msgid "Misleading" 5326 msgstr "" 5327 5328 - #: src/lib/moderation/useReportOptions.ts:47 5329 - msgid "Misleading Account" 5330 - msgstr "" 5331 - 5332 - #: src/lib/moderation/useReportOptions.ts:67 5333 - msgid "Misleading Post" 5334 - msgstr "" 5335 - 5336 #: src/Navigation.tsx:177 5337 #: src/screens/Moderation/index.tsx:100 5338 #: src/screens/Settings/Settings.tsx:188 ··· 5536 5537 #: src/components/dialogs/lists/CreateOrEditListDialog.tsx:399 5538 msgid "Name" 5539 - msgstr "" 5540 - 5541 - #: src/lib/moderation/useReportOptions.ts:59 5542 - #: src/lib/moderation/useReportOptions.ts:98 5543 - #: src/lib/moderation/useReportOptions.ts:106 5544 - #: src/lib/moderation/useReportOptions.ts:114 5545 - msgid "Name or Description Violates Community Standards" 5546 msgstr "" 5547 5548 #: src/lib/interests.ts:66 ··· 5585 msgid "New" 5586 msgstr "" 5587 5588 - #: src/view/screens/Lists.tsx:79 5589 #: src/view/screens/ModerationModlists.tsx:79 5590 msgctxt "action" 5591 msgid "New" ··· 5805 msgid "No results" 5806 msgstr "" 5807 5808 - #: src/screens/Search/Explore.tsx:794 5809 msgid "No results for \"{0}\"." 5810 msgstr "" 5811 ··· 5823 msgid "No results found for {query}" 5824 msgstr "" 5825 5826 - #: src/screens/Search/Explore.tsx:798 5827 msgid "No results." 5828 msgstr "" 5829 ··· 5956 msgid "Nudity" 5957 msgstr "" 5958 5959 - #: src/lib/moderation/useReportOptions.ts:78 5960 - msgid "Nudity or adult content not labeled as such" 5961 - msgstr "" 5962 - 5963 #: src/lib/moderation/useLabelBehaviorDescription.ts:14 5964 #: src/screens/Settings/NotificationSettings/index.tsx:291 5965 msgid "Off" ··· 6067 msgid "Open conversation options" 6068 msgstr "" 6069 6070 - #: src/components/Layout/Header/index.tsx:160 6071 msgid "Open drawer menu" 6072 msgstr "" 6073 ··· 6080 msgid "Open feed info screen" 6081 msgstr "" 6082 6083 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:291 6084 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:296 6085 msgid "Open feed options menu" 6086 msgstr "" 6087 ··· 6249 6250 #: src/components/moderation/ReportDialog/utils/useReportOptions.ts:238 6251 #: src/components/moderation/ReportDialog/utils/useReportOptions.ts:242 6252 - #: src/lib/moderation/useReportOptions.ts:27 6253 #: src/view/com/composer/labels/LabelsBtn.tsx:185 6254 msgid "Other" 6255 msgstr "" 6256 6257 - #: src/components/AccountList.tsx:88 6258 msgid "Other account" 6259 msgstr "" 6260 ··· 6383 msgid "Pictures meant for adults." 6384 msgstr "" 6385 6386 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:523 6387 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:530 6388 #: src/screens/SavedFeeds.tsx:351 6389 msgid "Pin feed" 6390 msgstr "" ··· 6398 msgid "Pin to home" 6399 msgstr "" 6400 6401 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:337 6402 msgid "Pin to Home" 6403 msgstr "" 6404 ··· 6647 #: src/screens/PostThread/components/ThreadItemAnchor.tsx:134 6648 #: src/screens/PostThread/components/ThreadItemPost.tsx:112 6649 #: src/screens/PostThread/components/ThreadItemTreePost.tsx:108 6650 - #: src/screens/VideoFeed/index.tsx:534 6651 msgid "Post has been deleted" 6652 msgstr "" 6653 ··· 6940 msgid "Read blog post" 6941 msgstr "" 6942 6943 - #: src/screens/VideoFeed/index.tsx:973 6944 msgid "Read less" 6945 msgstr "" 6946 6947 - #: src/screens/VideoFeed/index.tsx:973 6948 msgid "Read more" 6949 msgstr "" 6950 ··· 7077 msgid "Remove feed?" 7078 msgstr "" 7079 7080 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:319 7081 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:325 7082 #: src/screens/ProfileList/components/MoreOptionsMenu.tsx:181 7083 #: src/screens/ProfileList/components/MoreOptionsMenu.tsx:184 7084 #: src/screens/SavedFeeds.tsx:340 ··· 7296 msgid "Report dialog" 7297 msgstr "" 7298 7299 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:546 7300 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:552 7301 msgid "Report feed" 7302 msgstr "" 7303 ··· 7523 #: src/screens/Profile/ProfileFeed/index.tsx:93 7524 #: src/screens/ProfileList/components/ErrorScreen.tsx:35 7525 #: src/screens/Settings/components/ChangeHandleDialog.tsx:569 7526 - #: src/screens/VideoFeed/index.tsx:1149 7527 #: src/view/screens/NotFound.tsx:60 7528 msgid "Returns to previous page" 7529 msgstr "" ··· 7582 msgid "Save QR code" 7583 msgstr "" 7584 7585 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:320 7586 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:326 7587 msgid "Save to my feeds" 7588 msgstr "" 7589 ··· 7680 msgid "Search for feeds that you want to suggest to others." 7681 msgstr "" 7682 7683 - #: src/screens/Search/Explore.tsx:358 7684 msgid "Search for more accounts" 7685 msgstr "" 7686 7687 - #: src/screens/Search/Explore.tsx:435 7688 msgid "Search for more feeds" 7689 msgstr "" 7690 ··· 8112 msgid "Share QR code" 8113 msgstr "" 8114 8115 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:474 8116 msgid "Share this feed" 8117 msgstr "" 8118 ··· 8156 #: src/components/moderation/ScreenHider.tsx:178 8157 #: src/components/moderation/ScreenHider.tsx:181 8158 #: src/screens/List/ListHiddenScreen.tsx:190 8159 - #: src/screens/VideoFeed/index.tsx:633 8160 - #: src/screens/VideoFeed/index.tsx:639 8161 msgid "Show anyway" 8162 msgstr "" 8163 ··· 8272 msgid "Sign in" 8273 msgstr "" 8274 8275 - #: src/components/AccountList.tsx:129 8276 msgid "Sign in as {0}" 8277 msgstr "" 8278 8279 - #: src/screens/Login/ChooseAccountForm.tsx:80 8280 msgid "Sign in as..." 8281 msgstr "" 8282 ··· 8289 msgid "Sign in or create your account to join the conversation!" 8290 msgstr "" 8291 8292 - #: src/components/AccountList.tsx:68 8293 msgid "Sign in to account that is not listed" 8294 msgstr "" 8295 ··· 8425 msgid "Something went wrong. Please try again." 8426 msgstr "" 8427 8428 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:542 8429 msgid "Something wrong? Let us know." 8430 msgstr "" 8431 ··· 8456 msgstr "" 8457 8458 #: src/components/moderation/ReportDialog/utils/useReportOptions.ts:39 8459 - #: src/lib/moderation/useReportOptions.ts:72 8460 - #: src/lib/moderation/useReportOptions.ts:85 8461 msgid "Spam" 8462 msgstr "" 8463 ··· 8465 msgid "Spam or other inauthentic behavior or deception" 8466 msgstr "" 8467 8468 - #: src/lib/moderation/useReportOptions.ts:55 8469 - msgid "Spam; excessive mentions or replies" 8470 - msgstr "" 8471 - 8472 #: src/lib/interests.ts:72 8473 #: src/screens/Onboarding/index.tsx:58 8474 #: src/screens/Search/modules/ExploreTrendingTopics.tsx:230 ··· 8520 msgid "Starter pack is invalid" 8521 msgstr "" 8522 8523 - #: src/screens/Search/Explore.tsx:626 8524 #: src/view/screens/Profile.tsx:231 8525 msgid "Starter Packs" 8526 msgstr "" ··· 8607 msgid "Successfully verified" 8608 msgstr "" 8609 8610 - #: src/screens/Search/Explore.tsx:355 8611 msgid "Suggested Accounts" 8612 msgstr "" 8613 ··· 8754 msgid "Terms of Service" 8755 msgstr "" 8756 8757 - #: src/lib/moderation/useReportOptions.ts:60 8758 - #: src/lib/moderation/useReportOptions.ts:99 8759 - #: src/lib/moderation/useReportOptions.ts:107 8760 - #: src/lib/moderation/useReportOptions.ts:115 8761 - msgid "Terms used violate community standards" 8762 - msgstr "" 8763 - 8764 #: src/components/dialogs/MutedWords.tsx:271 8765 msgid "Text & tags" 8766 msgstr "" ··· 8804 msgid "That's all, folks!" 8805 msgstr "" 8806 8807 - #: src/screens/VideoFeed/index.tsx:1121 8808 msgid "That's everything!" 8809 msgstr "" 8810 ··· 8932 msgid "There was an issue contacting the server" 8933 msgstr "" 8934 8935 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:418 8936 #: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:109 8937 msgid "There was an issue contacting the server, please check your internet connection and try again." 8938 msgstr "" ··· 8941 msgid "There was an issue fetching notifications. Tap here to try again." 8942 msgstr "" 8943 8944 - #: src/screens/Search/Explore.tsx:993 8945 #: src/view/com/posts/PostFeed.tsx:712 8946 msgid "There was an issue fetching posts. Tap here to try again." 8947 msgstr "" ··· 9473 msgid "Undo repost ({0, plural, one {# repost} other {# reposts}})" 9474 msgstr "" 9475 9476 - #: src/view/com/profile/FollowButton.tsx:63 9477 - msgctxt "action" 9478 - msgid "Unfollow" 9479 - msgstr "" 9480 - 9481 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:242 9482 msgid "Unfollow {0}" 9483 msgstr "" ··· 9487 msgid "Unfollow account" 9488 msgstr "" 9489 9490 - #: src/screens/VideoFeed/index.tsx:837 9491 msgid "Unfollows the user" 9492 msgstr "" 9493 ··· 9511 msgid "Unlabeled, abusive, or non-consensual adult content" 9512 msgstr "" 9513 9514 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:518 9515 msgid "Unlike" 9516 msgstr "" 9517 ··· 9566 msgid "Unpin" 9567 msgstr "" 9568 9569 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:523 9570 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:530 9571 #: src/screens/SavedFeeds.tsx:351 9572 msgid "Unpin feed" 9573 msgstr "" ··· 9576 msgid "Unpin Feed" 9577 msgstr "" 9578 9579 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:310 9580 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:312 9581 msgid "Unpin from home" 9582 msgstr "" 9583 ··· 9627 9628 #: src/view/com/composer/Composer.tsx:895 9629 msgid "Unsupported video type: {mimeType}" 9630 - msgstr "" 9631 - 9632 - #: src/lib/moderation/useReportOptions.ts:77 9633 - #: src/lib/moderation/useReportOptions.ts:90 9634 - msgid "Unwanted Sexual Content" 9635 msgstr "" 9636 9637 #: src/screens/Settings/components/OTAInfo.tsx:58 ··· 9951 msgid "Video Games" 9952 msgstr "" 9953 9954 - #: src/screens/VideoFeed/index.tsx:1079 9955 msgid "Video is paused" 9956 msgstr "" 9957 9958 - #: src/screens/VideoFeed/index.tsx:1079 9959 msgid "Video is playing" 9960 msgstr "" 9961 ··· 9993 msgstr "" 9994 9995 #: src/components/ProfileCard.tsx:124 9996 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:454 9997 #: src/screens/Search/components/SearchProfileCard.tsx:36 9998 - #: src/screens/VideoFeed/index.tsx:796 9999 #: src/view/com/notifications/NotificationFeedItem.tsx:599 10000 msgid "View {0}'s profile" 10001 msgstr "" ··· 10016 msgid "View debug entry" 10017 msgstr "" 10018 10019 - #: src/screens/VideoFeed/index.tsx:661 10020 - #: src/screens/VideoFeed/index.tsx:679 10021 msgid "View details" 10022 msgstr "" 10023 ··· 10065 msgid "View this user's verifications" 10066 msgstr "" 10067 10068 - #: src/screens/Profile/components/ProfileFeedHeader.tsx:489 10069 msgid "View users who like this feed" 10070 msgstr "" 10071 ··· 10391 msgstr "" 10392 10393 #: src/components/dms/AfterReportDialog.tsx:49 10394 - msgid "Would you like to block this account or delete this conversation?" 10395 msgstr "" 10396 10397 #: src/screens/Messages/components/MessageInput.tsx:154 ··· 10861 msgid "You've reached your daily limit for video uploads (too many videos)" 10862 msgstr "" 10863 10864 - #: src/screens/VideoFeed/index.tsx:1130 10865 msgid "You've run out of videos to watch. Maybe it's a good time to take a break?" 10866 msgstr "" 10867
··· 1047 msgstr "" 1048 1049 #: src/components/moderation/ReportDialog/utils/useReportOptions.ts:239 1050 msgid "An issue not included in these options" 1051 msgstr "" 1052 ··· 1062 #: src/components/hooks/useFollowMethods.ts:50 1063 #: src/components/ProfileCard.tsx:484 1064 #: src/components/ProfileCard.tsx:505 1065 msgid "An issue occurred, please try again." 1066 msgstr "" 1067 ··· 1102 1103 #: src/components/dialogs/nuxs/InitialVerificationAnnouncement.tsx:37 1104 msgid "Announcing verification on Bluesky" 1105 msgstr "" 1106 1107 #: src/view/com/composer/threadgate/ThreadgateBtn.tsx:48 ··· 1297 1298 #: src/components/moderation/LabelsOnMeDialog.tsx:333 1299 #: src/components/moderation/LabelsOnMeDialog.tsx:334 1300 + #: src/screens/Login/ChooseAccountForm.tsx:91 1301 + #: src/screens/Login/ChooseAccountForm.tsx:96 1302 #: src/screens/Login/ForgotPasswordForm.tsx:123 1303 #: src/screens/Login/ForgotPasswordForm.tsx:129 1304 #: src/screens/Login/LoginForm.tsx:310 ··· 1405 msgid "Block and Delete" 1406 msgstr "" 1407 1408 #: src/screens/ProfileList/components/SubscribeMenu.tsx:125 1409 msgid "Block list" 1410 msgstr "" ··· 1426 msgid "Block User" 1427 msgstr "" 1428 1429 + #: src/components/dms/AfterReportDialog.tsx:180 1430 + msgid "Block user and/or delete this conversation" 1431 + msgstr "" 1432 + 1433 #: src/components/Post/Embed/index.tsx:186 1434 msgid "Blocked" 1435 msgstr "" ··· 1585 #: src/components/LabelingServiceCard/index.tsx:62 1586 #: src/components/moderation/ReportDialog/index.tsx:834 1587 #: src/screens/Search/components/StarterPackCard.tsx:106 1588 + #: src/screens/Search/Explore.tsx:936 1589 msgid "By {0}" 1590 msgstr "" 1591 1592 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:453 1593 msgid "By <0>{0}</0>" 1594 msgstr "" 1595 ··· 1635 #: src/components/live/GoLiveDialog.tsx:244 1636 #: src/components/live/GoLiveDialog.tsx:250 1637 #: src/components/Menu/index.tsx:350 1638 + #: src/components/PostControls/RepostButton.tsx:209 1639 #: src/components/Prompt.tsx:144 1640 #: src/components/Prompt.tsx:146 1641 #: src/screens/Deactivated.tsx:158 ··· 2253 msgid "Continue" 2254 msgstr "" 2255 2256 + #: src/components/AccountList.tsx:135 2257 msgid "Continue as {0} (currently signed in)" 2258 msgstr "" 2259 ··· 2832 msgid "Discover new custom feeds" 2833 msgstr "" 2834 2835 + #: src/screens/Search/Explore.tsx:431 2836 #: src/view/screens/Feeds.tsx:730 2837 msgid "Discover New Feeds" 2838 msgstr "" ··· 2944 msgid "Double tap to close the dialog" 2945 msgstr "" 2946 2947 + #: src/screens/VideoFeed/index.tsx:1101 2948 msgid "Double tap to like" 2949 msgstr "" 2950 ··· 3344 msgid "Everything else" 3345 msgstr "" 3346 3347 #: src/components/dialogs/MutedWords.tsx:316 3348 msgid "Exclude users you follow" 3349 msgstr "" ··· 3380 msgid "Expand post text" 3381 msgstr "" 3382 3383 + #: src/screens/VideoFeed/index.tsx:973 3384 msgid "Expands or collapses post text" 3385 msgstr "" 3386 ··· 3521 msgid "Failed to load conversations" 3522 msgstr "" 3523 3524 + #: src/screens/Search/Explore.tsx:467 3525 + #: src/screens/Search/Explore.tsx:519 3526 + #: src/screens/Search/Explore.tsx:557 3527 + #: src/screens/Search/Explore.tsx:596 3528 msgid "Failed to load feeds preferences" 3529 msgstr "" 3530 ··· 3554 msgid "Failed to load preference." 3555 msgstr "" 3556 3557 + #: src/screens/Search/Explore.tsx:460 3558 + #: src/screens/Search/Explore.tsx:512 3559 + #: src/screens/Search/Explore.tsx:550 3560 + #: src/screens/Search/Explore.tsx:589 3561 msgid "Failed to load suggested feeds" 3562 msgstr "" 3563 3564 + #: src/screens/Search/Explore.tsx:370 3565 msgid "Failed to load suggested follows" 3566 msgstr "" 3567 ··· 3688 msgid "Feed identifier" 3689 msgstr "" 3690 3691 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:355 3692 msgid "Feed menu" 3693 msgstr "" 3694 ··· 3831 #: src/components/ProfileHoverCard/index.web.tsx:507 3832 #: src/screens/PostThread/components/ThreadItemAnchorFollowButton.tsx:131 3833 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:258 3834 + #: src/screens/VideoFeed/index.tsx:857 3835 msgid "Follow" 3836 msgstr "" 3837 ··· 3840 msgid "Follow {0}" 3841 msgstr "" 3842 3843 + #: src/screens/VideoFeed/index.tsx:834 3844 msgid "Follow {handle}" 3845 msgstr "" 3846 ··· 3877 msgid "Follow back" 3878 msgstr "" 3879 3880 #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:113 3881 msgid "Followed all accounts!" 3882 msgstr "" ··· 3912 #: src/components/ProfileHoverCard/index.web.tsx:506 3913 #: src/screens/PostThread/components/ThreadItemAnchorFollowButton.tsx:134 3914 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:254 3915 + #: src/screens/VideoFeed/index.tsx:855 3916 msgid "Following" 3917 msgstr "" 3918 ··· 3927 msgid "Following {0}" 3928 msgstr "" 3929 3930 + #: src/screens/VideoFeed/index.tsx:833 3931 msgid "Following {handle}" 3932 msgstr "" 3933 ··· 4006 4007 #: src/screens/Onboarding/StepFinished/ValuePropositionPager.shared.tsx:12 4008 msgid "Free your feed" 4009 msgstr "" 4010 4011 #: src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx:157 ··· 4102 msgid "Give your profile a face" 4103 msgstr "" 4104 4105 #: src/components/moderation/ReportDialog/utils/useReportOptions.ts:142 4106 msgid "Glorification of violence" 4107 msgstr "" ··· 4116 #: src/screens/ProfileList/components/ErrorScreen.tsx:34 4117 #: src/screens/ProfileList/components/ErrorScreen.tsx:40 4118 #: src/screens/VideoFeed/components/Header.tsx:163 4119 + #: src/screens/VideoFeed/index.tsx:1162 4120 + #: src/screens/VideoFeed/index.tsx:1166 4121 #: src/view/com/auth/LoggedOut.tsx:72 4122 #: src/view/screens/NotFound.tsx:57 4123 msgid "Go back" ··· 4252 msgid "Harassment or hate" 4253 msgstr "" 4254 4255 #: src/components/moderation/ReportDialog/utils/useReportOptions.ts:189 4256 msgid "Harmful or high-risk activities" 4257 msgstr "" ··· 4307 msgid "Hidden" 4308 msgstr "" 4309 4310 + #: src/screens/VideoFeed/index.tsx:631 4311 msgid "Hidden by your moderation settings." 4312 msgstr "" 4313 ··· 4516 msgid "If you're trying to change your handle or email, do so before you deactivate." 4517 msgstr "" 4518 4519 #: src/view/com/util/images/Gallery.tsx:75 4520 msgid "Image" 4521 msgstr "" ··· 4542 msgid "Impersonation" 4543 msgstr "" 4544 4545 #: src/screens/Settings/NotificationSettings/index.tsx:284 4546 msgid "In-app" 4547 msgstr "" ··· 4568 4569 #: src/screens/Settings/NotificationSettings/index.tsx:273 4570 msgid "In-app, Push, People you follow" 4571 msgstr "" 4572 4573 #. Title message shown in chat requests inbox when it's empty ··· 4891 msgid "Light" 4892 msgstr "" 4893 4894 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:515 4895 msgid "Like" 4896 msgstr "" 4897 ··· 4913 msgid "Like notifications" 4914 msgstr "" 4915 4916 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:502 4917 msgid "Like this feed" 4918 msgstr "" 4919 ··· 4938 msgstr "" 4939 4940 #: src/components/LabelingServiceCard/index.tsx:96 4941 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:490 4942 #: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:290 4943 #: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:304 4944 msgid "Liked by {likeCount, plural, one {# user} other {# users}}" ··· 5079 msgid "Live link" 5080 msgstr "" 5081 5082 + #: src/screens/Search/Explore.tsx:83 5083 msgid "Load more" 5084 msgstr "" 5085 5086 + #: src/screens/Search/Explore.tsx:501 5087 + #: src/screens/Search/Explore.tsx:578 5088 msgid "Load more suggested feeds" 5089 msgstr "" 5090 ··· 5105 5106 #: src/Navigation.tsx:321 5107 msgid "Log" 5108 + msgstr "" 5109 + 5110 + #: src/components/AccountList.tsx:191 5111 + msgid "Logged out" 5112 msgstr "" 5113 5114 #: src/screens/Settings/PrivacyAndSecuritySettings.tsx:106 ··· 5276 msgid "Misleading" 5277 msgstr "" 5278 5279 #: src/Navigation.tsx:177 5280 #: src/screens/Moderation/index.tsx:100 5281 #: src/screens/Settings/Settings.tsx:188 ··· 5479 5480 #: src/components/dialogs/lists/CreateOrEditListDialog.tsx:399 5481 msgid "Name" 5482 msgstr "" 5483 5484 #: src/lib/interests.ts:66 ··· 5521 msgid "New" 5522 msgstr "" 5523 5524 + #: src/view/screens/Lists.tsx:78 5525 #: src/view/screens/ModerationModlists.tsx:79 5526 msgctxt "action" 5527 msgid "New" ··· 5741 msgid "No results" 5742 msgstr "" 5743 5744 + #: src/screens/Search/Explore.tsx:793 5745 msgid "No results for \"{0}\"." 5746 msgstr "" 5747 ··· 5759 msgid "No results found for {query}" 5760 msgstr "" 5761 5762 + #: src/screens/Search/Explore.tsx:797 5763 msgid "No results." 5764 msgstr "" 5765 ··· 5892 msgid "Nudity" 5893 msgstr "" 5894 5895 #: src/lib/moderation/useLabelBehaviorDescription.ts:14 5896 #: src/screens/Settings/NotificationSettings/index.tsx:291 5897 msgid "Off" ··· 5999 msgid "Open conversation options" 6000 msgstr "" 6001 6002 + #: src/components/Layout/Header/index.tsx:159 6003 msgid "Open drawer menu" 6004 msgstr "" 6005 ··· 6012 msgid "Open feed info screen" 6013 msgstr "" 6014 6015 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:292 6016 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:297 6017 msgid "Open feed options menu" 6018 msgstr "" 6019 ··· 6181 6182 #: src/components/moderation/ReportDialog/utils/useReportOptions.ts:238 6183 #: src/components/moderation/ReportDialog/utils/useReportOptions.ts:242 6184 #: src/view/com/composer/labels/LabelsBtn.tsx:185 6185 msgid "Other" 6186 msgstr "" 6187 6188 + #: src/components/AccountList.tsx:93 6189 msgid "Other account" 6190 msgstr "" 6191 ··· 6314 msgid "Pictures meant for adults." 6315 msgstr "" 6316 6317 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:520 6318 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:527 6319 #: src/screens/SavedFeeds.tsx:351 6320 msgid "Pin feed" 6321 msgstr "" ··· 6329 msgid "Pin to home" 6330 msgstr "" 6331 6332 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:338 6333 msgid "Pin to Home" 6334 msgstr "" 6335 ··· 6578 #: src/screens/PostThread/components/ThreadItemAnchor.tsx:134 6579 #: src/screens/PostThread/components/ThreadItemPost.tsx:112 6580 #: src/screens/PostThread/components/ThreadItemTreePost.tsx:108 6581 + #: src/screens/VideoFeed/index.tsx:535 6582 msgid "Post has been deleted" 6583 msgstr "" 6584 ··· 6871 msgid "Read blog post" 6872 msgstr "" 6873 6874 + #: src/screens/VideoFeed/index.tsx:974 6875 msgid "Read less" 6876 msgstr "" 6877 6878 + #: src/screens/VideoFeed/index.tsx:974 6879 msgid "Read more" 6880 msgstr "" 6881 ··· 7008 msgid "Remove feed?" 7009 msgstr "" 7010 7011 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:320 7012 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:326 7013 #: src/screens/ProfileList/components/MoreOptionsMenu.tsx:181 7014 #: src/screens/ProfileList/components/MoreOptionsMenu.tsx:184 7015 #: src/screens/SavedFeeds.tsx:340 ··· 7227 msgid "Report dialog" 7228 msgstr "" 7229 7230 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:543 7231 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:549 7232 msgid "Report feed" 7233 msgstr "" 7234 ··· 7454 #: src/screens/Profile/ProfileFeed/index.tsx:93 7455 #: src/screens/ProfileList/components/ErrorScreen.tsx:35 7456 #: src/screens/Settings/components/ChangeHandleDialog.tsx:569 7457 + #: src/screens/VideoFeed/index.tsx:1163 7458 #: src/view/screens/NotFound.tsx:60 7459 msgid "Returns to previous page" 7460 msgstr "" ··· 7513 msgid "Save QR code" 7514 msgstr "" 7515 7516 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:321 7517 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:327 7518 msgid "Save to my feeds" 7519 msgstr "" 7520 ··· 7611 msgid "Search for feeds that you want to suggest to others." 7612 msgstr "" 7613 7614 + #: src/screens/Search/Explore.tsx:357 7615 msgid "Search for more accounts" 7616 msgstr "" 7617 7618 + #: src/screens/Search/Explore.tsx:434 7619 msgid "Search for more feeds" 7620 msgstr "" 7621 ··· 8043 msgid "Share QR code" 8044 msgstr "" 8045 8046 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:471 8047 msgid "Share this feed" 8048 msgstr "" 8049 ··· 8087 #: src/components/moderation/ScreenHider.tsx:178 8088 #: src/components/moderation/ScreenHider.tsx:181 8089 #: src/screens/List/ListHiddenScreen.tsx:190 8090 + #: src/screens/VideoFeed/index.tsx:634 8091 + #: src/screens/VideoFeed/index.tsx:640 8092 msgid "Show anyway" 8093 msgstr "" 8094 ··· 8203 msgid "Sign in" 8204 msgstr "" 8205 8206 + #: src/components/AccountList.tsx:136 8207 msgid "Sign in as {0}" 8208 msgstr "" 8209 8210 + #: src/screens/Login/ChooseAccountForm.tsx:81 8211 msgid "Sign in as..." 8212 msgstr "" 8213 ··· 8220 msgid "Sign in or create your account to join the conversation!" 8221 msgstr "" 8222 8223 + #: src/components/AccountList.tsx:70 8224 msgid "Sign in to account that is not listed" 8225 msgstr "" 8226 ··· 8356 msgid "Something went wrong. Please try again." 8357 msgstr "" 8358 8359 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:539 8360 msgid "Something wrong? Let us know." 8361 msgstr "" 8362 ··· 8387 msgstr "" 8388 8389 #: src/components/moderation/ReportDialog/utils/useReportOptions.ts:39 8390 msgid "Spam" 8391 msgstr "" 8392 ··· 8394 msgid "Spam or other inauthentic behavior or deception" 8395 msgstr "" 8396 8397 #: src/lib/interests.ts:72 8398 #: src/screens/Onboarding/index.tsx:58 8399 #: src/screens/Search/modules/ExploreTrendingTopics.tsx:230 ··· 8445 msgid "Starter pack is invalid" 8446 msgstr "" 8447 8448 + #: src/screens/Search/Explore.tsx:625 8449 #: src/view/screens/Profile.tsx:231 8450 msgid "Starter Packs" 8451 msgstr "" ··· 8532 msgid "Successfully verified" 8533 msgstr "" 8534 8535 + #: src/screens/Search/Explore.tsx:354 8536 msgid "Suggested Accounts" 8537 msgstr "" 8538 ··· 8679 msgid "Terms of Service" 8680 msgstr "" 8681 8682 #: src/components/dialogs/MutedWords.tsx:271 8683 msgid "Text & tags" 8684 msgstr "" ··· 8722 msgid "That's all, folks!" 8723 msgstr "" 8724 8725 + #: src/screens/VideoFeed/index.tsx:1135 8726 msgid "That's everything!" 8727 msgstr "" 8728 ··· 8850 msgid "There was an issue contacting the server" 8851 msgstr "" 8852 8853 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:419 8854 #: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:109 8855 msgid "There was an issue contacting the server, please check your internet connection and try again." 8856 msgstr "" ··· 8859 msgid "There was an issue fetching notifications. Tap here to try again." 8860 msgstr "" 8861 8862 + #: src/screens/Search/Explore.tsx:992 8863 #: src/view/com/posts/PostFeed.tsx:712 8864 msgid "There was an issue fetching posts. Tap here to try again." 8865 msgstr "" ··· 9391 msgid "Undo repost ({0, plural, one {# repost} other {# reposts}})" 9392 msgstr "" 9393 9394 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:242 9395 msgid "Unfollow {0}" 9396 msgstr "" ··· 9400 msgid "Unfollow account" 9401 msgstr "" 9402 9403 + #: src/screens/VideoFeed/index.tsx:838 9404 msgid "Unfollows the user" 9405 msgstr "" 9406 ··· 9424 msgid "Unlabeled, abusive, or non-consensual adult content" 9425 msgstr "" 9426 9427 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:515 9428 msgid "Unlike" 9429 msgstr "" 9430 ··· 9479 msgid "Unpin" 9480 msgstr "" 9481 9482 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:520 9483 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:527 9484 #: src/screens/SavedFeeds.tsx:351 9485 msgid "Unpin feed" 9486 msgstr "" ··· 9489 msgid "Unpin Feed" 9490 msgstr "" 9491 9492 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:311 9493 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:313 9494 msgid "Unpin from home" 9495 msgstr "" 9496 ··· 9540 9541 #: src/view/com/composer/Composer.tsx:895 9542 msgid "Unsupported video type: {mimeType}" 9543 msgstr "" 9544 9545 #: src/screens/Settings/components/OTAInfo.tsx:58 ··· 9859 msgid "Video Games" 9860 msgstr "" 9861 9862 + #: src/screens/VideoFeed/index.tsx:1093 9863 msgid "Video is paused" 9864 msgstr "" 9865 9866 + #: src/screens/VideoFeed/index.tsx:1093 9867 msgid "Video is playing" 9868 msgstr "" 9869 ··· 9901 msgstr "" 9902 9903 #: src/components/ProfileCard.tsx:124 9904 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:456 9905 #: src/screens/Search/components/SearchProfileCard.tsx:36 9906 + #: src/screens/VideoFeed/index.tsx:797 9907 #: src/view/com/notifications/NotificationFeedItem.tsx:599 9908 msgid "View {0}'s profile" 9909 msgstr "" ··· 9924 msgid "View debug entry" 9925 msgstr "" 9926 9927 + #: src/screens/VideoFeed/index.tsx:662 9928 + #: src/screens/VideoFeed/index.tsx:680 9929 msgid "View details" 9930 msgstr "" 9931 ··· 9973 msgid "View this user's verifications" 9974 msgstr "" 9975 9976 + #: src/screens/Profile/components/ProfileFeedHeader.tsx:486 9977 msgid "View users who like this feed" 9978 msgstr "" 9979 ··· 10299 msgstr "" 10300 10301 #: src/components/dms/AfterReportDialog.tsx:49 10302 + msgid "Would you like to block this user and/or delete this conversation?" 10303 msgstr "" 10304 10305 #: src/screens/Messages/components/MessageInput.tsx:154 ··· 10769 msgid "You've reached your daily limit for video uploads (too many videos)" 10770 msgstr "" 10771 10772 + #: src/screens/VideoFeed/index.tsx:1144 10773 msgid "You've run out of videos to watch. Maybe it's a good time to take a break?" 10774 msgstr "" 10775
+3 -2
src/screens/Login/ChooseAccountForm.tsx
··· 8 import {type SessionAccount, useSession, useSessionApi} from '#/state/session' 9 import {useLoggedOutViewControls} from '#/state/shell/logged-out' 10 import * as Toast from '#/view/com/util/Toast' 11 - import {atoms as a} from '#/alf' 12 import {AccountList} from '#/components/AccountList' 13 import {Button, ButtonText} from '#/components/Button' 14 import * as TextField from '#/components/forms/TextField' ··· 74 return ( 75 <FormContainer 76 testID="chooseAccountForm" 77 - titleText={<Trans>Select account</Trans>}> 78 <View> 79 <TextField.LabelText> 80 <Trans>Sign in as...</Trans>
··· 8 import {type SessionAccount, useSession, useSessionApi} from '#/state/session' 9 import {useLoggedOutViewControls} from '#/state/shell/logged-out' 10 import * as Toast from '#/view/com/util/Toast' 11 + import {atoms as a, web} from '#/alf' 12 import {AccountList} from '#/components/AccountList' 13 import {Button, ButtonText} from '#/components/Button' 14 import * as TextField from '#/components/forms/TextField' ··· 74 return ( 75 <FormContainer 76 testID="chooseAccountForm" 77 + titleText={<Trans>Select account</Trans>} 78 + style={web([a.py_2xl])}> 79 <View> 80 <TextField.LabelText> 81 <Trans>Sign in as...</Trans>
+2 -2
src/screens/Messages/components/ChatDisabled.tsx
··· 1 import {useCallback, useState} from 'react' 2 import {View} from 'react-native' 3 - import {ComAtprotoModerationDefs} from '@atproto/api' 4 import {msg, Trans} from '@lingui/macro' 5 import {useLingui} from '@lingui/react' 6 import {useMutation} from '@tanstack/react-query' ··· 81 throw new Error('No current account, should be unreachable') 82 await agent.createModerationReport( 83 { 84 - reasonType: ComAtprotoModerationDefs.REASONAPPEAL, 85 subject: { 86 $type: 'com.atproto.admin.defs#repoRef', 87 did: currentAccount.did,
··· 1 import {useCallback, useState} from 'react' 2 import {View} from 'react-native' 3 + import {ToolsOzoneReportDefs} from '@atproto/api' 4 import {msg, Trans} from '@lingui/macro' 5 import {useLingui} from '@lingui/react' 6 import {useMutation} from '@tanstack/react-query' ··· 81 throw new Error('No current account, should be unreachable') 82 await agent.createModerationReport( 83 { 84 + reasonType: ToolsOzoneReportDefs.REASONAPPEAL, 85 subject: { 86 $type: 'com.atproto.admin.defs#repoRef', 87 did: currentAccount.did,
+4 -4
src/screens/Profile/Header/Shell.tsx
··· 9 } from 'react-native-reanimated' 10 import {useSafeAreaInsets} from 'react-native-safe-area-context' 11 import {type AppBskyActorDefs, type ModerationDecision} from '@atproto/api' 12 import {msg} from '@lingui/macro' 13 import {useLingui} from '@lingui/react' 14 import {useNavigation} from '@react-navigation/native' ··· 26 import {UserAvatar} from '#/view/com/util/UserAvatar' 27 import {UserBanner} from '#/view/com/util/UserBanner' 28 import {atoms as a, platform, useTheme} from '#/alf' 29 - import {transparentifyColor} from '#/alf/util/colorGeneration' 30 import {Button} from '#/components/Button' 31 import {useDialogControl} from '#/components/Dialog' 32 import {ArrowLeft_Stroke2_Corner0_Rounded as ArrowLeftIcon} from '#/components/icons/Arrow' ··· 175 style={[ 176 a.align_center, 177 a.justify_center, 178 - a.rounded_sm, 179 { 180 width: 31, 181 height: 31, 182 - backgroundColor: transparentifyColor('#000', 0.5), 183 }, 184 hovered && { 185 - backgroundColor: transparentifyColor('#000', 0.75), 186 }, 187 ]}> 188 <ArrowLeftIcon size="lg" fill="white" />
··· 9 } from 'react-native-reanimated' 10 import {useSafeAreaInsets} from 'react-native-safe-area-context' 11 import {type AppBskyActorDefs, type ModerationDecision} from '@atproto/api' 12 + import {utils} from '@bsky.app/alf' 13 import {msg} from '@lingui/macro' 14 import {useLingui} from '@lingui/react' 15 import {useNavigation} from '@react-navigation/native' ··· 27 import {UserAvatar} from '#/view/com/util/UserAvatar' 28 import {UserBanner} from '#/view/com/util/UserBanner' 29 import {atoms as a, platform, useTheme} from '#/alf' 30 import {Button} from '#/components/Button' 31 import {useDialogControl} from '#/components/Dialog' 32 import {ArrowLeft_Stroke2_Corner0_Rounded as ArrowLeftIcon} from '#/components/icons/Arrow' ··· 175 style={[ 176 a.align_center, 177 a.justify_center, 178 + a.rounded_full, 179 { 180 width: 31, 181 height: 31, 182 + backgroundColor: utils.alpha('#000', 0.5), 183 }, 184 hovered && { 185 + backgroundColor: utils.alpha('#000', 0.75), 186 }, 187 ]}> 188 <ArrowLeftIcon size="lg" fill="white" />
+1 -2
src/screens/Search/Explore.tsx
··· 15 import {sanitizeHandle} from '#/lib/strings/handles' 16 import {logger} from '#/logger' 17 import {type MetricEvents} from '#/logger/metrics' 18 - import {isNative} from '#/platform/detection' 19 import {useLanguagePrefs} from '#/state/preferences/languages' 20 import {useModerationOpts} from '#/state/preferences/moderation-opts' 21 import {RQKEY_ROOT_PAGINATED as useActorSearchPaginatedQueryKeyRoot} from '#/state/queries/actor-search' ··· 924 } 925 case 'preview:header': { 926 return ( 927 - <ModuleHeader.Container style={[a.pt_xs]} bottomBorder={isNative}> 928 {/* Very non-scientific way to avoid small gap on scroll */} 929 <View style={[a.absolute, a.inset_0, t.atoms.bg, {top: -2}]} /> 930 <ModuleHeader.FeedLink feed={item.feed}>
··· 15 import {sanitizeHandle} from '#/lib/strings/handles' 16 import {logger} from '#/logger' 17 import {type MetricEvents} from '#/logger/metrics' 18 import {useLanguagePrefs} from '#/state/preferences/languages' 19 import {useModerationOpts} from '#/state/preferences/moderation-opts' 20 import {RQKEY_ROOT_PAGINATED as useActorSearchPaginatedQueryKeyRoot} from '#/state/queries/actor-search' ··· 923 } 924 case 'preview:header': { 925 return ( 926 + <ModuleHeader.Container style={[a.pt_xs]} bottomBorder> 927 {/* Very non-scientific way to avoid small gap on scroll */} 928 <View style={[a.absolute, a.inset_0, t.atoms.bg, {top: -2}]} /> 929 <ModuleHeader.FeedLink feed={item.feed}>
+1 -1
src/screens/Search/Shell.tsx
··· 362 size="large" 363 variant="ghost" 364 color="secondary" 365 - style={[a.px_sm]} 366 onPress={onPressCancelSearch} 367 hitSlop={HITSLOP_10}> 368 <ButtonText>
··· 362 size="large" 363 variant="ghost" 364 color="secondary" 365 + style={[a.px_sm, a.rounded_sm]} 366 onPress={onPressCancelSearch} 367 hitSlop={HITSLOP_10}> 368 <ButtonText>
+1 -1
src/screens/Search/modules/ExploreTrendingTopics.tsx
··· 97 PressableComponent={Pressable}> 98 {({hovered, pressed}) => ( 99 <> 100 - <SubtleHover hover={hovered || pressed} /> 101 <View style={[gutters, a.w_full, a.py_lg, a.flex_row, a.gap_2xs]}> 102 <View style={[a.flex_1, a.gap_xs]}> 103 <View style={[a.flex_row]}>
··· 97 PressableComponent={Pressable}> 98 {({hovered, pressed}) => ( 99 <> 100 + <SubtleHover hover={hovered || pressed} native /> 101 <View style={[gutters, a.w_full, a.py_lg, a.flex_row, a.gap_2xs]}> 102 <View style={[a.flex_1, a.gap_xs]}> 103 <View style={[a.flex_row]}>
+1 -1
src/screens/Settings/components/SettingsList.tsx
··· 252 <View 253 style={[ 254 a.border_t, 255 - t.atoms.border_contrast_medium, 256 a.w_full, 257 a.my_sm, 258 style,
··· 252 <View 253 style={[ 254 a.border_t, 255 + t.atoms.border_contrast_low, 256 a.w_full, 257 a.my_sm, 258 style,
+2 -2
src/screens/Takendown.tsx
··· 3 import {SystemBars} from 'react-native-edge-to-edge' 4 import {KeyboardAwareScrollView} from 'react-native-keyboard-controller' 5 import {useSafeAreaInsets} from 'react-native-safe-area-context' 6 - import {type ComAtprotoAdminDefs, ComAtprotoModerationDefs} from '@atproto/api' 7 import {msg, Trans} from '@lingui/macro' 8 import {useLingui} from '@lingui/react' 9 import {useMutation} from '@tanstack/react-query' ··· 54 if (!currentAccount) throw new Error('No session') 55 await agent.com.atproto.moderation.createReport( 56 { 57 - reasonType: ComAtprotoModerationDefs.REASONAPPEAL, 58 subject: { 59 $type: 'com.atproto.admin.defs#repoRef', 60 did: currentAccount.did,
··· 3 import {SystemBars} from 'react-native-edge-to-edge' 4 import {KeyboardAwareScrollView} from 'react-native-keyboard-controller' 5 import {useSafeAreaInsets} from 'react-native-safe-area-context' 6 + import {type ComAtprotoAdminDefs, ToolsOzoneReportDefs} from '@atproto/api' 7 import {msg, Trans} from '@lingui/macro' 8 import {useLingui} from '@lingui/react' 9 import {useMutation} from '@tanstack/react-query' ··· 54 if (!currentAccount) throw new Error('No session') 55 await agent.com.atproto.moderation.createReport( 56 { 57 + reasonType: ToolsOzoneReportDefs.REASONAPPEAL, 58 subject: { 59 $type: 'com.atproto.admin.defs#repoRef', 60 did: currentAccount.did,
+22 -8
src/screens/VideoFeed/index.tsx
··· 57 import {sanitizeDisplayName} from '#/lib/strings/display-names' 58 import {cleanError} from '#/lib/strings/errors' 59 import {sanitizeHandle} from '#/lib/strings/handles' 60 import {isAndroid} from '#/platform/detection' 61 import {useA11y} from '#/state/a11y' 62 import { ··· 204 }, [params]) 205 const feedUri = params.type === 'feedgen' ? params.uri : undefined 206 const {data: feedInfo} = useFeedInfo(feedUri) 207 - const feedFeedback = useFeedFeedback(feedInfo, hasSession) 208 const {data, error, hasNextPage, isFetchingNextPage, fetchNextPage} = 209 usePostFeedQuery( 210 feedDesc, ··· 1044 const {isPlaying} = useEvent(player, 'playingChange', { 1045 isPlaying: player.playing, 1046 }) 1047 1048 - const togglePlayPause = () => { 1049 - if (!player) return 1050 doubleTapRef.current = null 1051 - if (player.playing) { 1052 - player.pause() 1053 - } else { 1054 - player.play() 1055 } 1056 - } 1057 1058 const onPress = () => { 1059 if (doubleTapRef.current) {
··· 57 import {sanitizeDisplayName} from '#/lib/strings/display-names' 58 import {cleanError} from '#/lib/strings/errors' 59 import {sanitizeHandle} from '#/lib/strings/handles' 60 + import {logger} from '#/logger' 61 import {isAndroid} from '#/platform/detection' 62 import {useA11y} from '#/state/a11y' 63 import { ··· 205 }, [params]) 206 const feedUri = params.type === 'feedgen' ? params.uri : undefined 207 const {data: feedInfo} = useFeedInfo(feedUri) 208 + const feedFeedback = useFeedFeedback(feedInfo ?? undefined, hasSession) 209 const {data, error, hasNextPage, isFetchingNextPage, fetchNextPage} = 210 usePostFeedQuery( 211 feedDesc, ··· 1045 const {isPlaying} = useEvent(player, 'playingChange', { 1046 isPlaying: player.playing, 1047 }) 1048 + const isMounted = useRef(false) 1049 1050 + useEffect(() => { 1051 + isMounted.current = true 1052 + return () => { 1053 + isMounted.current = false 1054 + } 1055 + }, []) 1056 + 1057 + const togglePlayPause = useNonReactiveCallback(() => { 1058 + // gets called after a timeout, so guard against being called after unmount -sfn 1059 + if (!player || !isMounted.current) return 1060 doubleTapRef.current = null 1061 + try { 1062 + if (player.playing) { 1063 + player.pause() 1064 + } else { 1065 + player.play() 1066 + } 1067 + } catch (err) { 1068 + logger.error('Could not toggle play/pause', {safeMessage: err}) 1069 } 1070 + }) 1071 1072 const onPress = () => { 1073 if (doubleTapRef.current) {
+1 -1
src/state/queries/feed.ts
··· 637 queryKey: [feedInfoQueryKeyRoot, feedUri], 638 queryFn: async () => { 639 if (!feedUri) { 640 - return undefined 641 } 642 643 const res = await agent.app.bsky.feed.getFeedGenerator({
··· 637 queryKey: [feedInfoQueryKeyRoot, feedUri], 638 queryFn: async () => { 639 if (!feedUri) { 640 + return null 641 } 642 643 const res = await agent.app.bsky.feed.getFeedGenerator({
+5 -12
src/state/session/util.ts
··· 1 import {jwtDecode} from 'jwt-decode' 2 3 import {hasProp} from '#/lib/type-guards' 4 - import {logger} from '#/logger' 5 import * as persisted from '#/state/persisted' 6 import {type SessionAccount} from './types' 7 ··· 22 } 23 24 export function isSessionExpired(account: SessionAccount) { 25 - try { 26 - if (account.accessJwt) { 27 - const decoded = jwtDecode(account.accessJwt) 28 - if (decoded.exp) { 29 - const didExpire = Date.now() >= decoded.exp * 1000 30 - return didExpire 31 - } 32 - } 33 - } catch (e) { 34 - logger.error(`session: could not decode jwt`) 35 } 36 - return true 37 }
··· 1 import {jwtDecode} from 'jwt-decode' 2 3 + import {isJwtExpired} from '#/lib/jwt' 4 import {hasProp} from '#/lib/type-guards' 5 import * as persisted from '#/state/persisted' 6 import {type SessionAccount} from './types' 7 ··· 22 } 23 24 export function isSessionExpired(account: SessionAccount) { 25 + if (account.accessJwt) { 26 + return isJwtExpired(account.accessJwt) 27 + } else { 28 + return true 29 } 30 }
-85
src/view/com/profile/FollowButton.tsx
··· 1 - import {type StyleProp, type TextStyle, View} from 'react-native' 2 - import {msg} from '@lingui/macro' 3 - import {useLingui} from '@lingui/react' 4 - 5 - import {type Shadow} from '#/state/cache/types' 6 - import {useProfileFollowMutationQueue} from '#/state/queries/profile' 7 - import type * as bsky from '#/types/bsky' 8 - import {Button, type ButtonType} from '../util/forms/Button' 9 - import * as Toast from '../util/Toast' 10 - 11 - export function FollowButton({ 12 - unfollowedType = 'inverted', 13 - followedType = 'default', 14 - profile, 15 - labelStyle, 16 - logContext, 17 - onFollow, 18 - }: { 19 - unfollowedType?: ButtonType 20 - followedType?: ButtonType 21 - profile: Shadow<bsky.profile.AnyProfileView> 22 - labelStyle?: StyleProp<TextStyle> 23 - logContext: 'ProfileCard' | 'StarterPackProfilesList' 24 - onFollow?: () => void 25 - }) { 26 - const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( 27 - profile, 28 - logContext, 29 - ) 30 - const {_} = useLingui() 31 - 32 - const onPressFollow = async () => { 33 - try { 34 - await queueFollow() 35 - onFollow?.() 36 - } catch (e: any) { 37 - if (e?.name !== 'AbortError') { 38 - Toast.show(_(msg`An issue occurred, please try again.`), 'xmark') 39 - } 40 - } 41 - } 42 - 43 - const onPressUnfollow = async () => { 44 - try { 45 - await queueUnfollow() 46 - } catch (e: any) { 47 - if (e?.name !== 'AbortError') { 48 - Toast.show(_(msg`An issue occurred, please try again.`), 'xmark') 49 - } 50 - } 51 - } 52 - 53 - if (!profile.viewer) { 54 - return <View /> 55 - } 56 - 57 - if (profile.viewer.following) { 58 - return ( 59 - <Button 60 - type={followedType} 61 - labelStyle={labelStyle} 62 - onPress={onPressUnfollow} 63 - label={_(msg({message: 'Unfollow', context: 'action'}))} 64 - /> 65 - ) 66 - } else if (!profile.viewer.followedBy) { 67 - return ( 68 - <Button 69 - type={unfollowedType} 70 - labelStyle={labelStyle} 71 - onPress={onPressFollow} 72 - label={_(msg({message: 'Follow', context: 'action'}))} 73 - /> 74 - ) 75 - } else { 76 - return ( 77 - <Button 78 - type={unfollowedType} 79 - labelStyle={labelStyle} 80 - onPress={onPressFollow} 81 - label={_(msg({message: 'Follow back', context: 'action'}))} 82 - /> 83 - ) 84 - } 85 - }
···
-88
src/view/com/util/EmptyStateWithButton.tsx
··· 1 - import {StyleSheet, View} from 'react-native' 2 - import {type IconProp} from '@fortawesome/fontawesome-svg-core' 3 - import { 4 - FontAwesomeIcon, 5 - type FontAwesomeIconStyle, 6 - } from '@fortawesome/react-native-fontawesome' 7 - 8 - import {usePalette} from '#/lib/hooks/usePalette' 9 - import {s} from '#/lib/styles' 10 - import {Button} from './forms/Button' 11 - import {Text} from './text/Text' 12 - 13 - interface Props { 14 - testID?: string 15 - icon: IconProp 16 - message: string 17 - buttonLabel: string 18 - onPress: () => void 19 - } 20 - 21 - export function EmptyStateWithButton(props: Props) { 22 - const pal = usePalette('default') 23 - const palInverted = usePalette('inverted') 24 - 25 - return ( 26 - <View testID={props.testID} style={styles.container}> 27 - <View style={styles.iconContainer}> 28 - <FontAwesomeIcon 29 - icon={props.icon} 30 - style={[styles.icon, pal.text]} 31 - size={62} 32 - /> 33 - </View> 34 - <Text type="xl-medium" style={[s.textCenter, pal.text]}> 35 - {props.message} 36 - </Text> 37 - <View style={styles.btns}> 38 - <Button 39 - testID={props.testID ? `${props.testID}-button` : undefined} 40 - type="inverted" 41 - style={styles.btn} 42 - onPress={props.onPress}> 43 - <FontAwesomeIcon 44 - icon="plus" 45 - style={palInverted.text as FontAwesomeIconStyle} 46 - size={14} 47 - /> 48 - <Text type="lg-medium" style={palInverted.text}> 49 - {props.buttonLabel} 50 - </Text> 51 - </Button> 52 - </View> 53 - </View> 54 - ) 55 - } 56 - const styles = StyleSheet.create({ 57 - container: { 58 - height: '100%', 59 - paddingVertical: 40, 60 - paddingHorizontal: 30, 61 - }, 62 - iconContainer: { 63 - marginBottom: 16, 64 - }, 65 - icon: { 66 - marginLeft: 'auto', 67 - marginRight: 'auto', 68 - }, 69 - btns: { 70 - flexDirection: 'row', 71 - justifyContent: 'center', 72 - }, 73 - btn: { 74 - gap: 10, 75 - marginVertical: 20, 76 - flexDirection: 'row', 77 - alignItems: 'center', 78 - paddingVertical: 14, 79 - paddingHorizontal: 24, 80 - borderRadius: 30, 81 - }, 82 - notice: { 83 - borderRadius: 12, 84 - paddingHorizontal: 12, 85 - paddingVertical: 10, 86 - marginHorizontal: 30, 87 - }, 88 - })
···
-1
src/view/screens/Lists.tsx
··· 71 label={_(msg`New list`)} 72 testID="newUserListBtn" 73 color="secondary" 74 - variant="solid" 75 size="small" 76 onPress={wrappedOnPressNewList}> 77 <ButtonIcon icon={PlusIcon} />
··· 71 label={_(msg`New list`)} 72 testID="newUserListBtn" 73 color="secondary" 74 size="small" 75 onPress={wrappedOnPressNewList}> 76 <ButtonIcon icon={PlusIcon} />