+58
-24
src/components/AccountList.tsx
+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
+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
-1
src/components/Layout/Header/index.tsx
+1
-2
src/components/PostControls/RepostButton.tsx
+1
-2
src/components/PostControls/RepostButton.tsx
+2
-2
src/components/ageAssurance/AgeAssuranceAppealDialog.tsx
+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
+1
-1
src/components/dialogs/SwitchAccount.tsx
+2
-2
src/components/dms/AfterReportDialog.tsx
+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
+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
+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
-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
+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
+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
+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
+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
+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
+1
-1
src/screens/Search/Shell.tsx
+1
-1
src/screens/Search/modules/ExploreTrendingTopics.tsx
+1
-1
src/screens/Search/modules/ExploreTrendingTopics.tsx
+1
-1
src/screens/Settings/components/SettingsList.tsx
+1
-1
src/screens/Settings/components/SettingsList.tsx
+2
-2
src/screens/Takendown.tsx
+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
+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
+1
-1
src/state/queries/feed.ts
+5
-12
src/state/session/util.ts
+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
-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
-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
-1
src/view/screens/Lists.tsx