From 3f5bdd8be37efbe3bf7b1b60bea2bfa4e32aa159 Mon Sep 17 00:00:00 2001 From: Minseo Lee Date: Wed, 14 Feb 2024 11:06:37 +0900 Subject: [PATCH 001/109] Mark more texts for localization --- .../AdultContentEnabledPref.tsx | 12 +++-- src/view/com/auth/HomeLoggedOutCTA.tsx | 8 +++- src/view/com/auth/SplashScreen.tsx | 8 +++- src/view/com/auth/create/Policies.tsx | 19 +++++--- src/view/com/auth/create/Step3.tsx | 2 +- src/view/com/auth/login/LoginForm.tsx | 2 +- .../onboarding/RecommendedFollowsItem.tsx | 6 ++- .../com/auth/onboarding/WelcomeMobile.tsx | 6 ++- src/view/com/auth/server-input/index.tsx | 2 +- src/view/com/lightbox/Lightbox.tsx | 4 +- src/view/com/modals/ChangeHandle.tsx | 46 ++++++++++--------- src/view/com/modals/ChangePassword.tsx | 4 +- src/view/com/modals/DeleteAccount.tsx | 6 +-- src/view/com/modals/InAppBrowserConsent.tsx | 2 +- src/view/com/modals/LinkWarning.tsx | 4 +- src/view/com/modals/ModerationDetails.tsx | 2 +- src/view/com/modals/VerifyEmail.tsx | 2 +- .../com/modals/crop-image/CropImage.web.tsx | 12 ++--- .../com/modals/report/InputIssueDetails.tsx | 6 +-- src/view/com/modals/report/Modal.tsx | 7 ++- src/view/com/post-thread/PostThreadItem.tsx | 4 +- .../profile/ProfileHeaderSuggestedFollows.tsx | 14 +++--- src/view/screens/LanguageSettings.tsx | 2 +- src/view/screens/Moderation.tsx | 4 +- src/view/screens/ProfileFeed.tsx | 2 +- src/view/screens/Settings/index.tsx | 32 +++++++------ src/view/shell/NavSignupCard.tsx | 2 +- 27 files changed, 127 insertions(+), 93 deletions(-) diff --git a/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx b/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx index b38b3df1ed..c3d6164079 100644 --- a/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx +++ b/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx @@ -85,7 +85,9 @@ export function AdultContentEnabledPref({ a.align_center, a.py_md, ]}> - Enable Adult Content + + Enable Adult Content + @@ -106,7 +108,9 @@ export function AdultContentEnabledPref({ )} - Adult Content + + Adult Content + Due to Apple policies, adult content can only be enabled on the web @@ -114,7 +118,9 @@ export function AdultContentEnabledPref({ - OK + + OK + diff --git a/src/view/com/auth/HomeLoggedOutCTA.tsx b/src/view/com/auth/HomeLoggedOutCTA.tsx index f796d8baee..a5b5bf7ba6 100644 --- a/src/view/com/auth/HomeLoggedOutCTA.tsx +++ b/src/view/com/auth/HomeLoggedOutCTA.tsx @@ -52,7 +52,9 @@ export function HomeLoggedOutCTA() { onPress={showCreateAccount} accessibilityRole="button" accessibilityLabel={_(msg`Create new account`)} - accessibilityHint="Opens flow to create a new Bluesky account"> + accessibilityHint={_( + msg`Opens flow to create a new Bluesky account`, + )}> + accessibilityHint={_( + msg`Opens flow to sign into your existing Bluesky account`, + )}> + accessibilityHint={_( + msg`Opens flow to create a new Bluesky account`, + )}> Create a new account @@ -77,7 +79,9 @@ export const SplashScreen = ({ onPress={onPressSignin} accessibilityRole="button" accessibilityLabel={_(msg`Sign in`)} - accessibilityHint="Opens flow to sign into your existing Bluesky account"> + accessibilityHint={_( + msg`Opens flow to sign into your existing Bluesky account`, + )}> Sign In diff --git a/src/view/com/auth/create/Policies.tsx b/src/view/com/auth/create/Policies.tsx index 2c7d60818e..803e2ad32b 100644 --- a/src/view/com/auth/create/Policies.tsx +++ b/src/view/com/auth/create/Policies.tsx @@ -9,6 +9,8 @@ import {TextLink} from '../../util/Link' import {Text} from '../../util/text/Text' import {s, colors} from 'lib/styles' import {usePalette} from 'lib/hooks/usePalette' +import {Trans, msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' type ServiceDescription = ComAtprotoServerDescribeServer.OutputSchema @@ -20,6 +22,7 @@ export const Policies = ({ needsGuardian: boolean }) => { const pal = usePalette('default') + const {_} = useLingui() if (!serviceDescription) { return } @@ -40,7 +43,9 @@ export const Policies = ({ /> - This service has not provided terms of service or a privacy policy. + + This service has not provided terms of service or a privacy policy. + ) @@ -51,7 +56,7 @@ export const Policies = ({ , ) @@ -61,7 +66,7 @@ export const Policies = ({ , ) @@ -79,12 +84,14 @@ export const Policies = ({ return ( - By creating an account you agree to the {els}. + By creating an account you agree to the {els}. {needsGuardian && ( - If you are not yet an adult according to the laws of your country, - your parent or legal guardian must read these Terms on your behalf. + + If you are not yet an adult according to the laws of your country, + your parent or legal guardian must read these Terms on your behalf. + )} diff --git a/src/view/com/auth/create/Step3.tsx b/src/view/com/auth/create/Step3.tsx index 3a52abf800..afd21a320a 100644 --- a/src/view/com/auth/create/Step3.tsx +++ b/src/view/com/auth/create/Step3.tsx @@ -30,7 +30,7 @@ export function Step3({ {profile.description ? ( diff --git a/src/view/com/auth/onboarding/WelcomeMobile.tsx b/src/view/com/auth/onboarding/WelcomeMobile.tsx index 5de1a78170..b8659d56cd 100644 --- a/src/view/com/auth/onboarding/WelcomeMobile.tsx +++ b/src/view/com/auth/onboarding/WelcomeMobile.tsx @@ -6,7 +6,8 @@ import {usePalette} from 'lib/hooks/usePalette' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {Button} from 'view/com/util/forms/Button' import {ViewHeader} from 'view/com/util/ViewHeader' -import {Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {Trans, msg} from '@lingui/macro' type Props = { next: () => void @@ -15,6 +16,7 @@ type Props = { export function WelcomeMobile({next, skip}: Props) { const pal = usePalette('default') + const {_} = useLingui() return ( @@ -91,7 +93,7 @@ export function WelcomeMobile({next, skip}: Props) { {canSave === true && ( @@ -504,8 +506,8 @@ function CustomHandleForm({ ) : ( {canSave - ? `Update to ${handle}` - : `Verify ${isDNSForm ? 'DNS Record' : 'Text File'}`} + ? _(msg`Update to ${handle}`) + : _(msg`Verify ${isDNSForm ? 'DNS Record' : 'Text File'}`)} )} @@ -513,9 +515,9 @@ function CustomHandleForm({ + accessibilityHint={_(msg`Use bsky.social as hosting provider`)}> - Nevermind, create a handle for me + Nevermind, create a handle for me diff --git a/src/view/com/modals/ChangePassword.tsx b/src/view/com/modals/ChangePassword.tsx index d8add97946..44d85fc441 100644 --- a/src/view/com/modals/ChangePassword.tsx +++ b/src/view/com/modals/ChangePassword.tsx @@ -180,7 +180,7 @@ export function Component() { Cancel diff --git a/src/view/com/modals/InAppBrowserConsent.tsx b/src/view/com/modals/InAppBrowserConsent.tsx index 86bb46ca81..3fa5159346 100644 --- a/src/view/com/modals/InAppBrowserConsent.tsx +++ b/src/view/com/modals/InAppBrowserConsent.tsx @@ -77,7 +77,7 @@ export function Component({href}: {href: string}) { }} accessibilityLabel={_(msg`Cancel`)} accessibilityHint="" - label="Cancel" + label={_(msg`Cancel`)} labelContainerStyle={{justifyContent: 'center', padding: 8}} labelStyle={[s.f18]} /> diff --git a/src/view/com/modals/LinkWarning.tsx b/src/view/com/modals/LinkWarning.tsx index 81fdc72853..4e6d8f9183 100644 --- a/src/view/com/modals/LinkWarning.tsx +++ b/src/view/com/modals/LinkWarning.tsx @@ -74,7 +74,7 @@ export function Component({text, href}: {text: string; href: string}) { onPress={onPressVisit} accessibilityLabel={_(msg`Visit Site`)} accessibilityHint="" - label="Visit Site" + label={_(msg`Visit Site`)} labelContainerStyle={{justifyContent: 'center', padding: 4}} labelStyle={[s.f18]} /> @@ -86,7 +86,7 @@ export function Component({text, href}: {text: string; href: string}) { }} accessibilityLabel={_(msg`Cancel`)} accessibilityHint="" - label="Cancel" + label={_(msg`Cancel`)} labelContainerStyle={{justifyContent: 'center', padding: 4}} labelStyle={[s.f18]} /> diff --git a/src/view/com/modals/ModerationDetails.tsx b/src/view/com/modals/ModerationDetails.tsx index f890d50dce..6c02276192 100644 --- a/src/view/com/modals/ModerationDetails.tsx +++ b/src/view/com/modals/ModerationDetails.tsx @@ -115,7 +115,7 @@ export function Component({ closeModal() }}> - Okay + Okay diff --git a/src/view/com/modals/VerifyEmail.tsx b/src/view/com/modals/VerifyEmail.tsx index 30a57afc58..d3086d3831 100644 --- a/src/view/com/modals/VerifyEmail.tsx +++ b/src/view/com/modals/VerifyEmail.tsx @@ -149,7 +149,7 @@ export function Component({showReminder}: {showReminder?: boolean}) { onPress={onEmailIncorrect} style={styles.changeEmailLink}> - Change + Change diff --git a/src/view/com/modals/crop-image/CropImage.web.tsx b/src/view/com/modals/crop-image/CropImage.web.tsx index 6f094a1fdf..98a2494edc 100644 --- a/src/view/com/modals/crop-image/CropImage.web.tsx +++ b/src/view/com/modals/crop-image/CropImage.web.tsx @@ -100,7 +100,7 @@ export function Component({ onPress={doSetAs(AspectRatio.Wide)} accessibilityRole="button" accessibilityLabel={_(msg`Wide`)} - accessibilityHint="Sets image aspect ratio to wide"> + accessibilityHint={_(msg`Sets image aspect ratio to wide`)}> + accessibilityHint={_(msg`Sets image aspect ratio to tall`)}> + accessibilityHint={_(msg`Sets image aspect ratio to square`)}> + accessibilityHint={_(msg`Exits image cropping process`)}> - Cancel + Cancel @@ -142,7 +142,7 @@ export function Component({ onPress={onPressDone} accessibilityRole="button" accessibilityLabel={_(msg`Save image crop`)} - accessibilityHint="Saves image crop settings"> + accessibilityHint={_(msg`Saves image crop settings`)}> + accessibilityHint={_(msg`Add more details to your report`)}> {' '} @@ -49,8 +49,8 @@ export function InputIssueDetails({ + accessibilityHint={_(msg`Add more details to your report`)}> Add details to report diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index 826d0d1617..fc13fa0eb8 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -296,7 +296,7 @@ let PostThreadItemLoaded = ({ color={pal.colors.textLight} /> - Muted + Muted )} @@ -578,7 +578,7 @@ let PostThreadItemLoaded = ({ title={itemTitle} noFeedback> - More + More { try { await queueUnfollow() } catch (e: any) { if (e?.name !== 'AbortError') { - Toast.show('An issue occurred, please try again.') + Toast.show(_(msg`An issue occurred, please try again.`)) } } - }, [queueUnfollow]) + }, [queueUnfollow, _]) if (!moderationOpts) { return null @@ -236,7 +238,7 @@ function SuggestedFollow({ From 44259948ccb290c2a52496491c4a8d1cbbd071ef Mon Sep 17 00:00:00 2001 From: Minseo Lee Date: Wed, 14 Feb 2024 16:14:29 +0900 Subject: [PATCH 002/109] Update Drawer.tsx --- src/view/shell/Drawer.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx index 2a37d1fe96..23a15d6bd0 100644 --- a/src/view/shell/Drawer.tsx +++ b/src/view/shell/Drawer.tsx @@ -93,10 +93,12 @@ let DrawerProfileCard = ({ {formatCountShortOnly(profile?.followersCount ?? 0)} {' '} {pluralize(profile?.followersCount || 0, 'follower')} ·{' '} - - {formatCountShortOnly(profile?.followsCount ?? 0)} - {' '} - following + + + {formatCountShortOnly(profile?.followsCount ?? 0)} + {' '} + following + ) From a7661b1f6fa38cec33465ce83f3a40afbeffa65a Mon Sep 17 00:00:00 2001 From: Minseo Lee Date: Thu, 15 Feb 2024 09:19:22 +0900 Subject: [PATCH 003/109] Update src/view/screens/Settings/index.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> --- src/view/screens/Settings/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/screens/Settings/index.tsx b/src/view/screens/Settings/index.tsx index daabf6dea8..a4224290f8 100644 --- a/src/view/screens/Settings/index.tsx +++ b/src/view/screens/Settings/index.tsx @@ -731,7 +731,7 @@ export function SettingsScreen({}: Props) { accessibilityRole="button" accessibilityLabel={_(msg`Change password`)} accessibilityHint={_( - msg`Opens modal for change your Bluesky password`, + msg`Opens modal for changing your Bluesky password`, )}> Date: Thu, 15 Feb 2024 09:19:28 +0900 Subject: [PATCH 004/109] Update src/view/screens/Settings/index.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> --- src/view/screens/Settings/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/screens/Settings/index.tsx b/src/view/screens/Settings/index.tsx index a4224290f8..461c378d20 100644 --- a/src/view/screens/Settings/index.tsx +++ b/src/view/screens/Settings/index.tsx @@ -754,7 +754,7 @@ export function SettingsScreen({}: Props) { accessibilityRole="button" accessibilityLabel={_(msg`Export my data`)} accessibilityHint={_( - msg`Opens modal for download Bluesky account data (repository)`, + msg`Opens modal for downloading Bluesky account data (repository)`, )}> Date: Thu, 15 Feb 2024 09:19:40 +0900 Subject: [PATCH 005/109] Update src/view/com/modals/LinkWarning.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> --- src/view/com/modals/LinkWarning.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/com/modals/LinkWarning.tsx b/src/view/com/modals/LinkWarning.tsx index 4e6d8f9183..6d2f687afd 100644 --- a/src/view/com/modals/LinkWarning.tsx +++ b/src/view/com/modals/LinkWarning.tsx @@ -85,7 +85,7 @@ export function Component({text, href}: {text: string; href: string}) { closeModal() }} accessibilityLabel={_(msg`Cancel`)} - accessibilityHint="" + accessibilityHint={_(msg`Cancels opening the linked website`)} label={_(msg`Cancel`)} labelContainerStyle={{justifyContent: 'center', padding: 4}} labelStyle={[s.f18]} From b0cdaf71ddbe9f6ba1b3b4db3536111c6a42f8a8 Mon Sep 17 00:00:00 2001 From: Minseo Lee Date: Thu, 15 Feb 2024 09:19:46 +0900 Subject: [PATCH 006/109] Update src/view/com/modals/LinkWarning.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> --- src/view/com/modals/LinkWarning.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/com/modals/LinkWarning.tsx b/src/view/com/modals/LinkWarning.tsx index 6d2f687afd..b5ff6700dd 100644 --- a/src/view/com/modals/LinkWarning.tsx +++ b/src/view/com/modals/LinkWarning.tsx @@ -73,7 +73,7 @@ export function Component({text, href}: {text: string; href: string}) { type="primary" onPress={onPressVisit} accessibilityLabel={_(msg`Visit Site`)} - accessibilityHint="" + accessibilityHint={_(msg`Opens the linked website`)} label={_(msg`Visit Site`)} labelContainerStyle={{justifyContent: 'center', padding: 4}} labelStyle={[s.f18]} From 2823e8aa47698bdaa3c1deae2a8e542e2f80592f Mon Sep 17 00:00:00 2001 From: Minseo Lee Date: Thu, 15 Feb 2024 09:19:54 +0900 Subject: [PATCH 007/109] Update src/view/screens/Moderation.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> --- src/view/screens/Moderation.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/screens/Moderation.tsx b/src/view/screens/Moderation.tsx index e96bb396f3..f12f6be0e3 100644 --- a/src/view/screens/Moderation.tsx +++ b/src/view/screens/Moderation.tsx @@ -70,7 +70,7 @@ export function ModerationScreen({}: Props) { onPress={onPressContentFiltering} accessibilityRole="tab" accessibilityLabel={_(msg`Content filtering`)} - accessibilityHint=""> + accessibilityHint={_(msg`Opens the content filtering preferences`)}> Date: Thu, 15 Feb 2024 09:39:29 +0900 Subject: [PATCH 008/109] Update index.tsx --- src/view/screens/Settings/index.tsx | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/view/screens/Settings/index.tsx b/src/view/screens/Settings/index.tsx index 461c378d20..c39fb50045 100644 --- a/src/view/screens/Settings/index.tsx +++ b/src/view/screens/Settings/index.tsx @@ -472,20 +472,20 @@ export function SettingsScreen({}: Props) { label={_(msg`System`)} left onSelect={() => setColorMode('system')} - accessibilityHint={_(msg`Set color theme to system setting`)} + accessibilityHint={_(msg`Sets color theme to system setting`)} /> setColorMode('light')} - accessibilityHint={_(msg`Set color theme to light`)} + accessibilityHint={_(msg`Sets color theme to light`)} /> setColorMode('dark')} - accessibilityHint={_(msg`Set color theme to dark`)} + accessibilityHint={_(msg`Sets color theme to dark`)} /> @@ -504,14 +504,14 @@ export function SettingsScreen({}: Props) { label={_(msg`Dim`)} left onSelect={() => setDarkTheme('dim')} - accessibilityHint={_(msg`Set dark theme to the dim theme`)} + accessibilityHint={_(msg`Sets dark theme to the dim theme`)} /> setDarkTheme('dark')} - accessibilityHint={_(msg`Set dark theme to the dark theme`)} + accessibilityHint={_(msg`Sets dark theme to the dark theme`)} /> @@ -572,9 +572,10 @@ export function SettingsScreen({}: Props) { pal.view, isSwitchingAccounts && styles.dimmed, ]} + onPress={onPressSavedFeeds} + accessibilityRole="button" accessibilityLabel={_(msg`My saved feeds`)} - accessibilityHint={_(msg`Opens screen with all saved feeds`)} - onPress={onPressSavedFeeds}> + accessibilityHint={_(msg`Opens screen with all saved feeds`)}> @@ -673,7 +674,7 @@ export function SettingsScreen({}: Props) { onPress={onPressAppPasswords} accessibilityRole="button" accessibilityLabel={_(msg`App password settings`)} - accessibilityHint={_(msg`Opens the app password settings page`)}> + accessibilityHint={_(msg`Opens the app password settings`)}> + accessibilityHint={_(msg`Opens modal for choosing or creating a new Bluesky username`)}> Date: Thu, 15 Feb 2024 09:41:51 +0900 Subject: [PATCH 009/109] Update index.tsx --- src/view/screens/Settings/index.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/view/screens/Settings/index.tsx b/src/view/screens/Settings/index.tsx index c39fb50045..dd208370d7 100644 --- a/src/view/screens/Settings/index.tsx +++ b/src/view/screens/Settings/index.tsx @@ -695,7 +695,9 @@ export function SettingsScreen({}: Props) { onPress={isSwitchingAccounts ? undefined : onPressChangeHandle} accessibilityRole="button" accessibilityLabel={_(msg`Change handle`)} - accessibilityHint={_(msg`Opens modal for choosing or creating a new Bluesky username`)}> + accessibilityHint={_( + msg`Opens modal for choosing or creating a new Bluesky username`, + )}> Date: Thu, 15 Feb 2024 09:46:30 +0900 Subject: [PATCH 010/109] Update ProfileFeed.tsx --- src/view/screens/ProfileFeed.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/screens/ProfileFeed.tsx b/src/view/screens/ProfileFeed.tsx index d502fdbfbe..4901308ba7 100644 --- a/src/view/screens/ProfileFeed.tsx +++ b/src/view/screens/ProfileFeed.tsx @@ -103,7 +103,7 @@ export function ProfileFeedScreen(props: Props) { From 312f54cfc02c74bf559bd05ebc026a30f054266f Mon Sep 17 00:00:00 2001 From: Minseo Lee Date: Fri, 16 Feb 2024 10:05:40 +0900 Subject: [PATCH 012/109] Update Moderation.tsx --- src/view/screens/Moderation.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/screens/Moderation.tsx b/src/view/screens/Moderation.tsx index f12f6be0e3..36f1fb831f 100644 --- a/src/view/screens/Moderation.tsx +++ b/src/view/screens/Moderation.tsx @@ -70,7 +70,7 @@ export function ModerationScreen({}: Props) { onPress={onPressContentFiltering} accessibilityRole="tab" accessibilityLabel={_(msg`Content filtering`)} - accessibilityHint={_(msg`Opens the content filtering preferences`)}> + accessibilityHint={_(msg`Opens modal for content filtering preferences`)}> Date: Fri, 16 Feb 2024 10:05:43 +0900 Subject: [PATCH 013/109] Update index.tsx --- src/view/screens/Settings/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/screens/Settings/index.tsx b/src/view/screens/Settings/index.tsx index dd208370d7..e2ddd377ec 100644 --- a/src/view/screens/Settings/index.tsx +++ b/src/view/screens/Settings/index.tsx @@ -776,7 +776,7 @@ export function SettingsScreen({}: Props) { accessibilityRole="button" accessibilityLabel={_(msg`Delete account`)} accessibilityHint={_( - msg`Opens modal for account deletion confirmation. Requires email code.`, + msg`Opens modal for account deletion confirmation. Requires email code`, )}> Date: Fri, 16 Feb 2024 10:08:28 +0900 Subject: [PATCH 014/109] Update Moderation.tsx --- src/view/screens/Moderation.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/view/screens/Moderation.tsx b/src/view/screens/Moderation.tsx index 36f1fb831f..9db3580647 100644 --- a/src/view/screens/Moderation.tsx +++ b/src/view/screens/Moderation.tsx @@ -70,7 +70,9 @@ export function ModerationScreen({}: Props) { onPress={onPressContentFiltering} accessibilityRole="tab" accessibilityLabel={_(msg`Content filtering`)} - accessibilityHint={_(msg`Opens modal for content filtering preferences`)}> + accessibilityHint={_( + msg`Opens modal for content filtering preferences`, + )}> Date: Fri, 16 Feb 2024 10:16:56 +0900 Subject: [PATCH 015/109] Update ExportCarDialog.tsx --- src/view/screens/Settings/ExportCarDialog.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/view/screens/Settings/ExportCarDialog.tsx b/src/view/screens/Settings/ExportCarDialog.tsx index 720cd4f090..8c028d4d33 100644 --- a/src/view/screens/Settings/ExportCarDialog.tsx +++ b/src/view/screens/Settings/ExportCarDialog.tsx @@ -78,8 +78,9 @@ export function ExportCarDialog({ - this blogpost. + this blogpost + .

From 2b02976923b6247c5754cea5b21a91d3b1cc0e6a Mon Sep 17 00:00:00 2001 From: Gabriella N <152436322+Titianbeetle@users.noreply.github.com> Date: Fri, 16 Feb 2024 15:27:30 +0100 Subject: [PATCH 016/109] Add files via upload --- src/locale/locales/it/messages.po | 877 +++++++++++++----------------- 1 file changed, 376 insertions(+), 501 deletions(-) diff --git a/src/locale/locales/it/messages.po b/src/locale/locales/it/messages.po index a76f3fdd83..ea93bdfd08 100644 --- a/src/locale/locales/it/messages.po +++ b/src/locale/locales/it/messages.po @@ -1,11 +1,11 @@ msgid "" msgstr "" -"Project-Id-Version: \n" +"Project-Id-Version: Italian localization\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-01-05 11:44+0530\n" "PO-Revision-Date: \n" "Last-Translator: Gabriella Nonino \n" -"Language-Team: \n" +"Language-Team: Gabriella Nonino sandsiwmmer@gmail.com\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,35 +18,10 @@ msgstr "" msgid "(no email)" msgstr "(no email)" -#: src/view/shell/desktop/RightNav.tsx:168 -#~ msgid "{0, plural, one {# invite code available} other {# invite codes available}}" -#~ msgstr "{0, plural, one {# codice d'invito disponibile} other {# codici d'inviti disponibili}}" - -#~ msgid "{0}" -#~ msgstr "{0}" - -#~ msgid "{0} {purposeLabel} List" -#~ msgstr "Llista {purposeLabel} {0}" - #: src/view/com/profile/ProfileHeader.tsx:592 msgid "{following} following" msgstr "{following} seguendo" -#: src/view/shell/desktop/RightNav.tsx:151 -#~ msgid "{invitesAvailable, plural, one {Invite codes: # available} other {Invite codes: # available}}" -#~ msgstr "{invitesAvailable, plural, one {Codici d'invito: # available} other {Codici d'invito: # available}}" - -#: src/view/screens/Settings.tsx:NaN -#~ msgid "{invitesAvailable} invite code available" -#~ msgstr "{invitesAvailable} codice d'invito disponibile" - -#: src/view/screens/Settings.tsx:NaN -#~ msgid "{invitesAvailable} invite codes available" -#~ msgstr "{invitesAvailable} codici d'invito disponibili" - -#~ msgid "{message}" -#~ msgstr "{message}" - #: src/view/shell/Drawer.tsx:440 msgid "{numUnreadNotifications} unread" msgstr "{numUnreadNotifications} non letto" @@ -83,8 +58,7 @@ msgstr "A questo post è stato applicato un avviso di contenuto {0}." msgid "A new version of the app is available. Please update to continue using the app." msgstr "È disponibile una nuova versione dell'app. Aggiorna per continuare a utilizzarla." -#: src/view/com/util/ViewHeader.tsx:83 -#: src/view/screens/Search/Search.tsx:624 +#: src/view/com/util/ViewHeader.tsx:83 src/view/screens/Search/Search.tsx:624 msgid "Access navigation links and settings" msgstr "Accedi alle impostazioni di navigazione" @@ -161,8 +135,7 @@ msgstr "Aggiungi account" msgid "Add alt text" msgstr "Aggiungi testo alternativo" -#: src/view/screens/AppPasswords.tsx:102 -#: src/view/screens/AppPasswords.tsx:143 +#: src/view/screens/AppPasswords.tsx:102 src/view/screens/AppPasswords.tsx:143 #: src/view/screens/AppPasswords.tsx:156 msgid "Add App Password" msgstr "Aggiungi la Password per l'App" @@ -228,12 +201,12 @@ msgstr "Avanzato" #: src/view/screens/Feeds.tsx:666 msgid "All the feeds you've saved, right in one place." -msgstr "" +msgstr "Tutti i feed che hai salvato, in un unico posto." #: src/view/com/auth/login/ForgotPasswordForm.tsx:221 #: src/view/com/modals/ChangePassword.tsx:168 msgid "Already have a code?" -msgstr "" +msgstr "Hai già un codice?" #: src/view/com/auth/login/ChooseAccountForm.tsx:98 msgid "Already signed in as @{0}" @@ -271,7 +244,7 @@ msgstr "e" #: src/screens/Onboarding/index.tsx:32 msgid "Animals" -msgstr "" +msgstr "Animali" #: src/view/screens/LanguageSettings.tsx:95 msgid "App Language" @@ -293,12 +266,7 @@ msgstr "I nomi delle password delle app devono contenere almeno 4 caratteri." msgid "App password settings" msgstr "Impostazioni della password dell'app" -#: src/view/screens/Settings.tsx:650 -#~ msgid "App passwords" -#~ msgstr "Passwords dell'app" - -#: src/Navigation.tsx:237 -#: src/view/screens/AppPasswords.tsx:187 +#: src/Navigation.tsx:237 src/view/screens/AppPasswords.tsx:187 #: src/view/screens/Settings/index.tsx:684 msgid "App Passwords" msgstr "Passwords dell'App" @@ -311,9 +279,6 @@ msgstr "Ricorso contro l'avviso sui contenuti" msgid "Appeal Content Warning" msgstr "Ricorso contro l'Avviso sui Contenuti" -#~ msgid "Appeal Decision" -#~ msgstr "Decisión de apelación" - #: src/view/com/util/moderation/LabelInfo.tsx:52 msgid "Appeal this decision" msgstr "Appella contro questa decisione" @@ -348,7 +313,7 @@ msgstr "Stai scrivendo in <0>{0}?" #: src/screens/Onboarding/index.tsx:26 msgid "Art" -msgstr "" +msgstr "Arte" #: src/view/com/modals/SelfLabel.tsx:123 msgid "Artistic or non-erotic nudity." @@ -375,7 +340,7 @@ msgstr "Indietro" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:136 msgid "Based on your interest in {interestsText}" -msgstr "" +msgstr "Basato su i tuoi interessi {interestsText}" #: src/view/screens/Settings/index.tsx:523 msgid "Basics" @@ -420,8 +385,7 @@ msgstr "Bloccato" msgid "Blocked accounts" msgstr "Accounts bloccati" -#: src/Navigation.tsx:130 -#: src/view/screens/ModerationBlockedAccounts.tsx:107 +#: src/Navigation.tsx:130 src/view/screens/ModerationBlockedAccounts.tsx:107 msgid "Blocked Accounts" msgstr "Accounts bloccati" @@ -454,7 +418,7 @@ msgstr "Bluesky" #: src/view/com/auth/server-input/index.tsx:150 msgid "Bluesky is an open network where you can choose your hosting provider. Custom hosting is now available in beta for developers." -msgstr "" +msgstr "Bluesky è una network aperto in cui puoi scegliere il tuo provider di hosting. L'hosting personalizzato adesso è disponibile in versione beta per i developers." #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:80 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:80 @@ -479,13 +443,9 @@ msgstr "Bluesky utilizza gli inviti per costruire una comunità più sana. Se no msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "Bluesky non mostrerà il tuo profilo e i tuoi post agli utenti disconnessi. Altre app potrebbero non rispettare questa richiesta. Questo non rende il tuo account privato." -#: src/view/com/modals/ServerInput.tsx:78 -#~ msgid "Bluesky.Social" -#~ msgstr "Bluesky.Social" - #: src/screens/Onboarding/index.tsx:33 msgid "Books" -msgstr "" +msgstr "Libri" #: src/view/screens/Settings/index.tsx:859 msgid "Build version {0} {1}" @@ -496,10 +456,6 @@ msgstr "Versione {0} {1}" msgid "Business" msgstr "Attività commerciale" -#: src/view/com/modals/ServerInput.tsx:115 -#~ msgid "Button disabled. Input custom domain to proceed." -#~ msgstr "Pulsante disabilitato. Inserisci il dominio personalizzato per procedere." - #: src/view/com/profile/ProfileSubpageHeader.tsx:157 msgid "by —" msgstr "da—" @@ -517,8 +473,7 @@ msgid "by you" msgstr "da te" #: src/view/com/composer/photos/OpenCameraBtn.tsx:60 -#: src/view/com/util/UserAvatar.tsx:224 -#: src/view/com/util/UserBanner.tsx:40 +#: src/view/com/util/UserAvatar.tsx:224 src/view/com/util/UserBanner.tsx:40 msgid "Camera" msgstr "Fotocamera" @@ -526,8 +481,7 @@ msgstr "Fotocamera" msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must be at least 4 characters long, but no more than 32 characters long." msgstr "Può contenere solo lettere, numeri, spazi, trattini e trattini bassi. Deve contenere almeno 4 caratteri, ma non più di 32 caratteri." -#: src/components/Prompt.tsx:91 -#: src/view/com/composer/Composer.tsx:300 +#: src/components/Prompt.tsx:91 src/view/com/composer/Composer.tsx:300 #: src/view/com/composer/Composer.tsx:305 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 @@ -537,18 +491,14 @@ msgstr "Può contenere solo lettere, numeri, spazi, trattini e trattini bassi. D #: src/view/com/modals/EditImage.tsx:323 #: src/view/com/modals/EditProfile.tsx:249 #: src/view/com/modals/InAppBrowserConsent.tsx:78 -#: src/view/com/modals/LinkWarning.tsx:87 -#: src/view/com/modals/Repost.tsx:87 +#: src/view/com/modals/LinkWarning.tsx:87 src/view/com/modals/Repost.tsx:87 #: src/view/com/modals/VerifyEmail.tsx:247 -#: src/view/com/modals/VerifyEmail.tsx:253 -#: src/view/com/modals/Waitlist.tsx:142 -#: src/view/screens/Search/Search.tsx:693 -#: src/view/shell/desktop/Search.tsx:238 +#: src/view/com/modals/VerifyEmail.tsx:253 src/view/com/modals/Waitlist.tsx:142 +#: src/view/screens/Search/Search.tsx:693 src/view/shell/desktop/Search.tsx:238 msgid "Cancel" msgstr "Cancella" -#: src/view/com/modals/Confirm.tsx:88 -#: src/view/com/modals/Confirm.tsx:91 +#: src/view/com/modals/Confirm.tsx:88 src/view/com/modals/Confirm.tsx:91 #: src/view/com/modals/CreateOrEditList.tsx:360 #: src/view/com/modals/DeleteAccount.tsx:156 #: src/view/com/modals/DeleteAccount.tsx:234 @@ -561,9 +511,6 @@ msgstr "Cancella" msgid "Cancel account deletion" msgstr "Annulla la cancellazione dell'account" -#~ msgid "Cancel add image alt text" -#~ msgstr "Cancel·la afegir text a la imatge" - #: src/view/com/modals/ChangeHandle.tsx:149 msgid "Cancel change handle" msgstr "Annulla il cambio del tuo nome utente" @@ -594,9 +541,6 @@ msgctxt "action" msgid "Change" msgstr "Cambia" -#~ msgid "Change" -#~ msgstr "Canvia" - #: src/view/screens/Settings/index.tsx:696 msgid "Change handle" msgstr "Cambia il nome utente" @@ -612,11 +556,11 @@ msgstr "Cambia la mia email" #: src/view/screens/Settings/index.tsx:732 msgid "Change password" -msgstr "" +msgstr "Cambia la password" #: src/view/screens/Settings/index.tsx:741 msgid "Change Password" -msgstr "" +msgstr "Cambia la Password" #: src/view/com/composer/select-language/SuggestedLanguage.tsx:73 msgid "Change post language to {0}" @@ -624,16 +568,15 @@ msgstr "Cambia la lingua del post a {0}" #: src/view/screens/Settings/index.tsx:733 msgid "Change your Bluesky password" -msgstr "" +msgstr "Cambia la tua password di Bluesky" #: src/view/com/modals/ChangeEmail.tsx:109 msgid "Change Your Email" msgstr "Cambia la tua email" -#: src/screens/Deactivated.tsx:72 -#: src/screens/Deactivated.tsx:76 +#: src/screens/Deactivated.tsx:72 src/screens/Deactivated.tsx:76 msgid "Check my status" -msgstr "" +msgstr "Verifica il mio stato" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:121 msgid "Check out some recommended feeds. Tap + to add them to your list of pinned feeds." @@ -661,7 +604,7 @@ msgstr "Scegli il servizio" #: src/screens/Onboarding/StepFinished.tsx:135 msgid "Choose the algorithms that power your custom feeds." -msgstr "" +msgstr "Scegli gli algoritmi che compilano i tuoi feed personalizzati." #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:83 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:83 @@ -670,7 +613,7 @@ msgstr "Scegli gli algoritmi che alimentano la tua esperienza con feed personali #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 msgid "Choose your main feeds" -msgstr "" +msgstr "Scegli i tuoi feed principali" #: src/view/com/auth/create/Step1.tsx:215 msgid "Choose your password" @@ -705,12 +648,12 @@ msgstr "clicca qui" #: src/screens/Onboarding/index.tsx:35 msgid "Climate" -msgstr "" +msgstr "Il clima" #: src/view/com/modals/ChangePassword.tsx:265 #: src/view/com/modals/ChangePassword.tsx:268 msgid "Close" -msgstr "" +msgstr "Chiudi" #: src/components/Dialog/index.web.tsx:78 msgid "Close active dialog" @@ -758,20 +701,19 @@ msgstr "Comprime l'elenco degli utenti per una determinata notifica" #: src/screens/Onboarding/index.tsx:41 msgid "Comedy" -msgstr "" +msgstr "Commedia" #: src/screens/Onboarding/index.tsx:27 msgid "Comics" -msgstr "" +msgstr "Fumetti" -#: src/Navigation.tsx:227 -#: src/view/screens/CommunityGuidelines.tsx:32 +#: src/Navigation.tsx:227 src/view/screens/CommunityGuidelines.tsx:32 msgid "Community Guidelines" msgstr "Linee guida della community" #: src/screens/Onboarding/StepFinished.tsx:148 msgid "Complete onboarding and start using your account" -msgstr "" +msgstr "Completa l'incorporazione e inizia a utilizzare il tuo account" #: src/view/com/composer/Composer.tsx:417 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" @@ -783,10 +725,9 @@ msgstr "Scrivi la risposta" #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:67 msgid "Configure content filtering setting for category: {0}" -msgstr "" +msgstr "Configura l'impostazione del filtro dei contenuti per la categoria:{0}" -#: src/components/Prompt.tsx:113 -#: src/view/com/modals/AppealLabel.tsx:98 +#: src/components/Prompt.tsx:113 src/view/com/modals/AppealLabel.tsx:98 #: src/view/com/modals/SelfLabel.tsx:154 #: src/view/com/modals/VerifyEmail.tsx:231 #: src/view/com/modals/VerifyEmail.tsx:233 @@ -795,8 +736,7 @@ msgstr "" msgid "Confirm" msgstr "Conferma" -#: src/view/com/modals/Confirm.tsx:75 -#: src/view/com/modals/Confirm.tsx:78 +#: src/view/com/modals/Confirm.tsx:75 src/view/com/modals/Confirm.tsx:78 msgctxt "action" msgid "Confirm" msgstr "Conferma" @@ -878,19 +818,19 @@ msgstr "Continua" #: src/screens/Onboarding/StepModeration/index.tsx:115 #: src/screens/Onboarding/StepTopicalFeeds.tsx:105 msgid "Continue to next step" -msgstr "" +msgstr "Vai al passaggio successivo" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:167 msgid "Continue to the next step" -msgstr "" +msgstr "Vai al passaggio successivo" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:191 msgid "Continue to the next step without following any accounts" -msgstr "" +msgstr "Vai al passaggio successivo senza seguire nessun account" #: src/screens/Onboarding/index.tsx:44 msgid "Cooking" -msgstr "" +msgstr "Cucina" #: src/view/com/modals/AddAppPasswords.tsx:195 #: src/view/com/modals/InviteCodes.tsx:182 @@ -931,8 +871,7 @@ msgstr "Copia il link al profilo" msgid "Copy post text" msgstr "Copia il testo del post" -#: src/Navigation.tsx:232 -#: src/view/screens/CopyrightPolicy.tsx:29 +#: src/Navigation.tsx:232 src/view/screens/CopyrightPolicy.tsx:29 msgid "Copyright Policy" msgstr "Politica sul diritto d'autore" @@ -989,12 +928,12 @@ msgstr "Crea una scheda con una miniatura. La scheda si collega a {url}" #: src/screens/Onboarding/index.tsx:29 msgid "Culture" -msgstr "" +msgstr "Cultura" #: src/view/com/auth/server-input/index.tsx:95 #: src/view/com/auth/server-input/index.tsx:96 msgid "Custom" -msgstr "" +msgstr "Personalizzatp" #: src/view/com/modals/ChangeHandle.tsx:389 msgid "Custom domain" @@ -1003,16 +942,12 @@ msgstr "Dominio personalizzato" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 #: src/view/screens/Feeds.tsx:692 msgid "Custom feeds built by the community bring you new experiences and help you find the content you love." -msgstr "" +msgstr "I feed personalizzati creati dalla comunità ti offrono nuove esperienze e ti aiutano a trovare i contenuti che ami." #: src/view/screens/PreferencesExternalEmbeds.tsx:55 msgid "Customize media from external sites." msgstr "Personalizza i media da i siti esterni." -#: src/view/screens/Settings.tsx:687 -#~ msgid "Danger Zone" -#~ msgstr "Zona di Pericolo" - #: src/view/screens/Settings/index.tsx:485 #: src/view/screens/Settings/index.tsx:511 msgid "Dark" @@ -1024,7 +959,7 @@ msgstr "Aspetto scuro" #: src/view/screens/Settings/index.tsx:498 msgid "Dark Theme" -msgstr "" +msgstr "Tema scuro" #: src/view/screens/Debug.tsx:83 msgid "Debug panel" @@ -1038,27 +973,21 @@ msgstr "Eliminare l'account" msgid "Delete Account" msgstr "Eliminare l'Account" -#: src/view/screens/AppPasswords.tsx:222 -#: src/view/screens/AppPasswords.tsx:242 +#: src/view/screens/AppPasswords.tsx:222 src/view/screens/AppPasswords.tsx:242 msgid "Delete app password" msgstr "Elimina la password dell'app" -#: src/view/screens/ProfileList.tsx:363 -#: src/view/screens/ProfileList.tsx:444 +#: src/view/screens/ProfileList.tsx:363 src/view/screens/ProfileList.tsx:444 msgid "Delete List" msgstr "Elimina la lista" #: src/view/com/modals/DeleteAccount.tsx:223 msgid "Delete my account" -msgstr "Cancella il mio account" - -#: src/view/screens/Settings.tsx:706 -#~ msgid "Delete my account…" -#~ msgstr "Cancella il mio account…" +msgstr "Cancellare account" #: src/view/screens/Settings/index.tsx:784 msgid "Delete My Account…" -msgstr "" +msgstr "Cancellare Account…" #: src/view/com/util/forms/PostDropdownBtn.tsx:228 msgid "Delete post" @@ -1083,20 +1012,13 @@ msgstr "Post eliminato." msgid "Description" msgstr "Descrizione" -#~ msgid "Dev Server" -#~ msgstr "Servidor de desenvolupament" - -#: src/view/screens/Settings.tsx:711 -#~ msgid "Developer Tools" -#~ msgstr "Strumenti per sviluppatori" - #: src/view/com/composer/Composer.tsx:211 msgid "Did you want to say anything?" msgstr "Volevi dire qualcosa?" #: src/view/screens/Settings/index.tsx:504 msgid "Dim" -msgstr "" +msgstr "Fioco" #: src/view/com/composer/Composer.tsx:144 msgid "Discard" @@ -1115,13 +1037,9 @@ msgstr "Scoraggia le app dal mostrare il mio account agli utenti disconnessi" msgid "Discover new custom feeds" msgstr "Scopri nuovi feed personalizzati" -#: src/view/screens/Feeds.tsx:409 -#~ msgid "Discover new feeds" -#~ msgstr "Scopri nuovi feeds" - #: src/view/screens/Feeds.tsx:689 msgid "Discover New Feeds" -msgstr "" +msgstr "Scopri nuovi feed" #: src/view/com/modals/EditProfile.tsx:192 msgid "Display name" @@ -1142,8 +1060,7 @@ msgstr "Non hai un codice di invito?" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:86 #: src/view/com/modals/EditImage.tsx:333 #: src/view/com/modals/ListAddRemoveUsers.tsx:144 -#: src/view/com/modals/SelfLabel.tsx:157 -#: src/view/com/modals/Threadgate.tsx:129 +#: src/view/com/modals/SelfLabel.tsx:157 src/view/com/modals/Threadgate.tsx:129 #: src/view/com/modals/Threadgate.tsx:132 #: src/view/com/modals/UserAddRemoveLists.tsx:95 #: src/view/com/modals/UserAddRemoveLists.tsx:98 @@ -1178,20 +1095,20 @@ msgstr "Usa il doppio tocco per accedere" #: src/view/screens/Settings/index.tsx:755 msgid "Download Bluesky account data (repository)" -msgstr "" +msgstr "Scarica i dati dell'account Bluesky (archivio)" #: src/view/screens/Settings/ExportCarDialog.tsx:59 #: src/view/screens/Settings/ExportCarDialog.tsx:63 msgid "Download CAR file" -msgstr "" +msgstr "Scarica il CAR file" #: src/view/com/composer/text-input/TextInput.web.tsx:247 msgid "Drop to add images" -msgstr "" +msgstr "Trascina e rilascia per aggiungere immagini" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:111 msgid "Due to Apple policies, adult content can only be enabled on the web after completing sign up." -msgstr "" +msgstr "A causa delle politiche di Apple, i contenuti per adulti possono essere abilitati sul Web solo dopo aver completato la registrazione." #: src/view/com/modals/EditProfile.tsx:185 msgid "e.g. Alice Roberts" @@ -1239,8 +1156,7 @@ msgstr "Modifica i dettagli della lista" msgid "Edit Moderation List" msgstr "Modifica l'elenco di moderazione" -#: src/Navigation.tsx:242 -#: src/view/screens/Feeds.tsx:434 +#: src/Navigation.tsx:242 src/view/screens/Feeds.tsx:434 #: src/view/screens/SavedFeeds.tsx:84 msgid "Edit My Feeds" msgstr "Modifica i miei feeds" @@ -1275,14 +1191,13 @@ msgstr "Modifica la descrizione del tuo profilo" #: src/screens/Onboarding/index.tsx:34 msgid "Education" -msgstr "" +msgstr "Formazione scolastica" #: src/view/com/auth/create/Step1.tsx:195 #: src/view/com/auth/create/Step2.tsx:194 #: src/view/com/auth/create/Step2.tsx:269 #: src/view/com/auth/login/ForgotPasswordForm.tsx:156 -#: src/view/com/modals/ChangeEmail.tsx:141 -#: src/view/com/modals/Waitlist.tsx:88 +#: src/view/com/modals/ChangeEmail.tsx:141 src/view/com/modals/Waitlist.tsx:88 msgid "Email" msgstr "Email" @@ -1319,7 +1234,7 @@ msgstr "Attiva Contenuto per Adulti" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:76 #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:77 msgid "Enable adult content in your feeds" -msgstr "" +msgstr "Abilita i contenuti per adulti nei tuoi feed" #: src/view/com/modals/EmbedConsent.tsx:97 msgid "Enable External Media" @@ -1345,12 +1260,9 @@ msgstr "Inserisci un nome per questa password dell'app" msgid "Enter Confirmation Code" msgstr "Inserire il codice di conferma" -#~ msgid "Enter the address of your provider:" -#~ msgstr "Introdueix l'adreça del teu proveïdor:" - #: src/view/com/modals/ChangePassword.tsx:151 msgid "Enter the code you received to change your password." -msgstr "" +msgstr "Inserisci il codice che hai ricevuto per modificare la tua password." #: src/view/com/modals/ChangeHandle.tsx:371 msgid "Enter the domain you want to use" @@ -1425,12 +1337,12 @@ msgstr "Espandi o comprimi l'intero post a cui stai rispondendo" #: src/view/screens/Settings/index.tsx:753 msgid "Export my data" -msgstr "" +msgstr "Esporta i miei dati" #: src/view/screens/Settings/ExportCarDialog.tsx:44 #: src/view/screens/Settings/index.tsx:764 msgid "Export My Data" -msgstr "" +msgstr "Esporta i miei dati" #: src/view/com/modals/EmbedConsent.tsx:64 msgid "External Media" @@ -1441,8 +1353,7 @@ msgstr "Media esterni" msgid "External media may allow websites to collect information about you and your device. No information is sent or requested until you press the \"play\" button." msgstr "I multimediali esterni possono consentire ai siti web di raccogliere informazioni su di te e sul tuo dispositivo. Nessuna informazione viene inviata o richiesta finché non si preme il pulsante \"Riproduci\"." -#: src/Navigation.tsx:258 -#: src/view/screens/PreferencesExternalEmbeds.tsx:52 +#: src/Navigation.tsx:258 src/view/screens/PreferencesExternalEmbeds.tsx:52 #: src/view/screens/Settings/index.tsx:657 msgid "External Media Preferences" msgstr "Preferenze multimediali esterni" @@ -1485,18 +1396,14 @@ msgstr "Feed offline" msgid "Feed Preferences" msgstr "Preferenze del feed" -#: src/view/shell/desktop/RightNav.tsx:69 -#: src/view/shell/Drawer.tsx:311 +#: src/view/shell/desktop/RightNav.tsx:69 src/view/shell/Drawer.tsx:311 msgid "Feedback" msgstr "Commenti" -#: src/Navigation.tsx:442 -#: src/view/screens/Feeds.tsx:419 -#: src/view/screens/Feeds.tsx:524 -#: src/view/screens/Profile.tsx:184 +#: src/Navigation.tsx:442 src/view/screens/Feeds.tsx:419 +#: src/view/screens/Feeds.tsx:524 src/view/screens/Profile.tsx:184 #: src/view/shell/bottom-bar/BottomBar.tsx:181 -#: src/view/shell/desktop/LeftNav.tsx:342 -#: src/view/shell/Drawer.tsx:476 +#: src/view/shell/desktop/LeftNav.tsx:342 src/view/shell/Drawer.tsx:476 #: src/view/shell/Drawer.tsx:477 msgid "Feeds" msgstr "Feeds" @@ -1511,11 +1418,11 @@ msgstr "I feed sono algoritmi personalizzati che gli utenti creano con un minimo #: src/screens/Onboarding/StepTopicalFeeds.tsx:70 msgid "Feeds can be topical as well!" -msgstr "" +msgstr "I feeds possono anche avere tematiche!" #: src/screens/Onboarding/StepFinished.tsx:151 msgid "Finalizing" -msgstr "" +msgstr "Finalizzando" #: src/view/com/posts/CustomFeedEmptyState.tsx:47 #: src/view/com/posts/FollowingEmptyState.tsx:57 @@ -1545,18 +1452,17 @@ msgstr "Ottimizza i la visualizzazione delle discussioni." #: src/screens/Onboarding/index.tsx:38 msgid "Fitness" -msgstr "" +msgstr "Fitness" #: src/screens/Onboarding/StepFinished.tsx:131 msgid "Flexible" -msgstr "" +msgstr "Flessibile" #: src/view/com/modals/EditImage.tsx:115 msgid "Flip horizontal" msgstr "Gira in orizzontale" -#: src/view/com/modals/EditImage.tsx:120 -#: src/view/com/modals/EditImage.tsx:287 +#: src/view/com/modals/EditImage.tsx:120 src/view/com/modals/EditImage.tsx:287 msgid "Flip vertically" msgstr "Gira in verticale" @@ -1579,11 +1485,11 @@ msgstr "Segui {0}" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:179 msgid "Follow All" -msgstr "" +msgstr "Segui tutti" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:174 msgid "Follow selected accounts and continue to the next step" -msgstr "" +msgstr "Segui gli account selezionati e vai al passaggio successivo" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:64 msgid "Follow some users to get started. We can recommend you more users based on who you find interesting." @@ -1609,9 +1515,6 @@ msgstr "ti segue" msgid "Followers" msgstr "Seguiti" -#~ msgid "following" -#~ msgstr "seguint" - #: src/view/com/post-thread/PostThreadFollowBtn.tsx:136 #: src/view/com/profile/ProfileHeader.tsx:494 #: src/view/screens/ProfileFollows.tsx:25 @@ -1632,7 +1535,7 @@ msgstr "Ti Segue" #: src/screens/Onboarding/index.tsx:43 msgid "Food" -msgstr "" +msgstr "Gastronomia" #: src/view/com/modals/DeleteAccount.tsx:111 msgid "For security reasons, we'll need to send a confirmation code to your email address." @@ -1650,8 +1553,7 @@ msgstr "Dimenticato" msgid "Forgot password" msgstr "Ho dimenticato il password" -#: src/view/com/auth/login/Login.tsx:127 -#: src/view/com/auth/login/Login.tsx:143 +#: src/view/com/auth/login/Login.tsx:127 src/view/com/auth/login/Login.tsx:143 msgid "Forgot Password" msgstr "Ho dimenticato il Password" @@ -1669,27 +1571,22 @@ msgstr "Galleria" msgid "Get Started" msgstr "Inizia" -#: src/view/com/auth/LoggedOut.tsx:81 -#: src/view/com/auth/LoggedOut.tsx:82 +#: src/view/com/auth/LoggedOut.tsx:81 src/view/com/auth/LoggedOut.tsx:82 #: src/view/com/util/moderation/ScreenHider.tsx:123 #: src/view/shell/desktop/LeftNav.tsx:104 msgid "Go back" msgstr "Torna indietro" -#: src/view/screens/ProfileFeed.tsx:105 -#: src/view/screens/ProfileFeed.tsx:110 -#: src/view/screens/ProfileList.tsx:897 -#: src/view/screens/ProfileList.tsx:902 +#: src/view/screens/ProfileFeed.tsx:105 src/view/screens/ProfileFeed.tsx:110 +#: src/view/screens/ProfileList.tsx:897 src/view/screens/ProfileList.tsx:902 msgid "Go Back" msgstr "Torna Indietro" -#: src/screens/Onboarding/Layout.tsx:104 -#: src/screens/Onboarding/Layout.tsx:193 +#: src/screens/Onboarding/Layout.tsx:104 src/screens/Onboarding/Layout.tsx:193 msgid "Go back to previous step" -msgstr "" +msgstr "Torna al passaggio precedente" -#: src/view/screens/Search/Search.tsx:724 -#: src/view/shell/desktop/Search.tsx:262 +#: src/view/screens/Search/Search.tsx:724 src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" msgstr "Vai a @{queryMaybeHandle}" @@ -1709,22 +1606,21 @@ msgstr "Nome Utente" msgid "Having trouble?" msgstr "Ci sono problemi?" -#: src/view/shell/desktop/RightNav.tsx:98 -#: src/view/shell/Drawer.tsx:321 +#: src/view/shell/desktop/RightNav.tsx:98 src/view/shell/Drawer.tsx:321 msgid "Help" msgstr "Aiuto" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:132 msgid "Here are some accounts for you to follow" -msgstr "" +msgstr "Ecco alcuni account da seguire" #: src/screens/Onboarding/StepTopicalFeeds.tsx:79 msgid "Here are some popular topical feeds. You can choose to follow as many as you like." -msgstr "" +msgstr "Ecco alcuni feed più visitati. Puoi seguire quanti ne vuoi." #: src/screens/Onboarding/StepTopicalFeeds.tsx:74 msgid "Here are some topical feeds based on your interests: {interestsText}. You can choose to follow as many as you like." -msgstr "" +msgstr "Ecco alcuni feed di attualità scelti in base ai tuoi interessi: {interestsText}. Puoi seguire quanti ne vuoi." #: src/view/com/modals/AddAppPasswords.tsx:153 msgid "Here is your app password." @@ -1784,16 +1680,13 @@ msgstr "Il server del feed ha dato una risposta negativa. Informa il proprietari msgid "Hmm, we're having trouble finding this feed. It may have been deleted." msgstr "Stiamo riscontrando problemi nel trovare questo feed. Potrebbe essere stato cancellato." -#: src/Navigation.tsx:432 -#: src/view/shell/bottom-bar/BottomBar.tsx:137 -#: src/view/shell/desktop/LeftNav.tsx:306 -#: src/view/shell/Drawer.tsx:398 +#: src/Navigation.tsx:432 src/view/shell/bottom-bar/BottomBar.tsx:137 +#: src/view/shell/desktop/LeftNav.tsx:306 src/view/shell/Drawer.tsx:398 #: src/view/shell/Drawer.tsx:399 msgid "Home" msgstr "Home" -#: src/Navigation.tsx:247 -#: src/view/com/pager/FeedsTabBarMobile.tsx:123 +#: src/Navigation.tsx:247 src/view/com/pager/FeedsTabBarMobile.tsx:123 #: src/view/screens/PreferencesHomeFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 msgid "Home Feed Preferences" @@ -1804,9 +1697,6 @@ msgstr "Preferenze per i feed per la pagina d'inizio" msgid "Hosting provider" msgstr "Servizio di hosting" -#~ msgid "Hosting provider address" -#~ msgstr "Adreça del proveïdor d'allotjament" - #: src/view/com/modals/InAppBrowserConsent.tsx:44 msgid "How should we open this link?" msgstr "Come dovremmo aprire questo link?" @@ -1833,7 +1723,7 @@ msgstr "Se niente è selezionato, adatto a tutte le età." #: src/view/com/modals/ChangePassword.tsx:146 msgid "If you want to change your password, we will send you a code to verify that this is your account." -msgstr "" +msgstr "Se vuoi modificare la password, ti invieremo un codice per verificare se questo è il tuo account." #: src/view/com/util/images/Gallery.tsx:38 msgid "Image" @@ -1843,8 +1733,7 @@ msgstr "Immagine" msgid "Image alt text" msgstr "Testo alternativo dell'immagine" -#: src/view/com/util/UserAvatar.tsx:311 -#: src/view/com/util/UserBanner.tsx:118 +#: src/view/com/util/UserAvatar.tsx:311 src/view/com/util/UserBanner.tsx:118 msgid "Image options" msgstr "Opzioni per l'immagine" @@ -1912,10 +1801,6 @@ msgstr "Protocollo del post non valido o non supportato" msgid "Invalid username or password" msgstr "Nome dell'utente o password errato" -#: src/view/screens/Settings.tsx:411 -#~ msgid "Invite" -#~ msgstr "Invita" - #: src/view/com/modals/InviteCodes.tsx:93 msgid "Invite a Friend" msgstr "Invita un amico" @@ -1933,17 +1818,13 @@ msgstr "Codice invito non accettato. Controlla di averlo inserito correttamente msgid "Invite codes: {0} available" msgstr "Codici di invito: {0} disponibili" -#: src/view/shell/Drawer.tsx:645 -#~ msgid "Invite codes: {invitesAvailable} available" -#~ msgstr "Codici di invito: {invitesAvailable} disponibili" - #: src/view/com/modals/InviteCodes.tsx:169 msgid "Invite codes: 1 available" msgstr "Codici di invito: 1 disponibile" #: src/screens/Onboarding/StepFollowingFeed.tsx:64 msgid "It shows posts from the people you follow as they happen." -msgstr "" +msgstr "Mostra i post delle persone che segui." #: src/view/com/auth/HomeLoggedOutCTA.tsx:99 #: src/view/com/auth/SplashScreen.web.tsx:138 @@ -1965,7 +1846,7 @@ msgstr "Iscriviti alla Lista d'Attesa" #: src/screens/Onboarding/index.tsx:24 msgid "Journalism" -msgstr "" +msgstr "Giornalismo" #: src/view/com/composer/select-language/SelectLangBtn.tsx:104 msgid "Language selection" @@ -1975,8 +1856,7 @@ msgstr "Seleziona la lingua" msgid "Language settings" msgstr "Impostazione delle lingue" -#: src/Navigation.tsx:140 -#: src/view/screens/LanguageSettings.tsx:89 +#: src/Navigation.tsx:140 src/view/screens/LanguageSettings.tsx:89 msgid "Language Settings" msgstr "Impostazione delle Lingue" @@ -2020,23 +1900,21 @@ msgstr "Stai lasciando Bluesky" #: src/screens/Deactivated.tsx:128 msgid "left to go." -msgstr "" +msgstr "mancano." #: src/view/screens/Settings/index.tsx:278 msgid "Legacy storage cleared, you need to restart the app now." msgstr "L'archivio legacy è stato cancellato, riattiva la app." -#: src/view/com/auth/login/Login.tsx:128 -#: src/view/com/auth/login/Login.tsx:144 +#: src/view/com/auth/login/Login.tsx:128 src/view/com/auth/login/Login.tsx:144 msgid "Let's get your password reset!" msgstr "Reimpostazione della password!" #: src/screens/Onboarding/StepFinished.tsx:151 msgid "Let's go!" -msgstr "" +msgstr "Andiamo!" -#: src/view/com/util/UserAvatar.tsx:248 -#: src/view/com/util/UserBanner.tsx:62 +#: src/view/com/util/UserAvatar.tsx:248 src/view/com/util/UserBanner.tsx:62 msgid "Library" msgstr "Biblioteca" @@ -2055,12 +1933,12 @@ msgstr "Metti mi piace a questo feed" #: src/Navigation.tsx:197 msgid "Liked by" -msgstr "Piaciuto a" +msgstr "È piaciuto a" #: src/view/screens/PostLikedBy.tsx:27 #: src/view/screens/ProfileFeedLikedBy.tsx:27 msgid "Liked By" -msgstr "" +msgstr "È Piaciuto A" #: src/view/com/feeds/FeedSourceCard.tsx:277 msgid "Liked by {0} {1}" @@ -2072,11 +1950,7 @@ msgstr "È piaciuto a {likeCount} {0}" #: src/view/com/notifications/FeedItem.tsx:170 msgid "liked your custom feed" -msgstr "" - -#: src/view/com/notifications/FeedItem.tsx:171 -#~ msgid "liked your custom feed{0}" -#~ msgstr "è piaciuto il feed personalizzato{0}" +msgstr "è piaciuto il tuo feed personalizzato" #: src/view/com/notifications/FeedItem.tsx:155 msgid "liked your post" @@ -2126,10 +2000,8 @@ msgstr "Lista sbloccata" msgid "List unmuted" msgstr "Lista non mutata" -#: src/Navigation.tsx:110 -#: src/view/screens/Profile.tsx:185 -#: src/view/shell/desktop/LeftNav.tsx:379 -#: src/view/shell/Drawer.tsx:492 +#: src/Navigation.tsx:110 src/view/screens/Profile.tsx:185 +#: src/view/shell/desktop/LeftNav.tsx:379 src/view/shell/Drawer.tsx:492 #: src/view/shell/Drawer.tsx:493 msgid "Lists" msgstr "Liste" @@ -2143,10 +2015,8 @@ msgstr "Carica più post" msgid "Load new notifications" msgstr "Carica più notifiche" -#: src/view/com/feeds/FeedPage.tsx:190 -#: src/view/screens/Profile.tsx:440 -#: src/view/screens/ProfileFeed.tsx:494 -#: src/view/screens/ProfileList.tsx:680 +#: src/view/com/feeds/FeedPage.tsx:190 src/view/screens/Profile.tsx:440 +#: src/view/screens/ProfileFeed.tsx:494 src/view/screens/ProfileList.tsx:680 msgid "Load new posts" msgstr "Carica nuovi posts" @@ -2154,20 +2024,14 @@ msgstr "Carica nuovi posts" msgid "Loading..." msgstr "Caricamento..." -#: src/view/com/modals/ServerInput.tsx:50 -#~ msgid "Local dev server" -#~ msgstr "Server di sviluppo locale" - #: src/Navigation.tsx:207 msgid "Log" msgstr "Log" -#: src/screens/Deactivated.tsx:149 -#: src/screens/Deactivated.tsx:152 -#: src/screens/Deactivated.tsx:178 -#: src/screens/Deactivated.tsx:181 +#: src/screens/Deactivated.tsx:149 src/screens/Deactivated.tsx:152 +#: src/screens/Deactivated.tsx:178 src/screens/Deactivated.tsx:181 msgid "Log out" -msgstr "" +msgstr "Disconnettiti dall'account" #: src/view/screens/Moderation.tsx:136 msgid "Logged-out visibility" @@ -2177,9 +2041,6 @@ msgstr "Visibilità degli utenti non connettati" msgid "Login to account that is not listed" msgstr "Accedi all'account che non è nella lista" -#~ msgid "Looks like this feed is only available to users with a Bluesky account. Please sign up or sign in to view this feed!" -#~ msgstr "Parece que este canal de noticias sólo está disponible para usuarios con una cuenta Bluesky. Por favor, ¡regístrate o inicia sesión para ver este canal!" - #: src/view/com/modals/LinkWarning.tsx:65 msgid "Make sure this is where you intend to go!" msgstr "Assicurati che questo sia dove intendi andare!" @@ -2196,23 +2057,17 @@ msgstr "utenti menzionati" msgid "Mentioned users" msgstr "Utenti menzionati" -#: src/view/com/util/ViewHeader.tsx:81 -#: src/view/screens/Search/Search.tsx:623 +#: src/view/com/util/ViewHeader.tsx:81 src/view/screens/Search/Search.tsx:623 msgid "Menu" msgstr "Menù" -#~ msgid "Message from server" -#~ msgstr "Missatge del servidor" - #: src/view/com/posts/FeedErrorMessage.tsx:197 msgid "Message from server: {0}" msgstr "Messaggio dal server: {0}" -#: src/Navigation.tsx:115 -#: src/view/screens/Moderation.tsx:64 +#: src/Navigation.tsx:115 src/view/screens/Moderation.tsx:64 #: src/view/screens/Settings/index.tsx:625 -#: src/view/shell/desktop/LeftNav.tsx:397 -#: src/view/shell/Drawer.tsx:511 +#: src/view/shell/desktop/LeftNav.tsx:397 src/view/shell/Drawer.tsx:511 #: src/view/shell/Drawer.tsx:512 msgid "Moderation" msgstr "Moderazione" @@ -2244,8 +2099,7 @@ msgstr "Lista di moderazione aggiornata" msgid "Moderation lists" msgstr "Liste di moderazione" -#: src/Navigation.tsx:120 -#: src/view/screens/ModerationModlists.tsx:58 +#: src/Navigation.tsx:120 src/view/screens/ModerationModlists.tsx:58 msgid "Moderation Lists" msgstr "Liste di Moderazione" @@ -2262,8 +2116,7 @@ msgid "More feeds" msgstr "Altri feed" #: src/view/com/profile/ProfileHeader.tsx:522 -#: src/view/screens/ProfileFeed.tsx:362 -#: src/view/screens/ProfileList.tsx:616 +#: src/view/screens/ProfileFeed.tsx:362 src/view/screens/ProfileList.tsx:616 msgid "More options" msgstr "Altre opzioni" @@ -2307,8 +2160,7 @@ msgstr "Silenziato" msgid "Muted accounts" msgstr "Account silenziato" -#: src/Navigation.tsx:125 -#: src/view/screens/ModerationMutedAccounts.tsx:107 +#: src/Navigation.tsx:125 src/view/screens/ModerationMutedAccounts.tsx:107 msgid "Muted Accounts" msgstr "Accounts Silenziati" @@ -2338,7 +2190,7 @@ msgstr "I miei Feeds Salvati" #: src/view/com/auth/server-input/index.tsx:118 msgid "my-server.com" -msgstr "" +msgstr "my-server.com" #: src/view/com/modals/AddAppPasswords.tsx:179 #: src/view/com/modals/CreateOrEditList.tsx:290 @@ -2351,7 +2203,7 @@ msgstr "Il nome è obbligatorio" #: src/screens/Onboarding/index.tsx:25 msgid "Nature" -msgstr "" +msgstr "Natura" #: src/view/com/auth/login/ForgotPasswordForm.tsx:190 #: src/view/com/auth/login/ForgotPasswordForm.tsx:219 @@ -2377,7 +2229,7 @@ msgstr "Non perdere mai l'accesso ai tuoi follower e ai tuoi dati." #: src/screens/Onboarding/StepFinished.tsx:119 msgid "Never lose access to your followers or data." -msgstr "" +msgstr "Non perdere mai l'accesso ai tuoi follower o ai tuoi dati." #: src/view/screens/Lists.tsx:76 msgctxt "action" @@ -2398,19 +2250,16 @@ msgstr "Nuovo Password" #: src/view/com/modals/ChangePassword.tsx:215 msgid "New Password" -msgstr "" +msgstr "Nuovo Password" #: src/view/com/feeds/FeedPage.tsx:201 msgctxt "action" msgid "New post" msgstr "Nuovo Post" -#: src/view/screens/Feeds.tsx:555 -#: src/view/screens/Notifications.tsx:168 -#: src/view/screens/Profile.tsx:382 -#: src/view/screens/ProfileFeed.tsx:432 -#: src/view/screens/ProfileList.tsx:195 -#: src/view/screens/ProfileList.tsx:223 +#: src/view/screens/Feeds.tsx:555 src/view/screens/Notifications.tsx:168 +#: src/view/screens/Profile.tsx:382 src/view/screens/ProfileFeed.tsx:432 +#: src/view/screens/ProfileList.tsx:195 src/view/screens/ProfileList.tsx:223 #: src/view/shell/desktop/LeftNav.tsx:248 msgid "New post" msgstr "Nuovo post" @@ -2420,9 +2269,6 @@ msgctxt "action" msgid "New Post" msgstr "Nuovo post" -#~ msgid "New Post" -#~ msgstr "Nova publicació" - #: src/view/com/modals/CreateOrEditList.tsx:247 msgid "New User List" msgstr "Nuova lista utenti" @@ -2433,7 +2279,7 @@ msgstr "Mostrare prima le risposte più recenti" #: src/screens/Onboarding/index.tsx:23 msgid "News" -msgstr "" +msgstr "Notizie" #: src/view/com/auth/create/CreateAccount.tsx:161 #: src/view/com/auth/login/ForgotPasswordForm.tsx:182 @@ -2465,8 +2311,7 @@ msgstr "Immagine seguente" msgid "No" msgstr "No" -#: src/view/screens/ProfileFeed.tsx:584 -#: src/view/screens/ProfileList.tsx:754 +#: src/view/screens/ProfileFeed.tsx:584 src/view/screens/ProfileList.tsx:754 msgid "No description" msgstr "Senza descrizione" @@ -2505,8 +2350,7 @@ msgstr "Nessuno" msgid "Not Applicable." msgstr "Non applicabile." -#: src/Navigation.tsx:105 -#: src/view/screens/Profile.tsx:106 +#: src/Navigation.tsx:105 src/view/screens/Profile.tsx:106 msgid "Not Found" msgstr "Non trovato" @@ -2519,15 +2363,13 @@ msgstr "Non adesso" msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "Nota: Bluesky è una rete aperta e pubblica. Questa impostazione limita solo la visibilità dei tuoi contenuti sull'app e sul sito Web di Bluesky e altre app potrebbero non rispettare questa impostazione. I tuoi contenuti potrebbero comunque essere mostrati agli utenti disconnessi da altre app e siti web." -#: src/Navigation.tsx:447 -#: src/view/screens/Notifications.tsx:124 +#: src/Navigation.tsx:447 src/view/screens/Notifications.tsx:124 #: src/view/screens/Notifications.tsx:148 #: src/view/shell/bottom-bar/BottomBar.tsx:205 -#: src/view/shell/desktop/LeftNav.tsx:361 -#: src/view/shell/Drawer.tsx:435 +#: src/view/shell/desktop/LeftNav.tsx:361 src/view/shell/Drawer.tsx:435 #: src/view/shell/Drawer.tsx:436 msgid "Notifications" -msgstr "Notifica" +msgstr "Notifiche" #: src/view/com/modals/SelfLabel.tsx:103 msgid "Nudity" @@ -2539,7 +2381,7 @@ msgstr "Oh no!" #: src/screens/Onboarding/StepInterests/index.tsx:128 msgid "Oh no! Something went wrong." -msgstr "" +msgstr "Oh no! Qualcosa è andato storto." #: src/view/com/auth/login/PasswordUpdatedForm.tsx:41 msgid "Okay" @@ -2547,7 +2389,7 @@ msgstr "Va bene" #: src/view/screens/PreferencesThreads.tsx:78 msgid "Oldest replies first" -msgstr "Prima le risposte più vecchie" +msgstr "Mostrare prima le risposte più vecchie" #: src/view/screens/Settings/index.tsx:234 msgid "Onboarding reset" @@ -2561,14 +2403,13 @@ msgstr "A una o più immagini manca il testo alternativo." msgid "Only {0} can reply." msgstr "Solo {0} può rispondere." -#: src/view/screens/AppPasswords.tsx:65 -#: src/view/screens/Profile.tsx:106 +#: src/view/screens/AppPasswords.tsx:65 src/view/screens/Profile.tsx:106 msgid "Oops!" msgstr "Ops!" #: src/screens/Onboarding/StepFinished.tsx:115 msgid "Open" -msgstr "" +msgstr "Apri" #: src/view/com/composer/Composer.tsx:470 #: src/view/com/composer/Composer.tsx:471 @@ -2631,10 +2472,6 @@ msgstr "Apre la lista dei followers" msgid "Opens following list" msgstr "Apre la lista di chi segui" -#: src/view/screens/Settings.tsx:412 -#~ msgid "Opens invite code list" -#~ msgstr "Apre la lista dei codici di invito" - #: src/view/com/modals/InviteCodes.tsx:172 msgid "Opens list of invite codes" msgstr "Apre la lista dei codici di invito" @@ -2695,10 +2532,6 @@ msgstr "Oppure combina queste opzioni:" msgid "Other account" msgstr "Altro account" -#: src/view/com/modals/ServerInput.tsx:88 -#~ msgid "Other service" -#~ msgstr "Altro servizio" - #: src/view/com/composer/select-language/SelectLangBtn.tsx:91 msgid "Other..." msgstr "Altro..." @@ -2709,7 +2542,7 @@ msgstr "Pagina non trovata" #: src/view/screens/NotFound.tsx:42 msgid "Page Not Found" -msgstr "" +msgstr "Pagina non trovata" #: src/view/com/auth/create/Step1.tsx:210 #: src/view/com/auth/create/Step1.tsx:220 @@ -2745,7 +2578,7 @@ msgstr "L'autorizzazione per accedere la cartella delle immagini è stata negata #: src/screens/Onboarding/index.tsx:31 msgid "Pets" -msgstr "" +msgstr "Animali di compagnia" #: src/view/com/auth/create/Step2.tsx:183 msgid "Phone number" @@ -2755,8 +2588,7 @@ msgstr "Numero di telefono" msgid "Pictures meant for adults." msgstr "Immagini per adulti." -#: src/view/screens/ProfileFeed.tsx:353 -#: src/view/screens/ProfileList.tsx:580 +#: src/view/screens/ProfileFeed.tsx:353 src/view/screens/ProfileList.tsx:580 msgid "Pin to home" msgstr "Fissa sulla pagina principale" @@ -2822,9 +2654,6 @@ msgstr "Inserisci anche la tua password:" msgid "Please tell us why you think this content warning was incorrectly applied!" msgstr "Spiegaci perché ritieni che questo avviso sui contenuti sia stato applicato in modo errato!" -#~ msgid "Please tell us why you think this decision was incorrect." -#~ msgstr "Por favor, dinos por qué crees que esta decisión fue incorrecta." - #: src/view/com/modals/VerifyEmail.tsx:101 msgid "Please Verify Your Email" msgstr "Verifica la tua email" @@ -2835,7 +2664,7 @@ msgstr "Attendi il caricamento della scheda di collegamento" #: src/screens/Onboarding/index.tsx:37 msgid "Politics" -msgstr "" +msgstr "Politica" #: src/view/com/modals/SelfLabel.tsx:111 msgid "Porn" @@ -2852,16 +2681,11 @@ msgctxt "description" msgid "Post" msgstr "Post" -#~ msgid "Post" -#~ msgstr "Publicació" - #: src/view/com/post-thread/PostThreadItem.tsx:174 msgid "Post by {0}" msgstr "Pubblicato da {0}" -#: src/Navigation.tsx:172 -#: src/Navigation.tsx:179 -#: src/Navigation.tsx:186 +#: src/Navigation.tsx:172 src/Navigation.tsx:179 src/Navigation.tsx:186 msgid "Post by @{0}" msgstr "Pubblicato da @{0}" @@ -2914,10 +2738,8 @@ msgstr "Dai priorità a quelli che segui" msgid "Privacy" msgstr "Privacy" -#: src/Navigation.tsx:217 -#: src/view/screens/PrivacyPolicy.tsx:29 -#: src/view/screens/Settings/index.tsx:891 -#: src/view/shell/Drawer.tsx:262 +#: src/Navigation.tsx:217 src/view/screens/PrivacyPolicy.tsx:29 +#: src/view/screens/Settings/index.tsx:891 src/view/shell/Drawer.tsx:262 msgid "Privacy Policy" msgstr "Informativa sulla privacy" @@ -2926,10 +2748,8 @@ msgid "Processing..." msgstr "Elaborazione in corso…" #: src/view/shell/bottom-bar/BottomBar.tsx:247 -#: src/view/shell/desktop/LeftNav.tsx:415 -#: src/view/shell/Drawer.tsx:70 -#: src/view/shell/Drawer.tsx:546 -#: src/view/shell/Drawer.tsx:547 +#: src/view/shell/desktop/LeftNav.tsx:415 src/view/shell/Drawer.tsx:70 +#: src/view/shell/Drawer.tsx:546 src/view/shell/Drawer.tsx:547 msgid "Profile" msgstr "Profilo" @@ -2943,7 +2763,7 @@ msgstr "Proteggi il tuo account verificando la tua email." #: src/screens/Onboarding/StepFinished.tsx:101 msgid "Public" -msgstr "" +msgstr "Pubblico" #: src/view/screens/ModerationModlists.tsx:61 msgid "Public, shareable lists of users to mute or block in bulk." @@ -2975,9 +2795,6 @@ msgctxt "action" msgid "Quote Post" msgstr "Cita il post" -#~ msgid "Quote Post" -#~ msgstr "Cita una publicació" - #: src/view/screens/PreferencesThreads.tsx:86 msgid "Random (aka \"Poster's Roulette\")" msgstr "Selezione a caso (nota anche come \"Poster's Roulette\")" @@ -2997,8 +2814,7 @@ msgstr "Utenti consigliati" #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:219 -#: src/view/com/util/UserAvatar.tsx:285 -#: src/view/com/util/UserBanner.tsx:91 +#: src/view/com/util/UserAvatar.tsx:285 src/view/com/util/UserBanner.tsx:91 msgid "Remove" msgstr "Rimuovi" @@ -3074,8 +2890,7 @@ msgstr "Rispondi" msgid "Reply Filters" msgstr "Filtri di risposta" -#: src/view/com/post/Post.tsx:166 -#: src/view/com/posts/FeedItem.tsx:287 +#: src/view/com/post/Post.tsx:166 src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" msgstr "Rispondi a <0/>" @@ -3101,8 +2916,7 @@ msgstr "Segnala la lista" msgid "Report post" msgstr "Segnala il post" -#: src/view/com/modals/Repost.tsx:43 -#: src/view/com/modals/Repost.tsx:48 +#: src/view/com/modals/Repost.tsx:43 src/view/com/modals/Repost.tsx:48 #: src/view/com/modals/Repost.tsx:53 #: src/view/com/util/post-ctrls/RepostButton.tsx:61 msgctxt "action" @@ -3118,21 +2932,13 @@ msgstr "Ripubblicare" msgid "Repost or quote post" msgstr "Ripubblicare o citare il post" -#: src/view/screens/PostRepostedBy.tsx:27 -#~ msgid "Reposted by" -#~ msgstr "Ripubblicato da" - #: src/view/screens/PostRepostedBy.tsx:27 msgid "Reposted By" -msgstr "" +msgstr "Ripubblicato da" #: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" -msgstr "" - -#: src/view/com/posts/FeedItem.tsx:206 -#~ msgid "Reposted by {0})" -#~ msgstr "Ripubblicato da {0})" +msgstr "Ripubblicato da {0}" #: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" @@ -3158,7 +2964,7 @@ msgstr "Richiedi un codice" #: src/view/com/modals/ChangePassword.tsx:239 #: src/view/com/modals/ChangePassword.tsx:241 msgid "Request Code" -msgstr "" +msgstr "Richiedi il codice" #: src/view/screens/Settings/index.tsx:456 msgid "Require alt text before posting" @@ -3175,7 +2981,7 @@ msgstr "Reimpostare il codice" #: src/view/com/modals/ChangePassword.tsx:190 msgid "Reset Code" -msgstr "" +msgstr "Reimposta il Codice" #: src/view/screens/Settings/index.tsx:824 msgid "Reset onboarding" @@ -3248,8 +3054,7 @@ msgstr "Salva" #: src/view/com/modals/BirthDateSettings.tsx:97 #: src/view/com/modals/ChangeHandle.tsx:173 #: src/view/com/modals/CreateOrEditList.tsx:337 -#: src/view/com/modals/EditProfile.tsx:224 -#: src/view/screens/ProfileFeed.tsx:345 +#: src/view/com/modals/EditProfile.tsx:224 src/view/screens/ProfileFeed.tsx:345 msgid "Save" msgstr "Salva" @@ -3283,14 +3088,13 @@ msgstr "Salva la modifica del cambio dell'utente in {handle}" #: src/screens/Onboarding/index.tsx:36 msgid "Science" -msgstr "" +msgstr "Scienza" #: src/view/screens/ProfileList.tsx:854 msgid "Scroll to top" msgstr "Scorri verso l'alto" -#: src/Navigation.tsx:437 -#: src/view/com/auth/LoggedOut.tsx:122 +#: src/Navigation.tsx:437 src/view/com/auth/LoggedOut.tsx:122 #: src/view/com/modals/ListAddRemoveUsers.tsx:75 #: src/view/com/util/forms/SearchInput.tsx:67 #: src/view/com/util/forms/SearchInput.tsx:79 @@ -3298,21 +3102,17 @@ msgstr "Scorri verso l'alto" #: src/view/screens/Search/Search.tsx:645 #: src/view/screens/Search/Search.tsx:663 #: src/view/shell/bottom-bar/BottomBar.tsx:159 -#: src/view/shell/desktop/LeftNav.tsx:324 -#: src/view/shell/desktop/Search.tsx:214 -#: src/view/shell/desktop/Search.tsx:223 -#: src/view/shell/Drawer.tsx:362 +#: src/view/shell/desktop/LeftNav.tsx:324 src/view/shell/desktop/Search.tsx:214 +#: src/view/shell/desktop/Search.tsx:223 src/view/shell/Drawer.tsx:362 #: src/view/shell/Drawer.tsx:363 msgid "Search" msgstr "Cerca" -#: src/view/screens/Search/Search.tsx:712 -#: src/view/shell/desktop/Search.tsx:255 +#: src/view/screens/Search/Search.tsx:712 src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" msgstr "Cerca \"{query}\"" -#: src/view/com/auth/LoggedOut.tsx:104 -#: src/view/com/auth/LoggedOut.tsx:105 +#: src/view/com/auth/LoggedOut.tsx:104 src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 msgid "Search for users" msgstr "Cerca utenti" @@ -3333,10 +3133,6 @@ msgstr "Scopri cosa c'è dopo" msgid "Select {item}" msgstr "Seleziona {item}" -#: src/view/com/modals/ServerInput.tsx:75 -#~ msgid "Select Bluesky Social" -#~ msgstr "Seleziona Bluesky Social" - #: src/view/com/auth/login/Login.tsx:117 msgid "Select from an existing account" msgstr "Seleziona da un account esistente" @@ -3352,19 +3148,19 @@ msgstr "Selecciona el servei" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:52 msgid "Select some accounts below to follow" -msgstr "" +msgstr "Seleziona alcuni account da seguire qui giù" #: src/view/com/auth/server-input/index.tsx:82 msgid "Select the service that hosts your data." -msgstr "" +msgstr "Seleziona il servizio che ospita i tuoi dati." #: src/screens/Onboarding/StepTopicalFeeds.tsx:90 msgid "Select topical feeds to follow from the list below" -msgstr "" +msgstr "Seleziona i feeds con temi da seguire dal seguente elenco" #: src/screens/Onboarding/StepModeration/index.tsx:75 msgid "Select what you want to see (or not see), and we’ll handle the rest." -msgstr "" +msgstr "Seleziona ciò che vuoi vedere (o non vedere) e noi gestiremo il resto." #: src/view/screens/LanguageSettings.tsx:281 msgid "Select which languages you want your subscribed feeds to include. If none are selected, all languages will be shown." @@ -3376,7 +3172,7 @@ msgstr "Seleziona la lingua dell'app per il testo predefinito da visualizzare ne #: src/screens/Onboarding/StepInterests/index.tsx:196 msgid "Select your interests from the options below" -msgstr "" +msgstr "Seleziona i tuoi interessi dalle seguenti opzioni" #: src/view/com/auth/create/Step2.tsx:155 msgid "Select your phone's country" @@ -3388,11 +3184,11 @@ msgstr "Seleziona la tua lingua preferita per le traduzioni nel tuo feed." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:116 msgid "Select your primary algorithmic feeds" -msgstr "" +msgstr "Seleziona i tuoi feed algoritmici principali" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:142 msgid "Select your secondary algorithmic feeds" -msgstr "" +msgstr "Seleziona i tuoi feed algoritmici secondari" #: src/view/com/modals/VerifyEmail.tsx:202 #: src/view/com/modals/VerifyEmail.tsx:204 @@ -3408,11 +3204,7 @@ msgctxt "action" msgid "Send Email" msgstr "Invia email" -#~ msgid "Send Email" -#~ msgstr "Envia correu" - -#: src/view/shell/Drawer.tsx:295 -#: src/view/shell/Drawer.tsx:316 +#: src/view/shell/Drawer.tsx:295 src/view/shell/Drawer.tsx:316 msgid "Send feedback" msgstr "Invia feedback" @@ -3426,7 +3218,7 @@ msgstr "Invia un'email con il codice di conferma per la cancellazione dell'accou #: src/view/com/auth/server-input/index.tsx:110 msgid "Server address" -msgstr "" +msgstr "Indirizzo del server" #: src/view/com/modals/ContentFilteringSettings.tsx:311 msgid "Set {value} for {labelGroup} content moderation policy" @@ -3452,11 +3244,11 @@ msgstr "Imposta il colore del tema basato sulle impostazioni del tuo sistema" #: src/view/screens/Settings/index.tsx:514 msgid "Set dark theme to the dark theme" -msgstr "" +msgstr "Imposta il tema scuro sul tema scuro" #: src/view/screens/Settings/index.tsx:507 msgid "Set dark theme to the dim theme" -msgstr "" +msgstr "Imposta il tema scuro sul tema scuro" #: src/view/com/auth/login/SetNewPasswordForm.tsx:104 msgid "Set new password" @@ -3488,7 +3280,7 @@ msgstr "Seleziona \"Sì\" per mostrare esempi dei feed salvati nel feed successi #: src/screens/Onboarding/Layout.tsx:50 msgid "Set up your account" -msgstr "" +msgstr "Configura il tuo account" #: src/view/com/modals/ChangeHandle.tsx:266 msgid "Sets Bluesky username" @@ -3507,10 +3299,8 @@ msgstr "Imposta il provider del hosting per la reimpostazione della password" msgid "Sets server for the Bluesky client" msgstr "Imposta il server per il client Bluesky" -#: src/Navigation.tsx:135 -#: src/view/screens/Settings/index.tsx:294 -#: src/view/shell/desktop/LeftNav.tsx:433 -#: src/view/shell/Drawer.tsx:567 +#: src/Navigation.tsx:135 src/view/screens/Settings/index.tsx:294 +#: src/view/shell/desktop/LeftNav.tsx:433 src/view/shell/Drawer.tsx:567 #: src/view/shell/Drawer.tsx:568 msgid "Settings" msgstr "Impostazioni" @@ -3559,8 +3349,7 @@ msgid "Show follows similar to {0}" msgstr "Mostra follows simile a {0}" #: src/view/com/post-thread/PostThreadItem.tsx:539 -#: src/view/com/post/Post.tsx:197 -#: src/view/com/posts/FeedItem.tsx:363 +#: src/view/com/post/Post.tsx:197 src/view/com/posts/FeedItem.tsx:363 msgid "Show More" msgstr "Mostra di più" @@ -3574,15 +3363,15 @@ msgstr "Mostra post con citazioni" #: src/screens/Onboarding/StepFollowingFeed.tsx:118 msgid "Show quote-posts in Following feed" -msgstr "" +msgstr "Mostra i post con citazioni nel feed Seguiti" #: src/screens/Onboarding/StepFollowingFeed.tsx:134 msgid "Show quotes in Following" -msgstr "" +msgstr "Mostra le citazioni in Seguiti" #: src/screens/Onboarding/StepFollowingFeed.tsx:94 msgid "Show re-posts in Following feed" -msgstr "" +msgstr "Mostra re-post nel feed Seguiti" #: src/view/screens/PreferencesHomeFeed.tsx:119 msgid "Show Replies" @@ -3594,11 +3383,11 @@ msgstr "Mostra le risposte delle persone che segui prima delle altre risposte." #: src/screens/Onboarding/StepFollowingFeed.tsx:86 msgid "Show replies in Following" -msgstr "" +msgstr "Mostra le risposte in Seguiti" #: src/screens/Onboarding/StepFollowingFeed.tsx:70 msgid "Show replies in Following feed" -msgstr "" +msgstr "Mostra le risposte nel feed Seguiti" #: src/view/screens/PreferencesHomeFeed.tsx:70 msgid "Show replies with at least {value} {0}" @@ -3610,7 +3399,7 @@ msgstr "Mostra ripubblicazioni" #: src/screens/Onboarding/StepFollowingFeed.tsx:110 msgid "Show reposts in Following" -msgstr "" +msgstr "Mostra i re-repost in Seguiti" #: src/view/com/util/moderation/ContentHider.tsx:67 #: src/view/com/util/moderation/PostHider.tsx:61 @@ -3631,16 +3420,14 @@ msgid "Shows posts from {0} in your feed" msgstr "Mostra i post di {0} nel tuo feed" #: src/view/com/auth/HomeLoggedOutCTA.tsx:70 -#: src/view/com/auth/login/Login.tsx:98 -#: src/view/com/auth/SplashScreen.tsx:79 +#: src/view/com/auth/login/Login.tsx:98 src/view/com/auth/SplashScreen.tsx:79 #: src/view/shell/bottom-bar/BottomBar.tsx:285 #: src/view/shell/bottom-bar/BottomBar.tsx:286 #: src/view/shell/bottom-bar/BottomBar.tsx:288 #: src/view/shell/bottom-bar/BottomBarWeb.tsx:178 #: src/view/shell/bottom-bar/BottomBarWeb.tsx:179 #: src/view/shell/bottom-bar/BottomBarWeb.tsx:181 -#: src/view/shell/NavSignupCard.tsx:58 -#: src/view/shell/NavSignupCard.tsx:59 +#: src/view/shell/NavSignupCard.tsx:58 src/view/shell/NavSignupCard.tsx:59 msgid "Sign in" msgstr "Accedi" @@ -3676,8 +3463,7 @@ msgstr "Disconnettiti" #: src/view/shell/bottom-bar/BottomBarWeb.tsx:168 #: src/view/shell/bottom-bar/BottomBarWeb.tsx:169 #: src/view/shell/bottom-bar/BottomBarWeb.tsx:171 -#: src/view/shell/NavSignupCard.tsx:49 -#: src/view/shell/NavSignupCard.tsx:50 +#: src/view/shell/NavSignupCard.tsx:49 src/view/shell/NavSignupCard.tsx:50 #: src/view/shell/NavSignupCard.tsx:52 msgid "Sign up" msgstr "Iscrizione" @@ -3710,7 +3496,7 @@ msgstr "Salta questo passo" #: src/screens/Onboarding/StepInterests/index.tsx:232 msgid "Skip this flow" -msgstr "" +msgstr "Salta questa corrente" #: src/view/com/auth/create/Step2.tsx:82 msgid "SMS verification" @@ -3718,11 +3504,7 @@ msgstr "Verifica tramite SMS" #: src/screens/Onboarding/index.tsx:40 msgid "Software Dev" -msgstr "" - -#: src/view/com/modals/ProfilePreview.tsx:62 -#~ msgid "Something went wrong and we're not sure what." -#~ msgstr "Qualcosa è andato storto ma non siamo sicuri di cosa." +msgstr "Sviluppo Software" #: src/view/com/modals/Waitlist.tsx:51 msgid "Something went wrong. Check your email and try again." @@ -3742,16 +3524,12 @@ msgstr "Ordina le risposte allo stesso post per:" #: src/screens/Onboarding/index.tsx:30 msgid "Sports" -msgstr "" +msgstr "Sports" #: src/view/com/modals/crop-image/CropImage.web.tsx:122 msgid "Square" msgstr "Quadrato" -#: src/view/com/modals/ServerInput.tsx:62 -#~ msgid "Staging" -#~ msgstr "Allestimento" - #: src/view/screens/Settings/index.tsx:871 msgid "Status page" msgstr "Pagina di stato" @@ -3764,8 +3542,7 @@ msgstr "Passo {0} di {numSteps}" msgid "Storage cleared, you need to restart the app now." msgstr "Spazio di archiviazione eliminato. Riavvia l'app." -#: src/Navigation.tsx:202 -#: src/view/screens/Settings/index.tsx:807 +#: src/Navigation.tsx:202 src/view/screens/Settings/index.tsx:807 msgid "Storybook" msgstr "Cronologia" @@ -3780,7 +3557,7 @@ msgstr "Iscriviti" #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:173 #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:307 msgid "Subscribe to the {0} feed" -msgstr "" +msgstr "Iscriviti a {0} feed" #: src/view/screens/ProfileList.tsx:603 msgid "Subscribe to this list" @@ -3798,16 +3575,11 @@ msgstr "Suggerito per te" msgid "Suggestive" msgstr "Suggestivo" -#: src/Navigation.tsx:212 -#: src/view/screens/Support.tsx:30 +#: src/Navigation.tsx:212 src/view/screens/Support.tsx:30 #: src/view/screens/Support.tsx:33 msgid "Support" msgstr "Supporto" -#: src/view/com/modals/ProfilePreview.tsx:110 -#~ msgid "Swipe up to see more" -#~ msgstr "Scorri verso l'alto per vedere di più" - #: src/view/com/modals/SwitchAccount.tsx:117 msgid "Switch Account" msgstr "Cambia account" @@ -3840,16 +3612,14 @@ msgstr "Tocca per visualizzare completamente" #: src/screens/Onboarding/index.tsx:39 msgid "Tech" -msgstr "" +msgstr "Tecnologia" #: src/view/shell/desktop/RightNav.tsx:89 msgid "Terms" msgstr "Termini" -#: src/Navigation.tsx:222 -#: src/view/screens/Settings/index.tsx:885 -#: src/view/screens/TermsOfService.tsx:29 -#: src/view/shell/Drawer.tsx:256 +#: src/Navigation.tsx:222 src/view/screens/Settings/index.tsx:885 +#: src/view/screens/TermsOfService.tsx:29 src/view/shell/Drawer.tsx:256 msgid "Terms of Service" msgstr "Termini di servizio" @@ -3872,7 +3642,7 @@ msgstr "La politica sul copyright è stata spostata a <0/>" #: src/screens/Onboarding/Layout.tsx:60 msgid "The following steps will help customize your Bluesky experience." -msgstr "" +msgstr "I passaggi seguenti ti aiuteranno a personalizzare la tua esperienza con Bluesky." #: src/view/com/post-thread/PostThread.tsx:482 msgid "The post may have been deleted." @@ -3886,16 +3656,13 @@ msgstr "La politica sulla privacy è stata spostata a <0/><0/>" msgid "The support form has been moved. If you need help, please <0/> or visit {HELP_DESK_URL} to get in touch with us." msgstr "Il modulo di supporto è stato spostato. Se hai bisogno di aiuto, <0/> o visita {HELP_DESK_URL} per metterti in contatto con noi." -#~ msgid "The support form has been moved. If you need help, please<0/> or visit {HELP_DESK_URL} to get in touch with us." -#~ msgstr "El formulari de suport ha estat traslladat. Si necessites ajuda, <0/> o visita {HELP_DESK_URL} per contactar amb nosaltres." - #: src/view/screens/TermsOfService.tsx:33 msgid "The Terms of Service have been moved to" msgstr "I Termini di Servizio sono stati spostati a" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:150 msgid "There are many feeds to try:" -msgstr "" +msgstr "Ci sono molti feed da provare:" #: src/view/screens/ProfileFeed.tsx:549 msgid "There was an an issue contacting the server, please check your internet connection and try again." @@ -3909,10 +3676,8 @@ msgstr "Si è verificato un problema durante la rimozione di questo feed. Per fa msgid "There was an an issue updating your feeds, please check your internet connection and try again." msgstr "Si è verificato un problema durante la rimozione di questo feed. Per favore controlla la tua connessione Internet e prova di nuovo." -#: src/view/screens/ProfileFeed.tsx:236 -#: src/view/screens/ProfileList.tsx:266 -#: src/view/screens/SavedFeeds.tsx:209 -#: src/view/screens/SavedFeeds.tsx:231 +#: src/view/screens/ProfileFeed.tsx:236 src/view/screens/ProfileList.tsx:266 +#: src/view/screens/SavedFeeds.tsx:209 src/view/screens/SavedFeeds.tsx:231 #: src/view/screens/SavedFeeds.tsx:252 msgid "There was an issue contacting the server" msgstr "Si è verificato un problema durante il contatto con il server" @@ -3962,10 +3727,8 @@ msgstr "Si è verificato un problema durante il recupero delle password dell'app msgid "There was an issue! {0}" msgstr "Si è verificato un problema! {0}" -#: src/view/screens/ProfileList.tsx:287 -#: src/view/screens/ProfileList.tsx:306 -#: src/view/screens/ProfileList.tsx:328 -#: src/view/screens/ProfileList.tsx:347 +#: src/view/screens/ProfileList.tsx:287 src/view/screens/ProfileList.tsx:306 +#: src/view/screens/ProfileList.tsx:328 src/view/screens/ProfileList.tsx:347 msgid "There was an issue. Please check your internet connection and try again." msgstr "Si è verificato un problema. Per favore controlla la tua connessione Internet e prova di nuovo." @@ -3975,7 +3738,7 @@ msgstr "Si è verificato un problema imprevisto nell'applicazione. Per favore fa #: src/screens/Deactivated.tsx:106 msgid "There's been a rush of new users to Bluesky! We'll activate your account as soon as we can." -msgstr "" +msgstr "C'è stata un'ondata di nuovi utenti su Bluesky! Attiveremo il tuo account il prima possibile." #: src/view/com/auth/create/Step2.tsx:55 msgid "There's something wrong with this number. Please choose your country and enter your full phone number!" @@ -3983,10 +3746,7 @@ msgstr "C'è qualcosa di sbagliato in questo numero. Scegli il tuo Paese e inser #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:138 msgid "These are popular accounts you might like:" -msgstr "" - -#~ msgid "This {0} has been labeled." -#~ msgstr "Este {0} ha sido etiquetado." +msgstr "Questi sono gli account popolari che potrebbero piacerti:" #: src/view/com/util/moderation/ScreenHider.tsx:88 msgid "This {screenDescription} has been flagged:" @@ -4010,14 +3770,13 @@ msgstr "Questo contenuto non è visualizzabile senza un account Bluesky." #: src/view/screens/Settings/ExportCarDialog.tsx:75 msgid "This feature is in beta. You can read more about repository exports in <0>this blogpost." -msgstr "" +msgstr "Questa funzionalità è in versione beta. Puoi leggere ulteriori informazioni sulle esportazioni dell' archivio in <0>questo post del blog." #: src/view/com/posts/FeedErrorMessage.tsx:114 msgid "This feed is currently receiving high traffic and is temporarily unavailable. Please try again later." msgstr "Questo canale al momento sta ricevendo molte visite ed è temporaneamente non disponibile. Riprova più tardi." -#: src/view/screens/Profile.tsx:420 -#: src/view/screens/ProfileFeed.tsx:475 +#: src/view/screens/Profile.tsx:420 src/view/screens/ProfileFeed.tsx:475 #: src/view/screens/ProfileList.tsx:660 msgid "This feed is empty!" msgstr "Questo feed è vuoto!" @@ -4034,9 +3793,6 @@ msgstr "Queste informazioni non vengono condivise con altri utenti." msgid "This is important in case you ever need to change your email or reset your password." msgstr "Questo è importante nel caso in cui avessi bisogno di modificare la tua email o reimpostare la password." -#~ msgid "This is the service that keeps you online." -#~ msgstr "Aquest és el servei que et manté connectat." - #: src/view/com/modals/LinkWarning.tsx:58 msgid "This link is taking you to the following website:" msgstr "Questo link ti porta al seguente sito web:" @@ -4063,11 +3819,7 @@ msgstr "Questo utente è incluso nell'elenco <0/> che hai bloccato." #: src/view/com/modals/ModerationDetails.tsx:74 msgid "This user is included in the <0/> list which you have muted." -msgstr "" - -#: src/view/com/modals/ModerationDetails.tsx:74 -#~ msgid "This user is included the <0/> list which you have muted." -#~ msgstr "Questo utente è incluso nell'elenco <0/> che hai silenziato." +msgstr "Questo utente è incluso nell'elenco <0/> che hai disattivato." #: src/view/com/modals/SelfLabel.tsx:137 msgid "This warning is only available for posts with media attached." @@ -4109,9 +3861,6 @@ msgctxt "action" msgid "Try again" msgstr "Riprova" -#~ msgid "Try again" -#~ msgstr "Torna-ho a provar" - #: src/view/screens/ProfileList.tsx:505 msgid "Un-block list" msgstr "Sblocca la lista" @@ -4143,8 +3892,7 @@ msgstr "Sblocca" msgid "Unblock Account" msgstr "Sblocca il conto" -#: src/view/com/modals/Repost.tsx:42 -#: src/view/com/modals/Repost.tsx:55 +#: src/view/com/modals/Repost.tsx:42 src/view/com/modals/Repost.tsx:55 #: src/view/com/util/post-ctrls/RepostButton.tsx:60 #: src/view/com/util/post-ctrls/RepostButton.web.tsx:48 msgid "Undo repost" @@ -4180,8 +3928,7 @@ msgstr "Riattiva questo account" msgid "Unmute thread" msgstr "Riattiva questa discussione" -#: src/view/screens/ProfileFeed.tsx:353 -#: src/view/screens/ProfileList.tsx:580 +#: src/view/screens/ProfileFeed.tsx:353 src/view/screens/ProfileList.tsx:580 msgid "Unpin" msgstr "Stacca dal profilo" @@ -4231,10 +3978,6 @@ msgstr "Utilizza il mio browser predefinito" msgid "Use this to sign into the other app along with your handle." msgstr "Utilizza questo per accedere all'altra app insieme al tuo nome utente." -#: src/view/com/modals/ServerInput.tsx:105 -#~ msgid "Use your domain as your Bluesky client service provider" -#~ msgstr "Utilizza il tuo dominio come provider di servizi clienti Bluesky" - #: src/view/com/modals/InviteCodes.tsx:200 msgid "Used by:" msgstr "Usato da:" @@ -4326,7 +4069,7 @@ msgstr "Verifica la tua email" #: src/screens/Onboarding/index.tsx:42 msgid "Video Games" -msgstr "" +msgstr "Video Games" #: src/view/com/profile/ProfileHeader.tsx:661 msgid "View {0}'s avatar" @@ -4359,15 +4102,15 @@ msgstr "Avvisa" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:134 msgid "We also think you'll like \"For You\" by Skygaze:" -msgstr "" +msgstr "Pensiamo che ti piacerà anche \"Per Te\" di Skygaze:" #: src/screens/Deactivated.tsx:133 msgid "We estimate {estimatedTime} until your account is ready." -msgstr "" +msgstr "Stimiamo {estimatedTime} prima che il tuo account sia pronto." #: src/screens/Onboarding/StepFinished.tsx:93 msgid "We hope you have a wonderful time. Remember, Bluesky is:" -msgstr "" +msgstr "Speriamo di darti dei momenti dei bei momenti. Ricorda, Bluesky è:" #: src/view/com/posts/DiscoverFallbackHeader.tsx:29 msgid "We ran out of posts from your follows. Here's the latest from <0/>." @@ -4375,15 +4118,15 @@ msgstr "Abbiamo esaurito i posts dei tuoi follower. Ecco le ultime novità da <0 #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" -msgstr "" +msgstr "Consigliamo il nostro feed \"Scopri\":" #: src/screens/Onboarding/StepInterests/index.tsx:133 msgid "We weren't able to connect. Please try again to continue setting up your account. If it continues to fail, you can skip this flow." -msgstr "" +msgstr "Non siamo riusciti a connetterci. Riprova per continuare a configurare il tuo account. Se il problema persiste, puoi ignorare questo flusso." #: src/screens/Deactivated.tsx:137 msgid "We will let you know when your account is ready." -msgstr "" +msgstr "Ti faremo sapere quando il tuo account sarà pronto." #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." @@ -4391,7 +4134,7 @@ msgstr "Esamineremo il tuo ricorso al più presto." #: src/screens/Onboarding/StepInterests/index.tsx:138 msgid "We'll use this to help customize your experience." -msgstr "" +msgstr "Lo useremo per personalizzare la tua esperienza." #: src/view/com/auth/create/CreateAccount.tsx:123 msgid "We're so excited to have you join us!" @@ -4415,17 +4158,13 @@ msgstr "Ti diamo il benvenuto a <0>Bluesky" #: src/screens/Onboarding/StepInterests/index.tsx:130 msgid "What are your interests?" -msgstr "" +msgstr "Quali sono i tuoi interessi?" #: src/view/com/modals/report/Modal.tsx:169 msgid "What is the issue with this {collectionName}?" msgstr "Qual è il problema con questo {collectionName}?" -#~ msgid "What's next?" -#~ msgstr "¿Qué sigue?" - -#: src/view/com/auth/SplashScreen.tsx:59 -#: src/view/com/composer/Composer.tsx:279 +#: src/view/com/auth/SplashScreen.tsx:59 src/view/com/composer/Composer.tsx:279 msgid "What's up?" msgstr "Come va?" @@ -4450,14 +4189,13 @@ msgstr "Largo" msgid "Write post" msgstr "Scrivi un post" -#: src/view/com/composer/Composer.tsx:278 -#: src/view/com/composer/Prompt.tsx:33 +#: src/view/com/composer/Composer.tsx:278 src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "Scrivi la tua risposta" #: src/screens/Onboarding/index.tsx:28 msgid "Writers" -msgstr "" +msgstr "Scrittori" #: src/view/com/auth/create/Step2.tsx:263 msgid "XXXXXX" @@ -4475,19 +4213,16 @@ msgstr "Si" #: src/screens/Deactivated.tsx:130 msgid "You are in line." -msgstr "" +msgstr "Sei nella fila." #: src/view/com/posts/FollowingEmptyState.tsx:67 #: src/view/com/posts/FollowingEndOfFeed.tsx:68 msgid "You can also discover new Custom Feeds to follow." msgstr "Puoi anche scoprire nuovi feed personalizzati da seguire." -#~ msgid "You can change hosting providers at any time." -#~ msgstr "Pots canviar el teu proveïdor d'allotjament quan vulguis." - #: src/screens/Onboarding/StepFollowingFeed.tsx:142 msgid "You can change these settings later." -msgstr "" +msgstr "Potrai modificare queste impostazioni in seguito." #: src/view/com/auth/login/Login.tsx:158 #: src/view/com/auth/login/PasswordUpdatedForm.tsx:31 @@ -4523,18 +4258,17 @@ msgstr "Hai bloccato questo utente. Non è possibile visualizzare il contenuto." #: src/view/com/modals/ChangePassword.tsx:87 #: src/view/com/modals/ChangePassword.tsx:121 msgid "You have entered an invalid code. It should look like XXXXX-XXXXX." -msgstr "" +msgstr "Hai inserito un codice non valido. Dovrebbe apparire come XXXX-XXXXXX." #: src/view/com/modals/ModerationDetails.tsx:87 msgid "You have muted this user." -msgstr "Hai silenziato questo utente." +msgstr "Hai disattivato questo utente." #: src/view/com/feeds/ProfileFeedgens.tsx:136 msgid "You have no feeds." msgstr "Non hai feeds." -#: src/view/com/lists/MyLists.tsx:89 -#: src/view/com/lists/ProfileLists.tsx:140 +#: src/view/com/lists/MyLists.tsx:89 src/view/com/lists/ProfileLists.tsx:140 msgid "You have no lists." msgstr "Non hai liste." @@ -4556,7 +4290,7 @@ msgstr "Devi avere almeno 18 anni per abilitare i contenuti per adulti." #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:103 msgid "You must be 18 years or older to enable adult content" -msgstr "" +msgstr "Devi avere almeno 18 anni per abilitare i contenuti per adulti" #: src/view/com/util/forms/PostDropdownBtn.tsx:98 msgid "You will no longer receive notifications for this thread" @@ -4572,17 +4306,16 @@ msgstr "Riceverai un'email con un \"codice di reset\". Inserisci il codice qui, #: src/screens/Onboarding/StepModeration/index.tsx:72 msgid "You're in control" -msgstr "" +msgstr "Sei in controllo" -#: src/screens/Deactivated.tsx:87 -#: src/screens/Deactivated.tsx:88 +#: src/screens/Deactivated.tsx:87 src/screens/Deactivated.tsx:88 #: src/screens/Deactivated.tsx:103 msgid "You're in line" -msgstr "" +msgstr "Sei in fila" #: src/screens/Onboarding/StepFinished.tsx:90 msgid "You're ready to go!" -msgstr "" +msgstr "Sei pronto per iniziare!" #: src/view/com/posts/FollowingEndOfFeed.tsx:48 msgid "You've reached the end of your feed! Find some more accounts to follow." @@ -4598,7 +4331,7 @@ msgstr "Il tuo account è stato eliminato" #: src/view/screens/Settings/ExportCarDialog.tsx:47 msgid "Your account repository, containing all public data records, can be downloaded as a \"CAR\" file. This file does not include media embeds, such as images, or your private data, which must be fetched separately." -msgstr "" +msgstr "L'archivio del tuo account, che contiene tutti i record di dati pubblici, può essere scaricato come file \"CAR\". Questo file non include elementi multimediali incorporati, come immagini o dati privati, che devono essere recuperati separatamente." #: src/view/com/auth/create/Step1.tsx:234 msgid "Your birth date" @@ -4610,7 +4343,7 @@ msgstr "La tua scelta verrà salvata, ma potrà essere modificata successivament #: src/screens/Onboarding/StepFollowingFeed.tsx:61 msgid "Your default feed is \"Following\"" -msgstr "" +msgstr "Il tuo feed predefinito è \"Following\"" #: src/view/com/auth/create/state.ts:153 #: src/view/com/auth/login/ForgotPasswordForm.tsx:70 @@ -4642,17 +4375,9 @@ msgstr "Il tuo nome di utente completo sarà" msgid "Your full handle will be <0>@{0}" msgstr "Il tuo nome di utente completo sarà <0>@{0}" -#~ msgid "Your hosting provider" -#~ msgstr "El teu proveïdor d'allotjament" - -#: src/view/screens/Settings.tsx:NaN -#: src/view/shell/Drawer.tsx:660 -#~ msgid "Your invite codes are hidden when logged in using an App Password" -#~ msgstr "I tuoi codici di invito vengono celati quando accedi utilizzando una password per l'app" - #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" -msgstr "" +msgstr "La tua password è stata modificata correttamente!" #: src/view/com/composer/Composer.tsx:267 msgid "Your post has been published" @@ -4676,3 +4401,153 @@ msgstr "La tua risposta è stata pubblicata" #: src/view/com/auth/create/Step3.tsx:28 msgid "Your user handle" msgstr "Il tuo handle utente" + +#~ msgid "{0, plural, one {# invite code available} other {# invite codes available}}" +#~ msgstr "{0, plural, one {# codice d'invito disponibile} other {# codici d'inviti disponibili}}" + +#~ msgid "{0}" +#~ msgstr "{0}" + +#~ msgid "{0} {purposeLabel} List" +#~ msgstr "Llista {purposeLabel} {0}" + +#~ msgid "{invitesAvailable, plural, one {Invite codes: # available} other {Invite codes: # available}}" +#~ msgstr "{invitesAvailable, plural, one {Codici d'invito: # available} other {Codici d'invito: # available}}" + +#~ msgid "{invitesAvailable} invite code available" +#~ msgstr "{invitesAvailable} codice d'invito disponibile" + +#~ msgid "{invitesAvailable} invite codes available" +#~ msgstr "{invitesAvailable} codici d'invito disponibili" + +#~ msgid "{message}" +#~ msgstr "{message}" + +#~ msgid "App passwords" +#~ msgstr "Passwords dell'app" + +#~ msgid "Appeal Decision" +#~ msgstr "Decisión de apelación" + +#~ msgid "Bluesky.Social" +#~ msgstr "Bluesky.Social" + +#~ msgid "Button disabled. Input custom domain to proceed." +#~ msgstr "Pulsante disabilitato. Inserisci il dominio personalizzato per procedere." + +#~ msgid "Cancel add image alt text" +#~ msgstr "Cancel·la afegir text a la imatge" + +#~ msgid "Change" +#~ msgstr "Canvia" + +#~ msgid "Danger Zone" +#~ msgstr "Zona di Pericolo" + +#~ msgid "Delete my account…" +#~ msgstr "Cancella il mio account…" + +#~ msgid "Dev Server" +#~ msgstr "Servidor de desenvolupament" + +#~ msgid "Developer Tools" +#~ msgstr "Strumenti per sviluppatori" + +#~ msgid "Discover new feeds" +#~ msgstr "Scopri nuovi feeds" + +#~ msgid "Enter the address of your provider:" +#~ msgstr "Introdueix l'adreça del teu proveïdor:" + +#~ msgid "following" +#~ msgstr "seguint" + +#~ msgid "Hosting provider address" +#~ msgstr "Adreça del proveïdor d'allotjament" + +#~ msgid "Invite" +#~ msgstr "Invita" + +#~ msgid "Invite codes: {invitesAvailable} available" +#~ msgstr "Codici di invito: {invitesAvailable} disponibili" + +#~ msgid "liked your custom feed{0}" +#~ msgstr "è piaciuto il feed personalizzato{0}" + +#~ msgid "Local dev server" +#~ msgstr "Server di sviluppo locale" + +#~ msgid "Looks like this feed is only available to users with a Bluesky account. Please sign up or sign in to view this feed!" +#~ msgstr "Parece que este canal de noticias sólo está disponible para usuarios con una cuenta Bluesky. Por favor, ¡regístrate o inicia sesión para ver este canal!" + +#~ msgid "Message from server" +#~ msgstr "Missatge del servidor" + +#~ msgid "New Post" +#~ msgstr "Nova publicació" + +#~ msgid "Opens invite code list" +#~ msgstr "Apre la lista dei codici di invito" + +#~ msgid "Other service" +#~ msgstr "Altro servizio" + +#~ msgid "Please tell us why you think this decision was incorrect." +#~ msgstr "Por favor, dinos por qué crees que esta decisión fue incorrecta." + +#~ msgid "Post" +#~ msgstr "Publicació" + +#~ msgid "Quote Post" +#~ msgstr "Cita una publicació" + +#~ msgid "Reposted by" +#~ msgstr "Ripubblicato da" + +#~ msgid "Reposted by {0})" +#~ msgstr "Ripubblicato da {0})" + +#~ msgid "Select Bluesky Social" +#~ msgstr "Seleziona Bluesky Social" + +#~ msgid "Send Email" +#~ msgstr "Envia correu" + +#~ msgid "Something went wrong and we're not sure what." +#~ msgstr "Qualcosa è andato storto ma non siamo sicuri di cosa." + +#~ msgid "Staging" +#~ msgstr "Allestimento" + +#~ msgid "Swipe up to see more" +#~ msgstr "Scorri verso l'alto per vedere di più" + +#~ msgid "The support form has been moved. If you need help, please<0/> or visit {HELP_DESK_URL} to get in touch with us." +#~ msgstr "El formulari de suport ha estat traslladat. Si necessites ajuda, <0/> o visita {HELP_DESK_URL} per contactar amb nosaltres." + +#~ msgid "This {0} has been labeled." +#~ msgstr "Este {0} ha sido etiquetado." + +#~ msgid "This is the service that keeps you online." +#~ msgstr "Aquest és el servei que et manté connectat." + +#~ msgid "This user is included the <0/> list which you have muted." +#~ msgstr "Questo utente è incluso nell'elenco <0/> che hai silenziato." + +#~ msgid "Try again" +#~ msgstr "Torna-ho a provar" + +#~ msgid "Use your domain as your Bluesky client service provider" +#~ msgstr "Utilizza il tuo dominio come provider di servizi clienti Bluesky" + +#~ msgid "What's next?" +#~ msgstr "¿Qué sigue?" + +#~ msgid "You can change hosting providers at any time." +#~ msgstr "Pots canviar el teu proveïdor d'allotjament quan vulguis." + +#~ msgid "Your hosting provider" +#~ msgstr "El teu proveïdor d'allotjament" + +#~ msgid "Your invite codes are hidden when logged in using an App Password" +#~ msgstr "I tuoi codici di invito vengono celati quando accedi utilizzando una password per l'app" From 4ab7909f8b730fefabb15c6e3b3199ecd2ab7e84 Mon Sep 17 00:00:00 2001 From: Gabriella N <152436322+Titianbeetle@users.noreply.github.com> Date: Fri, 16 Feb 2024 15:30:12 +0100 Subject: [PATCH 017/109] Update messages.po --- src/locale/locales/it/messages.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locale/locales/it/messages.po b/src/locale/locales/it/messages.po index ea93bdfd08..92ab483556 100644 --- a/src/locale/locales/it/messages.po +++ b/src/locale/locales/it/messages.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: Italian localization\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-01-05 11:44+0530\n" -"PO-Revision-Date: \n" +"PO-Revision-Date: 2024-02-16\n" "Last-Translator: Gabriella Nonino \n" "Language-Team: Gabriella Nonino sandsiwmmer@gmail.com\n" "Language: it\n" From 87825f19ec6a32ad3ba640c9c2928a9f6e0d109b Mon Sep 17 00:00:00 2001 From: Gabriella N <152436322+Titianbeetle@users.noreply.github.com> Date: Fri, 16 Feb 2024 20:06:57 +0100 Subject: [PATCH 018/109] Update messages.po Corrected a small grammatical error --- src/locale/locales/it/messages.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locale/locales/it/messages.po b/src/locale/locales/it/messages.po index 92ab483556..b3618cca64 100644 --- a/src/locale/locales/it/messages.po +++ b/src/locale/locales/it/messages.po @@ -2884,7 +2884,7 @@ msgstr "Le risposte a questo thread sono disabilitate" #: src/view/com/composer/Composer.tsx:348 msgctxt "action" msgid "Reply" -msgstr "Rispondi" +msgstr "Risposta" #: src/view/screens/PreferencesHomeFeed.tsx:144 msgid "Reply Filters" @@ -2893,7 +2893,7 @@ msgstr "Filtri di risposta" #: src/view/com/post/Post.tsx:166 src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" -msgstr "Rispondi a <0/>" +msgstr "In risposta a <0/>" #: src/view/com/modals/report/Modal.tsx:166 msgid "Report {collectionName}" From 646a685f264f3ec588e3ac59ebd24b9cc21d5fd6 Mon Sep 17 00:00:00 2001 From: Gabriella N <152436322+Titianbeetle@users.noreply.github.com> Date: Sat, 17 Feb 2024 09:40:59 +0100 Subject: [PATCH 019/109] Update messages.po Changed translation for the word "Following" in the header section --- src/locale/locales/it/messages.po | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/locale/locales/it/messages.po b/src/locale/locales/it/messages.po index b3618cca64..84b02731d7 100644 --- a/src/locale/locales/it/messages.po +++ b/src/locale/locales/it/messages.po @@ -5,7 +5,7 @@ msgstr "" "POT-Creation-Date: 2024-01-05 11:44+0530\n" "PO-Revision-Date: 2024-02-16\n" "Last-Translator: Gabriella Nonino \n" -"Language-Team: Gabriella Nonino sandsiwmmer@gmail.com\n" +"Language-Team: Gabriella Nonino sandswimmer@gmail.com\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -32,7 +32,7 @@ msgstr "<0/> membri" #: src/view/com/profile/ProfileHeader.tsx:594 msgid "<0>{following} <1>following" -msgstr "<0>{following} <1>seguiti" +msgstr "<0>{following} <1>following" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:30 msgid "<0>Choose your<1>Recommended<2>Feeds" @@ -1513,17 +1513,17 @@ msgstr "ti segue" #: src/view/screens/ProfileFollowers.tsx:25 msgid "Followers" -msgstr "Seguiti" +msgstr "Followers" #: src/view/com/post-thread/PostThreadFollowBtn.tsx:136 #: src/view/com/profile/ProfileHeader.tsx:494 #: src/view/screens/ProfileFollows.tsx:25 msgid "Following" -msgstr "Seguiti" +msgstr "Following" #: src/view/com/profile/ProfileHeader.tsx:148 msgid "Following {0}" -msgstr "Seguiti {0}" +msgstr "Following {0}" #: src/view/com/profile/ProfileHeader.tsx:545 msgid "Follows you" From 86df874dd3587c531a2f8ad2c85ee2b266a025af Mon Sep 17 00:00:00 2001 From: Gabriella <152436322+Titianbeetle@users.noreply.github.com> Date: Sat, 17 Feb 2024 10:18:44 +0100 Subject: [PATCH 020/109] Update messages.po changes some wordings, corrected a typo --- src/locale/locales/it/messages.po | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/locale/locales/it/messages.po b/src/locale/locales/it/messages.po index 84b02731d7..582e679557 100644 --- a/src/locale/locales/it/messages.po +++ b/src/locale/locales/it/messages.po @@ -648,7 +648,7 @@ msgstr "clicca qui" #: src/screens/Onboarding/index.tsx:35 msgid "Climate" -msgstr "Il clima" +msgstr "Clima" #: src/view/com/modals/ChangePassword.tsx:265 #: src/view/com/modals/ChangePassword.tsx:268 @@ -933,7 +933,7 @@ msgstr "Cultura" #: src/view/com/auth/server-input/index.tsx:95 #: src/view/com/auth/server-input/index.tsx:96 msgid "Custom" -msgstr "Personalizzatp" +msgstr "Personalizzato" #: src/view/com/modals/ChangeHandle.tsx:389 msgid "Custom domain" @@ -995,7 +995,7 @@ msgstr "Elimina il post" #: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Delete this post?" -msgstr "Elimina questo post?" +msgstr "Eliminare questo post?" #: src/view/com/util/post-embeds/QuoteEmbed.tsx:69 msgid "Deleted" @@ -1035,11 +1035,11 @@ msgstr "Scoraggia le app dal mostrare il mio account agli utenti disconnessi" #: src/view/com/posts/FollowingEmptyState.tsx:74 #: src/view/com/posts/FollowingEndOfFeed.tsx:75 msgid "Discover new custom feeds" -msgstr "Scopri nuovi feed personalizzati" +msgstr "Scopri nuovi feeds personalizzati" #: src/view/screens/Feeds.tsx:689 msgid "Discover New Feeds" -msgstr "Scopri nuovi feed" +msgstr "Scopri nuovi feeds" #: src/view/com/modals/EditProfile.tsx:192 msgid "Display name" @@ -1234,7 +1234,7 @@ msgstr "Attiva Contenuto per Adulti" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:76 #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:77 msgid "Enable adult content in your feeds" -msgstr "Abilita i contenuti per adulti nei tuoi feed" +msgstr "Abilita i contenuti per adulti nei tuoi feeds" #: src/view/com/modals/EmbedConsent.tsx:97 msgid "Enable External Media" From 65606b3929eeb6cba4c71312f8afa68c88e17322 Mon Sep 17 00:00:00 2001 From: Gabriella <152436322+Titianbeetle@users.noreply.github.com> Date: Sun, 18 Feb 2024 09:07:26 +0100 Subject: [PATCH 021/109] Update messages.po Changed the tense of a grammatical sentence to present --- src/locale/locales/it/messages.po | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/locale/locales/it/messages.po b/src/locale/locales/it/messages.po index 582e679557..57561a81e2 100644 --- a/src/locale/locales/it/messages.po +++ b/src/locale/locales/it/messages.po @@ -1933,28 +1933,28 @@ msgstr "Metti mi piace a questo feed" #: src/Navigation.tsx:197 msgid "Liked by" -msgstr "È piaciuto a" +msgstr "Piace a" #: src/view/screens/PostLikedBy.tsx:27 #: src/view/screens/ProfileFeedLikedBy.tsx:27 msgid "Liked By" -msgstr "È Piaciuto A" +msgstr "Piace A" #: src/view/com/feeds/FeedSourceCard.tsx:277 msgid "Liked by {0} {1}" -msgstr "È piaciuto a {0} {1}" +msgstr "Piace a {0} {1}" #: src/view/screens/ProfileFeed.tsx:606 msgid "Liked by {likeCount} {0}" -msgstr "È piaciuto a {likeCount} {0}" +msgstr "Piace a {likeCount} {0}" #: src/view/com/notifications/FeedItem.tsx:170 msgid "liked your custom feed" -msgstr "è piaciuto il tuo feed personalizzato" +msgstr "piace il tuo feed personalizzato" #: src/view/com/notifications/FeedItem.tsx:155 msgid "liked your post" -msgstr "è piaciuto il tuo post" +msgstr "piace il tuo post" #: src/view/screens/Profile.tsx:183 msgid "Likes" @@ -4472,7 +4472,7 @@ msgstr "Il tuo handle utente" #~ msgstr "Codici di invito: {invitesAvailable} disponibili" #~ msgid "liked your custom feed{0}" -#~ msgstr "è piaciuto il feed personalizzato{0}" +#~ msgstr "piace il feed personalizzato{0}" #~ msgid "Local dev server" #~ msgstr "Server di sviluppo locale" From 74895e18c3845c7c0527e58f46d4744f5e00d958 Mon Sep 17 00:00:00 2001 From: Gabriella <152436322+Titianbeetle@users.noreply.github.com> Date: Sun, 18 Feb 2024 09:26:02 +0100 Subject: [PATCH 022/109] Update messages.po grammatical changes related to the subject --- src/locale/locales/it/messages.po | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/locale/locales/it/messages.po b/src/locale/locales/it/messages.po index 57561a81e2..996829a94b 100644 --- a/src/locale/locales/it/messages.po +++ b/src/locale/locales/it/messages.po @@ -2234,11 +2234,11 @@ msgstr "Non perdere mai l'accesso ai tuoi follower o ai tuoi dati." #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" -msgstr "Nuovo" +msgstr "Nuova" #: src/view/screens/ModerationModlists.tsx:78 msgid "New" -msgstr "Nuovo" +msgstr "Nuova" #: src/view/com/modals/CreateOrEditList.tsx:252 msgid "New Moderation List" @@ -2271,7 +2271,7 @@ msgstr "Nuovo post" #: src/view/com/modals/CreateOrEditList.tsx:247 msgid "New User List" -msgstr "Nuova lista utenti" +msgstr "Nuova lista" #: src/view/screens/PreferencesThreads.tsx:79 msgid "Newest replies first" @@ -2771,7 +2771,7 @@ msgstr "Elenchi pubblici e condivisibili di utenti da disattivare o bloccare in #: src/view/screens/Lists.tsx:61 msgid "Public, shareable lists which can drive feeds." -msgstr "Elenchi pubblici e condivisibili che possono gestire i feeds." +msgstr "Liste pubbliche e condivisibili che possono impulsare i feeds." #: src/view/com/composer/Composer.tsx:335 msgid "Publish post" @@ -4001,29 +4001,29 @@ msgstr "Handle dell'utente" #: src/view/com/lists/ListCard.tsx:84 #: src/view/com/modals/UserAddRemoveLists.tsx:198 msgid "User list by {0}" -msgstr "Lista utenti di {0}" +msgstr "Lista di {0}" #: src/view/screens/ProfileList.tsx:762 msgid "User list by <0/>" -msgstr "Lista utenti di<0/>" +msgstr "Lista di<0/>" #: src/view/com/lists/ListCard.tsx:82 #: src/view/com/modals/UserAddRemoveLists.tsx:196 #: src/view/screens/ProfileList.tsx:760 msgid "User list by you" -msgstr "La tua lista utenti" +msgstr "La tua lista" #: src/view/com/modals/CreateOrEditList.tsx:196 msgid "User list created" -msgstr "Lista utenti creata" +msgstr "Lista creata" #: src/view/com/modals/CreateOrEditList.tsx:182 msgid "User list updated" -msgstr "Lista utenti aggiornata" +msgstr "Lista aggiornata" #: src/view/screens/Lists.tsx:58 msgid "User Lists" -msgstr "Lista utenti" +msgstr "Liste publiche" #: src/view/com/auth/login/LoginForm.tsx:177 #: src/view/com/auth/login/LoginForm.tsx:195 From 89f3135ebc440266427d37b5ea26730e8c9183e4 Mon Sep 17 00:00:00 2001 From: Gabriella <152436322+Titianbeetle@users.noreply.github.com> Date: Sun, 18 Feb 2024 09:34:21 +0100 Subject: [PATCH 023/109] Update messages.po Additional grammatical changes --- src/locale/locales/it/messages.po | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/locale/locales/it/messages.po b/src/locale/locales/it/messages.po index 996829a94b..61be5d5f58 100644 --- a/src/locale/locales/it/messages.po +++ b/src/locale/locales/it/messages.po @@ -2934,23 +2934,23 @@ msgstr "Ripubblicare o citare il post" #: src/view/screens/PostRepostedBy.tsx:27 msgid "Reposted By" -msgstr "Ripubblicato da" +msgstr "Repost di" #: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" -msgstr "Ripubblicato da {0}" +msgstr "Repost di {0}" #: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" -msgstr "Ripubblicato da <0/>" +msgstr "Repost di <0/>" #: src/view/com/notifications/FeedItem.tsx:162 msgid "reposted your post" -msgstr "ripubblicato il tuo post" +msgstr "reposted il tuo post" #: src/view/com/post-thread/PostThreadItem.tsx:187 msgid "Reposts of this post" -msgstr "Ripubblicazione di questo post" +msgstr "Repost di questo post" #: src/view/com/modals/ChangeEmail.tsx:181 #: src/view/com/modals/ChangeEmail.tsx:183 @@ -4502,10 +4502,10 @@ msgstr "Il tuo handle utente" #~ msgstr "Cita una publicació" #~ msgid "Reposted by" -#~ msgstr "Ripubblicato da" +#~ msgstr "Repost di" #~ msgid "Reposted by {0})" -#~ msgstr "Ripubblicato da {0})" +#~ msgstr "Repost di {0})" #~ msgid "Select Bluesky Social" #~ msgstr "Seleziona Bluesky Social" From 95bc461932b689a60f4df77aae01d66920e660ca Mon Sep 17 00:00:00 2001 From: Gabriella <152436322+Titianbeetle@users.noreply.github.com> Date: Sun, 18 Feb 2024 09:48:34 +0100 Subject: [PATCH 024/109] Update messages.po Updated Nozioni di Base to Preferenze, which has a more logical contest --- src/locale/locales/it/messages.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locale/locales/it/messages.po b/src/locale/locales/it/messages.po index 61be5d5f58..02e2aecbce 100644 --- a/src/locale/locales/it/messages.po +++ b/src/locale/locales/it/messages.po @@ -344,7 +344,7 @@ msgstr "Basato su i tuoi interessi {interestsText}" #: src/view/screens/Settings/index.tsx:523 msgid "Basics" -msgstr "Nozioni di base" +msgstr "Preferenze" #: src/view/com/auth/create/Step1.tsx:246 #: src/view/com/modals/BirthDateSettings.tsx:73 From 31b7f7601563adea2dd8372b62c911b183953eec Mon Sep 17 00:00:00 2001 From: Gabriella <152436322+Titianbeetle@users.noreply.github.com> Date: Sun, 18 Feb 2024 09:56:14 +0100 Subject: [PATCH 025/109] Update messages.po Additional grammatical correction related to subject gender --- src/locale/locales/it/messages.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/locale/locales/it/messages.po b/src/locale/locales/it/messages.po index 02e2aecbce..970ea80f55 100644 --- a/src/locale/locales/it/messages.po +++ b/src/locale/locales/it/messages.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: Italian localization\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-01-05 11:44+0530\n" -"PO-Revision-Date: 2024-02-16\n" +"PO-Revision-Date: 2024-02-18\n" "Last-Translator: Gabriella Nonino \n" "Language-Team: Gabriella Nonino sandswimmer@gmail.com\n" "Language: it\n" @@ -1386,7 +1386,7 @@ msgstr "Feed" #: src/view/com/feeds/FeedSourceCard.tsx:229 msgid "Feed by {0}" -msgstr "Feed realizzato da {0}" +msgstr "Feed fatto da {0}" #: src/view/screens/Feeds.tsx:605 msgid "Feed offline" @@ -2594,7 +2594,7 @@ msgstr "Fissa sulla pagina principale" #: src/view/screens/SavedFeeds.tsx:88 msgid "Pinned Feeds" -msgstr "Feed Fissati" +msgstr "Feeds Fissi" #: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:111 msgid "Play {0}" From 00103e8e58f6a214187649680028dee2daf92be6 Mon Sep 17 00:00:00 2001 From: jaoler Date: Sun, 18 Feb 2024 20:24:26 +0200 Subject: [PATCH 026/109] Create messages.po Finnish tranlation for Bluesky --- src/locale/locales/fi/messages.po | 4646 +++++++++++++++++++++++++++++ 1 file changed, 4646 insertions(+) create mode 100644 src/locale/locales/fi/messages.po diff --git a/src/locale/locales/fi/messages.po b/src/locale/locales/fi/messages.po new file mode 100644 index 0000000000..06481beac5 --- /dev/null +++ b/src/locale/locales/fi/messages.po @@ -0,0 +1,4646 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-05 16:01-0800\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: fi\n" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: \n" +"Last-Translator: @pekka.bsky.social\n" +"Language-Team: @pekka.bsky.social,@jaoler.fi,@rahi.bsky.social\n" +"Plural-Forms: \n" + +#: src/view/com/modals/VerifyEmail.tsx:142 +msgid "(no email)" +msgstr "(ei sähköpostiosoitetta)" + +#: src/view/shell/desktop/RightNav.tsx:168 +#~ msgid "{0, plural, one {# invite code available} other {# invite codes available}}" +#~ msgstr "" + +#: src/view/com/profile/ProfileHeader.tsx:592 +msgid "{following} following" +msgstr "{following} seuraajaa" + +#: src/view/shell/desktop/RightNav.tsx:151 +#~ msgid "{invitesAvailable, plural, one {Invite codes: # available} other {Invite codes: # available}}" +#~ msgstr "" + +#: src/view/screens/Settings.tsx:435 +#: src/view/shell/Drawer.tsx:664 +#~ msgid "{invitesAvailable} invite code available" +#~ msgstr "" + +#: src/view/screens/Settings.tsx:437 +#: src/view/shell/Drawer.tsx:666 +#~ msgid "{invitesAvailable} invite codes available" +#~ msgstr "" + +#: src/view/shell/Drawer.tsx:440 +msgid "{numUnreadNotifications} unread" +msgstr "{numUnreadNotifications} lukematonta" + +#: src/view/com/threadgate/WhoCanReply.tsx:158 +msgid "<0/> members" +msgstr "<0/> jäsentä" + +#: src/view/com/profile/ProfileHeader.tsx:594 +msgid "<0>{following} <1>following" +msgstr "<0>{following} <1>seuraajaa" + +#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:30 +msgid "<0>Choose your<1>Recommended<2>Feeds" +msgstr "<0>Valitse<1>Suositellut<2>syötteet" + +#: src/view/com/auth/onboarding/RecommendedFollows.tsx:37 +msgid "<0>Follow some<1>Recommended<2>Users" +msgstr "<0>Seuraa joitakin<1>suositeltuja<2>käyttäjiä" + +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:21 +msgid "<0>Welcome to<1>Bluesky" +msgstr "<0>Tervetuloa<1>Blueskyhin" + +#: src/view/com/profile/ProfileHeader.tsx:557 +msgid "⚠Invalid Handle" +msgstr "⚠Virheellinen käyttäjänimi" + +#: src/view/com/util/moderation/LabelInfo.tsx:45 +msgid "A content warning has been applied to this {0}." +msgstr "Tämä {0} sisältää sisältövaroituksen." + +#: src/lib/hooks/useOTAUpdate.ts:16 +msgid "A new version of the app is available. Please update to continue using the app." +msgstr "Sovelluksen uusi versio on saatavilla. Päivitä jatkaaksesi sovelluksen käyttöä." + +#: src/view/com/util/ViewHeader.tsx:83 +#: src/view/screens/Search/Search.tsx:624 +msgid "Access navigation links and settings" +msgstr "Siirry navigointilinkkeihin ja asetuksiin" + +#: src/view/com/pager/FeedsTabBarMobile.tsx:89 +msgid "Access profile and other navigation links" +msgstr "Siirry profiiliin ja muihin navigointilinkkeihin" + +#: src/view/com/modals/EditImage.tsx:299 +#: src/view/screens/Settings/index.tsx:451 +msgid "Accessibility" +msgstr "Saavutettavuus" + +#: src/view/com/auth/login/LoginForm.tsx:166 +#: src/view/screens/Settings/index.tsx:308 +#: src/view/screens/Settings/index.tsx:721 +msgid "Account" +msgstr "Tili" + +#: src/view/com/profile/ProfileHeader.tsx:245 +msgid "Account blocked" +msgstr "Tili on estetty" + +#: src/view/com/profile/ProfileHeader.tsx:212 +msgid "Account muted" +msgstr "Tili on hiljennetty" + +#: src/view/com/modals/ModerationDetails.tsx:86 +msgid "Account Muted" +msgstr "Tili on hiljennetty" + +#: src/view/com/modals/ModerationDetails.tsx:72 +msgid "Account Muted by List" +msgstr "Tili on hiljennetty listan toimesta" + +#: src/view/com/util/AccountDropdownBtn.tsx:41 +msgid "Account options" +msgstr "Tilin asetukset" + +#: src/view/com/util/AccountDropdownBtn.tsx:25 +msgid "Account removed from quick access" +msgstr "Tili poistettu pikalinkeistä" + +#: src/view/com/profile/ProfileHeader.tsx:267 +msgid "Account unblocked" +msgstr "Tilin esto poistettu" + +#: src/view/com/profile/ProfileHeader.tsx:225 +msgid "Account unmuted" +msgstr "Tilin hiljennys poistettu" + +#: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 +#: src/view/com/modals/ListAddRemoveUsers.tsx:264 +#: src/view/com/modals/UserAddRemoveLists.tsx:219 +#: src/view/screens/ProfileList.tsx:812 +msgid "Add" +msgstr "Lisää" + +#: src/view/com/modals/SelfLabel.tsx:56 +msgid "Add a content warning" +msgstr "Lisää sisältövaroitus" + +#: src/view/screens/ProfileList.tsx:802 +msgid "Add a user to this list" +msgstr "Lisää käyttäjä tähän listaan" + +#: src/view/screens/Settings/index.tsx:383 +#: src/view/screens/Settings/index.tsx:392 +msgid "Add account" +msgstr "Lisää tili" + +#: src/view/com/composer/photos/Gallery.tsx:119 +#: src/view/com/composer/photos/Gallery.tsx:180 +#: src/view/com/modals/AltImage.tsx:116 +msgid "Add alt text" +msgstr "Lisää ALT-teksti" + +#: src/view/screens/AppPasswords.tsx:102 +#: src/view/screens/AppPasswords.tsx:143 +#: src/view/screens/AppPasswords.tsx:156 +msgid "Add App Password" +msgstr "Lisää sovelluksen salasana" + +#: src/view/com/modals/report/InputIssueDetails.tsx:41 +#: src/view/com/modals/report/Modal.tsx:191 +msgid "Add details" +msgstr "Lisää tiedot" + +#: src/view/com/modals/report/Modal.tsx:194 +msgid "Add details to report" +msgstr "Lisää tiedot raporttiin" + +#: src/view/com/composer/Composer.tsx:446 +msgid "Add link card" +msgstr "Lisää linkkikortti" + +#: src/view/com/composer/Composer.tsx:451 +msgid "Add link card:" +msgstr "Lisää linkkikortti:" + +#: src/view/com/modals/ChangeHandle.tsx:417 +msgid "Add the following DNS record to your domain:" +msgstr "Lisää seuraava DNS-merkintä verkkotunnukseesi:" + +#: src/view/com/profile/ProfileHeader.tsx:309 +msgid "Add to Lists" +msgstr "Lisää listoihin" + +#: src/view/com/feeds/FeedSourceCard.tsx:243 +#: src/view/screens/ProfileFeed.tsx:272 +msgid "Add to my feeds" +msgstr "Lisää syötteisiini" + +#: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:139 +msgid "Added" +msgstr "Lisätty" + +#: src/view/com/modals/ListAddRemoveUsers.tsx:191 +#: src/view/com/modals/UserAddRemoveLists.tsx:144 +msgid "Added to list" +msgstr "Lisätty listaan" + +#: src/view/com/feeds/FeedSourceCard.tsx:125 +msgid "Added to my feeds" +msgstr "Lisätty syötteisiini" + +#: src/view/screens/PreferencesHomeFeed.tsx:173 +msgid "Adjust the number of likes a reply must have to be shown in your feed." +msgstr "Säädä, kuinka monta tykkäystä vastauksen on saatava näkyäkseen syötteessäsi." + +#: src/view/com/modals/SelfLabel.tsx:75 +msgid "Adult Content" +msgstr "Aikuissisältöä" + +#: src/view/com/modals/ContentFilteringSettings.tsx:141 +msgid "Adult content can only be enabled via the Web at <0/>." +msgstr "Aikuissisältö voidaan ottaa käyttöön vain verkon kautta osoitteessa <0/>." + +#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:78 +#~ msgid "Adult content can only be enabled via the Web at <0>bsky.app." +#~ msgstr "" + +#: src/view/screens/Settings/index.tsx:664 +msgid "Advanced" +msgstr "Edistynyt" + +#: src/view/screens/Feeds.tsx:666 +msgid "All the feeds you've saved, right in one place." +msgstr "Kaikki tallentamasi syötteet yhdessä paikassa." + +#: src/view/com/auth/login/ForgotPasswordForm.tsx:221 +#: src/view/com/modals/ChangePassword.tsx:168 +msgid "Already have a code?" +msgstr "Onko sinulla jo koodi?" + +#: src/view/com/auth/login/ChooseAccountForm.tsx:98 +msgid "Already signed in as @{0}" +msgstr "Kirjautuneena sisään nimellä @{0}" + +#: src/view/com/composer/photos/Gallery.tsx:130 +msgid "ALT" +msgstr "ALT" + +#: src/view/com/modals/EditImage.tsx:315 +msgid "Alt text" +msgstr "ALT-teksti" + +#: src/view/com/composer/photos/Gallery.tsx:209 +msgid "Alt text describes images for blind and low-vision users, and helps give context to everyone." +msgstr "ALT-teksti kuvailee kuvia sokeille ja heikkonäköisille käyttäjille sekä lisää kontekstia kaikille." + +#: src/view/com/modals/VerifyEmail.tsx:124 +msgid "An email has been sent to {0}. It includes a confirmation code which you can enter below." +msgstr "Sähköposti on lähetetty osoitteeseen {0}. Siinä on vahvistuskoodi, jonka voit syöttää alla." + +#: src/view/com/modals/ChangeEmail.tsx:119 +msgid "An email has been sent to your previous address, {0}. It includes a confirmation code which you can enter below." +msgstr "Sähköposti on lähetetty aiempaan osoitteeseesi, {0}. Siinä on vahvistuskoodi, jonka voit syöttää alla." + +#: src/view/com/profile/FollowButton.tsx:30 +#: src/view/com/profile/FollowButton.tsx:40 +msgid "An issue occurred, please try again." +msgstr "Tapahtui virhe, yritä uudelleen." + +#: src/view/com/notifications/FeedItem.tsx:236 +#: src/view/com/threadgate/WhoCanReply.tsx:178 +msgid "and" +msgstr "ja" + +#: src/screens/Onboarding/index.tsx:32 +msgid "Animals" +msgstr "Eläimet" + +#: src/view/screens/LanguageSettings.tsx:95 +msgid "App Language" +msgstr "Sovelluksen kieli" + +#: src/view/screens/AppPasswords.tsx:228 +msgid "App password deleted" +msgstr "Sovelluksen salasana poistettu" + +#: src/view/com/modals/AddAppPasswords.tsx:134 +msgid "App Password names can only contain letters, numbers, spaces, dashes, and underscores." +msgstr "Sovelluksen salasanan nimet voivat sisältää vain kirjaimia, numeroita, välilyöntejä, viivoja ja alaviivoja." + +#: src/view/com/modals/AddAppPasswords.tsx:99 +msgid "App Password names must be at least 4 characters long." +msgstr "Sovelluksen salasanojen nimien on oltava vähintään 4 merkkiä pitkiä." + +#: src/view/screens/Settings/index.tsx:675 +msgid "App password settings" +msgstr "Sovelluksen salasanan asetukset" + +#: src/view/screens/Settings.tsx:650 +#~ msgid "App passwords" +#~ msgstr "" + +#: src/Navigation.tsx:237 +#: src/view/screens/AppPasswords.tsx:187 +#: src/view/screens/Settings/index.tsx:684 +msgid "App Passwords" +msgstr "Sovellussalasanat" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:250 +msgid "Appeal content warning" +msgstr "Valita sisältövaroituksesta" + +#: src/view/com/modals/AppealLabel.tsx:65 +msgid "Appeal Content Warning" +msgstr "Valita sisältövaroituksesta" + +#: src/view/com/util/moderation/LabelInfo.tsx:52 +msgid "Appeal this decision" +msgstr "Valita tästä päätöksestä" + +#: src/view/com/util/moderation/LabelInfo.tsx:56 +msgid "Appeal this decision." +msgstr "Valita tästä päätöksestä." + +#: src/view/screens/Settings/index.tsx:466 +msgid "Appearance" +msgstr "Ulkonäkö" + +#: src/view/screens/AppPasswords.tsx:224 +msgid "Are you sure you want to delete the app password \"{name}\"?" +msgstr "Haluatko varmasti poistaa sovellussalasanan \"{name}\"?" + +#: src/view/com/composer/Composer.tsx:143 +msgid "Are you sure you'd like to discard this draft?" +msgstr "Haluatko varmasti hylätä tämän luonnoksen?" + +#: src/view/screens/ProfileList.tsx:364 +msgid "Are you sure?" +msgstr "Oletko varma?" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:233 +msgid "Are you sure? This cannot be undone." +msgstr "Oletko varma? Tätä ei voi perua." + +#: src/view/com/composer/select-language/SuggestedLanguage.tsx:60 +msgid "Are you writing in <0>{0}?" +msgstr "Onko viestisi kieli <0>{0}?" + +#: src/screens/Onboarding/index.tsx:26 +msgid "Art" +msgstr "Taide" + +#: src/view/com/modals/SelfLabel.tsx:123 +msgid "Artistic or non-erotic nudity." +msgstr "Taiteellinen tai ei-eroottinen alastomuus." + +#: src/view/com/auth/create/CreateAccount.tsx:154 +#: src/view/com/auth/login/ChooseAccountForm.tsx:151 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:174 +#: src/view/com/auth/login/LoginForm.tsx:259 +#: src/view/com/auth/login/SetNewPasswordForm.tsx:179 +#: src/view/com/modals/report/InputIssueDetails.tsx:46 +#: src/view/com/post-thread/PostThread.tsx:471 +#: src/view/com/post-thread/PostThread.tsx:521 +#: src/view/com/post-thread/PostThread.tsx:529 +#: src/view/com/profile/ProfileHeader.tsx:648 +#: src/view/com/util/ViewHeader.tsx:81 +msgid "Back" +msgstr "Takaisin" + +#: src/view/com/post-thread/PostThread.tsx:479 +msgctxt "action" +msgid "Back" +msgstr "Takaisin" + +#: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:136 +msgid "Based on your interest in {interestsText}" +msgstr "Perustuen kiinnostukseesi {interestsText}" + +#: src/view/screens/Settings/index.tsx:523 +msgid "Basics" +msgstr "Perusasiat" + +#: src/view/com/auth/create/Step1.tsx:250 +#: src/view/com/modals/BirthDateSettings.tsx:73 +msgid "Birthday" +msgstr "Syntymäpäivä" + +#: src/view/screens/Settings/index.tsx:340 +msgid "Birthday:" +msgstr "Syntymäpäivä:" + +#: src/view/com/profile/ProfileHeader.tsx:238 +#: src/view/com/profile/ProfileHeader.tsx:345 +msgid "Block Account" +msgstr "Estä käyttäjä" + +#: src/view/screens/ProfileList.tsx:555 +msgid "Block accounts" +msgstr "Estä käyttäjät" + +#: src/view/screens/ProfileList.tsx:505 +msgid "Block list" +msgstr "Estettyjen lista" + +#: src/view/screens/ProfileList.tsx:315 +msgid "Block these accounts?" +msgstr "Estetäänkö nämä käyttäjät?" + +#: src/view/screens/ProfileList.tsx:319 +msgid "Block this List" +msgstr "Estä tämä lista" + +#: src/view/com/lists/ListCard.tsx:109 +#: src/view/com/util/post-embeds/QuoteEmbed.tsx:60 +msgid "Blocked" +msgstr "Estetty" + +#: src/view/screens/Moderation.tsx:123 +msgid "Blocked accounts" +msgstr "Estetyt käyttäjät" + +#: src/Navigation.tsx:130 +#: src/view/screens/ModerationBlockedAccounts.tsx:107 +msgid "Blocked Accounts" +msgstr "Estetyt käyttäjät" + +#: src/view/com/profile/ProfileHeader.tsx:240 +msgid "Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you." +msgstr "Estetyt käyttäjät eivät voi vastata viesteihisi, mainita sinua tai muuten olla vuorovaikutuksessa kanssasi." + +#: src/view/screens/ModerationBlockedAccounts.tsx:115 +msgid "Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you. You will not see their content and they will be prevented from seeing yours." +msgstr "Estetyt käyttäjät eivät voi vastata viesteihisi, mainita sinua tai muuten olla vuorovaikutuksessa kanssasi. Et näe heidän sisältöään ja he eivät näe sinun sisältöäsi." + +#: src/view/com/post-thread/PostThread.tsx:324 +msgid "Blocked post." +msgstr "Estetty viesti." + +#: src/view/screens/ProfileList.tsx:317 +msgid "Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you." +msgstr "Estäminen on julkista. Estetyt käyttäjät eivät voi vastata viesteihisi, mainita sinua tai muuten olla vuorovaikutuksessa kanssasi." + +#: src/view/com/auth/HomeLoggedOutCTA.tsx:93 +#: src/view/com/auth/SplashScreen.web.tsx:133 +msgid "Blog" +msgstr "Blogi" + +#: src/view/com/auth/HomeLoggedOutCTA.tsx:31 +#: src/view/com/auth/server-input/index.tsx:89 +#: src/view/com/auth/server-input/index.tsx:90 +msgid "Bluesky" +msgstr "Bluesky" + +#: src/view/com/auth/server-input/index.tsx:150 +msgid "Bluesky is an open network where you can choose your hosting provider. Custom hosting is now available in beta for developers." +msgstr "Bluesky on avoin verkko, jossa voit valita palveluntarjoajasi. Räätälöity palveluntarjoajan määritys on nyt saatavilla betavaiheen kehittäjille." + +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:80 +#: src/view/com/auth/onboarding/WelcomeMobile.tsx:80 +msgid "Bluesky is flexible." +msgstr "Bluesky on joustava." + +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:69 +#: src/view/com/auth/onboarding/WelcomeMobile.tsx:69 +msgid "Bluesky is open." +msgstr "Bluesky on avoin." + +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:56 +#: src/view/com/auth/onboarding/WelcomeMobile.tsx:56 +msgid "Bluesky is public." +msgstr "Bluesky on julkinen." + +#: src/view/com/modals/Waitlist.tsx:70 +msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." +msgstr "Bluesky käyttää kutsuja rakentaakseen terveellisemmän yhteisön. Jos et tunne ketään, jolla on kutsu, voit ilmoittautua odotuslistalle, niin lähetämme sinulle pian yhden." + +#: src/view/screens/Moderation.tsx:226 +msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." +msgstr "Bluesky ei näytä profiiliasi ja viestejäsi kirjautumattomille käyttäjille. Toiset sovellukset eivät ehkä noudata tätä asetusta. Tämä ei tee tilistäsi yksityistä." + +#: src/view/com/modals/ServerInput.tsx:78 +#~ msgid "Bluesky.Social" +#~ msgstr "" + +#: src/screens/Onboarding/index.tsx:33 +msgid "Books" +msgstr "Kirjat" + +#: src/view/screens/Settings/index.tsx:859 +msgid "Build version {0} {1}" +msgstr "Versio {0} {1}" + +#: src/view/com/auth/HomeLoggedOutCTA.tsx:87 +#: src/view/com/auth/SplashScreen.web.tsx:128 +msgid "Business" +msgstr "Yritys" + +#: src/view/com/modals/ServerInput.tsx:115 +#~ msgid "Button disabled. Input custom domain to proceed." +#~ msgstr "" + +#: src/view/com/profile/ProfileSubpageHeader.tsx:157 +msgid "by —" +msgstr "käyttäjä —" + +#: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:100 +msgid "by {0}" +msgstr "käyttäjältä {0}" + +#: src/view/com/profile/ProfileSubpageHeader.tsx:161 +msgid "by <0/>" +msgstr "käyttäjältä <0/>" + +#: src/view/com/profile/ProfileSubpageHeader.tsx:159 +msgid "by you" +msgstr "sinulta" + +#: src/view/com/composer/photos/OpenCameraBtn.tsx:60 +#: src/view/com/util/UserAvatar.tsx:224 +#: src/view/com/util/UserBanner.tsx:40 +msgid "Camera" +msgstr "Kamera" + +#: src/view/com/modals/AddAppPasswords.tsx:216 +msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must be at least 4 characters long, but no more than 32 characters long." +msgstr "Voi sisältää vain kirjaimia, numeroita, välilyöntejä, viivoja ja alaviivoja. Täytyy olla vähintään 4 merkkiä pitkä, mutta enintään 32 merkkiä pitkä." + +#: src/components/Prompt.tsx:91 +#: src/view/com/composer/Composer.tsx:300 +#: src/view/com/composer/Composer.tsx:305 +#: src/view/com/modals/ChangeEmail.tsx:218 +#: src/view/com/modals/ChangeEmail.tsx:220 +#: src/view/com/modals/ChangePassword.tsx:265 +#: src/view/com/modals/ChangePassword.tsx:268 +#: src/view/com/modals/CreateOrEditList.tsx:355 +#: src/view/com/modals/EditImage.tsx:323 +#: src/view/com/modals/EditProfile.tsx:249 +#: src/view/com/modals/InAppBrowserConsent.tsx:78 +#: src/view/com/modals/LinkWarning.tsx:87 +#: src/view/com/modals/Repost.tsx:87 +#: src/view/com/modals/VerifyEmail.tsx:247 +#: src/view/com/modals/VerifyEmail.tsx:253 +#: src/view/com/modals/Waitlist.tsx:142 +#: src/view/screens/Search/Search.tsx:693 +#: src/view/shell/desktop/Search.tsx:238 +msgid "Cancel" +msgstr "Peruuta" + +#: src/view/com/modals/Confirm.tsx:88 +#: src/view/com/modals/Confirm.tsx:91 +#: src/view/com/modals/CreateOrEditList.tsx:360 +#: src/view/com/modals/DeleteAccount.tsx:156 +#: src/view/com/modals/DeleteAccount.tsx:234 +msgctxt "action" +msgid "Cancel" +msgstr "Peruuta" + +#: src/view/com/modals/DeleteAccount.tsx:152 +#: src/view/com/modals/DeleteAccount.tsx:230 +msgid "Cancel account deletion" +msgstr "Peruuta tilin poisto" + +#: src/view/com/modals/ChangeHandle.tsx:149 +msgid "Cancel change handle" +msgstr "Peruuta käyttäjänimen vaihto" + +#: src/view/com/modals/crop-image/CropImage.web.tsx:134 +msgid "Cancel image crop" +msgstr "Peruuta kuvan rajaus" + +#: src/view/com/modals/EditProfile.tsx:244 +msgid "Cancel profile editing" +msgstr "Peruuta profiilin muokkaus" + +#: src/view/com/modals/Repost.tsx:78 +msgid "Cancel quote post" +msgstr "Peruuta uudelleenpostaus" + +#: src/view/com/modals/ListAddRemoveUsers.tsx:87 +#: src/view/shell/desktop/Search.tsx:234 +msgid "Cancel search" +msgstr "Peruuta haku" + +#: src/view/com/modals/Waitlist.tsx:136 +msgid "Cancel waitlist signup" +msgstr "Peruuta odotuslistalle liittyminen" + +#: src/view/screens/Settings/index.tsx:334 +msgctxt "action" +msgid "Change" +msgstr "Vaihda" + +#: src/view/screens/Settings/index.tsx:696 +msgid "Change handle" +msgstr "Vaihda käyttäjänimi" + +#: src/view/com/modals/ChangeHandle.tsx:161 +#: src/view/screens/Settings/index.tsx:705 +msgid "Change Handle" +msgstr "Vaihda käyttäjänimi" + +#: src/view/com/modals/VerifyEmail.tsx:147 +msgid "Change my email" +msgstr "Vaihda sähköpostiosoitteeni" + +#: src/view/screens/Settings/index.tsx:732 +msgid "Change password" +msgstr "Vaihda salasana" + +#: src/view/screens/Settings/index.tsx:741 +msgid "Change Password" +msgstr "Vaihda salasana" + +#: src/view/com/composer/select-language/SuggestedLanguage.tsx:73 +msgid "Change post language to {0}" +msgstr "Vaihda julkaisun kieleksi {0}" + +#: src/view/screens/Settings/index.tsx:733 +msgid "Change your Bluesky password" +msgstr "Vaihda Bluesky-salasanasi" + +#: src/view/com/modals/ChangeEmail.tsx:109 +msgid "Change Your Email" +msgstr "Vaihda sähköpostiosoitteesi" + +#: src/screens/Deactivated.tsx:72 +#: src/screens/Deactivated.tsx:76 +msgid "Check my status" +msgstr "Tarkista tilani" + +#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:121 +msgid "Check out some recommended feeds. Tap + to add them to your list of pinned feeds." +msgstr "Katso joitakin suositeltuja syötteitä. Napauta + lisätäksesi ne kiinnitettyjen syötteiden luetteloon." + +#: src/view/com/auth/onboarding/RecommendedFollows.tsx:185 +msgid "Check out some recommended users. Follow them to see similar users." +msgstr "Tutustu suositeltuihin käyttäjiin. Seuraa heitä löytääksesi samankaltaisia käyttäjiä." + +#: src/view/com/modals/DeleteAccount.tsx:169 +msgid "Check your inbox for an email with the confirmation code to enter below:" +msgstr "Tarkista sähköpostisi ja syötä saamasi vahvistuskoodi alle:" + +#: src/view/com/modals/Threadgate.tsx:72 +msgid "Choose \"Everybody\" or \"Nobody\"" +msgstr "Valitse \"Kaikki\" tai \"Ei kukaan\"" + +#: src/view/screens/Settings/index.tsx:697 +msgid "Choose a new Bluesky username or create" +msgstr "Valitse uusi Bluesky-käyttäjänimi tai luo" + +#: src/view/com/auth/server-input/index.tsx:79 +msgid "Choose Service" +msgstr "Valitse palvelu" + +#: src/screens/Onboarding/StepFinished.tsx:135 +msgid "Choose the algorithms that power your custom feeds." +msgstr "Valitse algoritmit, jotka ohjaavat mukautettuja syötteitäsi." + +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:83 +#: src/view/com/auth/onboarding/WelcomeMobile.tsx:83 +msgid "Choose the algorithms that power your experience with custom feeds." +msgstr "Valitse algoritmit, jotka ohjaavat kokemustasi mukautettujen syötteiden kanssa." + +#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 +#~ msgid "Choose your algorithmic feeds" +#~ msgstr "" + +#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 +msgid "Choose your main feeds" +msgstr "Valitse pääsyötteet" + +#: src/view/com/auth/create/Step1.tsx:219 +msgid "Choose your password" +msgstr "Valitse salasanasi" + +#: src/view/screens/Settings/index.tsx:834 +#: src/view/screens/Settings/index.tsx:835 +msgid "Clear all legacy storage data" +msgstr "Tyhjennä kaikki vanhan tietomallin mukaiset tiedot" + +#: src/view/screens/Settings/index.tsx:837 +msgid "Clear all legacy storage data (restart after this)" +msgstr "Tyhjennä kaikki vanhan tietomallin tiedot (käynnistä uudelleen tämän jälkeen)" + +#: src/view/screens/Settings/index.tsx:846 +#: src/view/screens/Settings/index.tsx:847 +msgid "Clear all storage data" +msgstr "Tyhjennä kaikki tallennukset" + +#: src/view/screens/Settings/index.tsx:849 +msgid "Clear all storage data (restart after this)" +msgstr "Tyhjennä kaikki tallennukset (käynnistä uudelleen tämän jälkeen)" + +#: src/view/com/util/forms/SearchInput.tsx:88 +#: src/view/screens/Search/Search.tsx:674 +msgid "Clear search query" +msgstr "Tyhjennä hakukysely" + +#: src/view/screens/Support.tsx:40 +msgid "click here" +msgstr "klikkaa tästä" + +#: src/screens/Onboarding/index.tsx:35 +msgid "Climate" +msgstr "Ilmasto" + +#: src/view/com/modals/ChangePassword.tsx:265 +#: src/view/com/modals/ChangePassword.tsx:268 +msgid "Close" +msgstr "Sulje" + +#: src/components/Dialog/index.web.tsx:78 +msgid "Close active dialog" +msgstr "Sulje aktiivinen ikkuna" + +#: src/view/com/auth/login/PasswordUpdatedForm.tsx:38 +msgid "Close alert" +msgstr "Sulje hälytys" + +#: src/view/com/util/BottomSheetCustomBackdrop.tsx:33 +msgid "Close bottom drawer" +msgstr "Sulje alavalinnat" + +#: src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx:26 +msgid "Close image" +msgstr "Sulje kuva" + +#: src/view/com/lightbox/Lightbox.web.tsx:119 +msgid "Close image viewer" +msgstr "Sulje kuvankatselu" + +#: src/view/shell/index.web.tsx:49 +msgid "Close navigation footer" +msgstr "Sulje alanavigointi" + +#: src/view/shell/index.web.tsx:50 +msgid "Closes bottom navigation bar" +msgstr "Sulkee alanavigaation" + +#: src/view/com/auth/login/PasswordUpdatedForm.tsx:39 +msgid "Closes password update alert" +msgstr "Sulkee salasanan päivitysilmoituksen" + +#: src/view/com/composer/Composer.tsx:302 +msgid "Closes post composer and discards post draft" +msgstr "Sulkee editorin ja hylkää luonnoksen" + +#: src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx:27 +msgid "Closes viewer for header image" +msgstr "Sulkee kuvan katseluohjelman" + +#: src/view/com/notifications/FeedItem.tsx:317 +msgid "Collapses list of users for a given notification" +msgstr "Pienentää käyttäjäluettelon annetulle ilmoitukselle" + +#: src/screens/Onboarding/index.tsx:41 +msgid "Comedy" +msgstr "Komedia" + +#: src/screens/Onboarding/index.tsx:27 +msgid "Comics" +msgstr "Sarjakuvat" + +#: src/Navigation.tsx:227 +#: src/view/screens/CommunityGuidelines.tsx:32 +msgid "Community Guidelines" +msgstr "Yhteisöohjeet" + +#: src/screens/Onboarding/StepFinished.tsx:148 +msgid "Complete onboarding and start using your account" +msgstr "Suorita käyttöönotto loppuun ja aloita tilisi käyttö" + +#: src/view/com/auth/create/Step3.tsx:73 +msgid "Complete the challenge" +msgstr "Tee haaste loppuun" + +#: src/view/com/composer/Composer.tsx:417 +msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" +msgstr "Laadi viestejä, joiden pituus on enintään {MAX_GRAPHEME_LENGTH} merkkiä" + +#: src/view/com/composer/Prompt.tsx:24 +msgid "Compose reply" +msgstr "Kirjoita vastaus" + +#: src/screens/Onboarding/StepModeration/ModerationOption.tsx:67 +msgid "Configure content filtering setting for category: {0}" +msgstr "Määritä sisällönsuodatusasetus aiheille: {0}" + +#: src/components/Prompt.tsx:113 +#: src/view/com/modals/AppealLabel.tsx:98 +#: src/view/com/modals/SelfLabel.tsx:154 +#: src/view/com/modals/VerifyEmail.tsx:231 +#: src/view/com/modals/VerifyEmail.tsx:233 +#: src/view/screens/PreferencesHomeFeed.tsx:308 +#: src/view/screens/PreferencesThreads.tsx:159 +msgid "Confirm" +msgstr "Vahvista" + +#: src/view/com/modals/Confirm.tsx:75 +#: src/view/com/modals/Confirm.tsx:78 +msgctxt "action" +msgid "Confirm" +msgstr "Vahvista" + +#: src/view/com/modals/ChangeEmail.tsx:193 +#: src/view/com/modals/ChangeEmail.tsx:195 +msgid "Confirm Change" +msgstr "Vahvista muutos" + +#: src/view/com/modals/lang-settings/ConfirmLanguagesButton.tsx:34 +msgid "Confirm content language settings" +msgstr "Vahvista sisällön kieliasetukset" + +#: src/view/com/modals/DeleteAccount.tsx:220 +msgid "Confirm delete account" +msgstr "Vahvista tilin poisto" + +#: src/view/com/modals/ContentFilteringSettings.tsx:156 +msgid "Confirm your age to enable adult content." +msgstr "Vahvista ikäsi nähdäksesi ikärajarajoitettua sisältöä" + +#: src/view/com/modals/ChangeEmail.tsx:157 +#: src/view/com/modals/DeleteAccount.tsx:182 +#: src/view/com/modals/VerifyEmail.tsx:165 +msgid "Confirmation code" +msgstr "Vahvistuskoodi" + +#: src/view/com/modals/Waitlist.tsx:120 +msgid "Confirms signing up {email} to the waitlist" +msgstr "Vahvistaa sähköpostiosoitteen {email} - rekisteröinnin odotuslistalle" + +#: src/view/com/auth/create/CreateAccount.tsx:189 +#: src/view/com/auth/login/LoginForm.tsx:278 +msgid "Connecting..." +msgstr "Yhdistetään..." + +#: src/view/com/auth/create/CreateAccount.tsx:209 +msgid "Contact support" +msgstr "Ota yhteyttä tukeen" + +#: src/view/screens/Moderation.tsx:81 +msgid "Content filtering" +msgstr "Sisällönsuodatus" + +#: src/view/com/modals/ContentFilteringSettings.tsx:44 +msgid "Content Filtering" +msgstr "Sisällönsuodatus" + +#: src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx:74 +#: src/view/screens/LanguageSettings.tsx:278 +msgid "Content Languages" +msgstr "Sisältöjen kielet" + +#: src/view/com/modals/ModerationDetails.tsx:65 +msgid "Content Not Available" +msgstr "Sisältö ei ole saatavilla" + +#: src/view/com/modals/ModerationDetails.tsx:33 +#: src/view/com/util/moderation/ScreenHider.tsx:78 +msgid "Content Warning" +msgstr "Sisältövaroitus" + +#: src/view/com/composer/labels/LabelsBtn.tsx:31 +msgid "Content warnings" +msgstr "Sisältövaroitukset" + +#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:170 +#: src/screens/Onboarding/StepFollowingFeed.tsx:153 +#: src/screens/Onboarding/StepInterests/index.tsx:248 +#: src/screens/Onboarding/StepModeration/index.tsx:118 +#: src/screens/Onboarding/StepTopicalFeeds.tsx:108 +#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:148 +#: src/view/com/auth/onboarding/RecommendedFollows.tsx:209 +msgid "Continue" +msgstr "Jatka" + +#: src/screens/Onboarding/StepFollowingFeed.tsx:150 +#: src/screens/Onboarding/StepInterests/index.tsx:245 +#: src/screens/Onboarding/StepModeration/index.tsx:115 +#: src/screens/Onboarding/StepTopicalFeeds.tsx:105 +msgid "Continue to next step" +msgstr "Jatka seuraavaan vaiheeseen" + +#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:167 +msgid "Continue to the next step" +msgstr "Jatka seuraavaan vaiheeseen" + +#: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:191 +msgid "Continue to the next step without following any accounts" +msgstr "Jatka seuraavaan vaiheeseen seuraamatta yhtään tiliä" + +#: src/screens/Onboarding/index.tsx:44 +msgid "Cooking" +msgstr "Ruoanlaitto" + +#: src/view/com/modals/AddAppPasswords.tsx:195 +#: src/view/com/modals/InviteCodes.tsx:182 +msgid "Copied" +msgstr "Kopioitu" + +#: src/view/screens/Settings/index.tsx:241 +msgid "Copied build version to clipboard" +msgstr "Ohjelmiston versio kopioitu leikepöydälle" + +#: src/view/com/modals/AddAppPasswords.tsx:76 +#: src/view/com/modals/InviteCodes.tsx:152 +#: src/view/com/util/forms/PostDropdownBtn.tsx:112 +msgid "Copied to clipboard" +msgstr "Kopioitu leikepöydälle" + +#: src/view/com/modals/AddAppPasswords.tsx:189 +msgid "Copies app password" +msgstr "Kopioi sovellussalasanan" + +#: src/view/com/modals/AddAppPasswords.tsx:188 +msgid "Copy" +msgstr "Kopioi" + +#: src/view/screens/ProfileList.tsx:417 +msgid "Copy link to list" +msgstr "Kopioi listan linkki" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:153 +msgid "Copy link to post" +msgstr "Kopioi julkaisun linkki" + +#: src/view/com/profile/ProfileHeader.tsx:294 +msgid "Copy link to profile" +msgstr "Kopioi linkki profiiliin" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:139 +msgid "Copy post text" +msgstr "Kopioi viestin teksti" + +#: src/Navigation.tsx:232 +#: src/view/screens/CopyrightPolicy.tsx:29 +msgid "Copyright Policy" +msgstr "Tekijänoikeuskäytäntö" + +#: src/view/screens/ProfileFeed.tsx:96 +msgid "Could not load feed" +msgstr "Syötettä ei voitu ladata" + +#: src/view/screens/ProfileList.tsx:888 +msgid "Could not load list" +msgstr "Listaa ei voitu ladata" + +#: src/view/com/auth/create/Step2.tsx:91 +#~ msgid "Country" +#~ msgstr "Maa" + +#: src/view/com/auth/HomeLoggedOutCTA.tsx:62 +#: src/view/com/auth/SplashScreen.tsx:71 +#: src/view/com/auth/SplashScreen.web.tsx:81 +msgid "Create a new account" +msgstr "Luo uusi tili" + +#: src/view/screens/Settings/index.tsx:384 +msgid "Create a new Bluesky account" +msgstr "Luo uusi Bluesky-tili" + +#: src/view/com/auth/create/CreateAccount.tsx:129 +msgid "Create Account" +msgstr "Luo tili" + +#: src/view/com/modals/AddAppPasswords.tsx:226 +msgid "Create App Password" +msgstr "Luo sovellussalasana" + +#: src/view/com/auth/HomeLoggedOutCTA.tsx:54 +#: src/view/com/auth/SplashScreen.tsx:68 +msgid "Create new account" +msgstr "Luo uusi tili" + +#: src/view/screens/AppPasswords.tsx:249 +msgid "Created {0}" +msgstr "{0} luotu" + +#: src/view/screens/ProfileFeed.tsx:616 +msgid "Created by <0/>" +msgstr "Luonut <0/>" + +#: src/view/screens/ProfileFeed.tsx:614 +msgid "Created by you" +msgstr "Sinun luoma sisältö" + +#: src/view/com/composer/Composer.tsx:448 +msgid "Creates a card with a thumbnail. The card links to {url}" +msgstr "Luo kortin pikkukuvan kanssa. Kortti linkittyy osoitteeseen {url}" + +#: src/screens/Onboarding/index.tsx:29 +msgid "Culture" +msgstr "Kulttuuri" + +#: src/view/com/auth/server-input/index.tsx:95 +#: src/view/com/auth/server-input/index.tsx:96 +msgid "Custom" +msgstr "Mukautettu" + +#: src/view/com/modals/ChangeHandle.tsx:389 +msgid "Custom domain" +msgstr "Mukautettu verkkotunnus" + +#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 +#: src/view/screens/Feeds.tsx:692 +msgid "Custom feeds built by the community bring you new experiences and help you find the content you love." +msgstr "Yhteisön rakentamat mukautetut syötteet tuovat sinulle uusia kokemuksia ja auttavat löytämään sinulle mieluisaa sisältöä." + +#: src/view/screens/PreferencesExternalEmbeds.tsx:55 +msgid "Customize media from external sites." +msgstr "Muokkaa mediaa ulkoisista sivustoista." + +#: src/view/screens/Settings.tsx:687 +#~ msgid "Danger Zone" +#~ msgstr "" + +#: src/view/screens/Settings/index.tsx:485 +#: src/view/screens/Settings/index.tsx:511 +msgid "Dark" +msgstr "Tumma" + +#: src/view/screens/Debug.tsx:63 +msgid "Dark mode" +msgstr "Tumma ulkoasu" + +#: src/view/screens/Settings/index.tsx:498 +msgid "Dark Theme" +msgstr "Tumma teema" + +#: src/view/screens/Debug.tsx:83 +msgid "Debug panel" +msgstr "Vianetsintäpaneeli" + +#: src/view/screens/Settings/index.tsx:772 +msgid "Delete account" +msgstr "Poista käyttäjätili" + +#: src/view/com/modals/DeleteAccount.tsx:87 +msgid "Delete Account" +msgstr "Poista tili" + +#: src/view/screens/AppPasswords.tsx:222 +#: src/view/screens/AppPasswords.tsx:242 +msgid "Delete app password" +msgstr "Poista sovellussalasana" + +#: src/view/screens/ProfileList.tsx:363 +#: src/view/screens/ProfileList.tsx:444 +msgid "Delete List" +msgstr "Poista lista" + +#: src/view/com/modals/DeleteAccount.tsx:223 +msgid "Delete my account" +msgstr "Poista tilini" + +#: src/view/screens/Settings.tsx:706 +#~ msgid "Delete my account…" +#~ msgstr "" + +#: src/view/screens/Settings/index.tsx:784 +msgid "Delete My Account…" +msgstr "Poista tilini…" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:228 +msgid "Delete post" +msgstr "Poista viesti" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:232 +msgid "Delete this post?" +msgstr "Poista tämä viesti?" + +#: src/view/com/util/post-embeds/QuoteEmbed.tsx:69 +msgid "Deleted" +msgstr "Poistettu" + +#: src/view/com/post-thread/PostThread.tsx:316 +msgid "Deleted post." +msgstr "Poistettu viesti." + +#: src/view/com/modals/CreateOrEditList.tsx:300 +#: src/view/com/modals/CreateOrEditList.tsx:321 +#: src/view/com/modals/EditProfile.tsx:198 +#: src/view/com/modals/EditProfile.tsx:210 +msgid "Description" +msgstr "Kuvaus" + +#: src/view/screens/Settings.tsx:760 +#~ msgid "Developer Tools" +#~ msgstr "" + +#: src/view/com/composer/Composer.tsx:211 +msgid "Did you want to say anything?" +msgstr "Haluatko sanoa jotain?" + +#: src/view/screens/Settings/index.tsx:504 +msgid "Dim" +msgstr "Himmeä" + +#: src/view/com/composer/Composer.tsx:144 +msgid "Discard" +msgstr "Hylkää" + +#: src/view/com/composer/Composer.tsx:138 +msgid "Discard draft" +msgstr "Hylkää luonnos" + +#: src/view/screens/Moderation.tsx:207 +msgid "Discourage apps from showing my account to logged-out users" +msgstr "Estä sovelluksia näyttämästä tiliäni kirjautumattomille käyttäjille" + +#: src/view/com/posts/FollowingEmptyState.tsx:74 +#: src/view/com/posts/FollowingEndOfFeed.tsx:75 +msgid "Discover new custom feeds" +msgstr "Löydä uusia mukautettuja syötteitä" + +#: src/view/screens/Feeds.tsx:473 +#~ msgid "Discover new feeds" +#~ msgstr "" + +#: src/view/screens/Feeds.tsx:689 +msgid "Discover New Feeds" +msgstr "Löydä uusia syötteitä" + +#: src/view/com/modals/EditProfile.tsx:192 +msgid "Display name" +msgstr "Näyttönimi" + +#: src/view/com/modals/EditProfile.tsx:180 +msgid "Display Name" +msgstr "Näyttönimi" + +#: src/view/com/modals/ChangeHandle.tsx:487 +msgid "Domain verified!" +msgstr "Verkkotunnus vahvistettu!" + +#: src/view/com/auth/create/Step1.tsx:170 +msgid "Don't have an invite code?" +msgstr "Eikö sinulla ole kutsukoodia?" + +#: src/view/com/auth/onboarding/RecommendedFollows.tsx:86 +#: src/view/com/modals/EditImage.tsx:333 +#: src/view/com/modals/ListAddRemoveUsers.tsx:144 +#: src/view/com/modals/SelfLabel.tsx:157 +#: src/view/com/modals/Threadgate.tsx:129 +#: src/view/com/modals/Threadgate.tsx:132 +#: src/view/com/modals/UserAddRemoveLists.tsx:95 +#: src/view/com/modals/UserAddRemoveLists.tsx:98 +#: src/view/screens/PreferencesThreads.tsx:162 +msgctxt "action" +msgid "Done" +msgstr "Valmis" + +#: src/view/com/auth/server-input/index.tsx:165 +#: src/view/com/auth/server-input/index.tsx:166 +#: src/view/com/modals/AddAppPasswords.tsx:226 +#: src/view/com/modals/AltImage.tsx:139 +#: src/view/com/modals/ContentFilteringSettings.tsx:88 +#: src/view/com/modals/ContentFilteringSettings.tsx:96 +#: src/view/com/modals/crop-image/CropImage.web.tsx:152 +#: src/view/com/modals/InviteCodes.tsx:80 +#: src/view/com/modals/InviteCodes.tsx:123 +#: src/view/com/modals/ListAddRemoveUsers.tsx:142 +#: src/view/screens/PreferencesHomeFeed.tsx:311 +#: src/view/screens/Settings/ExportCarDialog.tsx:93 +#: src/view/screens/Settings/ExportCarDialog.tsx:94 +msgid "Done" +msgstr "Valmis" + +#: src/view/com/modals/lang-settings/ConfirmLanguagesButton.tsx:42 +msgid "Done{extraText}" +msgstr "Valmis{extraText}" + +#: src/view/com/auth/login/ChooseAccountForm.tsx:45 +msgid "Double tap to sign in" +msgstr "Kaksoisnapauta kirjautuaksesi sisään" + +#: src/view/screens/Settings/index.tsx:755 +msgid "Download Bluesky account data (repository)" +msgstr "Lataa Bluesky-tilin tiedot (repository)" + +#: src/view/screens/Settings/ExportCarDialog.tsx:59 +#: src/view/screens/Settings/ExportCarDialog.tsx:63 +msgid "Download CAR file" +msgstr "Lataa CAR tiedosto" + +#: src/view/com/composer/text-input/TextInput.web.tsx:247 +msgid "Drop to add images" +msgstr "Raahaa tähän lisätäksesi kuvia" + +#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:111 +msgid "Due to Apple policies, adult content can only be enabled on the web after completing sign up." +msgstr "Applen sääntöjen vuoksi aikuisviihde voidaan ottaa käyttöön vasta rekisteröitymisen jälkeen." + +#: src/view/com/modals/EditProfile.tsx:185 +msgid "e.g. Alice Roberts" +msgstr "esim. Mikko Mallikas" + +#: src/view/com/modals/EditProfile.tsx:203 +msgid "e.g. Artist, dog-lover, and avid reader." +msgstr "esim. Taiteilija, koiraharrastaja ja innokas lukija." + +#: src/view/com/modals/CreateOrEditList.tsx:283 +msgid "e.g. Great Posters" +msgstr "esim. Loistavat kirjoittajat" + +#: src/view/com/modals/CreateOrEditList.tsx:284 +msgid "e.g. Spammers" +msgstr "esim. Roskapostittajat" + +#: src/view/com/modals/CreateOrEditList.tsx:312 +msgid "e.g. The posters who never miss." +msgstr "esim. Julkaisijat, jotka osuvat maaliin aina." + +#: src/view/com/modals/CreateOrEditList.tsx:313 +msgid "e.g. Users that repeatedly reply with ads." +msgstr "esim. Käyttäjät, jotka vastaavat toistuvasti mainoksilla." + +#: src/view/com/modals/InviteCodes.tsx:96 +msgid "Each code works once. You'll receive more invite codes periodically." +msgstr "Jokainen koodi toimii vain kerran. Saat lisää kutsukoodeja säännöllisin väliajoin." + +#: src/view/com/lists/ListMembers.tsx:149 +msgctxt "action" +msgid "Edit" +msgstr "Muokkaa" + +#: src/view/com/composer/photos/Gallery.tsx:144 +#: src/view/com/modals/EditImage.tsx:207 +msgid "Edit image" +msgstr "Muokkaa kuvaa" + +#: src/view/screens/ProfileList.tsx:432 +msgid "Edit list details" +msgstr "Muokkaa listan tietoja" + +#: src/view/com/modals/CreateOrEditList.tsx:250 +msgid "Edit Moderation List" +msgstr "Muokkaa moderaatiolistaa" + +#: src/Navigation.tsx:242 +#: src/view/screens/Feeds.tsx:434 +#: src/view/screens/SavedFeeds.tsx:84 +msgid "Edit My Feeds" +msgstr "Muokkaa syötteitäni" + +#: src/view/com/modals/EditProfile.tsx:152 +msgid "Edit my profile" +msgstr "Muokkaa profiiliani" + +#: src/view/com/profile/ProfileHeader.tsx:417 +msgid "Edit profile" +msgstr "Muokkaa profiilia" + +#: src/view/com/profile/ProfileHeader.tsx:422 +msgid "Edit Profile" +msgstr "Muokkaa profiilia" + +#: src/view/screens/Feeds.tsx:355 +msgid "Edit Saved Feeds" +msgstr "Muokkaa tallennettuja syötteitä" + +#: src/view/com/modals/CreateOrEditList.tsx:245 +msgid "Edit User List" +msgstr "Muokkaa käyttäjälistaa" + +#: src/view/com/modals/EditProfile.tsx:193 +msgid "Edit your display name" +msgstr "Muokkaa näyttönimeäsi" + +#: src/view/com/modals/EditProfile.tsx:211 +msgid "Edit your profile description" +msgstr "Muokkaa profiilin kuvausta" + +#: src/screens/Onboarding/index.tsx:34 +msgid "Education" +msgstr "Koulutus" + +#: src/view/com/auth/create/Step1.tsx:199 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:156 +#: src/view/com/modals/ChangeEmail.tsx:141 +#: src/view/com/modals/Waitlist.tsx:88 +msgid "Email" +msgstr "Sähköposti" + +#: src/view/com/auth/create/Step1.tsx:190 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:147 +msgid "Email address" +msgstr "Sähköpostiosoite" + +#: src/view/com/modals/ChangeEmail.tsx:56 +#: src/view/com/modals/ChangeEmail.tsx:88 +msgid "Email updated" +msgstr "Sähköpostiosoite päivitetty" + +#: src/view/com/modals/ChangeEmail.tsx:111 +msgid "Email Updated" +msgstr "Sähköpostiosoite päivitetty" + +#: src/view/com/modals/VerifyEmail.tsx:78 +msgid "Email verified" +msgstr "Sähköpostiosoite vahvistettu" + +#: src/view/screens/Settings/index.tsx:312 +msgid "Email:" +msgstr "Sähköpostiosoite:" + +#: src/view/com/modals/EmbedConsent.tsx:113 +msgid "Enable {0} only" +msgstr "Ota käyttöön vain {0}" + +#: src/view/com/modals/ContentFilteringSettings.tsx:167 +msgid "Enable Adult Content" +msgstr "Ota aikuissisältö käyttöön" + +#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:76 +#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:77 +msgid "Enable adult content in your feeds" +msgstr "Näytä aikuissisältöä syötteissäsi" + +#: src/view/com/modals/EmbedConsent.tsx:97 +msgid "Enable External Media" +msgstr "Ota ulkoinen media käyttöön" + +#: src/view/screens/PreferencesExternalEmbeds.tsx:75 +msgid "Enable media players for" +msgstr "Ota mediatoistimet käyttöön kohteille" + +#: src/view/screens/PreferencesHomeFeed.tsx:147 +msgid "Enable this setting to only see replies between people you follow." +msgstr "Ota tämä asetus käyttöön nähdäksesi vastaukset vain seuraamiltasi ihmisiltä." + +#: src/view/screens/Profile.tsx:455 +msgid "End of feed" +msgstr "Syötteen loppu" + +#: src/view/com/modals/AddAppPasswords.tsx:166 +msgid "Enter a name for this App Password" +msgstr "Anna nimi tälle sovellussalasanalle" + +#: src/view/com/modals/VerifyEmail.tsx:105 +msgid "Enter Confirmation Code" +msgstr "Syötä vahvistuskoodi" + +#: src/view/com/modals/ChangePassword.tsx:151 +msgid "Enter the code you received to change your password." +msgstr "Anna saamasi koodi vaihtaaksesi salasanasi." + +#: src/view/com/modals/ChangeHandle.tsx:371 +msgid "Enter the domain you want to use" +msgstr "Anna verkkotunnus, jota haluat käyttää" + +#: src/view/com/auth/login/ForgotPasswordForm.tsx:107 +msgid "Enter the email you used to create your account. We'll send you a \"reset code\" so you can set a new password." +msgstr "Anna sähköpostiosoite, jotaa käytit tilin luomiseen. Lähetämme sinulle \"nollauskoodin\", jotta voit määritellä uuden salasanan." + +#: src/view/com/auth/create/Step1.tsx:251 +#: src/view/com/modals/BirthDateSettings.tsx:74 +msgid "Enter your birth date" +msgstr "Syötä syntymäaikasi" + +#: src/view/com/modals/Waitlist.tsx:78 +msgid "Enter your email" +msgstr "Syötä sähköpostiosoitteesi" + +#: src/view/com/auth/create/Step1.tsx:195 +msgid "Enter your email address" +msgstr "Syötä sähköpostiosoitteesi" + +#: src/view/com/modals/ChangeEmail.tsx:41 +msgid "Enter your new email above" +msgstr "Syötä uusi sähköpostiosoitteesi yläpuolelle" + +#: src/view/com/modals/ChangeEmail.tsx:117 +msgid "Enter your new email address below." +msgstr "Syötä uusi sähköpostiosoitteesi alle" + +#: src/view/com/auth/create/Step2.tsx:188 +#~ msgid "Enter your phone number" +msgstr "Syötä puhelinnumerosi" + +#: src/view/com/auth/login/Login.tsx:99 +msgid "Enter your username and password" +msgstr "Syötä käyttäjänimesi ja salasanasi" + +#: src/view/com/auth/create/Step3.tsx:67 +msgid "Error receiving captcha response." +msgstr "Virhe captcha-vastauksen vastaanottamisessa." + +#: src/view/screens/Search/Search.tsx:109 +msgid "Error:" +msgstr "Virhe:" + +#: src/view/com/modals/Threadgate.tsx:76 +msgid "Everybody" +msgstr "Kaikki" + +#: src/view/com/modals/ChangeHandle.tsx:150 +msgid "Exits handle change process" +msgstr "Peruuta käyttäjänimen vaihtaminen" + +#: src/view/com/lightbox/Lightbox.web.tsx:120 +msgid "Exits image view" +msgstr "Poistuu kuvan katselutilasta" + +#: src/view/com/modals/ListAddRemoveUsers.tsx:88 +#: src/view/shell/desktop/Search.tsx:235 +msgid "Exits inputting search query" +msgstr "Poistuu hakukyselyn kirjoittamisesta" + +#: src/view/com/modals/Waitlist.tsx:138 +msgid "Exits signing up for waitlist with {email}" +msgstr "Poistu odotuslistalle liittymisestä sähköpostilla {email}" + +#: src/view/com/lightbox/Lightbox.web.tsx:163 +msgid "Expand alt text" +msgstr "Laajenna ALT-teksti" + +#: src/view/com/composer/ComposerReplyTo.tsx:81 +#: src/view/com/composer/ComposerReplyTo.tsx:84 +msgid "Expand or collapse the full post you are replying to" +msgstr "Laajenna tai pienennä viesti johon olit vastaamassa" + +#: src/view/screens/Settings/index.tsx:753 +msgid "Export my data" +msgstr "Vie tietoni" + +#: src/view/screens/Settings/ExportCarDialog.tsx:44 +#: src/view/screens/Settings/index.tsx:764 +msgid "Export My Data" +msgstr "Vie tietoni" + +#: src/view/com/modals/EmbedConsent.tsx:64 +msgid "External Media" +msgstr "Ulkoiset mediat" + +#: src/view/com/modals/EmbedConsent.tsx:75 +#: src/view/screens/PreferencesExternalEmbeds.tsx:66 +msgid "External media may allow websites to collect information about you and your device. No information is sent or requested until you press the \"play\" button." +msgstr "Ulkoiset mediat voivat sallia verkkosivustojen kerätä tietoja sinusta ja laitteestasi. Tietoja ei lähetetä eikä pyydetä, ennen kuin painat \"toista\"-painiketta." + +#: src/Navigation.tsx:258 +#: src/view/screens/PreferencesExternalEmbeds.tsx:52 +#: src/view/screens/Settings/index.tsx:657 +msgid "External Media Preferences" +msgstr "Ulkoisten medioiden asetukset" + +#: src/view/screens/Settings/index.tsx:648 +msgid "External media settings" +msgstr "Ulkoisten medioiden asetukset" + +#: src/view/com/modals/AddAppPasswords.tsx:115 +#: src/view/com/modals/AddAppPasswords.tsx:119 +msgid "Failed to create app password." +msgstr "Sovellussalasanan luominen epäonnistui." + +#: src/view/com/modals/CreateOrEditList.tsx:206 +msgid "Failed to create the list. Check your internet connection and try again." +msgstr "Listan luominen epäonnistui. Tarkista internetyhteytesi ja yritä uudelleen." + +#: src/view/com/util/forms/PostDropdownBtn.tsx:88 +msgid "Failed to delete post, please try again" +msgstr "Viestin poistaminen epäonnistui, yritä uudelleen" + +#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:109 +#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:141 +msgid "Failed to load recommended feeds" +msgstr "Suositeltujen syötteiden lataaminen epäonnistui" + +#: src/Navigation.tsx:192 +msgid "Feed" +msgstr "Syöte" + +#: src/view/com/feeds/FeedSourceCard.tsx:229 +msgid "Feed by {0}" +msgstr "Syöte käyttäjältä {0}" + +#: src/view/screens/Feeds.tsx:605 +msgid "Feed offline" +msgstr "Syöte ei ole käytettävissä" + +#: src/view/com/feeds/FeedPage.tsx:143 +msgid "Feed Preferences" +msgstr "Syötteen asetukset" + +#: src/view/shell/desktop/RightNav.tsx:61 +#: src/view/shell/Drawer.tsx:311 +msgid "Feedback" +msgstr "Palaute" + +#: src/Navigation.tsx:442 +#: src/view/screens/Feeds.tsx:419 +#: src/view/screens/Feeds.tsx:524 +#: src/view/screens/Profile.tsx:184 +#: src/view/shell/bottom-bar/BottomBar.tsx:181 +#: src/view/shell/desktop/LeftNav.tsx:342 +#: src/view/shell/Drawer.tsx:476 +#: src/view/shell/Drawer.tsx:477 +msgid "Feeds" +msgstr "Syötteet" + +#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 +#~ msgid "Feeds are created by users and can give you entirely new experiences." +#~ msgstr "" + +#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 +#~ msgid "Feeds are created by users and organizations. They offer you varied experiences and suggest content you may like using algorithms." +#~ msgstr "" + +#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:57 +msgid "Feeds are created by users to curate content. Choose some feeds that you find interesting." +msgstr "Käyttäjät luovat syötteitä sisällön kuratointiin. Valitse joitakin syötteitä, jotka koet mielenkiintoisiksi." + +#: src/view/screens/SavedFeeds.tsx:156 +msgid "Feeds are custom algorithms that users build with a little coding expertise. <0/> for more information." +msgstr "Syötteet ovat käyttäjien rakentamia mukautettuja algoritmeja, jotka vaativat vain vähän koodaustaitoja. <0/> lisätietoa varten." + +#: src/screens/Onboarding/StepTopicalFeeds.tsx:70 +msgid "Feeds can be topical as well!" +msgstr "Syötteet voivat olla myös aihepiirikohtaisia!" + +#: src/screens/Onboarding/StepFinished.tsx:151 +msgid "Finalizing" +msgstr "Viimeistely" + +#: src/view/com/posts/CustomFeedEmptyState.tsx:47 +#: src/view/com/posts/FollowingEmptyState.tsx:57 +#: src/view/com/posts/FollowingEndOfFeed.tsx:58 +msgid "Find accounts to follow" +msgstr "Etsi seurattavia tilejä" + +#: src/view/screens/Search/Search.tsx:439 +msgid "Find users on Bluesky" +msgstr "Etsi käyttäjiä Bluesky-palvelusta" + +#: src/view/screens/Search/Search.tsx:437 +msgid "Find users with the search tool on the right" +msgstr "Etsi käyttäjiä oikealla olevan hakutyökalun avulla" + +#: src/view/com/auth/onboarding/RecommendedFollowsItem.tsx:150 +msgid "Finding similar accounts..." +msgstr "Etsitään samankaltaisia tilejä..." + +#: src/view/screens/PreferencesHomeFeed.tsx:111 +msgid "Fine-tune the content you see on your home screen." +msgstr "Hienosäädä näkemääsi sisältöä pääsivulla." + +#: src/view/screens/PreferencesThreads.tsx:60 +msgid "Fine-tune the discussion threads." +msgstr "Hienosäädä keskusteluketjuja." + +#: src/screens/Onboarding/index.tsx:38 +msgid "Fitness" +msgstr "Kuntoilu" + +#: src/screens/Onboarding/StepFinished.tsx:131 +msgid "Flexible" +msgstr "Joustava" + +#: src/view/com/modals/EditImage.tsx:115 +msgid "Flip horizontal" +msgstr "Käännä vaakasuunnassa" + +#: src/view/com/modals/EditImage.tsx:120 +#: src/view/com/modals/EditImage.tsx:287 +msgid "Flip vertically" +msgstr "Käännä pystysuunnassa" + +#: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:181 +#: src/view/com/post-thread/PostThreadFollowBtn.tsx:136 +#: src/view/com/profile/ProfileHeader.tsx:512 +msgid "Follow" +msgstr "Seuraa" + +#: src/view/com/profile/FollowButton.tsx:64 +msgctxt "action" +msgid "Follow" +msgstr "Seuraa" + +#: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:58 +#: src/view/com/post-thread/PostThreadFollowBtn.tsx:122 +#: src/view/com/profile/ProfileHeader.tsx:503 +msgid "Follow {0}" +msgstr "Seuraa {0}" + +#: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:179 +msgid "Follow All" +msgstr "Seuraa kaikkia" + +#: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:174 +msgid "Follow selected accounts and continue to the next step" +msgstr "Seuraa valittuja tilejä ja siirry seuraavaan vaiheeseen" + +#: src/view/com/auth/onboarding/RecommendedFollows.tsx:64 +msgid "Follow some users to get started. We can recommend you more users based on who you find interesting." +msgstr "Seuraa joitakin käyttäjiä aloittaaksesi. Suosittelemme sinulle lisää käyttäjiä sen perusteella, ketä pidät mielenkiintoisena." + +#: src/view/com/profile/ProfileCard.tsx:194 +msgid "Followed by {0}" +msgstr "Seuraajina {0}" + +#: src/view/com/modals/Threadgate.tsx:98 +msgid "Followed users" +msgstr "Seuratut käyttäjät" + +#: src/view/screens/PreferencesHomeFeed.tsx:154 +msgid "Followed users only" +msgstr "Vain seuratut käyttäjät" + +#: src/view/com/notifications/FeedItem.tsx:166 +msgid "followed you" +msgstr "seurasi sinua" + +#: src/view/screens/ProfileFollowers.tsx:25 +msgid "Followers" +msgstr "Seuraajat" + +#: src/view/com/post-thread/PostThreadFollowBtn.tsx:136 +#: src/view/com/profile/ProfileHeader.tsx:494 +#: src/view/screens/ProfileFollows.tsx:25 +msgid "Following" +msgstr "Seuraa" + +#: src/view/com/profile/ProfileHeader.tsx:148 +msgid "Following {0}" +msgstr "Seuraa {0}" + +#: src/view/com/profile/ProfileHeader.tsx:545 +msgid "Follows you" +msgstr "Seuraa sinua" + +#: src/view/com/profile/ProfileCard.tsx:141 +msgid "Follows You" +msgstr "Seuraa sinua" + +#: src/screens/Onboarding/index.tsx:43 +msgid "Food" +msgstr "Ruoka" + +#: src/view/com/modals/DeleteAccount.tsx:111 +msgid "For security reasons, we'll need to send a confirmation code to your email address." +msgstr "Turvallisuussyistä meidän on lähetettävä vahvistuskoodi sähköpostiosoitteeseesi." + +#: src/view/com/modals/AddAppPasswords.tsx:209 +msgid "For security reasons, you won't be able to view this again. If you lose this password, you'll need to generate a new one." +msgstr "Turvallisuussyistä et näe tätä uudelleen. Jos unohdat tämän salasanan, sinun on luotava uusi." + +#: src/view/com/auth/login/LoginForm.tsx:241 +msgid "Forgot" +msgstr "Unohtui" + +#: src/view/com/auth/login/LoginForm.tsx:238 +msgid "Forgot password" +msgstr "Unohtunut salasana" + +#: src/view/com/auth/login/Login.tsx:127 +#: src/view/com/auth/login/Login.tsx:143 +msgid "Forgot Password" +msgstr "Unohtunut salasana" + +#: src/view/com/posts/FeedItem.tsx:186 +msgctxt "from-feed" +msgid "From <0/>" +msgstr "Lähde: <0/>" + +#: src/view/com/composer/photos/SelectPhotoBtn.tsx:43 +msgid "Gallery" +msgstr "Galleria" + +#: src/view/com/modals/VerifyEmail.tsx:189 +#: src/view/com/modals/VerifyEmail.tsx:191 +msgid "Get Started" +msgstr "Aloita tästä" + +#: src/view/com/auth/LoggedOut.tsx:81 +#: src/view/com/auth/LoggedOut.tsx:82 +#: src/view/com/util/moderation/ScreenHider.tsx:123 +#: src/view/shell/desktop/LeftNav.tsx:104 +msgid "Go back" +msgstr "Palaa takaisin" + +#: src/view/screens/ProfileFeed.tsx:105 +#: src/view/screens/ProfileFeed.tsx:110 +#: src/view/screens/ProfileList.tsx:897 +#: src/view/screens/ProfileList.tsx:902 +msgid "Go Back" +msgstr "Palaa takaisin" + +#: src/screens/Onboarding/Layout.tsx:104 +#: src/screens/Onboarding/Layout.tsx:193 +msgid "Go back to previous step" +msgstr "Palaa edelliseen vaiheeseen" + +#: src/view/screens/Search/Search.tsx:724 +#: src/view/shell/desktop/Search.tsx:262 +msgid "Go to @{queryMaybeHandle}" +msgstr "Siirry @{queryMaybeHandle}" + +#: src/view/com/auth/login/ForgotPasswordForm.tsx:189 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:218 +#: src/view/com/auth/login/LoginForm.tsx:288 +#: src/view/com/auth/login/SetNewPasswordForm.tsx:195 +#: src/view/com/modals/ChangePassword.tsx:165 +msgid "Go to next" +msgstr "Siirry seuraavaan" + +#: src/view/com/modals/ChangeHandle.tsx:265 +msgid "Handle" +msgstr "Käyttäjätunnus" + +#: src/view/com/auth/create/CreateAccount.tsx:204 +msgid "Having trouble?" +msgstr "Ongelmia?" + +#: src/view/shell/desktop/RightNav.tsx:90 +#: src/view/shell/Drawer.tsx:321 +msgid "Help" +msgstr "Ohje" + +#: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:132 +msgid "Here are some accounts for you to follow" +msgstr "Tässä on joitakin tilejä seurattavaksi" + +#: src/screens/Onboarding/StepTopicalFeeds.tsx:79 +msgid "Here are some popular topical feeds. You can choose to follow as many as you like." +msgstr "Tässä on joitakin suosittuja aihepiirikohtaisia syötteitä. Voit valita seurattavaksi niin monta kuin haluat." + +#: src/screens/Onboarding/StepTopicalFeeds.tsx:74 +msgid "Here are some topical feeds based on your interests: {interestsText}. You can choose to follow as many as you like." +msgstr "Tässä on joitakin aihepiirikohtaisia syötteitä kiinnostuksiesi perusteella: {interestsText}. Voit valita seurata niin montaa kuin haluat." + +#: src/view/com/modals/AddAppPasswords.tsx:153 +msgid "Here is your app password." +msgstr "Tässä on sovelluksesi salasana." + +#: src/screens/Onboarding/StepModeration/ModerationOption.tsx:41 +#: src/view/com/modals/ContentFilteringSettings.tsx:251 +#: src/view/com/util/moderation/ContentHider.tsx:105 +#: src/view/com/util/moderation/PostHider.tsx:108 +msgid "Hide" +msgstr "Piilota" + +#: src/view/com/modals/ContentFilteringSettings.tsx:224 +#: src/view/com/notifications/FeedItem.tsx:325 +msgctxt "action" +msgid "Hide" +msgstr "Piilota" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:187 +msgid "Hide post" +msgstr "Piilota viesti" + +#: src/view/com/util/moderation/ContentHider.tsx:67 +#: src/view/com/util/moderation/PostHider.tsx:61 +msgid "Hide the content" +msgstr "Piilota sisältö" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:191 +msgid "Hide this post?" +msgstr "Piilota tämä viesti?" + +#: src/view/com/notifications/FeedItem.tsx:315 +msgid "Hide user list" +msgstr "Piilota käyttäjäluettelo" + +#: src/view/com/profile/ProfileHeader.tsx:486 +msgid "Hides posts from {0} in your feed" +msgstr "Piilottaa viestit käyttäjältä {0} syötteessäsi" + +#: src/view/com/posts/FeedErrorMessage.tsx:111 +msgid "Hmm, some kind of issue occurred when contacting the feed server. Please let the feed owner know about this issue." +msgstr "Hmm, jokin ongelma ilmeni ottaessa yhteyttä syötteen palvelimeen. Ilmoita asiasta syötteen omistajalle." + +#: src/view/com/posts/FeedErrorMessage.tsx:99 +msgid "Hmm, the feed server appears to be misconfigured. Please let the feed owner know about this issue." +msgstr "Hmm, syötteen palvelin vaikuttaa olevan väärin konfiguroitu. Ilmoita asiasta syötteen omistajalle." + +#: src/view/com/posts/FeedErrorMessage.tsx:105 +msgid "Hmm, the feed server appears to be offline. Please let the feed owner know about this issue." +msgstr "Hmm, syötteen palvelin vaikuttaa olevan poissa käytöstä. Ilmoita asiasta syötteen omistajalle." + +#: src/view/com/posts/FeedErrorMessage.tsx:102 +msgid "Hmm, the feed server gave a bad response. Please let the feed owner know about this issue." +msgstr "Hmm, syötteen palvelin antoi virheellisen vastauksen. Ilmoita asiasta syötteen omistajalle." + +#: src/view/com/posts/FeedErrorMessage.tsx:96 +msgid "Hmm, we're having trouble finding this feed. It may have been deleted." +msgstr "Hmm, meillä on vaikeuksia löytää tätä syötettä. Se saattaa olla poistettu." + +#: src/Navigation.tsx:432 +#: src/view/shell/bottom-bar/BottomBar.tsx:137 +#: src/view/shell/desktop/LeftNav.tsx:306 +#: src/view/shell/Drawer.tsx:398 +#: src/view/shell/Drawer.tsx:399 +msgid "Home" +msgstr "Koti" + +#: src/Navigation.tsx:247 +#: src/view/com/pager/FeedsTabBarMobile.tsx:123 +#: src/view/screens/PreferencesHomeFeed.tsx:104 +#: src/view/screens/Settings/index.tsx:543 +msgid "Home Feed Preferences" +msgstr "Aloitussivun Syötteiden Asetukset" + +#: src/view/com/auth/create/Step1.tsx:82 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:120 +msgid "Hosting provider" +msgstr "Hostingyritys" + +#: src/view/com/modals/InAppBrowserConsent.tsx:44 +msgid "How should we open this link?" +msgstr "Kuinka haluat avata tämän linkin?" + +#: src/view/com/modals/VerifyEmail.tsx:214 +msgid "I have a code" +msgstr "Minulla on koodi" + +#: src/view/com/modals/VerifyEmail.tsx:216 +msgid "I have a confirmation code" +msgstr "Minulla on vahvistuskoodi" + +#: src/view/com/modals/ChangeHandle.tsx:283 +msgid "I have my own domain" +msgstr "Minulla on oma verkkotunnus" + +#: src/view/com/lightbox/Lightbox.web.tsx:165 +msgid "If alt text is long, toggles alt text expanded state" +msgstr "Jos ALT-teksti on pitkä, vaihtaa ALT-tekstin laajennetun tilan" + +#: src/view/com/modals/SelfLabel.tsx:127 +msgid "If none are selected, suitable for all ages." +msgstr "Jos mitään ei ole valittu, sopii kaikenikäisille." + +#: src/view/com/modals/ChangePassword.tsx:146 +msgid "If you want to change your password, we will send you a code to verify that this is your account." +msgstr "Jos haluat vaihtaa salasanasi, lähetämme sinulle koodin varmistaaksemme, että tämä on tilisi." + +#: src/view/com/util/images/Gallery.tsx:38 +msgid "Image" +msgstr "Kuva" + +#: src/view/com/modals/AltImage.tsx:120 +msgid "Image alt text" +msgstr "Kuvan ALT-teksti" + +#: src/view/com/util/UserAvatar.tsx:311 +#: src/view/com/util/UserBanner.tsx:118 +msgid "Image options" +msgstr "Kuva-asetukset" + +#: src/view/com/auth/login/SetNewPasswordForm.tsx:138 +msgid "Input code sent to your email for password reset" +msgstr "Syötä sähköpostiisi lähetetty koodi salasanan nollaamista varten" + +#: src/view/com/modals/DeleteAccount.tsx:184 +msgid "Input confirmation code for account deletion" +msgstr "Syötä vahvistuskoodi tilin poistoa varten" + +#: src/view/com/auth/create/Step1.tsx:200 +msgid "Input email for Bluesky account" +msgstr "Syötä sähköposti Bluesky-tiliä varten" + +#: src/view/com/auth/create/Step1.tsx:158 +msgid "Input invite code to proceed" +msgstr "Syötä kutsukoodi jatkaaksesi" + +#: src/view/com/modals/AddAppPasswords.tsx:180 +msgid "Input name for app password" +msgstr "Syötä nimi sovellussalasanaa varten" + +#: src/view/com/auth/login/SetNewPasswordForm.tsx:162 +msgid "Input new password" +msgstr "Syötä uusi salasana" + +#: src/view/com/modals/DeleteAccount.tsx:203 +msgid "Input password for account deletion" +msgstr "Syötä salasana tilin poistoa varten" + +#: src/view/com/auth/create/Step2.tsx:196 +#~ msgid "Input phone number for SMS verification" +#~ msgstr "Syötä puhelinnumero SMS-varmennusta varten" + +#: src/view/com/auth/login/LoginForm.tsx:230 +msgid "Input the password tied to {identifier}" +msgstr "Syötä salasana, joka liittyy kohteeseen {identifier}" + +#: src/view/com/auth/login/LoginForm.tsx:197 +msgid "Input the username or email address you used at signup" +msgstr "Syötä käyttäjätunnus tai sähköpostiosoite, jonka käytit rekisteröityessäsi" + +#: src/view/com/auth/create/Step2.tsx:271 +#~ msgid "Input the verification code we have texted to you" +#~ msgstr "Syötä sinulle tekstattu varmennuskoodi" + +#: src/view/com/modals/Waitlist.tsx:90 +msgid "Input your email to get on the Bluesky waitlist" +msgstr "Syötä sähköpostiosoitteesi päästäksesi Bluesky-jonoon" + +#: src/view/com/auth/login/LoginForm.tsx:229 +msgid "Input your password" +msgstr "Syötä salasanasi" + +#: src/view/com/auth/create/Step2.tsx:45 +msgid "Input your user handle" +msgstr "Syötä käyttäjätunnuksesi" + +#: src/view/com/post-thread/PostThreadItem.tsx:223 +msgid "Invalid or unsupported post record" +msgstr "Virheellinen tai ei tuettu tietue" + +#: src/view/com/auth/login/LoginForm.tsx:113 +msgid "Invalid username or password" +msgstr "Virheellinen käyttäjätunnus tai salasana" + +#: src/view/screens/Settings.tsx:411 +#~ msgid "Invite" +#~ msgstr "" + +#: src/view/com/modals/InviteCodes.tsx:93 +msgid "Invite a Friend" +msgstr "Kutsu ystävä" + +#: src/view/com/auth/create/Step1.tsx:148 +#: src/view/com/auth/create/Step1.tsx:157 +msgid "Invite code" +msgstr "Kutsukoodi" + +#: src/view/com/auth/create/state.ts:158 +msgid "Invite code not accepted. Check that you input it correctly and try again." +msgstr "Kutsukoodia ei hyväksytty. Tarkista, että syötit sen oikein ja yritä uudelleen." + +#: src/view/com/modals/InviteCodes.tsx:170 +msgid "Invite codes: {0} available" +msgstr "Kutsukoodit: {0} saatavilla" + +#: src/view/shell/Drawer.tsx:645 +#~ msgid "Invite codes: {invitesAvailable} available" +#~ msgstr "" + +#: src/view/com/modals/InviteCodes.tsx:169 +msgid "Invite codes: 1 available" +msgstr "Kutsukoodit: 1 saatavilla" + +#: src/screens/Onboarding/StepFollowingFeed.tsx:64 +msgid "It shows posts from the people you follow as they happen." +msgstr "Se näyttää viestejä seuraamiltasi ihmisiltä reaaliajassa." + +#: src/view/com/auth/HomeLoggedOutCTA.tsx:99 +#: src/view/com/auth/SplashScreen.web.tsx:138 +msgid "Jobs" +msgstr "Työpaikat" + +#: src/view/com/modals/Waitlist.tsx:67 +msgid "Join the waitlist" +msgstr "Liity odotuslistalle" + +#: src/view/com/auth/create/Step1.tsx:174 +#: src/view/com/auth/create/Step1.tsx:178 +msgid "Join the waitlist." +msgstr "Liity odotuslistalle." + +#: src/view/com/modals/Waitlist.tsx:128 +msgid "Join Waitlist" +msgstr "Liity odotuslistalle" + +#: src/screens/Onboarding/index.tsx:24 +msgid "Journalism" +msgstr "Journalismi" + +#: src/view/com/composer/select-language/SelectLangBtn.tsx:104 +msgid "Language selection" +msgstr "Kielen valinta" + +#: src/view/screens/Settings/index.tsx:594 +msgid "Language settings" +msgstr "Kielen asetukset" + +#: src/Navigation.tsx:140 +#: src/view/screens/LanguageSettings.tsx:89 +msgid "Language Settings" +msgstr "Kielen asetukset" + +#: src/view/screens/Settings/index.tsx:603 +msgid "Languages" +msgstr "Kielet" + +#: src/view/com/auth/create/StepHeader.tsx:20 +msgid "Last step!" +msgstr "Viimeinen vaihe!" + +#: src/view/com/util/moderation/ContentHider.tsx:103 +msgid "Learn more" +msgstr "Lue lisää" + +#: src/view/com/util/moderation/PostAlerts.tsx:47 +#: src/view/com/util/moderation/ProfileHeaderAlerts.tsx:65 +#: src/view/com/util/moderation/ScreenHider.tsx:104 +msgid "Learn More" +msgstr "Lue lisää" + +#: src/view/com/util/moderation/ContentHider.tsx:85 +#: src/view/com/util/moderation/PostAlerts.tsx:40 +#: src/view/com/util/moderation/PostHider.tsx:78 +#: src/view/com/util/moderation/ProfileHeaderAlerts.tsx:49 +#: src/view/com/util/moderation/ScreenHider.tsx:101 +msgid "Learn more about this warning" +msgstr "Lue lisää tästä varoituksesta" + +#: src/view/screens/Moderation.tsx:243 +msgid "Learn more about what is public on Bluesky." +msgstr "Lue lisää siitä, mikä on julkista Blueskyssa." + +#: src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx:82 +msgid "Leave them all unchecked to see any language." +msgstr "Jätä kaikki valitsematta nähdäksesi minkä tahansa kielen." + +#: src/view/com/modals/LinkWarning.tsx:51 +msgid "Leaving Bluesky" +msgstr "Poistuminen Blueskysta" + +#: src/screens/Deactivated.tsx:128 +msgid "left to go." +msgstr "jäljellä." + +#: src/view/screens/Settings/index.tsx:278 +msgid "Legacy storage cleared, you need to restart the app now." +msgstr "Legacy tietovarasto tyhjennetty, sinun on käynnistettävä sovellus uudelleen nyt." + +#: src/view/com/auth/login/Login.tsx:128 +#: src/view/com/auth/login/Login.tsx:144 +msgid "Let's get your password reset!" +msgstr "Aloitetaan salasanasi nollaus!" + +#: src/screens/Onboarding/StepFinished.tsx:151 +msgid "Let's go!" +msgstr "Aloitetaan!" + +#: src/view/com/util/UserAvatar.tsx:248 +#: src/view/com/util/UserBanner.tsx:62 +msgid "Library" +msgstr "Kirjasto" + +#: src/view/screens/Settings/index.tsx:479 +msgid "Light" +msgstr "Vaalea" + +#: src/view/com/util/post-ctrls/PostCtrls.tsx:182 +#: src/view/com/util/post-ctrls/PostCtrls.tsx:216 +msgid "Like" +msgstr "Tykkää" + +#: src/view/screens/ProfileFeed.tsx:591 +msgid "Like this feed" +msgstr "Tykkää tästä syötteestä" + +#: src/Navigation.tsx:197 +msgid "Liked by" +msgstr "Tykänneet" + +#: src/view/screens/PostLikedBy.tsx:27 +#: src/view/screens/ProfileFeedLikedBy.tsx:27 +msgid "Liked By" +msgstr "Tykänneet" + +#: src/view/com/feeds/FeedSourceCard.tsx:277 +msgid "Liked by {0} {1}" +msgstr "Tykänneet {0} {1}" + +#: src/view/screens/ProfileFeed.tsx:606 +msgid "Liked by {likeCount} {0}" +msgstr "Tykkäyksiä {likeCount} {0}" + +#: src/view/com/notifications/FeedItem.tsx:170 +msgid "liked your custom feed" +msgstr "tykkäsi mukautetusta syötteestäsi" + +#: src/view/com/notifications/FeedItem.tsx:155 +msgid "liked your post" +msgstr "tykkäsi viestistäsi" + +#: src/view/screens/Profile.tsx:183 +msgid "Likes" +msgstr "Tykkäykset" + +#: src/view/com/post-thread/PostThreadItem.tsx:180 +msgid "Likes on this post" +msgstr "Tykkäykset tässä viestissä" + +#: src/Navigation.tsx:166 +msgid "List" +msgstr "Lista" + +#: src/view/com/modals/CreateOrEditList.tsx:261 +msgid "List Avatar" +msgstr "Listan kuvake" + +#: src/view/screens/ProfileList.tsx:323 +msgid "List blocked" +msgstr "Lista estetty" + +#: src/view/com/feeds/FeedSourceCard.tsx:231 +msgid "List by {0}" +msgstr "Listan on luonut {0}" + +#: src/view/screens/ProfileList.tsx:377 +msgid "List deleted" +msgstr "Lista poistettu" + +#: src/view/screens/ProfileList.tsx:282 +msgid "List muted" +msgstr "Lista hiljennetty" + +#: src/view/com/modals/CreateOrEditList.tsx:275 +msgid "List Name" +msgstr "Listan nimi" + +#: src/view/screens/ProfileList.tsx:342 +msgid "List unblocked" +msgstr "Listaa estosta poistetut" + +#: src/view/screens/ProfileList.tsx:301 +msgid "List unmuted" +msgstr "Listaa hiljennyksestä poistetut" + +#: src/Navigation.tsx:110 +#: src/view/screens/Profile.tsx:185 +#: src/view/shell/desktop/LeftNav.tsx:379 +#: src/view/shell/Drawer.tsx:492 +#: src/view/shell/Drawer.tsx:493 +msgid "Lists" +msgstr "Listat" + +#: src/view/com/post-thread/PostThread.tsx:333 +#: src/view/com/post-thread/PostThread.tsx:341 +msgid "Load more posts" +msgstr "Lataa lisää viestejä" + +#: src/view/screens/Notifications.tsx:159 +msgid "Load new notifications" +msgstr "Lataa uusia ilmoituksia" + +#: src/view/com/feeds/FeedPage.tsx:181 +#: src/view/screens/Profile.tsx:440 +#: src/view/screens/ProfileFeed.tsx:494 +#: src/view/screens/ProfileList.tsx:680 +msgid "Load new posts" +msgstr "Lataa uusia viestejä" + +#: src/view/com/composer/text-input/mobile/Autocomplete.tsx:95 +msgid "Loading..." +msgstr "Ladataan..." + +#: src/view/com/modals/ServerInput.tsx:50 +#~ msgid "Local dev server" +#~ msgstr "" + +#: src/Navigation.tsx:207 +msgid "Log" +msgstr "Loki" + +#: src/screens/Deactivated.tsx:149 +#: src/screens/Deactivated.tsx:152 +#: src/screens/Deactivated.tsx:178 +#: src/screens/Deactivated.tsx:181 +msgid "Log out" +msgstr "Kirjaudu ulos" + +#: src/view/screens/Moderation.tsx:136 +msgid "Logged-out visibility" +msgstr "Näkyvyys kirjautumattomana" + +#: src/view/com/auth/login/ChooseAccountForm.tsx:133 +msgid "Login to account that is not listed" +msgstr "Kirjaudu tiliin, joka ei ole luettelossa" + +#: src/view/com/modals/LinkWarning.tsx:65 +msgid "Make sure this is where you intend to go!" +msgstr "Varmista, että olet menossa oikeaan paikkaan!" + +#: src/view/screens/Profile.tsx:182 +msgid "Media" +msgstr "Media" + +#: src/view/com/threadgate/WhoCanReply.tsx:139 +msgid "mentioned users" +msgstr "mainitut käyttäjät" + +#: src/view/com/modals/Threadgate.tsx:93 +msgid "Mentioned users" +msgstr "Mainitut käyttäjät" + +#: src/view/com/util/ViewHeader.tsx:81 +#: src/view/screens/Search/Search.tsx:623 +msgid "Menu" +msgstr "Valikko" + +#: src/view/com/posts/FeedErrorMessage.tsx:197 +msgid "Message from server: {0}" +msgstr "Viesti palvelimelta: {0}" + +#: src/Navigation.tsx:115 +#: src/view/screens/Moderation.tsx:64 +#: src/view/screens/Settings/index.tsx:625 +#: src/view/shell/desktop/LeftNav.tsx:397 +#: src/view/shell/Drawer.tsx:511 +#: src/view/shell/Drawer.tsx:512 +msgid "Moderation" +msgstr "Moderointi" + +#: src/view/com/lists/ListCard.tsx:92 +#: src/view/com/modals/UserAddRemoveLists.tsx:206 +msgid "Moderation list by {0}" +msgstr "Moderointilista käyttäjältä {0}" + +#: src/view/screens/ProfileList.tsx:774 +msgid "Moderation list by <0/>" +msgstr "Moderointilista käyttäjältä <0/>" + +#: src/view/com/lists/ListCard.tsx:90 +#: src/view/com/modals/UserAddRemoveLists.tsx:204 +#: src/view/screens/ProfileList.tsx:772 +msgid "Moderation list by you" +msgstr "Sinun moderointilistasi" + +#: src/view/com/modals/CreateOrEditList.tsx:197 +msgid "Moderation list created" +msgstr "Moderointilista luotu" + +#: src/view/com/modals/CreateOrEditList.tsx:183 +msgid "Moderation list updated" +msgstr "Moderointilista päivitetty" + +#: src/view/screens/Moderation.tsx:95 +msgid "Moderation lists" +msgstr "Moderointilistat" + +#: src/Navigation.tsx:120 +#: src/view/screens/ModerationModlists.tsx:58 +msgid "Moderation Lists" +msgstr "Moderointilistat" + +#: src/view/screens/Settings/index.tsx:619 +msgid "Moderation settings" +msgstr "Moderointiasetukset" + +#: src/view/com/modals/ModerationDetails.tsx:35 +msgid "Moderator has chosen to set a general warning on the content." +msgstr "Ylläpitäjä on asettanut yleisen varoituksen sisällölle." + +#: src/view/shell/desktop/Feeds.tsx:63 +msgid "More feeds" +msgstr "Lisää syötteitä" + +#: src/view/com/profile/ProfileHeader.tsx:522 +#: src/view/screens/ProfileFeed.tsx:362 +#: src/view/screens/ProfileList.tsx:616 +msgid "More options" +msgstr "Lisää asetuksia" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:270 +msgid "More post options" +msgstr "Lisää viestiasetuksia" + +#: src/view/screens/PreferencesThreads.tsx:82 +msgid "Most-liked replies first" +msgstr "Eniten tykätyt vastaukset ensin" + +#: src/view/com/profile/ProfileHeader.tsx:326 +msgid "Mute Account" +msgstr "Hiljennä käyttäjä" + +#: src/view/screens/ProfileList.tsx:543 +msgid "Mute accounts" +msgstr "Hiljennä käyttäjät" + +#: src/view/screens/ProfileList.tsx:490 +msgid "Mute list" +msgstr "Hiljennä lista" + +#: src/view/screens/ProfileList.tsx:274 +msgid "Mute these accounts?" +msgstr "Hiljennä nämä käyttäjät?" + +#: src/view/screens/ProfileList.tsx:278 +msgid "Mute this List" +msgstr "Hiljennä tämä lista" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:171 +msgid "Mute thread" +msgstr "Hiljennäkeskustelu" + +#: src/view/com/lists/ListCard.tsx:101 +msgid "Muted" +msgstr "Hiljennetty" + +#: src/view/screens/Moderation.tsx:109 +msgid "Muted accounts" +msgstr "Hiljennetyt käyttäjät" + +#: src/Navigation.tsx:125 +#: src/view/screens/ModerationMutedAccounts.tsx:107 +msgid "Muted Accounts" +msgstr "Hiljennetyt käyttäjätilit" + +#: src/view/screens/ModerationMutedAccounts.tsx:115 +msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." +msgstr "Hiljennettyjen käyttäjien viestit poistetaan syötteestäsi ja ilmoituksistasi. Hiljennykset ovat täysin yksityisiä." + +#: src/view/screens/ProfileList.tsx:276 +msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." +msgstr "Hiljennys on yksityinen. Hiljennetyt käyttäjät voivat edelleen vuorovaikuttaa kanssasi, mutta et näe heidän viestejään tai saa ilmoituksia heiltä." + +#: src/view/com/modals/BirthDateSettings.tsx:56 +msgid "My Birthday" +msgstr "Syntymäpäiväni" + +#: src/view/screens/Feeds.tsx:663 +msgid "My Feeds" +msgstr "Omat syötteet" + +#: src/view/shell/desktop/LeftNav.tsx:65 +msgid "My Profile" +msgstr "Profiilini" + +#: src/view/screens/Settings/index.tsx:582 +msgid "My Saved Feeds" +msgstr "Omat tallennetut syötteet" + +#: src/view/com/auth/server-input/index.tsx:118 +msgid "my-server.com" +msgstr "oma-palvelimeni.com" + +#: src/view/com/modals/AddAppPasswords.tsx:179 +#: src/view/com/modals/CreateOrEditList.tsx:290 +msgid "Name" +msgstr "Nimi" + +#: src/view/com/modals/CreateOrEditList.tsx:145 +msgid "Name is required" +msgstr "Nimi vaaditaan" + +#: src/screens/Onboarding/index.tsx:25 +msgid "Nature" +msgstr "Luonto" + +#: src/view/com/auth/login/ForgotPasswordForm.tsx:190 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:219 +#: src/view/com/auth/login/LoginForm.tsx:289 +#: src/view/com/auth/login/SetNewPasswordForm.tsx:196 +#: src/view/com/modals/ChangePassword.tsx:166 +msgid "Navigates to the next screen" +msgstr "Siirtyy seuraavalle näytölle" + +#: src/view/shell/Drawer.tsx:71 +msgid "Navigates to your profile" +msgstr "Siirtyy profiiliisi" + +#: src/view/com/modals/EmbedConsent.tsx:107 +#: src/view/com/modals/EmbedConsent.tsx:123 +msgid "Never load embeds from {0}" +msgstr "Älä koskaan lataa upotuksia taholta {0}" + +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:72 +#: src/view/com/auth/onboarding/WelcomeMobile.tsx:72 +msgid "Never lose access to your followers and data." +msgstr "Älä koskaan menetä pääsyä seuraajiisi ja tietoihisi." + +#: src/screens/Onboarding/StepFinished.tsx:119 +msgid "Never lose access to your followers or data." +msgstr "Älä koskaan menetä pääsyä seuraajiisi tai tietoihisi." + +#: src/view/screens/Lists.tsx:76 +msgctxt "action" +msgid "New" +msgstr "Uusi" + +#: src/view/screens/ModerationModlists.tsx:78 +msgid "New" +msgstr "Uusi" + +#: src/view/com/modals/CreateOrEditList.tsx:252 +msgid "New Moderation List" +msgstr "Uusi moderointilista" + +#: src/view/com/auth/login/SetNewPasswordForm.tsx:150 +msgid "New password" +msgstr "Uusi salasana" + +#: src/view/com/modals/ChangePassword.tsx:215 +msgid "New Password" +msgstr "Uusi salasana" + +#: src/view/com/feeds/FeedPage.tsx:192 +msgctxt "action" +msgid "New post" +msgstr "Uusi viesti" + +#: src/view/screens/Feeds.tsx:555 +#: src/view/screens/Notifications.tsx:168 +#: src/view/screens/Profile.tsx:382 +#: src/view/screens/ProfileFeed.tsx:432 +#: src/view/screens/ProfileList.tsx:195 +#: src/view/screens/ProfileList.tsx:223 +#: src/view/shell/desktop/LeftNav.tsx:248 +msgid "New post" +msgstr "Uusi viesti" + +#: src/view/shell/desktop/LeftNav.tsx:258 +msgctxt "action" +msgid "New Post" +msgstr "Uusi viesti" + +#: src/view/com/modals/CreateOrEditList.tsx:247 +msgid "New User List" +msgstr "Uusi käyttäjälista" + +#: src/view/screens/PreferencesThreads.tsx:79 +msgid "Newest replies first" +msgstr "Uusimmat vastaukset ensin" + +#: src/screens/Onboarding/index.tsx:23 +msgid "News" +msgstr "Uutiset" + +#: src/view/com/auth/create/CreateAccount.tsx:168 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:182 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:192 +#: src/view/com/auth/login/LoginForm.tsx:291 +#: src/view/com/auth/login/SetNewPasswordForm.tsx:187 +#: src/view/com/auth/login/SetNewPasswordForm.tsx:198 +#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:79 +#: src/view/com/modals/ChangePassword.tsx:251 +#: src/view/com/modals/ChangePassword.tsx:253 +msgid "Next" +msgstr "Seuraava" + +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 +msgctxt "action" +msgid "Next" +msgstr "Seuraava" + +#: src/view/com/lightbox/Lightbox.web.tsx:149 +msgid "Next image" +msgstr "Seuraava kuva" + +#: src/view/screens/PreferencesHomeFeed.tsx:129 +#: src/view/screens/PreferencesHomeFeed.tsx:200 +#: src/view/screens/PreferencesHomeFeed.tsx:235 +#: src/view/screens/PreferencesHomeFeed.tsx:272 +#: src/view/screens/PreferencesThreads.tsx:106 +#: src/view/screens/PreferencesThreads.tsx:129 +msgid "No" +msgstr "Ei" + +#: src/view/screens/ProfileFeed.tsx:584 +#: src/view/screens/ProfileList.tsx:754 +msgid "No description" +msgstr "Ei kuvausta" + +#: src/view/com/profile/ProfileHeader.tsx:169 +msgid "No longer following {0}" +msgstr "Et enää seuraa käyttäjää {0}" + +#: src/view/com/notifications/Feed.tsx:109 +msgid "No notifications yet!" +msgstr "Ei vielä ilmoituksia!" + +#: src/view/com/composer/text-input/mobile/Autocomplete.tsx:97 +#: src/view/com/composer/text-input/web/Autocomplete.tsx:191 +msgid "No result" +msgstr "Ei tuloksia" + +#: src/view/screens/Feeds.tsx:495 +msgid "No results found for \"{query}\"" +msgstr "Ei tuloksia haulle \"{query}\"" + +#: src/view/com/modals/ListAddRemoveUsers.tsx:127 +#: src/view/screens/Search/Search.tsx:280 +#: src/view/screens/Search/Search.tsx:308 +msgid "No results found for {query}" +msgstr "Ei tuloksia haulle {query}" + +#: src/view/com/modals/EmbedConsent.tsx:129 +msgid "No thanks" +msgstr "Ei kiitos" + +#: src/view/com/modals/Threadgate.tsx:82 +msgid "Nobody" +msgstr "Ei ketään" + +#: src/view/com/modals/SelfLabel.tsx:135 +msgid "Not Applicable." +msgstr "Ei sovellettavissa." + +#: src/Navigation.tsx:105 +#: src/view/screens/Profile.tsx:106 +msgid "Not Found" +msgstr "Ei löytynyt" + +#: src/view/com/modals/VerifyEmail.tsx:246 +#: src/view/com/modals/VerifyEmail.tsx:252 +msgid "Not right now" +msgstr "Ei juuri nyt" + +#: src/view/screens/Moderation.tsx:233 +msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." +msgstr "Huomio: Bluesky on avoin ja julkinen verkosto. Tämä asetus rajoittaa vain sisältösi näkyvyyttä Bluesky-sovelluksessa ja -sivustolla, eikä muut sovellukset ehkä kunnioita tässä asetuksissaan. Sisältösi voi silti näkyä uloskirjautuneille käyttäjille muissa sovelluksissa ja verkkosivustoilla." + +#: src/Navigation.tsx:447 +#: src/view/screens/Notifications.tsx:124 +#: src/view/screens/Notifications.tsx:148 +#: src/view/shell/bottom-bar/BottomBar.tsx:205 +#: src/view/shell/desktop/LeftNav.tsx:361 +#: src/view/shell/Drawer.tsx:435 +#: src/view/shell/Drawer.tsx:436 +msgid "Notifications" +msgstr "Ilmoitukset" + +#: src/view/com/modals/SelfLabel.tsx:103 +msgid "Nudity" +msgstr "Alastomuus" + +#: src/view/com/util/ErrorBoundary.tsx:35 +msgid "Oh no!" +msgstr "Voi ei!" + +#: src/screens/Onboarding/StepInterests/index.tsx:128 +msgid "Oh no! Something went wrong." +msgstr "Voi ei! Jokin meni pieleen." + +#: src/view/com/auth/login/PasswordUpdatedForm.tsx:41 +msgid "Okay" +msgstr "Selvä" + +#: src/view/screens/PreferencesThreads.tsx:78 +msgid "Oldest replies first" +msgstr "Vanhimmat vastaukset ensin" + +#: src/view/screens/Settings/index.tsx:234 +msgid "Onboarding reset" +msgstr "Käyttöönoton nollaus" + +#: src/view/com/composer/Composer.tsx:375 +msgid "One or more images is missing alt text." +msgstr "Yksi tai useampi kuva on ilman vaihtoehtoista Alt-tekstiä." + +#: src/view/com/threadgate/WhoCanReply.tsx:100 +msgid "Only {0} can reply." +msgstr "Vain {0} voi vastata." + +#: src/view/screens/AppPasswords.tsx:65 +#: src/view/screens/Profile.tsx:106 +msgid "Oops!" +msgstr "Hups!" + +#: src/screens/Onboarding/StepFinished.tsx:115 +msgid "Open" +msgstr "Avaa" + +#: src/view/com/composer/Composer.tsx:470 +#: src/view/com/composer/Composer.tsx:471 +msgid "Open emoji picker" +msgstr "Avaa emoji-valitsin" + +#: src/view/screens/Settings/index.tsx:712 +msgid "Open links with in-app browser" +msgstr "Avaa linkit sovelluksen sisäisellä selaimella" + +#: src/view/com/pager/FeedsTabBarMobile.tsx:87 +msgid "Open navigation" +msgstr "Avaa navigointi" + +#: src/view/screens/Settings/index.tsx:804 +msgid "Open storybook page" +msgstr "Avaa storybook-sivu" + +#: src/view/com/util/forms/DropdownButton.tsx:154 +msgid "Opens {numItems} options" +msgstr "Avaa {numItems} asetusta" + +#: src/view/screens/Log.tsx:54 +msgid "Opens additional details for a debug entry" +msgstr "Avaa debug lisätiedot" + +#: src/view/com/notifications/FeedItem.tsx:348 +msgid "Opens an expanded list of users in this notification" +msgstr "Avaa laajennetun listan tämän ilmoituksen käyttäjistä" + +#: src/view/com/composer/photos/OpenCameraBtn.tsx:61 +msgid "Opens camera on device" +msgstr "Avaa laitteen kameran" + +#: src/view/com/composer/Prompt.tsx:25 +msgid "Opens composer" +msgstr "Avaa editorin" + +#: src/view/screens/Settings/index.tsx:595 +msgid "Opens configurable language settings" +msgstr "Avaa mukautettavat kielen asetukset" + +#: src/view/com/composer/photos/SelectPhotoBtn.tsx:44 +msgid "Opens device photo gallery" +msgstr "Avaa laitteen valokuvat" + +#: src/view/com/profile/ProfileHeader.tsx:419 +msgid "Opens editor for profile display name, avatar, background image, and description" +msgstr "Avaa editorin profiilin näyttönimeä, avataria, taustakuvaa ja kuvausta varten" + +#: src/view/screens/Settings/index.tsx:649 +msgid "Opens external embeds settings" +msgstr "Avaa ulkoiset upotusasetukset" + +#: src/view/com/profile/ProfileHeader.tsx:574 +msgid "Opens followers list" +msgstr "Avaa seuraajalistan" + +#: src/view/com/profile/ProfileHeader.tsx:593 +msgid "Opens following list" +msgstr "Avaa seurattavien listan" + +#: src/view/screens/Settings.tsx:412 +#~ msgid "Opens invite code list" +#~ msgstr "" + +#: src/view/com/modals/InviteCodes.tsx:172 +msgid "Opens list of invite codes" +msgstr "Avaa kutsukoodien luettelon" + +#: src/view/screens/Settings/index.tsx:774 +msgid "Opens modal for account deletion confirmation. Requires email code." +msgstr "Avaa tilin poistovahvistuksen. Vaatii sähköpostikoodin." + +#: src/view/com/modals/ChangeHandle.tsx:281 +msgid "Opens modal for using custom domain" +msgstr "Avaa asetukset oman verkkotunnuksen käyttöönottoon" + +#: src/view/screens/Settings/index.tsx:620 +msgid "Opens moderation settings" +msgstr "Avaa moderointiasetukset" + +#: src/view/com/auth/login/LoginForm.tsx:239 +msgid "Opens password reset form" +msgstr "Avaa salasanan palautuslomakkeen" + +#: src/view/screens/Feeds.tsx:356 +msgid "Opens screen to edit Saved Feeds" +msgstr "Avaa näkymän tallennettujen syötteiden muokkaamiseen" + +#: src/view/screens/Settings/index.tsx:576 +msgid "Opens screen with all saved feeds" +msgstr "Avaa näkymän kaikkiin tallennettuihin syötteisiin" + +#: src/view/screens/Settings/index.tsx:676 +msgid "Opens the app password settings page" +msgstr "Avaa sovellussalasanojen asetukset" + +#: src/view/screens/Settings/index.tsx:535 +msgid "Opens the home feed preferences" +msgstr "Avaa aloitussivun asetukset" + +#: src/view/screens/Settings/index.tsx:805 +msgid "Opens the storybook page" +msgstr "Avaa storybook-sivun" + +#: src/view/screens/Settings/index.tsx:793 +msgid "Opens the system log page" +msgstr "Avaa järjestelmän lokisivun" + +#: src/view/screens/Settings/index.tsx:556 +msgid "Opens the threads preferences" +msgstr "Avaa keskusteluasetukset" + +#: src/view/com/util/forms/DropdownButton.tsx:280 +msgid "Option {0} of {numItems}" +msgstr "Asetus {0}/{numItems}" + +#: src/view/com/modals/Threadgate.tsx:89 +msgid "Or combine these options:" +msgstr "Tai yhdistä nämä asetukset:" + +#: src/view/com/auth/login/ChooseAccountForm.tsx:138 +msgid "Other account" +msgstr "Toinen tili" + +#: src/view/com/modals/ServerInput.tsx:88 +#~ msgid "Other service" +#~ msgstr "" + +#: src/view/com/composer/select-language/SelectLangBtn.tsx:91 +msgid "Other..." +msgstr "Muu..." + +#: src/view/screens/NotFound.tsx:45 +msgid "Page not found" +msgstr "Sivua ei löytynyt" + +#: src/view/screens/NotFound.tsx:42 +msgid "Page Not Found" +msgstr "Sivua ei löytynyt" + +#: src/view/com/auth/create/Step1.tsx:214 +#: src/view/com/auth/create/Step1.tsx:224 +#: src/view/com/auth/login/LoginForm.tsx:226 +#: src/view/com/auth/login/SetNewPasswordForm.tsx:161 +#: src/view/com/modals/DeleteAccount.tsx:202 +msgid "Password" +msgstr "Salasana" + +#: src/view/com/auth/login/Login.tsx:157 +msgid "Password updated" +msgstr "Salasana päivitetty" + +#: src/view/com/auth/login/PasswordUpdatedForm.tsx:28 +msgid "Password updated!" +msgstr "Salasana päivitetty!" + +#: src/Navigation.tsx:160 +msgid "People followed by @{0}" +msgstr "Henkilöt, joita @{0} seuraa" + +#: src/Navigation.tsx:153 +msgid "People following @{0}" +msgstr "Henkilöt, jotka seuraavat käyttäjää @{0}" + +#: src/view/com/lightbox/Lightbox.tsx:66 +msgid "Permission to access camera roll is required." +msgstr "Käyttöoikeus valokuviin tarvitaan." + +#: src/view/com/lightbox/Lightbox.tsx:72 +msgid "Permission to access camera roll was denied. Please enable it in your system settings." +msgstr "Lupa valokuviin evättiin. Anna lupa järjestelmäasetuksissa." + +#: src/screens/Onboarding/index.tsx:31 +msgid "Pets" +msgstr "Lemmikit" + +#: src/view/com/auth/create/Step2.tsx:183 +#~ msgid "Phone number" +#~ msgstr "Puhelinnumero" + +#: src/view/com/modals/SelfLabel.tsx:121 +msgid "Pictures meant for adults." +msgstr "Aikuisille tarkoitetut kuvat." + +#: src/view/screens/ProfileFeed.tsx:353 +#: src/view/screens/ProfileList.tsx:580 +msgid "Pin to home" +msgstr "Kiinnitä etusivulle" + +#: src/view/screens/SavedFeeds.tsx:88 +msgid "Pinned Feeds" +msgstr "Kiinnitetyt syötteet" + +#: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:111 +msgid "Play {0}" +msgstr "Toista {0}" + +#: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:54 +#: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:55 +msgid "Play Video" +msgstr "Toista video" + +#: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:110 +msgid "Plays the GIF" +msgstr "Toistaa GIFin" + +#: src/view/com/auth/create/state.ts:124 +msgid "Please choose your handle." +msgstr "Valitse käyttäjänimesi." + +#: src/view/com/auth/create/state.ts:117 +msgid "Please choose your password." +msgstr "Valitse salasanasi." + +#: src/view/com/auth/create/state.ts:131 +msgid "Please complete the verification captcha." +msgstr "Täydennä varmennus-captcha, ole hyvä." + +#: src/view/com/modals/ChangeEmail.tsx:67 +msgid "Please confirm your email before changing it. This is a temporary requirement while email-updating tools are added, and it will soon be removed." +msgstr "Vahvista sähköpostiosoitteesi ennen sen vaihtamista. Tämä on väliaikainen vaatimus, kunnes sähköpostin muokkaamisen liittyvät asetukset ovat lisätty ja se poistetaan piakkoin." + +#: src/view/com/modals/AddAppPasswords.tsx:90 +msgid "Please enter a name for your app password. All spaces is not allowed." +msgstr "Anna nimi sovellussalasanalle. Kaikki välilyönnit eivät ole sallittuja." + +#: src/view/com/auth/create/Step2.tsx:206 +#~ msgid "Please enter a phone number that can receive SMS text messages." +#~ msgstr "Anna puhelinnumero, joka voi vastaanottaa tekstiviestejä." + +#: src/view/com/modals/AddAppPasswords.tsx:145 +msgid "Please enter a unique name for this App Password or use our randomly generated one." +msgstr "Anna uniikki nimi tälle sovellussalasanalle tai käytä satunnaisesti luotua." + +#: src/view/com/auth/create/state.ts:170 +#~ msgid "Please enter the code you received by SMS." +#~ msgstr "Anna tekstiviestitse saamasi koodi." + +#: src/view/com/auth/create/Step2.tsx:282 +#~ msgid "Please enter the verification code sent to {phoneNumberFormatted}." +#~ msgstr "Anna numeroon {phoneNumberFormatted} vastaanottamasi vahvistuskoodi." + +#: src/view/com/auth/create/state.ts:103 +msgid "Please enter your email." +msgstr "Anna sähköpostiosoitteesi." + +#: src/view/com/modals/DeleteAccount.tsx:191 +msgid "Please enter your password as well:" +msgstr "Anna myös salasanasi:" + +#: src/view/com/modals/AppealLabel.tsx:72 +#: src/view/com/modals/AppealLabel.tsx:75 +msgid "Please tell us why you think this content warning was incorrectly applied!" +msgstr "Kerro meille, miksi luulet, että tämä sisältövaroitus on sovellettu virheellisesti!" + +#: src/view/com/modals/AppealLabel.tsx:72 +#: src/view/com/modals/AppealLabel.tsx:75 +#~ msgid "Please tell us why you think this decision was incorrect." +#~ msgstr "" + +#: src/view/com/modals/VerifyEmail.tsx:101 +msgid "Please Verify Your Email" +msgstr "Vahvista sähköpostiosoitteesi" + +#: src/view/com/composer/Composer.tsx:215 +msgid "Please wait for your link card to finish loading" +msgstr "Odota, että linkkikortti latautuu kokonaan" + +#: src/screens/Onboarding/index.tsx:37 +msgid "Politics" +msgstr "Politiikka" + +#: src/view/com/modals/SelfLabel.tsx:111 +msgid "Porn" +msgstr "Porno" + +#: src/view/com/composer/Composer.tsx:350 +#: src/view/com/composer/Composer.tsx:358 +msgctxt "action" +msgid "Post" +msgstr "Lähetä" + +#: src/view/com/post-thread/PostThread.tsx:303 +msgctxt "description" +msgid "Post" +msgstr "Lähetä" + +#: src/view/com/post-thread/PostThreadItem.tsx:172 +msgid "Post by {0}" +msgstr "Lähettäjä {0}" + +#: src/Navigation.tsx:172 +#: src/Navigation.tsx:179 +#: src/Navigation.tsx:186 +msgid "Post by @{0}" +msgstr "Lähettäjä @{0}" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:84 +msgid "Post deleted" +msgstr "Viesti poistettu" + +#: src/view/com/post-thread/PostThread.tsx:461 +msgid "Post hidden" +msgstr "Viesti piilotettu" + +#: src/view/com/composer/select-language/SelectLangBtn.tsx:87 +msgid "Post language" +msgstr "Lähetyskieli" + +#: src/view/com/modals/lang-settings/PostLanguagesSettings.tsx:75 +msgid "Post Languages" +msgstr "Lähetyskielet" + +#: src/view/com/post-thread/PostThread.tsx:513 +msgid "Post not found" +msgstr "Viestiä ei löydy" + +#: src/view/screens/Profile.tsx:180 +msgid "Posts" +msgstr "Viestit" + +#: src/view/com/posts/FeedErrorMessage.tsx:64 +msgid "Posts hidden" +msgstr "Piilotetut viestit" + +#: src/view/com/modals/LinkWarning.tsx:46 +msgid "Potentially Misleading Link" +msgstr "Mahdollisesti harhaanjohtava linkki" + +#: src/view/com/lightbox/Lightbox.web.tsx:135 +msgid "Previous image" +msgstr "Edellinen kuva" + +#: src/view/screens/LanguageSettings.tsx:187 +msgid "Primary Language" +msgstr "Ensisijainen kieli" + +#: src/view/screens/PreferencesThreads.tsx:97 +msgid "Prioritize Your Follows" +msgstr "Aseta seurattavat tärkeysjärjestykseen" + +#: src/view/screens/Settings/index.tsx:632 +#: src/view/shell/desktop/RightNav.tsx:72 +msgid "Privacy" +msgstr "Yksityisyys" + +#: src/Navigation.tsx:217 +#: src/view/screens/PrivacyPolicy.tsx:29 +#: src/view/screens/Settings/index.tsx:891 +#: src/view/shell/Drawer.tsx:262 +msgid "Privacy Policy" +msgstr "Yksityisyydensuojakäytäntö" + +#: src/view/com/auth/login/ForgotPasswordForm.tsx:198 +msgid "Processing..." +msgstr "Käsitellään..." + +#: src/view/shell/bottom-bar/BottomBar.tsx:247 +#: src/view/shell/desktop/LeftNav.tsx:415 +#: src/view/shell/Drawer.tsx:70 +#: src/view/shell/Drawer.tsx:546 +#: src/view/shell/Drawer.tsx:547 +msgid "Profile" +msgstr "Profiili" + +#: src/view/com/modals/EditProfile.tsx:128 +msgid "Profile updated" +msgstr "Profiili päivitetty" + +#: src/view/screens/Settings/index.tsx:949 +msgid "Protect your account by verifying your email." +msgstr "Suojaa tilisi vahvistamalla sähköpostiosoitteesi." + +#: src/screens/Onboarding/StepFinished.tsx:101 +msgid "Public" +msgstr "Julkinen" + +#: src/view/screens/ModerationModlists.tsx:61 +msgid "Public, shareable lists of users to mute or block in bulk." +msgstr "Julkinen, jaettava käyttäjäluettelo hiljennettyjen tai estettyjen käyttäjien massamäärityksiä varten." + +#: src/view/screens/Lists.tsx:61 +msgid "Public, shareable lists which can drive feeds." +msgstr "Julkinen, jaettava lista, joka voi ohjata syötteitä." + +#: src/view/com/composer/Composer.tsx:335 +msgid "Publish post" +msgstr "Julkaise viesti" + +#: src/view/com/composer/Composer.tsx:335 +msgid "Publish reply" +msgstr "Julkaise vastaus" + +#: src/view/com/modals/Repost.tsx:65 +msgctxt "action" +msgid "Quote post" +msgstr "Lainaa viestiä" + +#: src/view/com/util/post-ctrls/RepostButton.web.tsx:58 +msgid "Quote post" +msgstr "Lainaa viestiä" + +#: src/view/com/modals/Repost.tsx:70 +msgctxt "action" +msgid "Quote Post" +msgstr "Lainaa viestiä" + +#: src/view/screens/PreferencesThreads.tsx:86 +msgid "Random (aka \"Poster's Roulette\")" +msgstr "Satunnainen (tunnetaan myös nimellä \"Lähettäjän ruletti\")" + +#: src/view/com/modals/EditImage.tsx:236 +msgid "Ratios" +msgstr "Suhdeluvut" + +#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:116 +msgid "Recommended Feeds" +msgstr "Suositellut syötteet" + +#: src/view/com/auth/onboarding/RecommendedFollows.tsx:180 +msgid "Recommended Users" +msgstr "Suositellut käyttäjät" + +#: src/view/com/modals/ListAddRemoveUsers.tsx:264 +#: src/view/com/modals/SelfLabel.tsx:83 +#: src/view/com/modals/UserAddRemoveLists.tsx:219 +#: src/view/com/util/UserAvatar.tsx:285 +#: src/view/com/util/UserBanner.tsx:91 +msgid "Remove" +msgstr "Poista" + +#: src/view/com/feeds/FeedSourceCard.tsx:106 +msgid "Remove {0} from my feeds?" +msgstr "Poistetaanko {0} syötteistäni?" + +#: src/view/com/util/AccountDropdownBtn.tsx:22 +msgid "Remove account" +msgstr "Poista tili" + +#: src/view/com/posts/FeedErrorMessage.tsx:131 +#: src/view/com/posts/FeedErrorMessage.tsx:166 +msgid "Remove feed" +msgstr "Poista syöte" + +#: src/view/com/feeds/FeedSourceCard.tsx:105 +#: src/view/com/feeds/FeedSourceCard.tsx:167 +#: src/view/com/feeds/FeedSourceCard.tsx:172 +#: src/view/com/feeds/FeedSourceCard.tsx:243 +#: src/view/screens/ProfileFeed.tsx:272 +msgid "Remove from my feeds" +msgstr "Poista syötteistäni" + +#: src/view/com/composer/photos/Gallery.tsx:167 +msgid "Remove image" +msgstr "Poista kuva" + +#: src/view/com/composer/ExternalEmbed.tsx:70 +msgid "Remove image preview" +msgstr "Poista kuvan esikatselu" + +#: src/view/com/modals/Repost.tsx:47 +msgid "Remove repost" +msgstr "Poista uudelleenjako" + +#: src/view/com/feeds/FeedSourceCard.tsx:173 +msgid "Remove this feed from my feeds?" +msgstr "Poistetaanko tämä syöte omista syötteistäni?" + +#: src/view/com/posts/FeedErrorMessage.tsx:132 +msgid "Remove this feed from your saved feeds?" +msgstr "Poistetaanko tämä syöte tallennetuista syötteistäsi?" + +#: src/view/com/modals/ListAddRemoveUsers.tsx:199 +#: src/view/com/modals/UserAddRemoveLists.tsx:152 +msgid "Removed from list" +msgstr "Poistettu listalta" + +#: src/view/com/feeds/FeedSourceCard.tsx:111 +#: src/view/com/feeds/FeedSourceCard.tsx:178 +msgid "Removed from my feeds" +msgstr "Poistettu syötteistäni" + +#: src/view/com/composer/ExternalEmbed.tsx:71 +msgid "Removes default thumbnail from {0}" +msgstr "Poistaa {0} oletuskuvakkeen" + +#: src/view/screens/Profile.tsx:181 +msgid "Replies" +msgstr "Vastaukset" + +#: src/view/com/threadgate/WhoCanReply.tsx:98 +msgid "Replies to this thread are disabled" +msgstr "Tähän keskusteluun vastaaminen on estetty" + +#: src/view/com/composer/Composer.tsx:348 +msgctxt "action" +msgid "Reply" +msgstr "Vastaa" + +#: src/view/screens/PreferencesHomeFeed.tsx:144 +msgid "Reply Filters" +msgstr "Vastaussuodattimet" + +#: src/view/com/post/Post.tsx:166 +#: src/view/com/posts/FeedItem.tsx:284 +msgctxt "description" +msgid "Reply to <0/>" +msgstr "Vastaa käyttäjälle <0/>" + +#: src/view/com/modals/report/Modal.tsx:166 +msgid "Report {collectionName}" +msgstr "Raportoi {collectionName}" + +#: src/view/com/profile/ProfileHeader.tsx:360 +msgid "Report Account" +msgstr "Ilmoita tili" + +#: src/view/screens/ProfileFeed.tsx:292 +msgid "Report feed" +msgstr "Ilmoita syöte" + +#: src/view/screens/ProfileList.tsx:458 +msgid "Report List" +msgstr "Ilmoita luettelo" + +#: src/view/com/modals/report/SendReportButton.tsx:37 +#: src/view/com/util/forms/PostDropdownBtn.tsx:210 +msgid "Report post" +msgstr "Ilmoita viesti" + +#: src/view/com/modals/Repost.tsx:43 +#: src/view/com/modals/Repost.tsx:48 +#: src/view/com/modals/Repost.tsx:53 +#: src/view/com/util/post-ctrls/RepostButton.tsx:61 +msgctxt "action" +msgid "Repost" +msgstr "Uudelleenjaa" + +#: src/view/com/util/post-ctrls/RepostButton.web.tsx:48 +msgid "Repost" +msgstr "Uudelleenjaa" + +#: src/view/com/util/post-ctrls/RepostButton.web.tsx:94 +#: src/view/com/util/post-ctrls/RepostButton.web.tsx:105 +msgid "Repost or quote post" +msgstr "Uudelleenjaa tai lainaa viestiä" + +#: src/view/screens/PostRepostedBy.tsx:27 +msgid "Reposted By" +msgstr "Uudelleenjakanut" + +#: src/view/com/posts/FeedItem.tsx:204 +msgid "Reposted by {0}" +msgstr "Uudelleenjakanut {0}" + +#: src/view/com/posts/FeedItem.tsx:221 +msgid "Reposted by <0/>" +msgstr "Uudelleenjakanut <0/>" + +#: src/view/com/notifications/FeedItem.tsx:162 +msgid "reposted your post" +msgstr "uudelleenjakoi viestisi" + +#: src/view/com/post-thread/PostThreadItem.tsx:185 +msgid "Reposts of this post" +msgstr "Tämän viestin uudelleenjulkaisut" + +#: src/view/com/modals/ChangeEmail.tsx:181 +#: src/view/com/modals/ChangeEmail.tsx:183 +msgid "Request Change" +msgstr "Pyydä muutosta" + +#: src/view/com/auth/create/Step2.tsx:219 +#~ msgid "Request code" +#~ msgstr "Pyydä koodia" + +#: src/view/com/modals/ChangePassword.tsx:239 +#: src/view/com/modals/ChangePassword.tsx:241 +msgid "Request Code" +msgstr "Pyydä koodia" + +#: src/view/screens/Settings/index.tsx:456 +msgid "Require alt text before posting" +msgstr "Vaadi vaihtoehtoista ALT-tekstiä ennen julkaisua" + +#: src/view/com/auth/create/Step1.tsx:153 +msgid "Required for this provider" +msgstr "Vaaditaan tälle instanssille" + +#: src/view/com/auth/login/SetNewPasswordForm.tsx:124 +#: src/view/com/auth/login/SetNewPasswordForm.tsx:136 +msgid "Reset code" +msgstr "Nollauskoodi" + +#: src/view/com/modals/ChangePassword.tsx:190 +msgid "Reset Code" +msgstr "Nollauskoodi" + +#: src/view/screens/Settings/index.tsx:824 +msgid "Reset onboarding" +msgstr "Nollaa käyttöönotto" + +#: src/view/screens/Settings/index.tsx:827 +msgid "Reset onboarding state" +msgstr "Nollaa käyttöönoton tila" + +#: src/view/com/auth/login/ForgotPasswordForm.tsx:104 +msgid "Reset password" +msgstr "Nollaa salasana" + +#: src/view/screens/Settings/index.tsx:814 +msgid "Reset preferences" +msgstr "Nollaa asetukset" + +#: src/view/screens/Settings/index.tsx:817 +msgid "Reset preferences state" +msgstr "Nollaa asetusten tila" + +#: src/view/screens/Settings/index.tsx:825 +msgid "Resets the onboarding state" +msgstr "Nollaa käyttöönoton tilan" + +#: src/view/screens/Settings/index.tsx:815 +msgid "Resets the preferences state" +msgstr "Nollaa asetusten tilan" + +#: src/view/com/auth/login/LoginForm.tsx:269 +msgid "Retries login" +msgstr "Yrittää uudelleen kirjautumista" + +#: src/view/com/util/error/ErrorMessage.tsx:57 +#: src/view/com/util/error/ErrorScreen.tsx:74 +msgid "Retries the last action, which errored out" +msgstr "Yrittää uudelleen viimeisintä toimintoa, joka epäonnistui" + +#: src/screens/Onboarding/StepInterests/index.tsx:221 +#: src/screens/Onboarding/StepInterests/index.tsx:224 +#: src/view/com/auth/create/CreateAccount.tsx:177 +#: src/view/com/auth/create/CreateAccount.tsx:182 +#: src/view/com/auth/login/LoginForm.tsx:268 +#: src/view/com/auth/login/LoginForm.tsx:271 +#: src/view/com/util/error/ErrorMessage.tsx:55 +#: src/view/com/util/error/ErrorScreen.tsx:72 +msgid "Retry" +msgstr "Yritä uudelleen" + +#: src/view/com/auth/create/Step2.tsx:247 +#~ msgid "Retry." +#~ msgstr "Yritä uudelleen." + +#: src/view/screens/ProfileList.tsx:898 +msgid "Return to previous page" +msgstr "Palaa edelliselle sivulle" + +#: src/view/shell/desktop/RightNav.tsx:55 +#~ msgid "SANDBOX. Posts and accounts are not permanent." +#~ msgstr "HIEKKALAATIKKO. Viestit ja tilit eivät ole pysyviä." + +#: src/view/com/lightbox/Lightbox.tsx:132 +#: src/view/com/modals/CreateOrEditList.tsx:345 +msgctxt "action" +msgid "Save" +msgstr "Tallenna" + +#: src/view/com/modals/BirthDateSettings.tsx:94 +#: src/view/com/modals/BirthDateSettings.tsx:97 +#: src/view/com/modals/ChangeHandle.tsx:173 +#: src/view/com/modals/CreateOrEditList.tsx:337 +#: src/view/com/modals/EditProfile.tsx:224 +#: src/view/screens/ProfileFeed.tsx:345 +msgid "Save" +msgstr "Tallenna" + +#: src/view/com/modals/AltImage.tsx:130 +msgid "Save alt text" +msgstr "Tallenna vaihtoehtoinen ALT-teksti" + +#: src/view/com/modals/EditProfile.tsx:232 +msgid "Save Changes" +msgstr "Tallenna muutokset" + +#: src/view/com/modals/ChangeHandle.tsx:170 +msgid "Save handle change" +msgstr "Tallenna käyttäjätunnuksen muutos" + +#: src/view/com/modals/crop-image/CropImage.web.tsx:144 +msgid "Save image crop" +msgstr "Tallenna kuvan rajaus" + +#: src/view/screens/SavedFeeds.tsx:122 +msgid "Saved Feeds" +msgstr "Tallennetut syötteet" + +#: src/view/com/modals/EditProfile.tsx:225 +msgid "Saves any changes to your profile" +msgstr "Tallentaa kaikki muutokset profiiliisi" + +#: src/view/com/modals/ChangeHandle.tsx:171 +msgid "Saves handle change to {handle}" +msgstr "Tallentaa käyttäjätunnuksen muutoksen muotoon {handle}" + +#: src/screens/Onboarding/index.tsx:36 +msgid "Science" +msgstr "Tiede" + +#: src/view/screens/ProfileList.tsx:854 +msgid "Scroll to top" +msgstr "Vieritä alkuun" + +#: src/Navigation.tsx:437 +#: src/view/com/auth/LoggedOut.tsx:122 +#: src/view/com/modals/ListAddRemoveUsers.tsx:75 +#: src/view/com/util/forms/SearchInput.tsx:67 +#: src/view/com/util/forms/SearchInput.tsx:79 +#: src/view/screens/Search/Search.tsx:418 +#: src/view/screens/Search/Search.tsx:645 +#: src/view/screens/Search/Search.tsx:663 +#: src/view/shell/bottom-bar/BottomBar.tsx:159 +#: src/view/shell/desktop/LeftNav.tsx:324 +#: src/view/shell/desktop/Search.tsx:214 +#: src/view/shell/desktop/Search.tsx:223 +#: src/view/shell/Drawer.tsx:362 +#: src/view/shell/Drawer.tsx:363 +msgid "Search" +msgstr "Haku" + +#: src/view/screens/Search/Search.tsx:712 +#: src/view/shell/desktop/Search.tsx:255 +msgid "Search for \"{query}\"" +msgstr "Haku hakusanalla \"{query}\"" + +#: src/view/com/auth/LoggedOut.tsx:104 +#: src/view/com/auth/LoggedOut.tsx:105 +#: src/view/com/modals/ListAddRemoveUsers.tsx:70 +msgid "Search for users" +msgstr "Hae käyttäjiä" + +#: src/view/com/modals/ChangeEmail.tsx:110 +msgid "Security Step Required" +msgstr "Turvatarkistus vaaditaan" + +#: src/view/screens/SavedFeeds.tsx:163 +msgid "See this guide" +msgstr "Katso tämä opas" + +#: src/view/com/auth/HomeLoggedOutCTA.tsx:39 +msgid "See what's next" +msgstr "Katso, mitä seuraavaksi tapahtuu" + +#: src/view/com/util/Selector.tsx:106 +msgid "Select {item}" +msgstr "Valitse {item}" + +#: src/view/com/modals/ServerInput.tsx:75 +#~ msgid "Select Bluesky Social" +#~ msgstr "" + +#: src/view/com/auth/login/Login.tsx:117 +msgid "Select from an existing account" +msgstr "Valitse olemassa olevalta tililtä" + +#: src/view/com/util/Selector.tsx:107 +msgid "Select option {i} of {numItems}" +msgstr "Valitse vaihtoehto {i} / {numItems}" + +#: src/view/com/auth/create/Step1.tsx:103 +#: src/view/com/auth/login/LoginForm.tsx:150 +msgid "Select service" +msgstr "Valitse palvelu" + +#: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:52 +msgid "Select some accounts below to follow" +msgstr "Valitse alla olevista tileistä jotain seurattavaksi" + +#: src/view/com/auth/server-input/index.tsx:82 +msgid "Select the service that hosts your data." +msgstr "Valitse palvelu, joka hostaa tietojasi." + +#: src/screens/Onboarding/StepModeration/index.tsx:49 +#~ msgid "Select the types of content that you want to see (or not see), and we'll handle the rest." +#~ msgstr "" + +#: src/screens/Onboarding/StepTopicalFeeds.tsx:90 +msgid "Select topical feeds to follow from the list below" +msgstr "Valitse ajankohtaisia syötteitä alla olevasta listasta" + +#: src/screens/Onboarding/StepModeration/index.tsx:75 +msgid "Select what you want to see (or not see), and we’ll handle the rest." +msgstr "Valitse, mitä haluat nähdä (tai olla näkemättä) ja me huolehdimme lopusta." + +#: src/view/screens/LanguageSettings.tsx:281 +msgid "Select which languages you want your subscribed feeds to include. If none are selected, all languages will be shown." +msgstr "Valitse, mitä kieliä haluat tilattujen syötteidesi sisältävän. Jos mitään ei ole valittu, kaikki kielet näytetään." + +#: src/view/screens/LanguageSettings.tsx:98 +msgid "Select your app language for the default text to display in the app" +msgstr "Valitse sovelluksen oletuskieli, joka näytetään sovelluksessa" + +#: src/screens/Onboarding/StepInterests/index.tsx:196 +msgid "Select your interests from the options below" +msgstr "Valitse kiinnostuksenkohteesi alla olevista vaihtoehdoista" + +#: src/view/com/auth/create/Step2.tsx:155 +#~ msgid "Select your phone's country" +#~ msgstr "Valitse puhelinnumerosi maa" + +#: src/view/screens/LanguageSettings.tsx:190 +msgid "Select your preferred language for translations in your feed." +msgstr "Valitse haluamasi kieli käännöksille syötteessäsi." + +#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:116 +msgid "Select your primary algorithmic feeds" +msgstr "Valitse ensisijaiset algoritmisyötteet" + +#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:142 +msgid "Select your secondary algorithmic feeds" +msgstr "Valitse toissijaiset algoritmisyötteet" + +#: src/view/com/modals/VerifyEmail.tsx:202 +#: src/view/com/modals/VerifyEmail.tsx:204 +msgid "Send Confirmation Email" +msgstr "Lähetä vahvistussähköposti" + +#: src/view/com/modals/DeleteAccount.tsx:131 +msgid "Send email" +msgstr "Lähetä sähköposti" + +#: src/view/com/modals/DeleteAccount.tsx:144 +msgctxt "action" +msgid "Send Email" +msgstr "Lähetä sähköposti" + +#: src/view/shell/Drawer.tsx:295 +#: src/view/shell/Drawer.tsx:316 +msgid "Send feedback" +msgstr "Lähetä palautetta" + +#: src/view/com/modals/report/SendReportButton.tsx:45 +msgid "Send Report" +msgstr "Lähetä raportti" + +#: src/view/com/modals/DeleteAccount.tsx:133 +msgid "Sends email with confirmation code for account deletion" +msgstr "Lähettää sähköpostin tilin poistamiseen tarvittavan vahvistuskoodin" + +#: src/view/com/auth/server-input/index.tsx:110 +msgid "Server address" +msgstr "Palvelimen osoite" + +#: src/view/com/modals/ContentFilteringSettings.tsx:311 +msgid "Set {value} for {labelGroup} content moderation policy" +msgstr "Aseta {value} {labelGroup} sisällön moderointisäännöksi" + +#: src/view/com/modals/ContentFilteringSettings.tsx:160 +#: src/view/com/modals/ContentFilteringSettings.tsx:179 +msgctxt "action" +msgid "Set Age" +msgstr "Aseta ikä" + +#: src/view/screens/Settings/index.tsx:488 +msgid "Set color theme to dark" +msgstr "Aseta väriteema tummaksi" + +#: src/view/screens/Settings/index.tsx:481 +msgid "Set color theme to light" +msgstr "Aseta väriteema vaaleaksi" + +#: src/view/screens/Settings/index.tsx:475 +msgid "Set color theme to system setting" +msgstr "Aseta väriteema järjestelmäasetuksiin" + +#: src/view/screens/Settings/index.tsx:514 +msgid "Set dark theme to the dark theme" +msgstr "Aseta tumma teema tummaksi" + +#: src/view/screens/Settings/index.tsx:507 +msgid "Set dark theme to the dim theme" +msgstr "Aseta tumma teema hämäräksi" + +#: src/view/com/auth/login/SetNewPasswordForm.tsx:104 +msgid "Set new password" +msgstr "Aseta uusi salasana" + +#: src/view/com/auth/create/Step1.tsx:225 +msgid "Set password" +msgstr "Aseta salasana" + +#: src/view/screens/PreferencesHomeFeed.tsx:225 +msgid "Set this setting to \"No\" to hide all quote posts from your feed. Reposts will still be visible." +msgstr "Aseta tämä asetus \"Ei\"-tilaan piilottaaksesi kaikki lainaukset syötteestäsi. Uudelleenjulkaisut näkyvät silti." + +#: src/view/screens/PreferencesHomeFeed.tsx:122 +msgid "Set this setting to \"No\" to hide all replies from your feed." +msgstr "Aseta tämä asetus \"Ei\"-tilaan piilottaaksesi kaikki vastaukset syötteestäsi." + +#: src/view/screens/PreferencesHomeFeed.tsx:191 +msgid "Set this setting to \"No\" to hide all reposts from your feed." +msgstr "Aseta tämä asetus \"Ei\"-tilaan piilottaaksesi kaikki uudelleenjulkaisut syötteestäsi." + +#: src/view/screens/PreferencesThreads.tsx:122 +msgid "Set this setting to \"Yes\" to show replies in a threaded view. This is an experimental feature." +msgstr "Aseta tämä asetus \"Kyllä\" tilaan näyttääksesi vastaukset ketjumaisessa näkymässä. Tämä on kokeellinen ominaisuus." + +#: src/view/screens/PreferencesHomeFeed.tsx:261 +msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your following feed. This is an experimental feature." +msgstr "Aseta tämä asetus \"Kyllä\"-tilaan nähdäksesi esimerkkejä tallennetuista syötteistäsi seuraamissasi syötteessäsi. Tämä on kokeellinen ominaisuus." + +#: src/screens/Onboarding/Layout.tsx:50 +msgid "Set up your account" +msgstr "Luo tili" + +#: src/view/com/modals/ChangeHandle.tsx:266 +msgid "Sets Bluesky username" +msgstr "Asettaa Bluesky-käyttäjätunnuksen" + +#: src/view/com/auth/login/ForgotPasswordForm.tsx:157 +msgid "Sets email for password reset" +msgstr "Asettaa sähköpostin salasanan palautusta varten" + +#: src/view/com/auth/login/ForgotPasswordForm.tsx:122 +msgid "Sets hosting provider for password reset" +msgstr "Asettaa palveluntarjoajan salasanan palautusta varten" + +#: src/view/com/auth/create/Step1.tsx:104 +#: src/view/com/auth/login/LoginForm.tsx:151 +msgid "Sets server for the Bluesky client" +msgstr "Asettaa palvelimen Bluesky-ohjelmalle" + +#: src/Navigation.tsx:135 +#: src/view/screens/Settings/index.tsx:294 +#: src/view/shell/desktop/LeftNav.tsx:433 +#: src/view/shell/Drawer.tsx:567 +#: src/view/shell/Drawer.tsx:568 +msgid "Settings" +msgstr "Asetukset" + +#: src/view/com/modals/SelfLabel.tsx:125 +msgid "Sexual activity or erotic nudity." +msgstr "Erotiikka tai muu aikuisviihde." + +#: src/view/com/lightbox/Lightbox.tsx:141 +msgctxt "action" +msgid "Share" +msgstr "Jaa" + +#: src/view/com/profile/ProfileHeader.tsx:294 +#: src/view/com/util/forms/PostDropdownBtn.tsx:153 +#: src/view/screens/ProfileList.tsx:417 +msgid "Share" +msgstr "Jaa" + +#: src/view/screens/ProfileFeed.tsx:304 +msgid "Share feed" +msgstr "Jaa syöte" + +#: src/screens/Onboarding/StepModeration/ModerationOption.tsx:43 +#: src/view/com/modals/ContentFilteringSettings.tsx:266 +#: src/view/com/util/moderation/ContentHider.tsx:107 +#: src/view/com/util/moderation/PostHider.tsx:108 +#: src/view/screens/Settings/index.tsx:344 +msgid "Show" +msgstr "Näytä" + +#: src/view/screens/PreferencesHomeFeed.tsx:68 +msgid "Show all replies" +msgstr "Näytä kaikki vastaukset" + +#: src/view/com/util/moderation/ScreenHider.tsx:132 +msgid "Show anyway" +msgstr "Näytä silti" + +#: src/view/com/modals/EmbedConsent.tsx:87 +msgid "Show embeds from {0}" +msgstr "Näytä upotukset taholta {0}" + +#: src/view/com/profile/ProfileHeader.tsx:458 +msgid "Show follows similar to {0}" +msgstr "Näytä seurannat samankaltaisilta käyttäjiltä kuin {0}" + +#: src/view/com/post-thread/PostThreadItem.tsx:535 +#: src/view/com/post/Post.tsx:197 +#: src/view/com/posts/FeedItem.tsx:360 +msgid "Show More" +msgstr "Näytä lisää" + +#: src/view/screens/PreferencesHomeFeed.tsx:258 +msgid "Show Posts from My Feeds" +msgstr "Näytä viestit omista syötteistäni" + +#: src/view/screens/PreferencesHomeFeed.tsx:222 +msgid "Show Quote Posts" +msgstr "Näytä lainatut viestit" + +#: src/screens/Onboarding/StepFollowingFeed.tsx:118 +msgid "Show quote-posts in Following feed" +msgstr "Näytä lainatut viestit seurattavien syötteessä" + +#: src/screens/Onboarding/StepFollowingFeed.tsx:134 +msgid "Show quotes in Following" +msgstr "Näytä lainaukset seurattavissa" + +#: src/screens/Onboarding/StepFollowingFeed.tsx:94 +msgid "Show re-posts in Following feed" +msgstr "Näytä uudelleenjulkaistut viestit seurattavissa" + +#: src/view/screens/PreferencesHomeFeed.tsx:119 +msgid "Show Replies" +msgstr "Näytä vastaukset" + +#: src/view/screens/PreferencesThreads.tsx:100 +msgid "Show replies by people you follow before all other replies." +msgstr "Näytä seurattujen henkilöiden vastaukset ennen muita vastauksia." + +#: src/screens/Onboarding/StepFollowingFeed.tsx:86 +msgid "Show replies in Following" +msgstr "Näytä vastaukset seurattavissa" + +#: src/screens/Onboarding/StepFollowingFeed.tsx:70 +msgid "Show replies in Following feed" +msgstr "Näytä vastaukset seurattavissa" + +#: src/view/screens/PreferencesHomeFeed.tsx:70 +msgid "Show replies with at least {value} {0}" +msgstr "Näytä vastaukset, joissa on vähintään {value} {0}" + +#: src/view/screens/PreferencesHomeFeed.tsx:188 +msgid "Show Reposts" +msgstr "Näytä uudelleenjulkaisut" + +#: src/screens/Onboarding/StepFollowingFeed.tsx:110 +msgid "Show reposts in Following" +msgstr "Näytä uudelleenjulkaisut seurattavissa" + +#: src/view/com/util/moderation/ContentHider.tsx:67 +#: src/view/com/util/moderation/PostHider.tsx:61 +msgid "Show the content" +msgstr "Näytä sisältö" + +#: src/view/com/notifications/FeedItem.tsx:346 +msgid "Show users" +msgstr "Näytä käyttäjät" + +#: src/view/com/profile/ProfileHeader.tsx:461 +msgid "Shows a list of users similar to this user." +msgstr "Näyttää luettelon käyttäjistä, jotka ovat samankaltaisia kuin tämä käyttäjä." + +#: src/view/com/post-thread/PostThreadFollowBtn.tsx:124 +#: src/view/com/profile/ProfileHeader.tsx:505 +msgid "Shows posts from {0} in your feed" +msgstr "Näyttää viestit käyttäjältä {0} syötteessäsi" + +#: src/view/com/auth/HomeLoggedOutCTA.tsx:70 +#: src/view/com/auth/login/Login.tsx:98 +#: src/view/com/auth/SplashScreen.tsx:79 +#: src/view/shell/bottom-bar/BottomBar.tsx:285 +#: src/view/shell/bottom-bar/BottomBar.tsx:286 +#: src/view/shell/bottom-bar/BottomBar.tsx:288 +#: src/view/shell/bottom-bar/BottomBarWeb.tsx:178 +#: src/view/shell/bottom-bar/BottomBarWeb.tsx:179 +#: src/view/shell/bottom-bar/BottomBarWeb.tsx:181 +#: src/view/shell/NavSignupCard.tsx:58 +#: src/view/shell/NavSignupCard.tsx:59 +msgid "Sign in" +msgstr "Kirjaudu sisään" + +#: src/view/com/auth/HomeLoggedOutCTA.tsx:78 +#: src/view/com/auth/SplashScreen.tsx:82 +#: src/view/com/auth/SplashScreen.web.tsx:91 +msgid "Sign In" +msgstr "Kirjaudu sisään" + +#: src/view/com/auth/login/ChooseAccountForm.tsx:44 +msgid "Sign in as {0}" +msgstr "Kirjaudu sisään nimellä {0}" + +#: src/view/com/auth/login/ChooseAccountForm.tsx:118 +#: src/view/com/auth/login/Login.tsx:116 +msgid "Sign in as..." +msgstr "Kirjaudu sisään nimellä..." + +#: src/view/com/auth/login/LoginForm.tsx:137 +msgid "Sign into" +msgstr "Kirjaudu sisään" + +#: src/view/com/modals/SwitchAccount.tsx:64 +#: src/view/com/modals/SwitchAccount.tsx:69 +#: src/view/screens/Settings/index.tsx:100 +#: src/view/screens/Settings/index.tsx:103 +msgid "Sign out" +msgstr "Kirjaudu ulos" + +#: src/view/shell/bottom-bar/BottomBar.tsx:275 +#: src/view/shell/bottom-bar/BottomBar.tsx:276 +#: src/view/shell/bottom-bar/BottomBar.tsx:278 +#: src/view/shell/bottom-bar/BottomBarWeb.tsx:168 +#: src/view/shell/bottom-bar/BottomBarWeb.tsx:169 +#: src/view/shell/bottom-bar/BottomBarWeb.tsx:171 +#: src/view/shell/NavSignupCard.tsx:49 +#: src/view/shell/NavSignupCard.tsx:50 +#: src/view/shell/NavSignupCard.tsx:52 +msgid "Sign up" +msgstr "Rekisteröidy" + +#: src/view/shell/NavSignupCard.tsx:42 +msgid "Sign up or sign in to join the conversation" +msgstr "Rekisteröidy tai kirjaudu sisään liittyäksesi keskusteluun" + +#: src/view/com/util/moderation/ScreenHider.tsx:76 +msgid "Sign-in Required" +msgstr "Sisäänkirjautuminen vaaditaan" + +#: src/view/screens/Settings/index.tsx:355 +msgid "Signed in as" +msgstr "Kirjautunut sisään nimellä" + +#: src/view/com/auth/login/ChooseAccountForm.tsx:103 +msgid "Signed in as @{0}" +msgstr "Kirjautunut sisään käyttäjänimellä @{0}" + +#: src/view/com/modals/SwitchAccount.tsx:66 +msgid "Signs {0} out of Bluesky" +msgstr "{0} kirjautuu ulos Blueskysta" + +#: src/screens/Onboarding/StepInterests/index.tsx:235 +#: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:195 +#: src/view/com/auth/onboarding/WelcomeMobile.tsx:33 +msgid "Skip" +msgstr "Ohita" + +#: src/screens/Onboarding/StepInterests/index.tsx:232 +msgid "Skip this flow" +msgstr "Ohita tämä vaihe" + +#: src/view/com/auth/create/Step2.tsx:82 +#~ msgid "SMS verification" +#~ msgstr "SMS-varmennus" + +#: src/screens/Onboarding/index.tsx:40 +msgid "Software Dev" +msgstr "Ohjelmistokehitys" + +#: src/view/com/modals/ProfilePreview.tsx:62 +#~ msgid "Something went wrong and we're not sure what." +#~ msgstr "" + +#: src/view/com/modals/Waitlist.tsx:51 +msgid "Something went wrong. Check your email and try again." +msgstr "Jotain meni pieleen. Tarkista sähköpostisi ja yritä uudelleen." + +#: src/App.native.tsx:61 +msgid "Sorry! Your session expired. Please log in again." +msgstr "Pahoittelut! Istuntosi on vanhentunut. Kirjaudu sisään uudelleen." + +#: src/view/screens/PreferencesThreads.tsx:69 +msgid "Sort Replies" +msgstr "Lajittele vastaukset" + +#: src/view/screens/PreferencesThreads.tsx:72 +msgid "Sort replies to the same post by:" +msgstr "Lajittele saman viestin vastaukset seuraavasti:" + +#: src/screens/Onboarding/index.tsx:30 +msgid "Sports" +msgstr "Urheilu" + +#: src/view/com/modals/crop-image/CropImage.web.tsx:122 +msgid "Square" +msgstr "Neliö" + +#: src/view/com/modals/ServerInput.tsx:62 +#~ msgid "Staging" +#~ msgstr "" + +#: src/view/screens/Settings/index.tsx:871 +msgid "Status page" +msgstr "Tilasivu" + +#: src/view/com/auth/create/StepHeader.tsx:22 +msgid "Step {0} of {numSteps}" +msgstr "Vaihe {0}/{numSteps}" + +#: src/view/screens/Settings/index.tsx:274 +msgid "Storage cleared, you need to restart the app now." +msgstr "Tallennustila tyhjennetty, sinun on käynnistettävä sovellus uudelleen." + +#: src/Navigation.tsx:202 +#: src/view/screens/Settings/index.tsx:807 +msgid "Storybook" +msgstr "Storybook" + +#: src/view/com/modals/AppealLabel.tsx:101 +msgid "Submit" +msgstr "Lähetä" + +#: src/view/screens/ProfileList.tsx:607 +msgid "Subscribe" +msgstr "Tilaa" + +#: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:173 +#: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:307 +msgid "Subscribe to the {0} feed" +msgstr "Tilaa {0}-syöte" + +#: src/view/screens/ProfileList.tsx:603 +msgid "Subscribe to this list" +msgstr "Tilaa tämä lista" + +#: src/view/screens/Search/Search.tsx:373 +msgid "Suggested Follows" +msgstr "Ehdotetut seurattavat" + +#: src/view/com/profile/ProfileHeaderSuggestedFollows.tsx:64 +msgid "Suggested for you" +msgstr "Suositeltua sinulle" + +#: src/view/com/modals/SelfLabel.tsx:95 +msgid "Suggestive" +msgstr "Viittaava" + +#: src/Navigation.tsx:212 +#: src/view/screens/Support.tsx:30 +#: src/view/screens/Support.tsx:33 +msgid "Support" +msgstr "Tuki" + +#: src/view/com/modals/ProfilePreview.tsx:110 +#~ msgid "Swipe up to see more" +#~ msgstr "" + +#: src/view/com/modals/SwitchAccount.tsx:117 +msgid "Switch Account" +msgstr "Vaihda tiliä" + +#: src/view/com/modals/SwitchAccount.tsx:97 +#: src/view/screens/Settings/index.tsx:130 +msgid "Switch to {0}" +msgstr "Vaihda käyttäjään {0}" + +#: src/view/com/modals/SwitchAccount.tsx:98 +#: src/view/screens/Settings/index.tsx:131 +msgid "Switches the account you are logged in to" +msgstr "Vaihtaa sisäänkirjautuneen käyttäjän tilin" + +#: src/view/screens/Settings/index.tsx:472 +msgid "System" +msgstr "Järjestelmä" + +#: src/view/screens/Settings/index.tsx:795 +msgid "System log" +msgstr "Järjestelmäloki" + +#: src/view/com/modals/crop-image/CropImage.web.tsx:112 +msgid "Tall" +msgstr "Pitkä" + +#: src/view/com/util/images/AutoSizedImage.tsx:70 +msgid "Tap to view fully" +msgstr "Napauta nähdäksesi kokonaan" + +#: src/screens/Onboarding/index.tsx:39 +msgid "Tech" +msgstr "Teknologia" + +#: src/view/shell/desktop/RightNav.tsx:81 +msgid "Terms" +msgstr "Ehdot" + +#: src/Navigation.tsx:222 +#: src/view/screens/Settings/index.tsx:885 +#: src/view/screens/TermsOfService.tsx:29 +#: src/view/shell/Drawer.tsx:256 +msgid "Terms of Service" +msgstr "Käyttöehdot" + +#: src/view/com/modals/AppealLabel.tsx:70 +#: src/view/com/modals/report/InputIssueDetails.tsx:51 +msgid "Text input field" +msgstr "Tekstikenttä" + +#: src/view/com/auth/create/CreateAccount.tsx:90 +msgid "That handle is already taken." +msgstr "Tuo käyttäjänimi on jo käytössä." + +#: src/view/com/profile/ProfileHeader.tsx:262 +msgid "The account will be able to interact with you after unblocking." +msgstr "Tili voi olla vuorovaikutuksessa kanssasi, kun estäminen on poistettu." + +#: src/view/screens/CommunityGuidelines.tsx:36 +msgid "The Community Guidelines have been moved to <0/>" +msgstr "Yhteisöohjeet on siirretty kohtaan <0/>" + +#: src/view/screens/CopyrightPolicy.tsx:33 +msgid "The Copyright Policy has been moved to <0/>" +msgstr "Tekijänoikeuskäytäntö on siirretty kohtaan <0/>" + +#: src/screens/Onboarding/Layout.tsx:60 +msgid "The following steps will help customize your Bluesky experience." +msgstr "Seuraavat vaiheet auttavat mukauttamaan Bluesky-kokemustasi." + +#: src/view/com/post-thread/PostThread.tsx:516 +msgid "The post may have been deleted." +msgstr "Viesti saattaa olla poistettu." + +#: src/view/screens/PrivacyPolicy.tsx:33 +msgid "The Privacy Policy has been moved to <0/>" +msgstr "Tietosuojakäytäntö on siirretty kohtaan <0/>" + +#: src/view/screens/Support.tsx:36 +msgid "The support form has been moved. If you need help, please <0/> or visit {HELP_DESK_URL} to get in touch with us." +msgstr "Tukilomake on siirretty. Jos tarvitset apua, käy osoitteessa <0/> tai vieraile {HELP_DESK_URL} ottaaksesi meihin yhteyttä." + +#: src/view/screens/TermsOfService.tsx:33 +msgid "The Terms of Service have been moved to" +msgstr "Käyttöehdot on siirretty kohtaan" + +#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:150 +msgid "There are many feeds to try:" +msgstr "On monia syötteitä kokeiltavaksi:" + +#: src/view/screens/ProfileFeed.tsx:549 +msgid "There was an an issue contacting the server, please check your internet connection and try again." +msgstr "Emme saaneet yhteyttä palvelimeen, tarkista internetyhteytesi ja yritä uudelleen." + +#: src/view/com/posts/FeedErrorMessage.tsx:139 +msgid "There was an an issue removing this feed. Please check your internet connection and try again." +msgstr "Syötteen poistossa on ongelmia. Tarkista internetyhteytesi ja yritä uudelleen." + +#: src/view/screens/ProfileFeed.tsx:209 +msgid "There was an an issue updating your feeds, please check your internet connection and try again." +msgstr "Syötteiden päivittämisessä on ongelmia, tarkista internetyhteytesi ja yritä uudelleen." + +#: src/view/screens/ProfileFeed.tsx:236 +#: src/view/screens/ProfileList.tsx:266 +#: src/view/screens/SavedFeeds.tsx:209 +#: src/view/screens/SavedFeeds.tsx:231 +#: src/view/screens/SavedFeeds.tsx:252 +msgid "There was an issue contacting the server" +msgstr "Yhteydenotto palvelimeen epäonnistui" + +#: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:57 +#: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:66 +#: src/view/com/feeds/FeedSourceCard.tsx:113 +#: src/view/com/feeds/FeedSourceCard.tsx:127 +#: src/view/com/feeds/FeedSourceCard.tsx:181 +msgid "There was an issue contacting your server" +msgstr "Yhteydenotto palvelimeen epäonnistui" + +#: src/view/com/notifications/Feed.tsx:117 +msgid "There was an issue fetching notifications. Tap here to try again." +msgstr "Ongelma ilmoitusten hakemisessa. Napauta tästä yrittääksesi uudelleen." + +#: src/view/com/posts/Feed.tsx:263 +msgid "There was an issue fetching posts. Tap here to try again." +msgstr "Ongelma viestien hakemisessa. Napauta tästä yrittääksesi uudelleen." + +#: src/view/com/lists/ListMembers.tsx:172 +msgid "There was an issue fetching the list. Tap here to try again." +msgstr "Ongelma listan hakemisessa. Napauta tästä yrittääksesi uudelleen." + +#: src/view/com/feeds/ProfileFeedgens.tsx:148 +#: src/view/com/lists/ProfileLists.tsx:155 +msgid "There was an issue fetching your lists. Tap here to try again." +msgstr "Ongelma listojesi hakemisessa. Napauta tästä yrittääksesi uudelleen." + +#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:63 +#: src/view/com/modals/ContentFilteringSettings.tsx:126 +msgid "There was an issue syncing your preferences with the server" +msgstr "Ongelma asetuksiesi synkronoinnissa palvelimelle" + +#: src/view/screens/AppPasswords.tsx:66 +msgid "There was an issue with fetching your app passwords" +msgstr "Sovellussalasanojen hakemisessa tapahtui virhe" + +#: src/view/com/post-thread/PostThreadFollowBtn.tsx:93 +#: src/view/com/post-thread/PostThreadFollowBtn.tsx:105 +#: src/view/com/profile/ProfileHeader.tsx:156 +#: src/view/com/profile/ProfileHeader.tsx:177 +#: src/view/com/profile/ProfileHeader.tsx:216 +#: src/view/com/profile/ProfileHeader.tsx:229 +#: src/view/com/profile/ProfileHeader.tsx:249 +#: src/view/com/profile/ProfileHeader.tsx:271 +msgid "There was an issue! {0}" +msgstr "Ilmeni ongelma! {0}" + +#: src/view/screens/ProfileList.tsx:287 +#: src/view/screens/ProfileList.tsx:306 +#: src/view/screens/ProfileList.tsx:328 +#: src/view/screens/ProfileList.tsx:347 +msgid "There was an issue. Please check your internet connection and try again." +msgstr "Ilmeni joku ongelma. Tarkista internet-yhteys ja yritä uudelleen." + +#: src/view/com/util/ErrorBoundary.tsx:36 +msgid "There was an unexpected issue in the application. Please let us know if this happened to you!" +msgstr "Sovelluksessa ilmeni odottamaton ongelma. Kerro meille, jos tämä tapahtui sinulle!" + +#: src/screens/Deactivated.tsx:106 +msgid "There's been a rush of new users to Bluesky! We'll activate your account as soon as we can." +msgstr "Blueskyyn on tullut paljon uusia käyttäjiä! Aktivoimme tilisi niin pian kuin mahdollista." + +#: src/view/com/auth/create/Step2.tsx:55 +#~ msgid "There's something wrong with this number. Please choose your country and enter your full phone number!" +#~ msgstr "Tässä numerossa on jotain vikaa. Valitse maasi ja syötä koko puhelinnumerosi!" + +#: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:138 +msgid "These are popular accounts you might like:" +msgstr "Nämä ovat suosittuja tilejä, joista saatat pitää:" + +#: src/view/com/util/moderation/ScreenHider.tsx:88 +msgid "This {screenDescription} has been flagged:" +msgstr "Tämä {screenDescription} on liputettu:" + +#: src/view/com/util/moderation/ScreenHider.tsx:83 +msgid "This account has requested that users sign in to view their profile." +msgstr "Tämä tili pyytää käyttäjiä kirjautumaan sisään nähdäkseen profiilinsa." + +#: src/view/com/modals/EmbedConsent.tsx:68 +msgid "This content is hosted by {0}. Do you want to enable external media?" +msgstr "Tämä sisältö on hostattu palvelussa {0}. Haluatko sallia ulkoisen median?" + +#: src/view/com/modals/ModerationDetails.tsx:67 +msgid "This content is not available because one of the users involved has blocked the other." +msgstr "Tämä sisältö ei ole saatavilla, koska toinen käyttäjistä on estänyt toisen." + +#: src/view/com/posts/FeedErrorMessage.tsx:108 +msgid "This content is not viewable without a Bluesky account." +msgstr "Tätä sisältöä ei voi katsoa ilman Bluesky-tiliä." + +#: src/view/screens/Settings/ExportCarDialog.tsx:75 +msgid "This feature is in beta. You can read more about repository exports in <0>this blogpost." +msgstr "Tämä ominaisuus on betavaiheessa. Voit lukea lisää pakettivarastojen vientitoiminnosta <0>tässä blogikirjoituksessa." + +#: src/view/com/posts/FeedErrorMessage.tsx:114 +msgid "This feed is currently receiving high traffic and is temporarily unavailable. Please try again later." +msgstr "Tämä syöte saa tällä hetkellä paljon liikennettä ja on tilapäisesti pois käytöstä. Yritä uudelleen myöhemmin." + +#: src/view/screens/Profile.tsx:420 +#: src/view/screens/ProfileFeed.tsx:475 +#: src/view/screens/ProfileList.tsx:660 +msgid "This feed is empty!" +msgstr "Tämä syöte on tyhjä!" + +#: src/view/com/posts/CustomFeedEmptyState.tsx:37 +msgid "This feed is empty! You may need to follow more users or tune your language settings." +msgstr "Tämä syöte on tyhjä! Sinun on ehkä seurattava useampia käyttäjiä tai säädettävä kieliasetuksiasi." + +#: src/view/com/modals/BirthDateSettings.tsx:61 +msgid "This information is not shared with other users." +msgstr "Tätä tietoa ei jaeta muiden käyttäjien kanssa." + +#: src/view/com/modals/VerifyEmail.tsx:119 +msgid "This is important in case you ever need to change your email or reset your password." +msgstr "Tämä on tärkeää, jos sinun tarvitsee vaihtaa sähköpostiosoitteesi tai palauttaa salasanasi." + +#: src/view/com/modals/LinkWarning.tsx:58 +msgid "This link is taking you to the following website:" +msgstr "Tämä linkki vie sinut tälle verkkosivustolle:" + +#: src/view/screens/ProfileList.tsx:834 +msgid "This list is empty!" +msgstr "Tämä lista on tyhjä!" + +#: src/view/com/modals/AddAppPasswords.tsx:106 +msgid "This name is already in use" +msgstr "Tämä nimi on jo käytössä" + +#: src/view/com/post-thread/PostThreadItem.tsx:122 +msgid "This post has been deleted." +msgstr "Tämä viesti on poistettu." + +#: src/view/com/modals/ModerationDetails.tsx:62 +msgid "This user has blocked you. You cannot view their content." +msgstr "Tämä käyttäjä on estänyt sinut. Et voi nähdä heidän sisältöään." + +#: src/view/com/modals/ModerationDetails.tsx:42 +msgid "This user is included in the <0/> list which you have blocked." +msgstr "Tämä käyttäjä on <0/>-listassa, jonka olet estänyt." + +#: src/view/com/modals/ModerationDetails.tsx:74 +msgid "This user is included in the <0/> list which you have muted." +msgstr "Tämä käyttäjä on <0/>-listassa, jonka olet hiljentänyt." + +#: src/view/com/modals/ModerationDetails.tsx:74 +#~ msgid "This user is included the <0/> list which you have muted." +#~ msgstr "" + +#: src/view/com/modals/SelfLabel.tsx:137 +msgid "This warning is only available for posts with media attached." +msgstr "Tämä varoitus on saatavilla vain viesteille, joihin on liitetty mediatiedosto." + +#: src/view/com/util/forms/PostDropdownBtn.tsx:192 +msgid "This will hide this post from your feeds." +msgstr "Tämä piilottaa tämän viestin syötteistäsi." + +#: src/view/screens/PreferencesThreads.tsx:53 +#: src/view/screens/Settings/index.tsx:565 +msgid "Thread Preferences" +msgstr "Keskusteluketjun asetukset" + +#: src/view/screens/PreferencesThreads.tsx:119 +msgid "Threaded Mode" +msgstr "Ketjumainen näkymä" + +#: src/Navigation.tsx:252 +msgid "Threads Preferences" +msgstr "Keskusteluketjujen asetukset" + +#: src/view/com/util/forms/DropdownButton.tsx:246 +msgid "Toggle dropdown" +msgstr "Vaihda pudotusvalikko" + +#: src/view/com/modals/EditImage.tsx:271 +msgid "Transformations" +msgstr "Muutokset" + +#: src/view/com/post-thread/PostThreadItem.tsx:682 +#: src/view/com/post-thread/PostThreadItem.tsx:684 +#: src/view/com/util/forms/PostDropdownBtn.tsx:125 +msgid "Translate" +msgstr "Käännä" + +#: src/view/com/util/error/ErrorScreen.tsx:82 +msgctxt "action" +msgid "Try again" +msgstr "Yritä uudelleen" + +#: src/view/screens/ProfileList.tsx:505 +msgid "Un-block list" +msgstr "Poista listan esto" + +#: src/view/screens/ProfileList.tsx:490 +msgid "Un-mute list" +msgstr "Poista listan hiljennys" + +#: src/view/com/auth/create/CreateAccount.tsx:58 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:87 +#: src/view/com/auth/login/Login.tsx:76 +#: src/view/com/auth/login/LoginForm.tsx:118 +#: src/view/com/modals/ChangePassword.tsx:70 +msgid "Unable to contact your service. Please check your Internet connection." +msgstr "Yhteys palveluusi ei onnistu. Tarkista internet-yhteytesi." + +#: src/view/com/profile/ProfileHeader.tsx:432 +#: src/view/screens/ProfileList.tsx:589 +msgid "Unblock" +msgstr "Poista esto" + +#: src/view/com/profile/ProfileHeader.tsx:435 +msgctxt "action" +msgid "Unblock" +msgstr "Poista esto" + +#: src/view/com/profile/ProfileHeader.tsx:260 +#: src/view/com/profile/ProfileHeader.tsx:344 +msgid "Unblock Account" +msgstr "Poista tilin esto" + +#: src/view/com/modals/Repost.tsx:42 +#: src/view/com/modals/Repost.tsx:55 +#: src/view/com/util/post-ctrls/RepostButton.tsx:60 +#: src/view/com/util/post-ctrls/RepostButton.web.tsx:48 +msgid "Undo repost" +msgstr "Kumoa uudelleenjako" + +#: src/view/com/profile/FollowButton.tsx:55 +msgctxt "action" +msgid "Unfollow" +msgstr "Lopeta seuraaminen" + +#: src/view/com/profile/ProfileHeader.tsx:484 +msgid "Unfollow {0}" +msgstr "Lopeta seuraaminen {0}" + +#: src/view/com/auth/create/state.ts:262 +msgid "Unfortunately, you do not meet the requirements to create an account." +msgstr "Valitettavasti et täytä tilin luomisen vaatimuksia." + +#: src/view/com/util/post-ctrls/PostCtrls.tsx:182 +#: src/view/com/util/post-ctrls/PostCtrls.tsx:216 +msgid "Unlike" +msgstr "En tykkää" + +#: src/view/screens/ProfileList.tsx:596 +msgid "Unmute" +msgstr "Poista hiljennys" + +#: src/view/com/profile/ProfileHeader.tsx:325 +msgid "Unmute Account" +msgstr "Poista tilin hiljennys" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:171 +msgid "Unmute thread" +msgstr "Poista keskusteluketjun hiljennys" + +#: src/view/screens/ProfileFeed.tsx:353 +#: src/view/screens/ProfileList.tsx:580 +msgid "Unpin" +msgstr "Poista kiinnitys" + +#: src/view/screens/ProfileList.tsx:473 +msgid "Unpin moderation list" +msgstr "Poista moderointilistan kiinnitys" + +#: src/view/screens/ProfileFeed.tsx:345 +msgid "Unsave" +msgstr "Poista tallennus" + +#: src/view/com/modals/UserAddRemoveLists.tsx:70 +msgid "Update {displayName} in Lists" +msgstr "Päivitä {displayName} listoissa" + +#: src/lib/hooks/useOTAUpdate.ts:15 +msgid "Update Available" +msgstr "Päivitys saatavilla" + +#: src/view/com/auth/login/SetNewPasswordForm.tsx:204 +msgid "Updating..." +msgstr "Päivitetään..." + +#: src/view/com/modals/ChangeHandle.tsx:455 +msgid "Upload a text file to:" +msgstr "Lataa tekstitiedosto kohteeseen:" + +#: src/view/screens/AppPasswords.tsx:195 +msgid "Use app passwords to login to other Bluesky clients without giving full access to your account or password." +msgstr "Käytä sovellussalasanoja kirjautuaksesi muihin Bluesky-sovelluksiin antamatta niille täyttä hallintaa tilillesi tai salasanallesi." + +#: src/view/com/modals/ChangeHandle.tsx:515 +msgid "Use default provider" +msgstr "Käytä oletustoimittajaa" + +#: src/view/com/modals/InAppBrowserConsent.tsx:56 +#: src/view/com/modals/InAppBrowserConsent.tsx:58 +msgid "Use in-app browser" +msgstr "Käytä sovelluksen sisäistä selainta" + +#: src/view/com/modals/InAppBrowserConsent.tsx:66 +#: src/view/com/modals/InAppBrowserConsent.tsx:68 +msgid "Use my default browser" +msgstr "Käytä oletusselaintani" + +#: src/view/com/modals/AddAppPasswords.tsx:155 +msgid "Use this to sign into the other app along with your handle." +msgstr "Käytä tätä kirjautuaksesi toiseen sovellukseen käyttäjätunnuksellasi." + +#: src/view/com/modals/ServerInput.tsx:105 +#~ msgid "Use your domain as your Bluesky client service provider" +#~ msgstr "" + +#: src/view/com/modals/InviteCodes.tsx:200 +msgid "Used by:" +msgstr "Käyttänyt:" + +#: src/view/com/modals/ModerationDetails.tsx:54 +msgid "User Blocked" +msgstr "Käyttäjä estetty" + +#: src/view/com/modals/ModerationDetails.tsx:40 +msgid "User Blocked by List" +msgstr "Käyttäjä estetty listan vuoksi" + +#: src/view/com/modals/ModerationDetails.tsx:60 +msgid "User Blocks You" +msgstr "Käyttäjä on estänyt sinut" + +#: src/view/com/auth/create/Step2.tsx:44 +msgid "User handle" +msgstr "Käyttäjätunnus" + +#: src/view/com/lists/ListCard.tsx:84 +#: src/view/com/modals/UserAddRemoveLists.tsx:198 +msgid "User list by {0}" +msgstr "Käyttäjälistan on tehnyt {0}" + +#: src/view/screens/ProfileList.tsx:762 +msgid "User list by <0/>" +msgstr "Käyttäjälistan on tehnyt <0/>" + +#: src/view/com/lists/ListCard.tsx:82 +#: src/view/com/modals/UserAddRemoveLists.tsx:196 +#: src/view/screens/ProfileList.tsx:760 +msgid "User list by you" +msgstr "Sinun käyttäjälistasi" + +#: src/view/com/modals/CreateOrEditList.tsx:196 +msgid "User list created" +msgstr "Käyttäjälista luotu" + +#: src/view/com/modals/CreateOrEditList.tsx:182 +msgid "User list updated" +msgstr "Käyttäjälista päivitetty" + +#: src/view/screens/Lists.tsx:58 +msgid "User Lists" +msgstr "Käyttäjälistat" + +#: src/view/com/auth/login/LoginForm.tsx:177 +#: src/view/com/auth/login/LoginForm.tsx:195 +msgid "Username or email address" +msgstr "Käyttäjätunnus tai sähköpostiosoite" + +#: src/view/screens/ProfileList.tsx:796 +msgid "Users" +msgstr "Käyttäjät" + +#: src/view/com/threadgate/WhoCanReply.tsx:143 +msgid "users followed by <0/>" +msgstr "käyttäjät, joita <0/> seuraa" + +#: src/view/com/modals/Threadgate.tsx:106 +msgid "Users in \"{0}\"" +msgstr "Käyttäjät ryhmässä \"{0}\"" + +#: src/view/com/auth/create/Step2.tsx:243 +#~ msgid "Verification code" +#~ msgstr "Varmistuskoodi" + +#: src/view/screens/Settings/index.tsx:910 +msgid "Verify email" +msgstr "Varmista sähköposti" + +#: src/view/screens/Settings/index.tsx:935 +msgid "Verify my email" +msgstr "Vahvista sähköpostini" + +#: src/view/screens/Settings/index.tsx:944 +msgid "Verify My Email" +msgstr "Vahvista sähköpostini" + +#: src/view/com/modals/ChangeEmail.tsx:205 +#: src/view/com/modals/ChangeEmail.tsx:207 +msgid "Verify New Email" +msgstr "Vahvista uusi sähköposti" + +#: src/view/com/modals/VerifyEmail.tsx:103 +msgid "Verify Your Email" +msgstr "Vahvista sähköpostisi" + +#: src/screens/Onboarding/index.tsx:42 +msgid "Video Games" +msgstr "Videopelit" + +#: src/view/com/profile/ProfileHeader.tsx:661 +msgid "View {0}'s avatar" +msgstr "Katso {0}:n avatar" + +#: src/view/screens/Log.tsx:52 +msgid "View debug entry" +msgstr "Katso vianmääritystietue" + +#: src/view/com/posts/FeedSlice.tsx:103 +msgid "View full thread" +msgstr "Katso koko keskusteluketju" + +#: src/view/com/posts/FeedErrorMessage.tsx:172 +msgid "View profile" +msgstr "Katso profiilia" + +#: src/view/com/profile/ProfileSubpageHeader.tsx:128 +msgid "View the avatar" +msgstr "Katso avatar" + +#: src/view/com/modals/LinkWarning.tsx:75 +msgid "Visit Site" +msgstr "Vieraile sivustolla" + +#: src/screens/Onboarding/StepModeration/ModerationOption.tsx:42 +#: src/view/com/modals/ContentFilteringSettings.tsx:259 +msgid "Warn" +msgstr "Varoita" + +#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:134 +msgid "We also think you'll like \"For You\" by Skygaze:" +msgstr "Uskomme myös, että pitäisit Skygazen \"For You\" -syötteestä:" + +#: src/screens/Deactivated.tsx:133 +msgid "We estimate {estimatedTime} until your account is ready." +msgstr "Arvioimme, että tilisi valmistumiseen on {estimatedTime} aikaa." + +#: src/screens/Onboarding/StepFinished.tsx:93 +msgid "We hope you have a wonderful time. Remember, Bluesky is:" +msgstr "Toivomme sinulle ihania hetkiä. Muista, että Bluesky on:" + +#: src/view/com/posts/DiscoverFallbackHeader.tsx:29 +msgid "We ran out of posts from your follows. Here's the latest from <0/>." +msgstr "Emme enää löytäneet viestejä seurattavilta. Tässä on uusin tekijältä <0/>." + +#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:118 +#~ msgid "We recommend \"For You\" by Skygaze:" +#~ msgstr "" + +#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 +msgid "We recommend our \"Discover\" feed:" +msgstr "Suosittelemme \"Tutustu\"-syötettämme:" + +#: src/screens/Onboarding/StepInterests/index.tsx:133 +msgid "We weren't able to connect. Please try again to continue setting up your account. If it continues to fail, you can skip this flow." +msgstr "Yhteyden muodostaminen ei onnistunut. Yritä uudelleen jatkaaksesi tilisi määritystä. Jos ongelma jatkuu, voit ohittaa tämän vaiheen." + +#: src/screens/Deactivated.tsx:137 +msgid "We will let you know when your account is ready." +msgstr "Ilmoitamme sinulle, kun tilisi on valmis." + +#: src/view/com/modals/AppealLabel.tsx:48 +msgid "We'll look into your appeal promptly." +msgstr "Käsittelemme vetoomuksesi pikaisesti." + +#: src/screens/Onboarding/StepInterests/index.tsx:138 +msgid "We'll use this to help customize your experience." +msgstr "Käytämme tätä mukauttaaksemme kokemustasi." + +#: src/view/com/auth/create/CreateAccount.tsx:130 +msgid "We're so excited to have you join us!" +msgstr "Olemme innoissamme, että liityt joukkoomme!" + +#: src/view/screens/ProfileList.tsx:85 +msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." +msgstr "Pahoittelemme, emme saaneet avattua tätä listaa. Jos ongelma jatkuu, ota yhteyttä listan tekijään: @{handleOrDid}." + +#: src/view/screens/Search/Search.tsx:253 +msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." +msgstr "Pahoittelemme, hakuasi ei voitu suorittaa loppuun. Yritä uudelleen muutaman minuutin kuluttua." + +#: src/view/screens/NotFound.tsx:48 +msgid "We're sorry! We can't find the page you were looking for." +msgstr "Pahoittelut! Emme löydä etsimääsi sivua." + +#: src/view/com/auth/onboarding/WelcomeMobile.tsx:46 +msgid "Welcome to <0>Bluesky" +msgstr "Tervetuloa <0>Bluesky:iin" + +#: src/screens/Onboarding/StepInterests/index.tsx:130 +msgid "What are your interests?" +msgstr "Mitkä ovat kiinnostuksenkohteesi?" + +#: src/view/com/modals/report/Modal.tsx:169 +msgid "What is the issue with this {collectionName}?" +msgstr "Mikä on ongelma tämän {collectionName} kanssa?" + +#: src/view/com/auth/SplashScreen.tsx:59 +#: src/view/com/composer/Composer.tsx:279 +msgid "What's up?" +msgstr "Mitä kuuluu?" + +#: src/view/com/modals/lang-settings/PostLanguagesSettings.tsx:78 +msgid "Which languages are used in this post?" +msgstr "Mitä kieliä tässä viestissä käytetään?" + +#: src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx:77 +msgid "Which languages would you like to see in your algorithmic feeds?" +msgstr "Mitä kieliä haluaisit nähdä algoritmisissä syötteissä?" + +#: src/view/com/composer/threadgate/ThreadgateBtn.tsx:47 +#: src/view/com/modals/Threadgate.tsx:66 +msgid "Who can reply" +msgstr "Kuka voi vastata" + +#: src/view/com/modals/crop-image/CropImage.web.tsx:102 +msgid "Wide" +msgstr "Laaja" + +#: src/view/com/composer/Composer.tsx:415 +msgid "Write post" +msgstr "Kirjoita viesti" + +#: src/view/com/composer/Composer.tsx:278 +#: src/view/com/composer/Prompt.tsx:33 +msgid "Write your reply" +msgstr "Kirjoita vastauksesi" + +#: src/screens/Onboarding/index.tsx:28 +msgid "Writers" +msgstr "Kirjoittajat" + +#: src/view/com/auth/create/Step2.tsx:263 +#~ msgid "XXXXXX" +#~ msgstr "XXXXXX" + +#: src/view/com/composer/select-language/SuggestedLanguage.tsx:77 +#: src/view/screens/PreferencesHomeFeed.tsx:129 +#: src/view/screens/PreferencesHomeFeed.tsx:201 +#: src/view/screens/PreferencesHomeFeed.tsx:236 +#: src/view/screens/PreferencesHomeFeed.tsx:271 +#: src/view/screens/PreferencesThreads.tsx:106 +#: src/view/screens/PreferencesThreads.tsx:129 +msgid "Yes" +msgstr "Kyllä" + +#: src/screens/Onboarding/StepModeration/index.tsx:46 +#~ msgid "You are in control" +#~ msgstr "" + +#: src/screens/Deactivated.tsx:130 +msgid "You are in line." +msgstr "Olet jonossa." + +#: src/view/com/posts/FollowingEmptyState.tsx:67 +#: src/view/com/posts/FollowingEndOfFeed.tsx:68 +msgid "You can also discover new Custom Feeds to follow." +msgstr "Voit myös selata uusia mukautettuja syötteitä seurattavaksi." + +#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:123 +#~ msgid "You can also try our \"Discover\" algorithm:" +#~ msgstr "" + +#: src/screens/Onboarding/StepFollowingFeed.tsx:142 +msgid "You can change these settings later." +msgstr "Voit muuttaa näitä asetuksia myöhemmin." + +#: src/view/com/auth/login/Login.tsx:158 +#: src/view/com/auth/login/PasswordUpdatedForm.tsx:31 +msgid "You can now sign in with your new password." +msgstr "Voit nyt kirjautua sisään uudella salasanallasi." + +#: src/view/com/modals/InviteCodes.tsx:66 +msgid "You don't have any invite codes yet! We'll send you some when you've been on Bluesky for a little longer." +msgstr "Sinulla ei ole vielä kutsukoodia! Lähetämme sinulle sellaisen, kun olet ollut Bluesky-palvelussa hieman pidempään." + +#: src/view/screens/SavedFeeds.tsx:102 +msgid "You don't have any pinned feeds." +msgstr "Sinulla ei ole kiinnitettyjä syötteitä." + +#: src/view/screens/Feeds.tsx:452 +msgid "You don't have any saved feeds!" +msgstr "Sinulla ei ole tallennettuja syötteitä!" + +#: src/view/screens/SavedFeeds.tsx:135 +msgid "You don't have any saved feeds." +msgstr "Sinulla ei ole tallennettuja syötteitä." + +#: src/view/com/post-thread/PostThread.tsx:464 +msgid "You have blocked the author or you have been blocked by the author." +msgstr "Olet estänyt tekijän tai sinut on estetty tekijän toimesta." + +#: src/view/com/modals/ModerationDetails.tsx:56 +msgid "You have blocked this user. You cannot view their content." +msgstr "Olet estänyt tämän käyttäjän. Et voi nähdä heidän sisältöään." + +#: src/view/com/auth/login/SetNewPasswordForm.tsx:57 +#: src/view/com/auth/login/SetNewPasswordForm.tsx:92 +#: src/view/com/modals/ChangePassword.tsx:87 +#: src/view/com/modals/ChangePassword.tsx:121 +msgid "You have entered an invalid code. It should look like XXXXX-XXXXX." +msgstr "Olet syöttänyt virheellisen koodin. Sen tulisi näyttää muodoltaan XXXXX-XXXXX." + +#: src/view/com/modals/ModerationDetails.tsx:87 +msgid "You have muted this user." +msgstr "Olet hiljentänyt tämän käyttäjän." + +#: src/view/com/feeds/ProfileFeedgens.tsx:136 +msgid "You have no feeds." +msgstr "Sinulla ei ole syötteitä." + +#: src/view/com/lists/MyLists.tsx:89 +#: src/view/com/lists/ProfileLists.tsx:140 +msgid "You have no lists." +msgstr "Sinulla ei ole listoja." + +#: src/view/screens/ModerationBlockedAccounts.tsx:132 +msgid "You have not blocked any accounts yet. To block an account, go to their profile and selected \"Block account\" from the menu on their account." +msgstr "Et ole vielä estänyt yhtään käyttäjää. Estääksesi käyttäjän, siirry heidän profiiliinsa ja valitse \"Estä käyttäjä\"-vaihtoehto heidän tilinsä valikosta." + +#: src/view/screens/AppPasswords.tsx:87 +msgid "You have not created any app passwords yet. You can create one by pressing the button below." +msgstr "Et ole vielä luonut yhtään sovelluksen salasanaa. Voit luoda sellaisen painamalla alla olevaa painiketta." + +#: src/view/screens/ModerationMutedAccounts.tsx:131 +msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." +msgstr "Et ole vielä hiljentänyt yhtään käyttäjää. Hiljentääksesi käyttäjän, siirry heidän profiiliinsa ja valitse \"Hiljennä käyttäjä\"-vaihtoehto heidän tilinsä valikosta." + +#: src/view/com/modals/ContentFilteringSettings.tsx:175 +msgid "You must be 18 or older to enable adult content." +msgstr "Sinun on oltava vähintään 18-vuotias katsoaksesi aikuissisältöä." + +#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:103 +msgid "You must be 18 years or older to enable adult content" +msgstr "Sinun on oltava vähintään 18-vuotias katsoaksesi aikuissisältöä" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:98 +msgid "You will no longer receive notifications for this thread" +msgstr "Et enää saa ilmoituksia tästä keskustelusta" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:101 +msgid "You will now receive notifications for this thread" +msgstr "Saat nyt ilmoituksia tästä keskustelusta" + +#: src/view/com/auth/login/SetNewPasswordForm.tsx:107 +msgid "You will receive an email with a \"reset code.\" Enter that code here, then enter your new password." +msgstr "Saat sähköpostin \"nollauskoodin\". Syötä koodi tähän ja syötä sitten uusi salasanasi." + +#: src/screens/Onboarding/StepModeration/index.tsx:72 +msgid "You're in control" +msgstr "Sinulla on ohjat" + +#: src/screens/Deactivated.tsx:87 +#: src/screens/Deactivated.tsx:88 +#: src/screens/Deactivated.tsx:103 +msgid "You're in line" +msgstr "Olet jonossa" + +#: src/screens/Onboarding/StepFinished.tsx:90 +msgid "You're ready to go!" +msgstr "Olet valmis aloittamaan!" + +#: src/view/com/posts/FollowingEndOfFeed.tsx:48 +msgid "You've reached the end of your feed! Find some more accounts to follow." +msgstr "Olet saavuttanut syötteesi lopun! Etsi lisää käyttäjiä seurattavaksi." + +#: src/view/com/auth/create/Step1.tsx:74 +msgid "Your account" +msgstr "Tilisi" + +#: src/view/com/modals/DeleteAccount.tsx:67 +msgid "Your account has been deleted" +msgstr "Tilisi on poistettu" + +#: src/view/screens/Settings/ExportCarDialog.tsx:47 +msgid "Your account repository, containing all public data records, can be downloaded as a \"CAR\" file. This file does not include media embeds, such as images, or your private data, which must be fetched separately." +msgstr "Tilisi arkisto, joka sisältää kaikki julkiset tietueet, voidaan ladata \"CAR\"-tiedostona. Tämä tiedosto ei sisällä upotettuja mediaelementtejä, kuten kuvia, tai yksityisiä tietojasi, jotka on haettava erikseen." + +#: src/view/com/auth/create/Step1.tsx:238 +msgid "Your birth date" +msgstr "Syntymäaikasi" + +#: src/view/com/modals/InAppBrowserConsent.tsx:47 +msgid "Your choice will be saved, but can be changed later in settings." +msgstr "Valintasi tallennetaan, mutta sitä voit muuttaa myöhemmin asetuksissa." + +#: src/screens/Onboarding/StepFollowingFeed.tsx:61 +msgid "Your default feed is \"Following\"" +msgstr "Oletussyötteesi on \"Following\"" + +#: src/view/com/auth/create/state.ts:110 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:70 +#: src/view/com/modals/ChangePassword.tsx:54 +msgid "Your email appears to be invalid." +msgstr "Sähköpostiosoitteesi näyttää olevan virheellinen." + +#: src/view/com/modals/Waitlist.tsx:109 +msgid "Your email has been saved! We'll be in touch soon." +msgstr "Sähköpostiosoitteesi on tallennettu! Olemme pian yhteydessä." + +#: src/view/com/modals/ChangeEmail.tsx:125 +msgid "Your email has been updated but not verified. As a next step, please verify your new email." +msgstr "Sähköpostiosoitteesi on päivitetty, mutta sitä ei ole vielä vahvistettu. Seuraavana vaiheena vahvista uusi sähköpostiosoitteesi." + +#: src/view/com/modals/VerifyEmail.tsx:114 +msgid "Your email has not yet been verified. This is an important security step which we recommend." +msgstr "Sähköpostiosoitettasi ei ole vielä vahvistettu. Tämä on tärkeä turvatoimi, jonka suosittelemme suorittamaan." + +#: src/view/com/posts/FollowingEmptyState.tsx:47 +msgid "Your following feed is empty! Follow more users to see what's happening." +msgstr "Seuraamiesi syöte on tyhjä! Seuraa lisää käyttäjiä nähdäksesi, mitä tapahtuu." + +#: src/view/com/auth/create/Step2.tsx:48 +msgid "Your full handle will be" +msgstr "Käyttäjätunnuksesi tulee olemaan" + +#: src/view/com/modals/ChangeHandle.tsx:270 +msgid "Your full handle will be <0>@{0}" +msgstr "Käyttäjätunnuksesi tulee olemaan <0>@{0}" + +#: src/view/screens/Settings.tsx:430 +#: src/view/shell/desktop/RightNav.tsx:137 +#: src/view/shell/Drawer.tsx:660 +#~ msgid "Your invite codes are hidden when logged in using an App Password" +#~ msgstr "" + +#: src/view/com/modals/ChangePassword.tsx:155 +msgid "Your password has been changed successfully!" +msgstr "Salasanasi on vaihdettu onnistuneesti!" + +#: src/view/com/composer/Composer.tsx:267 +msgid "Your post has been published" +msgstr "Viestisi on julkaistu" + +#: src/screens/Onboarding/StepFinished.tsx:105 +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:59 +#: src/view/com/auth/onboarding/WelcomeMobile.tsx:59 +msgid "Your posts, likes, and blocks are public. Mutes are private." +msgstr "Julkaisusi, tykkäyksesi ja estosi ovat julkisia. Hiljennykset ovat yksityisiä." + +#: src/view/com/modals/SwitchAccount.tsx:84 +#: src/view/screens/Settings/index.tsx:118 +msgid "Your profile" +msgstr "Profiilisi" + +#: src/view/com/composer/Composer.tsx:266 +msgid "Your reply has been published" +msgstr "Vastauksesi on julkaistu" + +#: src/view/com/auth/create/Step2.tsx:28 +msgid "Your user handle" +msgstr "Käyttäjätunnuksesi" From 123c73029d1c29cb0e9ab6c3c1f14fed4fc8d611 Mon Sep 17 00:00:00 2001 From: Jan-Olof Eriksson Date: Sun, 18 Feb 2024 23:21:22 +0200 Subject: [PATCH 027/109] Update messages.po Some fixes. --- src/locale/locales/fi/messages.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/locale/locales/fi/messages.po b/src/locale/locales/fi/messages.po index 06481beac5..63581587a4 100644 --- a/src/locale/locales/fi/messages.po +++ b/src/locale/locales/fi/messages.po @@ -1031,7 +1031,7 @@ msgstr "Poista käyttäjätili" #: src/view/com/modals/DeleteAccount.tsx:87 msgid "Delete Account" -msgstr "Poista tili" +msgstr "Poista käyttäjätili" #: src/view/screens/AppPasswords.tsx:222 #: src/view/screens/AppPasswords.tsx:242 @@ -1045,7 +1045,7 @@ msgstr "Poista lista" #: src/view/com/modals/DeleteAccount.tsx:223 msgid "Delete my account" -msgstr "Poista tilini" +msgstr "Poista käyttäjätilini" #: src/view/screens/Settings.tsx:706 #~ msgid "Delete my account…" @@ -1793,7 +1793,7 @@ msgstr "Koti" #: src/view/screens/PreferencesHomeFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 msgid "Home Feed Preferences" -msgstr "Aloitussivun Syötteiden Asetukset" +msgstr "Aloitussivun syötteiden asetukset" #: src/view/com/auth/create/Step1.tsx:82 #: src/view/com/auth/login/ForgotPasswordForm.tsx:120 @@ -2836,7 +2836,7 @@ msgstr "Lähetä" #: src/view/com/post-thread/PostThread.tsx:303 msgctxt "description" msgid "Post" -msgstr "Lähetä" +msgstr "Viesti" #: src/view/com/post-thread/PostThreadItem.tsx:172 msgid "Post by {0}" From 91a4e0687895e887bb2436c5094d3ae8e5891023 Mon Sep 17 00:00:00 2001 From: Jan-Olof Eriksson Date: Sun, 18 Feb 2024 23:41:58 +0200 Subject: [PATCH 028/109] Update messages.po MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Minor changes. (Handle=käyttäjätunnus) --- src/locale/locales/fi/messages.po | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/locale/locales/fi/messages.po b/src/locale/locales/fi/messages.po index 63581587a4..f550462b3b 100644 --- a/src/locale/locales/fi/messages.po +++ b/src/locale/locales/fi/messages.po @@ -65,7 +65,7 @@ msgstr "<0>Tervetuloa<1>Blueskyhin" #: src/view/com/profile/ProfileHeader.tsx:557 msgid "⚠Invalid Handle" -msgstr "⚠Virheellinen käyttäjänimi" +msgstr "⚠Virheellinen käyttäjätunnus" #: src/view/com/util/moderation/LabelInfo.tsx:45 msgid "A content warning has been applied to this {0}." @@ -586,12 +586,12 @@ msgstr "Vaihda" #: src/view/screens/Settings/index.tsx:696 msgid "Change handle" -msgstr "Vaihda käyttäjänimi" +msgstr "Vaihda käyttäjätunnus" #: src/view/com/modals/ChangeHandle.tsx:161 #: src/view/screens/Settings/index.tsx:705 msgid "Change Handle" -msgstr "Vaihda käyttäjänimi" +msgstr "Vaihda käyttäjätunnus" #: src/view/com/modals/VerifyEmail.tsx:147 msgid "Change my email" @@ -640,7 +640,7 @@ msgstr "Valitse \"Kaikki\" tai \"Ei kukaan\"" #: src/view/screens/Settings/index.tsx:697 msgid "Choose a new Bluesky username or create" -msgstr "Valitse uusi Bluesky-käyttäjänimi tai luo" +msgstr "Valitse uusi Bluesky-käyttäjätunnus tai luo" #: src/view/com/auth/server-input/index.tsx:79 msgid "Choose Service" @@ -1374,7 +1374,7 @@ msgstr "Syötä puhelinnumerosi" #: src/view/com/auth/login/Login.tsx:99 msgid "Enter your username and password" -msgstr "Syötä käyttäjänimesi ja salasanasi" +msgstr "Syötä käyttäjätunnuksesi ja salasanasi" #: src/view/com/auth/create/Step3.tsx:67 msgid "Error receiving captcha response." @@ -1390,7 +1390,7 @@ msgstr "Kaikki" #: src/view/com/modals/ChangeHandle.tsx:150 msgid "Exits handle change process" -msgstr "Peruuta käyttäjänimen vaihtaminen" +msgstr "Peruuta käyttäjätunnuksen vaihtaminen" #: src/view/com/lightbox/Lightbox.web.tsx:120 msgid "Exits image view" @@ -2759,7 +2759,7 @@ msgstr "Toistaa GIFin" #: src/view/com/auth/create/state.ts:124 msgid "Please choose your handle." -msgstr "Valitse käyttäjänimesi." +msgstr "Valitse käyttäjätunnuksesi." #: src/view/com/auth/create/state.ts:117 msgid "Please choose your password." @@ -3668,7 +3668,7 @@ msgstr "Kirjautunut sisään nimellä" #: src/view/com/auth/login/ChooseAccountForm.tsx:103 msgid "Signed in as @{0}" -msgstr "Kirjautunut sisään käyttäjänimellä @{0}" +msgstr "Kirjautunut sisään käyttäjätunnuksella @{0}" #: src/view/com/modals/SwitchAccount.tsx:66 msgid "Signs {0} out of Bluesky" @@ -3832,7 +3832,7 @@ msgstr "Tekstikenttä" #: src/view/com/auth/create/CreateAccount.tsx:90 msgid "That handle is already taken." -msgstr "Tuo käyttäjänimi on jo käytössä." +msgstr "Tuo käyttätunnus on jo käytössä." #: src/view/com/profile/ProfileHeader.tsx:262 msgid "The account will be able to interact with you after unblocking." From 79921b65f8087b08ef5a541139c7c0c3c3c524aa Mon Sep 17 00:00:00 2001 From: Jan-Olof Eriksson Date: Sun, 18 Feb 2024 23:47:34 +0200 Subject: [PATCH 029/109] Update messages.po --- src/locale/locales/fi/messages.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/locale/locales/fi/messages.po b/src/locale/locales/fi/messages.po index f550462b3b..05df94f8d0 100644 --- a/src/locale/locales/fi/messages.po +++ b/src/locale/locales/fi/messages.po @@ -556,7 +556,7 @@ msgstr "Peruuta tilin poisto" #: src/view/com/modals/ChangeHandle.tsx:149 msgid "Cancel change handle" -msgstr "Peruuta käyttäjänimen vaihto" +msgstr "Peruuta käyttäjätunnuksen vaihto" #: src/view/com/modals/crop-image/CropImage.web.tsx:134 msgid "Cancel image crop" @@ -1390,7 +1390,7 @@ msgstr "Kaikki" #: src/view/com/modals/ChangeHandle.tsx:150 msgid "Exits handle change process" -msgstr "Peruuta käyttäjätunnuksen vaihtaminen" +msgstr "Peruuttaa käyttäjätunnuksen vaihtamisen" #: src/view/com/lightbox/Lightbox.web.tsx:120 msgid "Exits image view" @@ -1403,7 +1403,7 @@ msgstr "Poistuu hakukyselyn kirjoittamisesta" #: src/view/com/modals/Waitlist.tsx:138 msgid "Exits signing up for waitlist with {email}" -msgstr "Poistu odotuslistalle liittymisestä sähköpostilla {email}" +msgstr "Poistuu odotuslistalle liittymisestä sähköpostilla {email}" #: src/view/com/lightbox/Lightbox.web.tsx:163 msgid "Expand alt text" From c97d971f098029750f43c824d6517abf7f09afc5 Mon Sep 17 00:00:00 2001 From: Jan-Olof Eriksson Date: Mon, 19 Feb 2024 00:12:13 +0200 Subject: [PATCH 030/109] Update messages.po --- src/locale/locales/fi/messages.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locale/locales/fi/messages.po b/src/locale/locales/fi/messages.po index 05df94f8d0..be89f18f56 100644 --- a/src/locale/locales/fi/messages.po +++ b/src/locale/locales/fi/messages.po @@ -109,7 +109,7 @@ msgstr "Tili on hiljennetty" #: src/view/com/modals/ModerationDetails.tsx:72 msgid "Account Muted by List" -msgstr "Tili on hiljennetty listan toimesta" +msgstr "Tili on hiljennetty listalla" #: src/view/com/util/AccountDropdownBtn.tsx:41 msgid "Account options" @@ -4409,7 +4409,7 @@ msgstr "Kuka voi vastata" #: src/view/com/modals/crop-image/CropImage.web.tsx:102 msgid "Wide" -msgstr "Laaja" +msgstr "Leveä" #: src/view/com/composer/Composer.tsx:415 msgid "Write post" From 93318bef05d93e81a93dc315e03b5999e02c1a91 Mon Sep 17 00:00:00 2001 From: Jan-Olof Eriksson Date: Mon, 19 Feb 2024 07:20:57 +0200 Subject: [PATCH 031/109] Update languages.ts Added Finnish - Suomi --- src/locale/languages.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/locale/languages.ts b/src/locale/languages.ts index 3fdabd02ec..4f9d74e9ea 100644 --- a/src/locale/languages.ts +++ b/src/locale/languages.ts @@ -8,6 +8,7 @@ export enum AppLanguage { en = 'en', de = 'de', es = 'es', + fi = 'fi', fr = 'fr', hi = 'hi', id = 'id', @@ -29,6 +30,7 @@ export const APP_LANGUAGES: AppLanguageConfig[] = [ {code2: AppLanguage.en, name: 'English'}, {code2: AppLanguage.de, name: 'Deutsch – German'}, {code2: AppLanguage.es, name: 'Español – Spanish'}, + {code2: AppLanguage.fi, name: 'Finnish - Suomi'}, {code2: AppLanguage.fr, name: 'Français – French'}, {code2: AppLanguage.hi, name: 'हिंदी – Hindi'}, {code2: AppLanguage.id, name: 'Bahasa Indonesia – Indonesian'}, From 003e18b94d4a9b76bc4f5746b480ef4d4aead754 Mon Sep 17 00:00:00 2001 From: Jan-Olof Eriksson Date: Mon, 19 Feb 2024 07:33:17 +0200 Subject: [PATCH 032/109] Update languages.ts Suomi - Finnish --- src/locale/languages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locale/languages.ts b/src/locale/languages.ts index 4f9d74e9ea..3a104b7173 100644 --- a/src/locale/languages.ts +++ b/src/locale/languages.ts @@ -30,7 +30,7 @@ export const APP_LANGUAGES: AppLanguageConfig[] = [ {code2: AppLanguage.en, name: 'English'}, {code2: AppLanguage.de, name: 'Deutsch – German'}, {code2: AppLanguage.es, name: 'Español – Spanish'}, - {code2: AppLanguage.fi, name: 'Finnish - Suomi'}, + {code2: AppLanguage.fi, name: 'Suomi - Finnish'}, {code2: AppLanguage.fr, name: 'Français – French'}, {code2: AppLanguage.hi, name: 'हिंदी – Hindi'}, {code2: AppLanguage.id, name: 'Bahasa Indonesia – Indonesian'}, From 76a5e3af716d33e31e76aff0c35ca480a7965a97 Mon Sep 17 00:00:00 2001 From: Jan-Olof Eriksson Date: Mon, 19 Feb 2024 07:39:46 +0200 Subject: [PATCH 033/109] Update helpers.ts Added Finnish --- src/locale/helpers.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/locale/helpers.ts b/src/locale/helpers.ts index c73242e707..d07b95d93e 100644 --- a/src/locale/helpers.ts +++ b/src/locale/helpers.ts @@ -122,6 +122,8 @@ export function sanitizeAppLanguageSetting(appLanguage: string): AppLanguage { return AppLanguage.de case 'es': return AppLanguage.es + case 'fi': + return AppLanguage.fi case 'fr': return AppLanguage.fr case 'hi': From 1cfa4aabbdc15d77950908daf9630ecf5c9f15c1 Mon Sep 17 00:00:00 2001 From: Jan-Olof Eriksson Date: Mon, 19 Feb 2024 07:42:07 +0200 Subject: [PATCH 034/109] Update i18n.ts Added Finnish --- src/locale/i18n.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/locale/i18n.ts b/src/locale/i18n.ts index e8addb0b4f..40c9da172f 100644 --- a/src/locale/i18n.ts +++ b/src/locale/i18n.ts @@ -6,6 +6,7 @@ import {messages as messagesEn} from '#/locale/locales/en/messages' import {messages as messagesDe} from '#/locale/locales/de/messages' import {messages as messagesId} from '#/locale/locales/id/messages' import {messages as messagesEs} from '#/locale/locales/es/messages' +import {messages as messagesEs} from '#/locale/locales/fi/messages' import {messages as messagesFr} from '#/locale/locales/fr/messages' import {messages as messagesHi} from '#/locale/locales/hi/messages' import {messages as messagesJa} from '#/locale/locales/ja/messages' @@ -32,6 +33,10 @@ export async function dynamicActivate(locale: AppLanguage) { i18n.loadAndActivate({locale, messages: messagesEs}) break } + case AppLanguage.fi: { + i18n.loadAndActivate({locale, messages: messagesFi}) + break + } case AppLanguage.fr: { i18n.loadAndActivate({locale, messages: messagesFr}) break From f78e4c2433da1c36e2e373daf4316946d1b69510 Mon Sep 17 00:00:00 2001 From: Jan-Olof Eriksson Date: Mon, 19 Feb 2024 07:43:24 +0200 Subject: [PATCH 035/109] Update i18n.web.ts Added Finnish --- src/locale/i18n.web.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/locale/i18n.web.ts b/src/locale/i18n.web.ts index d8e51723ff..1c5112f067 100644 --- a/src/locale/i18n.web.ts +++ b/src/locale/i18n.web.ts @@ -19,6 +19,10 @@ export async function dynamicActivate(locale: AppLanguage) { case AppLanguage.es: { mod = await import(`./locales/es/messages`) break + } + case AppLanguage.fi: { + mod = await import(`./locales/fi/messages`) + break } case AppLanguage.fr: { mod = await import(`./locales/fr/messages`) From f78b55a2357e46879109235f2e59cccede608b25 Mon Sep 17 00:00:00 2001 From: Jan-Olof Eriksson Date: Mon, 19 Feb 2024 08:07:18 +0200 Subject: [PATCH 036/109] Update languages.ts Typo --- src/locale/languages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locale/languages.ts b/src/locale/languages.ts index 3a104b7173..1cbe8fa830 100644 --- a/src/locale/languages.ts +++ b/src/locale/languages.ts @@ -30,7 +30,7 @@ export const APP_LANGUAGES: AppLanguageConfig[] = [ {code2: AppLanguage.en, name: 'English'}, {code2: AppLanguage.de, name: 'Deutsch – German'}, {code2: AppLanguage.es, name: 'Español – Spanish'}, - {code2: AppLanguage.fi, name: 'Suomi - Finnish'}, + {code2: AppLanguage.fi, name: 'Suomi – Finnish'}, {code2: AppLanguage.fr, name: 'Français – French'}, {code2: AppLanguage.hi, name: 'हिंदी – Hindi'}, {code2: AppLanguage.id, name: 'Bahasa Indonesia – Indonesian'}, From a612aa276c3a4ab55bc84b598a966a7c90a651ef Mon Sep 17 00:00:00 2001 From: Jan-Olof Eriksson Date: Mon, 19 Feb 2024 08:09:49 +0200 Subject: [PATCH 037/109] Update i18n.ts Fixed typo in line 9 --- src/locale/i18n.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locale/i18n.ts b/src/locale/i18n.ts index 40c9da172f..045fa0addb 100644 --- a/src/locale/i18n.ts +++ b/src/locale/i18n.ts @@ -6,7 +6,7 @@ import {messages as messagesEn} from '#/locale/locales/en/messages' import {messages as messagesDe} from '#/locale/locales/de/messages' import {messages as messagesId} from '#/locale/locales/id/messages' import {messages as messagesEs} from '#/locale/locales/es/messages' -import {messages as messagesEs} from '#/locale/locales/fi/messages' +import {messages as messagesFi} from '#/locale/locales/fi/messages' import {messages as messagesFr} from '#/locale/locales/fr/messages' import {messages as messagesHi} from '#/locale/locales/hi/messages' import {messages as messagesJa} from '#/locale/locales/ja/messages' From 1269e76071ea7c79b93d1a58e80b74746c71ecd9 Mon Sep 17 00:00:00 2001 From: Jan-Olof Eriksson Date: Mon, 19 Feb 2024 08:33:20 +0200 Subject: [PATCH 038/109] Update Finnish to lingui.config.js Added Finnish localization --- lingui.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lingui.config.js b/lingui.config.js index 3916df5e62..6da69e98ed 100644 --- a/lingui.config.js +++ b/lingui.config.js @@ -4,6 +4,7 @@ module.exports = { 'en', 'de', 'es', + 'fi', 'fr', 'hi', 'id', From 25d7e2449fcb7f23ae636a2d4e00a2191a00ceab Mon Sep 17 00:00:00 2001 From: Minseo Lee Date: Sat, 24 Feb 2024 18:23:14 +0900 Subject: [PATCH 039/109] Update NotFound.tsx --- src/view/screens/NotFound.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/screens/NotFound.tsx b/src/view/screens/NotFound.tsx index dfa840abbc..bdf55b895a 100644 --- a/src/view/screens/NotFound.tsx +++ b/src/view/screens/NotFound.tsx @@ -51,7 +51,7 @@ export const NotFoundScreen = () => {
@@ -144,6 +146,7 @@ export function ListMaybePlaceholder({ const navigation = useNavigation() const t = useTheme() const {gtMobile} = useBreakpoints() + const {_} = useLingui() const canGoBack = navigation.canGoBack() const onGoBack = React.useCallback(() => { @@ -218,7 +221,7 @@ export function ListMaybePlaceholder({ )}
From 4022598692610f5a69acd0664ebbdcd03084d8ea Mon Sep 17 00:00:00 2001 From: Gabriella <152436322+Titianbeetle@users.noreply.github.com> Date: Sun, 3 Mar 2024 12:47:39 +0100 Subject: [PATCH 051/109] Update messages.po Updated two expression --- src/locale/locales/it/messages.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locale/locales/it/messages.po b/src/locale/locales/it/messages.po index 1c4431ad62..39f6653c73 100644 --- a/src/locale/locales/it/messages.po +++ b/src/locale/locales/it/messages.po @@ -2041,7 +2041,7 @@ msgstr "Log" #: src/screens/Deactivated.tsx:149 src/screens/Deactivated.tsx:152 #: src/screens/Deactivated.tsx:178 src/screens/Deactivated.tsx:181 msgid "Log out" -msgstr "Disconnettiti dall'account" +msgstr "Disconnetta l'account" #: src/view/screens/Moderation.tsx:136 msgid "Logged-out visibility" @@ -3473,7 +3473,7 @@ msgstr "Accedere a" #: src/view/screens/Settings/index.tsx:100 #: src/view/screens/Settings/index.tsx:103 msgid "Sign out" -msgstr "Disconnettiti" +msgstr "Disconnetta" #: src/view/shell/bottom-bar/BottomBar.tsx:275 #: src/view/shell/bottom-bar/BottomBar.tsx:276 From e8bc44e166e3d9765862147f9b67623612a9e164 Mon Sep 17 00:00:00 2001 From: Jan-Olof Eriksson Date: Mon, 4 Mar 2024 19:02:48 +0200 Subject: [PATCH 052/109] Update messages.po Updated new strings --- src/locale/locales/en/messages.po | 2113 ++++++++++++++--------------- 1 file changed, 1056 insertions(+), 1057 deletions(-) diff --git a/src/locale/locales/en/messages.po b/src/locale/locales/en/messages.po index cc40e1f0ef..f5b40f4214 100644 --- a/src/locale/locales/en/messages.po +++ b/src/locale/locales/en/messages.po @@ -5,17 +5,17 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: @lingui/cli\n" -"Language: en\n" +"Language: fi\n" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: \n" -"Last-Translator: \n" -"Language-Team: \n" +"Last-Translator:@jaoler.fi\n" +"Language-Team: @pekka.bsky.social,@jaoler.fi,@rahi.bsky.social\n" "Plural-Forms: \n" #: src/view/com/modals/VerifyEmail.tsx:142 msgid "(no email)" -msgstr "" +msgstr "(ei sähköpostiosoitetta)" #: src/view/shell/desktop/RightNav.tsx:168 #~ msgid "{0, plural, one {# invite code available} other {# invite codes available}}" @@ -23,7 +23,7 @@ msgstr "" #: src/view/com/profile/ProfileHeader.tsx:593 msgid "{following} following" -msgstr "" +msgstr "{following} seuraajaa" #: src/view/shell/desktop/RightNav.tsx:151 #~ msgid "{invitesAvailable, plural, one {Invite codes: # available} other {Invite codes: # available}}" @@ -41,91 +41,91 @@ msgstr "" #: src/view/shell/Drawer.tsx:440 msgid "{numUnreadNotifications} unread" -msgstr "" +msgstr "{numUnreadNotifications} lukematonta" #: src/view/com/threadgate/WhoCanReply.tsx:158 msgid "<0/> members" -msgstr "" +msgstr "<0/> jäsentä" #: src/view/com/profile/ProfileHeader.tsx:595 msgid "<0>{following} <1>following" -msgstr "" +msgstr "<0>{following} <1>seuraajaa" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:30 msgid "<0>Choose your<1>Recommended<2>Feeds" -msgstr "" +msgstr "<0>Valitse<1>Suositellut<2>syötteet" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:37 msgid "<0>Follow some<1>Recommended<2>Users" -msgstr "" +msgstr "<0>Seuraa joitakin<1>suositeltuja<2>käyttäjiä" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:21 msgid "<0>Welcome to<1>Bluesky" -msgstr "" +msgstr "<0>Tervetuloa<1>Blueskyhin" #: src/view/com/profile/ProfileHeader.tsx:558 msgid "⚠Invalid Handle" -msgstr "" +msgstr "⚠Virheellinen käyttäjätunnus" #: src/view/com/util/moderation/LabelInfo.tsx:45 msgid "A content warning has been applied to this {0}." -msgstr "" +msgstr "Tämä {0} sisältää sisältövaroituksen." #: src/lib/hooks/useOTAUpdate.ts:16 msgid "A new version of the app is available. Please update to continue using the app." -msgstr "" +msgstr "Sovelluksen uusi versio on saatavilla. Päivitä jatkaaksesi sovelluksen käyttöä." #: src/view/com/util/ViewHeader.tsx:83 #: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" -msgstr "" +msgstr "Siirry navigointilinkkeihin ja asetuksiin" #: src/view/com/home/HomeHeaderLayoutMobile.tsx:51 msgid "Access profile and other navigation links" -msgstr "" +msgstr "Siirry profiiliin ja muihin navigointilinkkeihin" #: src/view/com/modals/EditImage.tsx:299 #: src/view/screens/Settings/index.tsx:451 msgid "Accessibility" -msgstr "" +msgstr "Saavutettavuus" #: src/view/com/auth/login/LoginForm.tsx:166 #: src/view/screens/Settings/index.tsx:308 #: src/view/screens/Settings/index.tsx:721 msgid "Account" -msgstr "" +msgstr "Tili" #: src/view/com/profile/ProfileHeader.tsx:246 msgid "Account blocked" -msgstr "" +msgstr "Tili on estetty" #: src/view/com/profile/ProfileHeader.tsx:213 msgid "Account muted" -msgstr "" +msgstr "Tili on hiljennetty" #: src/view/com/modals/ModerationDetails.tsx:86 msgid "Account Muted" -msgstr "" +msgstr "Tili on hiljennetty" #: src/view/com/modals/ModerationDetails.tsx:72 msgid "Account Muted by List" -msgstr "" +msgstr "Tili on hiljennetty listalla" #: src/view/com/util/AccountDropdownBtn.tsx:41 msgid "Account options" -msgstr "" +msgstr "Tilin asetukset" #: src/view/com/util/AccountDropdownBtn.tsx:25 msgid "Account removed from quick access" -msgstr "" +msgstr "Tili poistettu pikalinkeistä" #: src/view/com/profile/ProfileHeader.tsx:268 msgid "Account unblocked" -msgstr "" +msgstr "Tilin esto poistettu" #: src/view/com/profile/ProfileHeader.tsx:226 msgid "Account unmuted" -msgstr "" +msgstr "Tilin hiljennys poistettu" #: src/components/dialogs/MutedWords.tsx:147 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 @@ -133,95 +133,95 @@ msgstr "" #: src/view/com/modals/UserAddRemoveLists.tsx:219 #: src/view/screens/ProfileList.tsx:812 msgid "Add" -msgstr "" +msgstr "Lisää" #: src/view/com/modals/SelfLabel.tsx:56 msgid "Add a content warning" -msgstr "" +msgstr "Lisää sisältövaroitus" #: src/view/screens/ProfileList.tsx:802 msgid "Add a user to this list" -msgstr "" +msgstr "Lisää käyttäjä tähän listaan" #: src/view/screens/Settings/index.tsx:383 #: src/view/screens/Settings/index.tsx:392 msgid "Add account" -msgstr "" +msgstr "Lisää tili" #: src/view/com/composer/photos/Gallery.tsx:119 #: src/view/com/composer/photos/Gallery.tsx:180 #: src/view/com/modals/AltImage.tsx:116 msgid "Add alt text" -msgstr "" +msgstr "Lisää ALT-teksti" #: src/view/screens/AppPasswords.tsx:102 #: src/view/screens/AppPasswords.tsx:143 #: src/view/screens/AppPasswords.tsx:156 msgid "Add App Password" -msgstr "" +msgstr "Lisää sovelluksen salasana" #: src/view/com/modals/report/InputIssueDetails.tsx:41 #: src/view/com/modals/report/Modal.tsx:191 msgid "Add details" -msgstr "" +msgstr "Lisää tiedot" #: src/view/com/modals/report/Modal.tsx:194 msgid "Add details to report" -msgstr "" +msgstr "Lisää tiedot raporttiin" #: src/view/com/composer/Composer.tsx:453 msgid "Add link card" -msgstr "" +msgstr "Lisää linkkikortti" #: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" -msgstr "" +msgstr "Lisää linkkikortti:" #: src/components/dialogs/MutedWords.tsx:140 msgid "Add mute word for configured settings" -msgstr "" +msgstr "Lisää hiljennetty sana määritettyihin asetuksiin" #: src/components/dialogs/MutedWords.tsx:74 msgid "Add muted words and tags" -msgstr "" +msgstr "Lisää hiljennetyt sanat ja tunnisteet" #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" -msgstr "" +msgstr "Lisää seuraava DNS-merkintä verkkotunnukseesi:" #: src/view/com/profile/ProfileHeader.tsx:310 msgid "Add to Lists" -msgstr "" +msgstr "Lisää listoihin" #: src/view/com/feeds/FeedSourceCard.tsx:245 #: src/view/screens/ProfileFeed.tsx:273 msgid "Add to my feeds" -msgstr "" +msgstr "Lisää syötteisiini" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:139 msgid "Added" -msgstr "" +msgstr "Lisätty" #: src/view/com/modals/ListAddRemoveUsers.tsx:191 #: src/view/com/modals/UserAddRemoveLists.tsx:144 msgid "Added to list" -msgstr "" +msgstr "Lisätty listaan" #: src/view/com/feeds/FeedSourceCard.tsx:127 msgid "Added to my feeds" -msgstr "" +msgstr "Lisätty syötteisiini" #: src/view/screens/PreferencesFollowingFeed.tsx:173 msgid "Adjust the number of likes a reply must have to be shown in your feed." -msgstr "" +msgstr "Säädä, kuinka monta tykkäystä vastauksen on saatava näkyäkseen syötteessäsi." #: src/view/com/modals/SelfLabel.tsx:75 msgid "Adult Content" -msgstr "" +msgstr "Aikuissisältöä" #: src/view/com/modals/ContentFilteringSettings.tsx:141 msgid "Adult content can only be enabled via the Web at <0/>." -msgstr "" +msgstr "Aikuissisältö voidaan ottaa käyttöön vain verkon kautta osoitteessa <0/>." #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:78 #~ msgid "Adult content can only be enabled via the Web at <0>bsky.app." @@ -229,74 +229,74 @@ msgstr "" #: src/view/screens/Settings/index.tsx:664 msgid "Advanced" -msgstr "" +msgstr "Edistynyt" #: src/view/screens/Feeds.tsx:666 msgid "All the feeds you've saved, right in one place." -msgstr "" +msgstr "Kaikki tallentamasi syötteet yhdessä paikassa." #: src/view/com/auth/login/ForgotPasswordForm.tsx:221 #: src/view/com/modals/ChangePassword.tsx:168 msgid "Already have a code?" -msgstr "" +msgstr "Onko sinulla jo koodi?" #: src/view/com/auth/login/ChooseAccountForm.tsx:98 msgid "Already signed in as @{0}" -msgstr "" +msgstr "Kirjautuneena sisään nimellä @{0}" #: src/view/com/composer/photos/Gallery.tsx:130 msgid "ALT" -msgstr "" +msgstr "ALT" #: src/view/com/modals/EditImage.tsx:315 msgid "Alt text" -msgstr "" +msgstr "ALT-teksti" #: src/view/com/composer/photos/Gallery.tsx:209 msgid "Alt text describes images for blind and low-vision users, and helps give context to everyone." -msgstr "" +msgstr "ALT-teksti kuvailee kuvia sokeille ja heikkonäköisille käyttäjille sekä lisää kontekstia kaikille." #: src/view/com/modals/VerifyEmail.tsx:124 msgid "An email has been sent to {0}. It includes a confirmation code which you can enter below." -msgstr "" +msgstr "Sähköposti on lähetetty osoitteeseen {0}. Siinä on vahvistuskoodi, jonka voit syöttää alla." #: src/view/com/modals/ChangeEmail.tsx:119 msgid "An email has been sent to your previous address, {0}. It includes a confirmation code which you can enter below." -msgstr "" +msgstr "Sähköposti on lähetetty aiempaan osoitteeseesi, {0}. Siinä on vahvistuskoodi, jonka voit syöttää alla." #: src/view/com/profile/FollowButton.tsx:30 #: src/view/com/profile/FollowButton.tsx:40 msgid "An issue occurred, please try again." -msgstr "" +msgstr "Tapahtui virhe, yritä uudelleen." #: src/view/com/notifications/FeedItem.tsx:236 #: src/view/com/threadgate/WhoCanReply.tsx:178 msgid "and" -msgstr "" +msgstr "ja" #: src/screens/Onboarding/index.tsx:32 msgid "Animals" -msgstr "" +msgstr "Eläimet" #: src/view/screens/LanguageSettings.tsx:95 msgid "App Language" -msgstr "" +msgstr "Sovelluksen kieli" #: src/view/screens/AppPasswords.tsx:228 msgid "App password deleted" -msgstr "" +msgstr "Sovelluksen salasana poistettu" #: src/view/com/modals/AddAppPasswords.tsx:134 msgid "App Password names can only contain letters, numbers, spaces, dashes, and underscores." -msgstr "" +msgstr "Sovelluksen salasanan nimet voivat sisältää vain kirjaimia, numeroita, välilyöntejä, viivoja ja alaviivoja." #: src/view/com/modals/AddAppPasswords.tsx:99 msgid "App Password names must be at least 4 characters long." -msgstr "" +msgstr "Sovelluksen salasanojen nimien on oltava vähintään 4 merkkiä pitkiä." #: src/view/screens/Settings/index.tsx:675 msgid "App password settings" -msgstr "" +msgstr "Sovelluksen salasanan asetukset" #: src/view/screens/Settings.tsx:650 #~ msgid "App passwords" @@ -306,56 +306,56 @@ msgstr "" #: src/view/screens/AppPasswords.tsx:187 #: src/view/screens/Settings/index.tsx:684 msgid "App Passwords" -msgstr "" +msgstr "Sovellussalasanat" #: src/view/com/util/forms/PostDropdownBtn.tsx:295 msgid "Appeal content warning" -msgstr "" +msgstr "Valita sisältövaroituksesta" #: src/view/com/modals/AppealLabel.tsx:65 msgid "Appeal Content Warning" -msgstr "" +msgstr "Valita sisältövaroituksesta" #: src/view/com/util/moderation/LabelInfo.tsx:52 msgid "Appeal this decision" -msgstr "" +msgstr "Valita tästä päätöksestä" #: src/view/com/util/moderation/LabelInfo.tsx:56 msgid "Appeal this decision." -msgstr "" +msgstr "Valita tästä päätöksestä." #: src/view/screens/Settings/index.tsx:466 msgid "Appearance" -msgstr "" +msgstr "Ulkonäkö" #: src/view/screens/AppPasswords.tsx:224 msgid "Are you sure you want to delete the app password \"{name}\"?" -msgstr "" +msgstr "Haluatko varmasti poistaa sovellussalasanan \"{name}\"?" #: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" -msgstr "" +msgstr "Haluatko varmasti hylätä tämän luonnoksen?" #: src/components/dialogs/MutedWords.tsx:233 #: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" -msgstr "" +msgstr "Oletko varma?" #: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Are you sure? This cannot be undone." -msgstr "" +msgstr "Oletko varma? Tätä ei voi perua." #: src/view/com/composer/select-language/SuggestedLanguage.tsx:60 msgid "Are you writing in <0>{0}?" -msgstr "" +msgstr "Onko viestisi kieli <0>{0}?" #: src/screens/Onboarding/index.tsx:26 msgid "Art" -msgstr "" +msgstr "Taide" #: src/view/com/modals/SelfLabel.tsx:123 msgid "Artistic or non-erotic nudity." -msgstr "" +msgstr "Taiteellinen tai ei-eroottinen alastomuus." #: src/view/com/auth/create/CreateAccount.tsx:158 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 @@ -369,118 +369,118 @@ msgstr "" #: src/view/com/profile/ProfileHeader.tsx:649 #: src/view/com/util/ViewHeader.tsx:81 msgid "Back" -msgstr "" +msgstr "Takaisin" #: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" -msgstr "" +msgstr "Takaisin" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:136 msgid "Based on your interest in {interestsText}" -msgstr "" +msgstr "Perustuen kiinnostukseesi {interestsText}" #: src/view/screens/Settings/index.tsx:523 msgid "Basics" -msgstr "" +msgstr "Perusasiat" #: src/view/com/auth/create/Step1.tsx:250 #: src/view/com/modals/BirthDateSettings.tsx:73 msgid "Birthday" -msgstr "" +msgstr "Syntymäpäivä" #: src/view/screens/Settings/index.tsx:340 msgid "Birthday:" -msgstr "" +msgstr "Syntymäpäivä:" #: src/view/com/profile/ProfileHeader.tsx:239 #: src/view/com/profile/ProfileHeader.tsx:346 msgid "Block Account" -msgstr "" +msgstr "Estä käyttäjä" #: src/view/screens/ProfileList.tsx:556 msgid "Block accounts" -msgstr "" +msgstr "Estä käyttäjät" #: src/view/screens/ProfileList.tsx:506 msgid "Block list" -msgstr "" +msgstr "Estettyjen lista" #: src/view/screens/ProfileList.tsx:316 msgid "Block these accounts?" -msgstr "" +msgstr "Estetäänkö nämä käyttäjät?" #: src/view/screens/ProfileList.tsx:320 msgid "Block this List" -msgstr "" +msgstr "Estä tämä lista" #: src/view/com/lists/ListCard.tsx:110 #: src/view/com/util/post-embeds/QuoteEmbed.tsx:61 msgid "Blocked" -msgstr "" +msgstr "Estetty" #: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" -msgstr "" +msgstr "Estetyt käyttäjät" #: src/Navigation.tsx:130 #: src/view/screens/ModerationBlockedAccounts.tsx:107 msgid "Blocked Accounts" -msgstr "" +msgstr "Estetyt käyttäjät" #: src/view/com/profile/ProfileHeader.tsx:241 msgid "Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you." -msgstr "" +msgstr "Estetyt käyttäjät eivät voi vastata viesteihisi, mainita sinua tai muuten olla vuorovaikutuksessa kanssasi." #: src/view/screens/ModerationBlockedAccounts.tsx:115 msgid "Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you. You will not see their content and they will be prevented from seeing yours." -msgstr "" +msgstr "Estetyt käyttäjät eivät voi vastata viesteihisi, mainita sinua tai muuten olla vuorovaikutuksessa kanssasi. Et näe heidän sisältöään ja he eivät näe sinun sisältöäsi." #: src/view/com/post-thread/PostThread.tsx:324 msgid "Blocked post." -msgstr "" +msgstr "Estetty viesti." #: src/view/screens/ProfileList.tsx:318 msgid "Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you." -msgstr "" +msgstr "Estäminen on julkista. Estetyt käyttäjät eivät voi vastata viesteihisi, mainita sinua tai muuten olla vuorovaikutuksessa kanssasi." #: src/view/com/auth/HomeLoggedOutCTA.tsx:93 #: src/view/com/auth/SplashScreen.web.tsx:133 msgid "Blog" -msgstr "" +msgstr "Blogi" #: src/view/com/auth/HomeLoggedOutCTA.tsx:31 #: src/view/com/auth/server-input/index.tsx:89 #: src/view/com/auth/server-input/index.tsx:90 msgid "Bluesky" -msgstr "" +msgstr "Bluesky" #: src/view/com/auth/server-input/index.tsx:150 msgid "Bluesky is an open network where you can choose your hosting provider. Custom hosting is now available in beta for developers." -msgstr "" +msgstr "Bluesky on avoin verkko, jossa voit valita palveluntarjoajasi. Räätälöity palveluntarjoajan määritys on nyt saatavilla betavaiheen kehittäjille." #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:80 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:80 msgid "Bluesky is flexible." -msgstr "" +msgstr "Bluesky on joustava." #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:69 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:69 msgid "Bluesky is open." -msgstr "" +msgstr "Bluesky on avoin." #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:56 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:56 msgid "Bluesky is public." -msgstr "" +msgstr "Bluesky on julkinen." #: src/view/com/modals/Waitlist.tsx:70 msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." -msgstr "" +msgstr "Bluesky käyttää kutsuja rakentaakseen terveellisemmän yhteisön. Jos et tunne ketään, jolla on kutsu, voit ilmoittautua odotuslistalle, niin lähetämme sinulle pian yhden." #: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." -msgstr "" +msgstr "Bluesky ei näytä profiiliasi ja viestejäsi kirjautumattomille käyttäjille. Toiset sovellukset eivät ehkä noudata tätä asetusta. Tämä ei tee tilistäsi yksityistä." #: src/view/com/modals/ServerInput.tsx:78 #~ msgid "Bluesky.Social" @@ -488,16 +488,16 @@ msgstr "" #: src/screens/Onboarding/index.tsx:33 msgid "Books" -msgstr "" +msgstr "Kirjat" #: src/view/screens/Settings/index.tsx:859 msgid "Build version {0} {1}" -msgstr "" +msgstr "Versio {0} {1}" #: src/view/com/auth/HomeLoggedOutCTA.tsx:87 #: src/view/com/auth/SplashScreen.web.tsx:128 msgid "Business" -msgstr "" +msgstr "Yritys" #: src/view/com/modals/ServerInput.tsx:115 #~ msgid "Button disabled. Input custom domain to proceed." @@ -505,29 +505,29 @@ msgstr "" #: src/view/com/profile/ProfileSubpageHeader.tsx:157 msgid "by —" -msgstr "" +msgstr "käyttäjä —" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:100 msgid "by {0}" -msgstr "" +msgstr "käyttäjältä {0}" #: src/view/com/profile/ProfileSubpageHeader.tsx:161 msgid "by <0/>" -msgstr "" +msgstr "käyttäjältä <0/>" #: src/view/com/profile/ProfileSubpageHeader.tsx:159 msgid "by you" -msgstr "" +msgstr "sinulta" #: src/view/com/composer/photos/OpenCameraBtn.tsx:60 #: src/view/com/util/UserAvatar.tsx:224 #: src/view/com/util/UserBanner.tsx:40 msgid "Camera" -msgstr "" +msgstr "Kamera" #: src/view/com/modals/AddAppPasswords.tsx:216 msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must be at least 4 characters long, but no more than 32 characters long." -msgstr "" +msgstr "Voi sisältää vain kirjaimia, numeroita, välilyöntejä, viivoja ja alaviivoja. Täytyy olla vähintään 4 merkkiä pitkä, mutta enintään 32 merkkiä pitkä." #: src/components/Prompt.tsx:91 #: src/view/com/composer/Composer.tsx:307 @@ -545,10 +545,10 @@ msgstr "" #: src/view/com/modals/VerifyEmail.tsx:247 #: src/view/com/modals/VerifyEmail.tsx:253 #: src/view/com/modals/Waitlist.tsx:142 -#: src/view/screens/Search/Search.tsx:716 +#: src/view/screens/Search/Search.tsx:693 #: src/view/shell/desktop/Search.tsx:238 msgid "Cancel" -msgstr "" +msgstr "Peruuta" #: src/view/com/modals/Confirm.tsx:88 #: src/view/com/modals/Confirm.tsx:91 @@ -557,113 +557,113 @@ msgstr "" #: src/view/com/modals/DeleteAccount.tsx:234 msgctxt "action" msgid "Cancel" -msgstr "" +msgstr "Peruuta" #: src/view/com/modals/DeleteAccount.tsx:152 #: src/view/com/modals/DeleteAccount.tsx:230 msgid "Cancel account deletion" -msgstr "" +msgstr "Peruuta tilin poisto" #: src/view/com/modals/ChangeHandle.tsx:149 msgid "Cancel change handle" -msgstr "" +msgstr "Peruuta käyttäjätunnuksen vaihto" #: src/view/com/modals/crop-image/CropImage.web.tsx:134 msgid "Cancel image crop" -msgstr "" +msgstr "Peruuta kuvan rajaus" #: src/view/com/modals/EditProfile.tsx:244 msgid "Cancel profile editing" -msgstr "" +msgstr "Peruuta profiilin muokkaus" #: src/view/com/modals/Repost.tsx:78 msgid "Cancel quote post" -msgstr "" +msgstr "Peruuta uudelleenpostaus" #: src/view/com/modals/ListAddRemoveUsers.tsx:87 #: src/view/shell/desktop/Search.tsx:234 msgid "Cancel search" -msgstr "" +msgstr "Peruuta haku" #: src/view/com/modals/Waitlist.tsx:136 msgid "Cancel waitlist signup" -msgstr "" +msgstr "Peruuta odotuslistalle liittyminen" #: src/view/screens/Settings/index.tsx:334 msgctxt "action" msgid "Change" -msgstr "" +msgstr "Vaihda" #: src/view/screens/Settings/index.tsx:696 msgid "Change handle" -msgstr "" +msgstr "Vaihda käyttäjätunnus" #: src/view/com/modals/ChangeHandle.tsx:161 #: src/view/screens/Settings/index.tsx:705 msgid "Change Handle" -msgstr "" +msgstr "Vaihda käyttäjätunnus" #: src/view/com/modals/VerifyEmail.tsx:147 msgid "Change my email" -msgstr "" +msgstr "Vaihda sähköpostiosoitteeni" #: src/view/screens/Settings/index.tsx:732 msgid "Change password" -msgstr "" +msgstr "Vaihda salasana" #: src/view/screens/Settings/index.tsx:741 msgid "Change Password" -msgstr "" +msgstr "Vaihda salasana" #: src/view/com/composer/select-language/SuggestedLanguage.tsx:73 msgid "Change post language to {0}" -msgstr "" +msgstr "Vaihda julkaisun kieleksi {0}" #: src/view/screens/Settings/index.tsx:733 msgid "Change your Bluesky password" -msgstr "" +msgstr "Vaihda Bluesky-salasanasi" #: src/view/com/modals/ChangeEmail.tsx:109 msgid "Change Your Email" -msgstr "" +msgstr "Vaihda sähköpostiosoitteesi" #: src/screens/Deactivated.tsx:72 #: src/screens/Deactivated.tsx:76 msgid "Check my status" -msgstr "" +msgstr "Tarkista tilani" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:121 msgid "Check out some recommended feeds. Tap + to add them to your list of pinned feeds." -msgstr "" +msgstr "Katso joitakin suositeltuja syötteitä. Napauta + lisätäksesi ne kiinnitettyjen syötteiden luetteloon." #: src/view/com/auth/onboarding/RecommendedFollows.tsx:185 msgid "Check out some recommended users. Follow them to see similar users." -msgstr "" +msgstr "Tutustu suositeltuihin käyttäjiin. Seuraa heitä löytääksesi samankaltaisia käyttäjiä." #: src/view/com/modals/DeleteAccount.tsx:169 msgid "Check your inbox for an email with the confirmation code to enter below:" -msgstr "" +msgstr "Tarkista sähköpostisi ja syötä saamasi vahvistuskoodi alle:" #: src/view/com/modals/Threadgate.tsx:72 msgid "Choose \"Everybody\" or \"Nobody\"" -msgstr "" +msgstr "Valitse \"Kaikki\" tai \"Ei kukaan\"" #: src/view/screens/Settings/index.tsx:697 msgid "Choose a new Bluesky username or create" -msgstr "" +msgstr "Valitse uusi Bluesky-käyttäjätunnus tai luo" #: src/view/com/auth/server-input/index.tsx:79 msgid "Choose Service" -msgstr "" +msgstr "Valitse palvelu" #: src/screens/Onboarding/StepFinished.tsx:135 msgid "Choose the algorithms that power your custom feeds." -msgstr "" +msgstr "Valitse algoritmit, jotka ohjaavat mukautettuja syötteitäsi." #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:83 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:83 msgid "Choose the algorithms that power your experience with custom feeds." -msgstr "" +msgstr "Valitse algoritmit, jotka ohjaavat kokemustasi mukautettujen syötteiden kanssa." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 #~ msgid "Choose your algorithmic feeds" @@ -671,134 +671,134 @@ msgstr "" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 msgid "Choose your main feeds" -msgstr "" +msgstr "Valitse pääsyötteet" #: src/view/com/auth/create/Step1.tsx:219 msgid "Choose your password" -msgstr "" +msgstr "Valitse salasanasi" #: src/view/screens/Settings/index.tsx:834 #: src/view/screens/Settings/index.tsx:835 msgid "Clear all legacy storage data" -msgstr "" +msgstr "Tyhjennä kaikki vanhan tietomallin mukaiset tiedot" #: src/view/screens/Settings/index.tsx:837 msgid "Clear all legacy storage data (restart after this)" -msgstr "" +msgstr "Tyhjennä kaikki vanhan tietomallin tiedot (käynnistä uudelleen tämän jälkeen)" #: src/view/screens/Settings/index.tsx:846 #: src/view/screens/Settings/index.tsx:847 msgid "Clear all storage data" -msgstr "" +msgstr "Tyhjennä kaikki tallennukset" #: src/view/screens/Settings/index.tsx:849 msgid "Clear all storage data (restart after this)" -msgstr "" +msgstr "Tyhjennä kaikki tallennukset (käynnistä uudelleen tämän jälkeen)" #: src/view/com/util/forms/SearchInput.tsx:88 #: src/view/screens/Search/Search.tsx:697 msgid "Clear search query" -msgstr "" +msgstr "Tyhjennä hakukysely" #: src/view/screens/Support.tsx:40 msgid "click here" -msgstr "" +msgstr "klikkaa tästä" #: src/components/RichText.tsx:189 #: src/components/TagMenu/index.web.tsx:125 msgid "Click here to open tag menu for {tag}" -msgstr "" +msgstr "Avaa tästä valikko tunnisteelle {tag}" #: src/screens/Onboarding/index.tsx:35 msgid "Climate" -msgstr "" +msgstr "Ilmasto" #: src/view/com/modals/ChangePassword.tsx:265 #: src/view/com/modals/ChangePassword.tsx:268 msgid "Close" -msgstr "" +msgstr "Sulje" #: src/components/Dialog/index.web.tsx:80 #: src/components/Dialog/index.web.tsx:194 msgid "Close active dialog" -msgstr "" +msgstr "Sulje aktiivinen ikkuna" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:38 msgid "Close alert" -msgstr "" +msgstr "Sulje hälytys" #: src/view/com/util/BottomSheetCustomBackdrop.tsx:33 msgid "Close bottom drawer" -msgstr "" +msgstr "Sulje alavalinnat" #: src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx:26 msgid "Close image" -msgstr "" +msgstr "Sulje kuva" #: src/view/com/lightbox/Lightbox.web.tsx:119 msgid "Close image viewer" -msgstr "" +msgstr "Sulje kuvankatselu" #: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" -msgstr "" +msgstr "Sulje alanavigointi" #: src/components/TagMenu/index.tsx:266 msgid "Close this dialog" -msgstr "" +msgstr "Sulje tämä valintaikkuna" #: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" -msgstr "" +msgstr "Sulkee alanavigaation" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:39 msgid "Closes password update alert" -msgstr "" +msgstr "Sulkee salasanan päivitysilmoituksen" #: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" -msgstr "" +msgstr "Sulkee editorin ja hylkää luonnoksen" #: src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx:27 msgid "Closes viewer for header image" -msgstr "" +msgstr "Sulkee kuvan katseluohjelman" #: src/view/com/notifications/FeedItem.tsx:317 msgid "Collapses list of users for a given notification" -msgstr "" +msgstr "Pienentää käyttäjäluettelon annetulle ilmoitukselle" #: src/screens/Onboarding/index.tsx:41 msgid "Comedy" -msgstr "" +msgstr "Komedia" #: src/screens/Onboarding/index.tsx:27 msgid "Comics" -msgstr "" +msgstr "Sarjakuvat" #: src/Navigation.tsx:227 #: src/view/screens/CommunityGuidelines.tsx:32 msgid "Community Guidelines" -msgstr "" +msgstr "Yhteisöohjeet" #: src/screens/Onboarding/StepFinished.tsx:148 msgid "Complete onboarding and start using your account" -msgstr "" +msgstr "Suorita käyttöönotto loppuun ja aloita tilisi käyttö" #: src/view/com/auth/create/Step3.tsx:73 msgid "Complete the challenge" -msgstr "" +msgstr "Tee haaste loppuun" #: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" -msgstr "" +msgstr "Laadi viestejä, joiden pituus on enintään {MAX_GRAPHEME_LENGTH} merkkiä" #: src/view/com/composer/Prompt.tsx:24 msgid "Compose reply" -msgstr "" +msgstr "Kirjoita vastaus" #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:67 msgid "Configure content filtering setting for category: {0}" -msgstr "" +msgstr "Määritä sisällönsuodatusasetus aiheille: {0}" #: src/components/Prompt.tsx:113 #: src/view/com/modals/AppealLabel.tsx:98 @@ -808,75 +808,75 @@ msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:308 #: src/view/screens/PreferencesThreads.tsx:159 msgid "Confirm" -msgstr "" +msgstr "Vahvista" #: src/view/com/modals/Confirm.tsx:75 #: src/view/com/modals/Confirm.tsx:78 msgctxt "action" msgid "Confirm" -msgstr "" +msgstr "Vahvista" #: src/view/com/modals/ChangeEmail.tsx:193 #: src/view/com/modals/ChangeEmail.tsx:195 msgid "Confirm Change" -msgstr "" +msgstr "Vahvista muutos" #: src/view/com/modals/lang-settings/ConfirmLanguagesButton.tsx:34 msgid "Confirm content language settings" -msgstr "" +msgstr "Vahvista sisällön kieliasetukset" #: src/view/com/modals/DeleteAccount.tsx:220 msgid "Confirm delete account" -msgstr "" +msgstr "Vahvista tilin poisto" #: src/view/com/modals/ContentFilteringSettings.tsx:156 msgid "Confirm your age to enable adult content." -msgstr "" +msgstr "Vahvista ikäsi nähdäksesi ikärajarajoitettua sisältöä" #: src/view/com/modals/ChangeEmail.tsx:157 #: src/view/com/modals/DeleteAccount.tsx:182 #: src/view/com/modals/VerifyEmail.tsx:165 msgid "Confirmation code" -msgstr "" +msgstr "Vahvistuskoodi" #: src/view/com/modals/Waitlist.tsx:120 msgid "Confirms signing up {email} to the waitlist" -msgstr "" +msgstr "Vahvistaa sähköpostiosoitteen {email} - rekisteröinnin odotuslistalle" #: src/view/com/auth/create/CreateAccount.tsx:193 #: src/view/com/auth/login/LoginForm.tsx:278 msgid "Connecting..." -msgstr "" +msgstr "Yhdistetään..." #: src/view/com/auth/create/CreateAccount.tsx:213 msgid "Contact support" -msgstr "" +msgstr "Ota yhteyttä tukeen" #: src/view/screens/Moderation.tsx:83 msgid "Content filtering" -msgstr "" +msgstr "Sisällönsuodatus" #: src/view/com/modals/ContentFilteringSettings.tsx:44 msgid "Content Filtering" -msgstr "" +msgstr "Sisällönsuodatus" #: src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx:74 #: src/view/screens/LanguageSettings.tsx:278 msgid "Content Languages" -msgstr "" +msgstr "Sisältöjen kielet" #: src/view/com/modals/ModerationDetails.tsx:65 msgid "Content Not Available" -msgstr "" +msgstr "Sisältö ei ole saatavilla" #: src/view/com/modals/ModerationDetails.tsx:33 #: src/view/com/util/moderation/ScreenHider.tsx:78 msgid "Content Warning" -msgstr "" +msgstr "Sisältövaroitus" #: src/view/com/composer/labels/LabelsBtn.tsx:31 msgid "Content warnings" -msgstr "" +msgstr "Sisältövaroitukset" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:170 #: src/screens/Onboarding/StepFollowingFeed.tsx:153 @@ -886,143 +886,143 @@ msgstr "" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:148 #: src/view/com/auth/onboarding/RecommendedFollows.tsx:209 msgid "Continue" -msgstr "" +msgstr "Jatka" #: src/screens/Onboarding/StepFollowingFeed.tsx:150 #: src/screens/Onboarding/StepInterests/index.tsx:245 #: src/screens/Onboarding/StepModeration/index.tsx:115 #: src/screens/Onboarding/StepTopicalFeeds.tsx:111 msgid "Continue to next step" -msgstr "" +msgstr "Jatka seuraavaan vaiheeseen" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:167 msgid "Continue to the next step" -msgstr "" +msgstr "Jatka seuraavaan vaiheeseen" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:191 msgid "Continue to the next step without following any accounts" -msgstr "" +msgstr "Jatka seuraavaan vaiheeseen seuraamatta yhtään tiliä" #: src/screens/Onboarding/index.tsx:44 msgid "Cooking" -msgstr "" +msgstr "Ruoanlaitto" #: src/view/com/modals/AddAppPasswords.tsx:195 #: src/view/com/modals/InviteCodes.tsx:182 msgid "Copied" -msgstr "" +msgstr "Kopioitu" #: src/view/screens/Settings/index.tsx:241 msgid "Copied build version to clipboard" -msgstr "" +msgstr "Ohjelmiston versio kopioitu leikepöydälle" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 #: src/view/com/util/forms/PostDropdownBtn.tsx:143 msgid "Copied to clipboard" -msgstr "" +msgstr "Kopioitu leikepöydälle" #: src/view/com/modals/AddAppPasswords.tsx:189 msgid "Copies app password" -msgstr "" +msgstr "Kopioi sovellussalasanan" #: src/view/com/modals/AddAppPasswords.tsx:188 msgid "Copy" -msgstr "" +msgstr "Kopioi" #: src/view/screens/ProfileList.tsx:418 msgid "Copy link to list" -msgstr "" +msgstr "Kopioi listan linkki" #: src/view/com/util/forms/PostDropdownBtn.tsx:184 msgid "Copy link to post" -msgstr "" +msgstr "Kopioi julkaisun linkki" #: src/view/com/profile/ProfileHeader.tsx:295 msgid "Copy link to profile" -msgstr "" +msgstr "Kopioi linkki profiiliin" #: src/view/com/util/forms/PostDropdownBtn.tsx:170 msgid "Copy post text" -msgstr "" +msgstr "Kopioi viestin teksti" #: src/Navigation.tsx:232 #: src/view/screens/CopyrightPolicy.tsx:29 msgid "Copyright Policy" -msgstr "" +msgstr "Tekijänoikeuskäytäntö" #: src/view/screens/ProfileFeed.tsx:97 msgid "Could not load feed" -msgstr "" +msgstr "Syötettä ei voitu ladata" #: src/view/screens/ProfileList.tsx:888 msgid "Could not load list" -msgstr "" +msgstr "Listaa ei voitu ladata" #: src/view/com/auth/create/Step2.tsx:91 #~ msgid "Country" -#~ msgstr "" +#~ msgstr "Maa" #: src/view/com/auth/HomeLoggedOutCTA.tsx:62 #: src/view/com/auth/SplashScreen.tsx:71 #: src/view/com/auth/SplashScreen.web.tsx:81 msgid "Create a new account" -msgstr "" +msgstr "Luo uusi tili" #: src/view/screens/Settings/index.tsx:384 msgid "Create a new Bluesky account" -msgstr "" +msgstr "Luo uusi Bluesky-tili" #: src/view/com/auth/create/CreateAccount.tsx:133 msgid "Create Account" -msgstr "" +msgstr "Luo tili" #: src/view/com/modals/AddAppPasswords.tsx:226 msgid "Create App Password" -msgstr "" +msgstr "Luo sovellussalasana" #: src/view/com/auth/HomeLoggedOutCTA.tsx:54 #: src/view/com/auth/SplashScreen.tsx:68 msgid "Create new account" -msgstr "" +msgstr "Luo uusi tili" #: src/view/screens/AppPasswords.tsx:249 msgid "Created {0}" -msgstr "" +msgstr "{0} luotu" #: src/view/screens/ProfileFeed.tsx:616 msgid "Created by <0/>" -msgstr "" +msgstr "Luonut <0/>" #: src/view/screens/ProfileFeed.tsx:614 msgid "Created by you" -msgstr "" +msgstr "Sinun luoma sisältö" #: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" -msgstr "" +msgstr "Luo kortin pikkukuvan kanssa. Kortti linkittyy osoitteeseen {url}" #: src/screens/Onboarding/index.tsx:29 msgid "Culture" -msgstr "" +msgstr "Kulttuuri" #: src/view/com/auth/server-input/index.tsx:95 #: src/view/com/auth/server-input/index.tsx:96 msgid "Custom" -msgstr "" +msgstr "Mukautettu" #: src/view/com/modals/ChangeHandle.tsx:389 msgid "Custom domain" -msgstr "" +msgstr "Mukautettu verkkotunnus" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 #: src/view/screens/Feeds.tsx:692 msgid "Custom feeds built by the community bring you new experiences and help you find the content you love." -msgstr "" +msgstr "Yhteisön rakentamat mukautetut syötteet tuovat sinulle uusia kokemuksia ja auttavat löytämään sinulle mieluisaa sisältöä." #: src/view/screens/PreferencesExternalEmbeds.tsx:55 msgid "Customize media from external sites." -msgstr "" +msgstr "Muokkaa mediaa ulkoisista sivustoista." #: src/view/screens/Settings.tsx:687 #~ msgid "Danger Zone" @@ -1031,41 +1031,41 @@ msgstr "" #: src/view/screens/Settings/index.tsx:485 #: src/view/screens/Settings/index.tsx:511 msgid "Dark" -msgstr "" +msgstr "Tumma" #: src/view/screens/Debug.tsx:63 msgid "Dark mode" -msgstr "" +msgstr "Tumma ulkoasu" #: src/view/screens/Settings/index.tsx:498 msgid "Dark Theme" -msgstr "" +msgstr "Tumma teema" #: src/view/screens/Debug.tsx:83 msgid "Debug panel" -msgstr "" +msgstr "Vianetsintäpaneeli" #: src/view/screens/Settings/index.tsx:772 msgid "Delete account" -msgstr "" +msgstr "Poista käyttäjätili" #: src/view/com/modals/DeleteAccount.tsx:87 msgid "Delete Account" -msgstr "" +msgstr "Poista käyttäjätili" #: src/view/screens/AppPasswords.tsx:222 #: src/view/screens/AppPasswords.tsx:242 msgid "Delete app password" -msgstr "" +msgstr "Poista sovellussalasana" #: src/view/screens/ProfileList.tsx:364 #: src/view/screens/ProfileList.tsx:445 msgid "Delete List" -msgstr "" +msgstr "Poista lista" #: src/view/com/modals/DeleteAccount.tsx:223 msgid "Delete my account" -msgstr "" +msgstr "Poista käyttäjätilini" #: src/view/screens/Settings.tsx:706 #~ msgid "Delete my account…" @@ -1073,30 +1073,30 @@ msgstr "" #: src/view/screens/Settings/index.tsx:784 msgid "Delete My Account…" -msgstr "" +msgstr "Poista tilini…" #: src/view/com/util/forms/PostDropdownBtn.tsx:273 msgid "Delete post" -msgstr "" +msgstr "Poista viesti" #: src/view/com/util/forms/PostDropdownBtn.tsx:277 msgid "Delete this post?" -msgstr "" +msgstr "Poista tämä viesti?" #: src/view/com/util/post-embeds/QuoteEmbed.tsx:70 msgid "Deleted" -msgstr "" +msgstr "Poistettu" #: src/view/com/post-thread/PostThread.tsx:316 msgid "Deleted post." -msgstr "" +msgstr "Poistettu viesti." #: src/view/com/modals/CreateOrEditList.tsx:300 #: src/view/com/modals/CreateOrEditList.tsx:321 #: src/view/com/modals/EditProfile.tsx:198 #: src/view/com/modals/EditProfile.tsx:210 msgid "Description" -msgstr "" +msgstr "Kuvaus" #: src/view/screens/Settings.tsx:760 #~ msgid "Developer Tools" @@ -1104,28 +1104,28 @@ msgstr "" #: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" -msgstr "" +msgstr "Haluatko sanoa jotain?" #: src/view/screens/Settings/index.tsx:504 msgid "Dim" -msgstr "" +msgstr "Himmeä" #: src/view/com/composer/Composer.tsx:151 msgid "Discard" -msgstr "" +msgstr "Hylkää" #: src/view/com/composer/Composer.tsx:145 msgid "Discard draft" -msgstr "" +msgstr "Hylkää luonnos" #: src/view/screens/Moderation.tsx:226 msgid "Discourage apps from showing my account to logged-out users" -msgstr "" +msgstr "Estä sovelluksia näyttämästä tiliäni kirjautumattomille käyttäjille" #: src/view/com/posts/FollowingEmptyState.tsx:74 #: src/view/com/posts/FollowingEndOfFeed.tsx:75 msgid "Discover new custom feeds" -msgstr "" +msgstr "Löydä uusia mukautettuja syötteitä" #: src/view/screens/Feeds.tsx:473 #~ msgid "Discover new feeds" @@ -1133,23 +1133,23 @@ msgstr "" #: src/view/screens/Feeds.tsx:689 msgid "Discover New Feeds" -msgstr "" +msgstr "Löydä uusia syötteitä" #: src/view/com/modals/EditProfile.tsx:192 msgid "Display name" -msgstr "" +msgstr "Näyttönimi" #: src/view/com/modals/EditProfile.tsx:180 msgid "Display Name" -msgstr "" +msgstr "Näyttönimi" #: src/view/com/modals/ChangeHandle.tsx:487 msgid "Domain verified!" -msgstr "" +msgstr "Verkkotunnus vahvistettu!" #: src/view/com/auth/create/Step1.tsx:170 msgid "Don't have an invite code?" -msgstr "" +msgstr "Eikö sinulla ole kutsukoodia?" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:86 #: src/view/com/modals/EditImage.tsx:333 @@ -1162,7 +1162,7 @@ msgstr "" #: src/view/screens/PreferencesThreads.tsx:162 msgctxt "action" msgid "Done" -msgstr "" +msgstr "Valmis" #: src/view/com/auth/server-input/index.tsx:165 #: src/view/com/auth/server-input/index.tsx:166 @@ -1178,336 +1178,336 @@ msgstr "" #: src/view/screens/Settings/ExportCarDialog.tsx:93 #: src/view/screens/Settings/ExportCarDialog.tsx:94 msgid "Done" -msgstr "" +msgstr "Valmis" #: src/view/com/modals/lang-settings/ConfirmLanguagesButton.tsx:42 msgid "Done{extraText}" -msgstr "" +msgstr "Valmis{extraText}" #: src/view/com/auth/login/ChooseAccountForm.tsx:45 msgid "Double tap to sign in" -msgstr "" +msgstr "Kaksoisnapauta kirjautuaksesi sisään" #: src/view/screens/Settings/index.tsx:755 msgid "Download Bluesky account data (repository)" -msgstr "" +msgstr "Lataa Bluesky-tilin tiedot (repository)" #: src/view/screens/Settings/ExportCarDialog.tsx:59 #: src/view/screens/Settings/ExportCarDialog.tsx:63 msgid "Download CAR file" -msgstr "" +msgstr "Lataa CAR tiedosto" #: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" -msgstr "" +msgstr "Raahaa tähän lisätäksesi kuvia" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:111 msgid "Due to Apple policies, adult content can only be enabled on the web after completing sign up." -msgstr "" +msgstr "Applen sääntöjen vuoksi aikuisviihde voidaan ottaa käyttöön vasta rekisteröitymisen jälkeen." #: src/view/com/modals/EditProfile.tsx:185 msgid "e.g. Alice Roberts" -msgstr "" +msgstr "esim. Mikko Mallikas" #: src/view/com/modals/EditProfile.tsx:203 msgid "e.g. Artist, dog-lover, and avid reader." -msgstr "" +msgstr "esim. Taiteilija, koiraharrastaja ja innokas lukija." #: src/view/com/modals/CreateOrEditList.tsx:283 msgid "e.g. Great Posters" -msgstr "" +msgstr "esim. Loistavat kirjoittajat" #: src/view/com/modals/CreateOrEditList.tsx:284 msgid "e.g. Spammers" -msgstr "" +msgstr "esim. Roskapostittajat" #: src/view/com/modals/CreateOrEditList.tsx:312 msgid "e.g. The posters who never miss." -msgstr "" +msgstr "esim. Julkaisijat, jotka osuvat maaliin aina." #: src/view/com/modals/CreateOrEditList.tsx:313 msgid "e.g. Users that repeatedly reply with ads." -msgstr "" +msgstr "esim. Käyttäjät, jotka vastaavat toistuvasti mainoksilla." #: src/view/com/modals/InviteCodes.tsx:96 msgid "Each code works once. You'll receive more invite codes periodically." -msgstr "" +msgstr "Jokainen koodi toimii vain kerran. Saat lisää kutsukoodeja säännöllisin väliajoin." #: src/view/com/lists/ListMembers.tsx:149 msgctxt "action" msgid "Edit" -msgstr "" +msgstr "Muokkaa" #: src/view/com/composer/photos/Gallery.tsx:144 #: src/view/com/modals/EditImage.tsx:207 msgid "Edit image" -msgstr "" +msgstr "Muokkaa kuvaa" #: src/view/screens/ProfileList.tsx:433 msgid "Edit list details" -msgstr "" +msgstr "Muokkaa listan tietoja" #: src/view/com/modals/CreateOrEditList.tsx:250 msgid "Edit Moderation List" -msgstr "" +msgstr "Muokkaa moderaatiolistaa" #: src/Navigation.tsx:242 #: src/view/screens/Feeds.tsx:434 #: src/view/screens/SavedFeeds.tsx:84 msgid "Edit My Feeds" -msgstr "" +msgstr "Muokkaa syötteitäni" #: src/view/com/modals/EditProfile.tsx:152 msgid "Edit my profile" -msgstr "" +msgstr "Muokkaa profiiliani" #: src/view/com/profile/ProfileHeader.tsx:418 msgid "Edit profile" -msgstr "" +msgstr "Muokkaa profiilia" #: src/view/com/profile/ProfileHeader.tsx:423 msgid "Edit Profile" -msgstr "" +msgstr "Muokkaa profiilia" #: src/view/com/home/HomeHeaderLayout.web.tsx:59 #: src/view/screens/Feeds.tsx:355 msgid "Edit Saved Feeds" -msgstr "" +msgstr "Muokkaa tallennettuja syötteitä" #: src/view/com/modals/CreateOrEditList.tsx:245 msgid "Edit User List" -msgstr "" +msgstr "Muokkaa käyttäjälistaa" #: src/view/com/modals/EditProfile.tsx:193 msgid "Edit your display name" -msgstr "" +msgstr "Muokkaa näyttönimeäsi" #: src/view/com/modals/EditProfile.tsx:211 msgid "Edit your profile description" -msgstr "" +msgstr "Muokkaa profiilin kuvausta" #: src/screens/Onboarding/index.tsx:34 msgid "Education" -msgstr "" +msgstr "Koulutus" #: src/view/com/auth/create/Step1.tsx:199 #: src/view/com/auth/login/ForgotPasswordForm.tsx:156 #: src/view/com/modals/ChangeEmail.tsx:141 #: src/view/com/modals/Waitlist.tsx:88 msgid "Email" -msgstr "" +msgstr "Sähköposti" #: src/view/com/auth/create/Step1.tsx:190 #: src/view/com/auth/login/ForgotPasswordForm.tsx:147 msgid "Email address" -msgstr "" +msgstr "Sähköpostiosoite" #: src/view/com/modals/ChangeEmail.tsx:56 #: src/view/com/modals/ChangeEmail.tsx:88 msgid "Email updated" -msgstr "" +msgstr "Sähköpostiosoite päivitetty" #: src/view/com/modals/ChangeEmail.tsx:111 msgid "Email Updated" -msgstr "" +msgstr "Sähköpostiosoite päivitetty" #: src/view/com/modals/VerifyEmail.tsx:78 msgid "Email verified" -msgstr "" +msgstr "Sähköpostiosoite vahvistettu" #: src/view/screens/Settings/index.tsx:312 msgid "Email:" -msgstr "" +msgstr "Sähköpostiosoite:" #: src/view/com/modals/EmbedConsent.tsx:113 msgid "Enable {0} only" -msgstr "" +msgstr "Ota käyttöön vain {0}" #: src/view/com/modals/ContentFilteringSettings.tsx:167 msgid "Enable Adult Content" -msgstr "" +msgstr "Ota aikuissisältö käyttöön" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:76 #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:77 msgid "Enable adult content in your feeds" -msgstr "" +msgstr "Näytä aikuissisältöä syötteissäsi" #: src/view/com/modals/EmbedConsent.tsx:97 msgid "Enable External Media" -msgstr "" +msgstr "Ota ulkoinen media käyttöön" #: src/view/screens/PreferencesExternalEmbeds.tsx:75 msgid "Enable media players for" -msgstr "" +msgstr "Ota mediatoistimet käyttöön kohteille" #: src/view/screens/PreferencesFollowingFeed.tsx:147 msgid "Enable this setting to only see replies between people you follow." -msgstr "" +msgstr "Ota tämä asetus käyttöön nähdäksesi vastaukset vain seuraamiltasi ihmisiltä." #: src/view/screens/Profile.tsx:455 msgid "End of feed" -msgstr "" +msgstr "Syötteen loppu" #: src/view/com/modals/AddAppPasswords.tsx:166 msgid "Enter a name for this App Password" -msgstr "" +msgstr "Anna sovellusalasanalle nimi" #: src/components/dialogs/MutedWords.tsx:87 #: src/components/dialogs/MutedWords.tsx:88 msgid "Enter a word or tag" -msgstr "" +msgstr "Kirjoita sana tai tunniste" #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" -msgstr "" +msgstr "Syötä vahvistuskoodi" #: src/view/com/modals/ChangePassword.tsx:151 msgid "Enter the code you received to change your password." -msgstr "" +msgstr "Anna saamasi koodi vaihtaaksesi salasanasi." #: src/view/com/modals/ChangeHandle.tsx:371 msgid "Enter the domain you want to use" -msgstr "" +msgstr "Anna verkkotunnus, jota haluat käyttää" #: src/view/com/auth/login/ForgotPasswordForm.tsx:107 msgid "Enter the email you used to create your account. We'll send you a \"reset code\" so you can set a new password." -msgstr "" +msgstr "Anna sähköpostiosoite, jotaa käytit tilin luomiseen. Lähetämme sinulle \"nollauskoodin\", jotta voit määritellä uuden salasanan." #: src/view/com/auth/create/Step1.tsx:251 #: src/view/com/modals/BirthDateSettings.tsx:74 msgid "Enter your birth date" -msgstr "" +msgstr "Syötä syntymäaikasi" #: src/view/com/modals/Waitlist.tsx:78 msgid "Enter your email" -msgstr "" +msgstr "Syötä sähköpostiosoitteesi" #: src/view/com/auth/create/Step1.tsx:195 msgid "Enter your email address" -msgstr "" +msgstr "Syötä sähköpostiosoitteesi" #: src/view/com/modals/ChangeEmail.tsx:41 msgid "Enter your new email above" -msgstr "" +msgstr "Syötä uusi sähköpostiosoitteesi yläpuolelle" #: src/view/com/modals/ChangeEmail.tsx:117 msgid "Enter your new email address below." -msgstr "" +msgstr "Syötä uusi sähköpostiosoitteesi alle" #: src/view/com/auth/create/Step2.tsx:188 #~ msgid "Enter your phone number" -#~ msgstr "" +msgstr "Syötä puhelinnumerosi" #: src/view/com/auth/login/Login.tsx:99 msgid "Enter your username and password" -msgstr "" +msgstr "Syötä käyttäjätunnuksesi ja salasanasi" #: src/view/com/auth/create/Step3.tsx:67 msgid "Error receiving captcha response." -msgstr "" +msgstr "Virhe captcha-vastauksen vastaanottamisessa." #: src/view/screens/Search/Search.tsx:110 msgid "Error:" -msgstr "" +msgstr "Virhe:" #: src/view/com/modals/Threadgate.tsx:76 msgid "Everybody" -msgstr "" +msgstr "Kaikki" #: src/view/com/modals/ChangeHandle.tsx:150 msgid "Exits handle change process" -msgstr "" +msgstr "Peruuttaa käyttäjätunnuksen vaihtamisen" #: src/view/com/lightbox/Lightbox.web.tsx:120 msgid "Exits image view" -msgstr "" +msgstr "Poistuu kuvan katselutilasta" #: src/view/com/modals/ListAddRemoveUsers.tsx:88 #: src/view/shell/desktop/Search.tsx:235 msgid "Exits inputting search query" -msgstr "" +msgstr "Poistuu hakukyselyn kirjoittamisesta" #: src/view/com/modals/Waitlist.tsx:138 msgid "Exits signing up for waitlist with {email}" -msgstr "" +msgstr "Poistuu odotuslistalle liittymisestä sähköpostilla {email}" #: src/view/com/lightbox/Lightbox.web.tsx:163 msgid "Expand alt text" -msgstr "" +msgstr "Laajenna ALT-teksti" #: src/view/com/composer/ComposerReplyTo.tsx:81 #: src/view/com/composer/ComposerReplyTo.tsx:84 msgid "Expand or collapse the full post you are replying to" -msgstr "" +msgstr "Laajenna tai pienennä viesti johon olit vastaamassa" #: src/view/screens/Settings/index.tsx:753 msgid "Export my data" -msgstr "" +msgstr "Vie tietoni" #: src/view/screens/Settings/ExportCarDialog.tsx:44 #: src/view/screens/Settings/index.tsx:764 msgid "Export My Data" -msgstr "" +msgstr "Vie tietoni" #: src/view/com/modals/EmbedConsent.tsx:64 msgid "External Media" -msgstr "" +msgstr "Ulkoiset mediat" #: src/view/com/modals/EmbedConsent.tsx:75 #: src/view/screens/PreferencesExternalEmbeds.tsx:66 msgid "External media may allow websites to collect information about you and your device. No information is sent or requested until you press the \"play\" button." -msgstr "" +msgstr "Ulkoiset mediat voivat sallia verkkosivustojen kerätä tietoja sinusta ja laitteestasi. Tietoja ei lähetetä eikä pyydetä, ennen kuin painat \"toista\"-painiketta." #: src/Navigation.tsx:261 #: src/view/screens/PreferencesExternalEmbeds.tsx:52 #: src/view/screens/Settings/index.tsx:657 msgid "External Media Preferences" -msgstr "" +msgstr "Ulkoisten medioiden asetukset" #: src/view/screens/Settings/index.tsx:648 msgid "External media settings" -msgstr "" +msgstr "Ulkoisten medioiden asetukset" #: src/view/com/modals/AddAppPasswords.tsx:115 #: src/view/com/modals/AddAppPasswords.tsx:119 msgid "Failed to create app password." -msgstr "" +msgstr "Sovellussalasanan luominen epäonnistui." #: src/view/com/modals/CreateOrEditList.tsx:206 msgid "Failed to create the list. Check your internet connection and try again." -msgstr "" +msgstr "Listan luominen epäonnistui. Tarkista internetyhteytesi ja yritä uudelleen." #: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Failed to delete post, please try again" -msgstr "" +msgstr "Viestin poistaminen epäonnistui, yritä uudelleen" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:109 #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:141 msgid "Failed to load recommended feeds" -msgstr "" +msgstr "Suositeltujen syötteiden lataaminen epäonnistui" #: src/Navigation.tsx:192 msgid "Feed" -msgstr "" +msgstr "Syöte" #: src/view/com/feeds/FeedSourceCard.tsx:231 msgid "Feed by {0}" -msgstr "" +msgstr "Syöte käyttäjältä {0}" #: src/view/screens/Feeds.tsx:605 msgid "Feed offline" -msgstr "" +msgstr "Syöte ei ole käytettävissä" #: src/view/com/feeds/FeedPage.tsx:143 #~ msgid "Feed Preferences" -#~ msgstr "" +#~ msgstr "Syötteen asetukset" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 msgid "Feedback" -msgstr "" +msgstr "Palaute" -#: src/Navigation.tsx:445 +#: src/Navigation.tsx:442 #: src/view/screens/Feeds.tsx:419 #: src/view/screens/Feeds.tsx:524 #: src/view/screens/Profile.tsx:184 @@ -1516,7 +1516,7 @@ msgstr "" #: src/view/shell/Drawer.tsx:476 #: src/view/shell/Drawer.tsx:477 msgid "Feeds" -msgstr "" +msgstr "Syötteet" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 #~ msgid "Feeds are created by users and can give you entirely new experiences." @@ -1528,125 +1528,125 @@ msgstr "" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:57 msgid "Feeds are created by users to curate content. Choose some feeds that you find interesting." -msgstr "" +msgstr "Käyttäjät luovat syötteitä sisällön kuratointiin. Valitse joitakin syötteitä, jotka koet mielenkiintoisiksi." #: src/view/screens/SavedFeeds.tsx:156 msgid "Feeds are custom algorithms that users build with a little coding expertise. <0/> for more information." -msgstr "" +msgstr "Syötteet ovat käyttäjien rakentamia mukautettuja algoritmeja, jotka vaativat vain vähän koodaustaitoja. <0/> lisätietoa varten." #: src/screens/Onboarding/StepTopicalFeeds.tsx:76 msgid "Feeds can be topical as well!" -msgstr "" +msgstr "Syötteet voivat olla myös aihepiirikohtaisia!" #: src/screens/Onboarding/StepFinished.tsx:151 msgid "Finalizing" -msgstr "" +msgstr "Viimeistely" #: src/view/com/posts/CustomFeedEmptyState.tsx:47 #: src/view/com/posts/FollowingEmptyState.tsx:57 #: src/view/com/posts/FollowingEndOfFeed.tsx:58 msgid "Find accounts to follow" -msgstr "" +msgstr "Etsi seurattavia tilejä" #: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" -msgstr "" +msgstr "Etsi käyttäjiä Bluesky-palvelusta" #: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" -msgstr "" +msgstr "Etsi käyttäjiä oikealla olevan hakutyökalun avulla" #: src/view/com/auth/onboarding/RecommendedFollowsItem.tsx:150 msgid "Finding similar accounts..." -msgstr "" +msgstr "Etsitään samankaltaisia käyttäjätilejä" #: src/view/screens/PreferencesFollowingFeed.tsx:111 msgid "Fine-tune the content you see on your Following feed." -msgstr "" +msgstr "Hienosäädä näkemääsi sisältöä Seuraavat-syötteessäsi." #: src/view/screens/PreferencesHomeFeed.tsx:111 #~ msgid "Fine-tune the content you see on your home screen." -#~ msgstr "" +#~ msgstr "Hienosäädä näkemääsi sisältöä pääsivulla." #: src/view/screens/PreferencesThreads.tsx:60 msgid "Fine-tune the discussion threads." -msgstr "" +msgstr "Hienosäädä keskusteluketjuja." #: src/screens/Onboarding/index.tsx:38 msgid "Fitness" -msgstr "" +msgstr "Kuntoilu" #: src/screens/Onboarding/StepFinished.tsx:131 msgid "Flexible" -msgstr "" +msgstr "Joustava" #: src/view/com/modals/EditImage.tsx:115 msgid "Flip horizontal" -msgstr "" +msgstr "Käännä vaakasuunnassa" #: src/view/com/modals/EditImage.tsx:120 #: src/view/com/modals/EditImage.tsx:287 msgid "Flip vertically" -msgstr "" +msgstr "Käännä pystysuunnassa" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:181 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:136 #: src/view/com/profile/ProfileHeader.tsx:513 msgid "Follow" -msgstr "" +msgstr "Seuraa" #: src/view/com/profile/FollowButton.tsx:64 msgctxt "action" msgid "Follow" -msgstr "" +msgstr "Seuraa" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:58 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:122 #: src/view/com/profile/ProfileHeader.tsx:504 msgid "Follow {0}" -msgstr "" +msgstr "Seuraa {0}" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:179 msgid "Follow All" -msgstr "" +msgstr "Seuraa kaikkia" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:174 msgid "Follow selected accounts and continue to the next step" -msgstr "" +msgstr "Seuraa valittuja tilejä ja siirry seuraavaan vaiheeseen" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:64 msgid "Follow some users to get started. We can recommend you more users based on who you find interesting." -msgstr "" +msgstr "Seuraa joitakin käyttäjiä aloittaaksesi. Suosittelemme sinulle lisää käyttäjiä sen perusteella, ketä pidät mielenkiintoisena." #: src/view/com/profile/ProfileCard.tsx:194 msgid "Followed by {0}" -msgstr "" +msgstr "Seuraajina {0}" #: src/view/com/modals/Threadgate.tsx:98 msgid "Followed users" -msgstr "" +msgstr "Seuratut käyttäjät" #: src/view/screens/PreferencesFollowingFeed.tsx:154 msgid "Followed users only" -msgstr "" +msgstr "Vain seuratut käyttäjät" #: src/view/com/notifications/FeedItem.tsx:166 msgid "followed you" -msgstr "" +msgstr "seurasi sinua" #: src/view/screens/ProfileFollowers.tsx:25 msgid "Followers" -msgstr "" +msgstr "Seuraajat" #: src/view/com/post-thread/PostThreadFollowBtn.tsx:136 #: src/view/com/profile/ProfileHeader.tsx:495 #: src/view/screens/ProfileFollows.tsx:25 msgid "Following" -msgstr "" +msgstr "Seuraa" #: src/view/com/profile/ProfileHeader.tsx:149 msgid "Following {0}" -msgstr "" +msgstr "Seuraa {0}" #: src/Navigation.tsx:248 #: src/view/com/home/HomeHeaderLayout.web.tsx:45 @@ -1654,78 +1654,78 @@ msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 msgid "Following Feed Preferences" -msgstr "" +msgstr "Seuratut -syötteen asetukset" #: src/view/com/profile/ProfileHeader.tsx:546 msgid "Follows you" -msgstr "" +msgstr "Seuraa sinua" #: src/view/com/profile/ProfileCard.tsx:141 msgid "Follows You" -msgstr "" +msgstr "Seuraa sinua" #: src/screens/Onboarding/index.tsx:43 msgid "Food" -msgstr "" +msgstr "Ruoka" #: src/view/com/modals/DeleteAccount.tsx:111 msgid "For security reasons, we'll need to send a confirmation code to your email address." -msgstr "" +msgstr "Turvallisuussyistä meidän on lähetettävä vahvistuskoodi sähköpostiosoitteeseesi." #: src/view/com/modals/AddAppPasswords.tsx:209 msgid "For security reasons, you won't be able to view this again. If you lose this password, you'll need to generate a new one." -msgstr "" +msgstr "Turvallisuussyistä et näe tätä uudelleen. Jos unohdat tämän salasanan, sinun on luotava uusi." #: src/view/com/auth/login/LoginForm.tsx:241 msgid "Forgot" -msgstr "" +msgstr "Unohtui" #: src/view/com/auth/login/LoginForm.tsx:238 msgid "Forgot password" -msgstr "" +msgstr "Unohtunut salasana" #: src/view/com/auth/login/Login.tsx:127 #: src/view/com/auth/login/Login.tsx:143 msgid "Forgot Password" -msgstr "" +msgstr "Unohtunut salasana" #: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" -msgstr "" +msgstr "Lähde: <0/>" #: src/view/com/composer/photos/SelectPhotoBtn.tsx:43 msgid "Gallery" -msgstr "" +msgstr "Galleria" #: src/view/com/modals/VerifyEmail.tsx:189 #: src/view/com/modals/VerifyEmail.tsx:191 msgid "Get Started" -msgstr "" +msgstr "Aloita tästä" #: src/view/com/auth/LoggedOut.tsx:81 #: src/view/com/auth/LoggedOut.tsx:82 #: src/view/com/util/moderation/ScreenHider.tsx:123 #: src/view/shell/desktop/LeftNav.tsx:104 msgid "Go back" -msgstr "" +msgstr "Palaa takaisin" #: src/view/screens/ProfileFeed.tsx:106 #: src/view/screens/ProfileFeed.tsx:111 #: src/view/screens/ProfileList.tsx:897 #: src/view/screens/ProfileList.tsx:902 msgid "Go Back" -msgstr "" +msgstr "Palaa takaisin" #: src/screens/Onboarding/Layout.tsx:104 #: src/screens/Onboarding/Layout.tsx:193 msgid "Go back to previous step" -msgstr "" +msgstr "Palaa edelliseen vaiheeseen" #: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" -msgstr "" +msgstr "Siirry @{queryMaybeHandle}" #: src/view/com/auth/login/ForgotPasswordForm.tsx:189 #: src/view/com/auth/login/ForgotPasswordForm.tsx:218 @@ -1733,94 +1733,94 @@ msgstr "" #: src/view/com/auth/login/SetNewPasswordForm.tsx:195 #: src/view/com/modals/ChangePassword.tsx:165 msgid "Go to next" -msgstr "" +msgstr "Siirry seuraavaan" #: src/view/com/modals/ChangeHandle.tsx:265 msgid "Handle" -msgstr "" +msgstr "Käyttäjätunnus" #: src/components/RichText.tsx:188 msgid "Hashtag: {tag}" -msgstr "" +msgstr "Tunniste: {tag}" #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" -msgstr "" +msgstr "Ongelmia?" #: src/view/shell/desktop/RightNav.tsx:90 #: src/view/shell/Drawer.tsx:321 msgid "Help" -msgstr "" +msgstr "Ohje" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:132 msgid "Here are some accounts for you to follow" -msgstr "" +msgstr "Tässä on joitakin tilejä seurattavaksi" #: src/screens/Onboarding/StepTopicalFeeds.tsx:85 msgid "Here are some popular topical feeds. You can choose to follow as many as you like." -msgstr "" +msgstr "Tässä on joitakin suosittuja aihepiirikohtaisia syötteitä. Voit valita seurattavaksi niin monta kuin haluat." #: src/screens/Onboarding/StepTopicalFeeds.tsx:80 msgid "Here are some topical feeds based on your interests: {interestsText}. You can choose to follow as many as you like." -msgstr "" +msgstr "Tässä on joitakin aihepiirikohtaisia syötteitä kiinnostuksiesi perusteella: {interestsText}. Voit valita seurata niin montaa kuin haluat." #: src/view/com/modals/AddAppPasswords.tsx:153 msgid "Here is your app password." -msgstr "" +msgstr "Tässä on sovelluksesi salasana." #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:41 #: src/view/com/modals/ContentFilteringSettings.tsx:251 #: src/view/com/util/moderation/ContentHider.tsx:105 #: src/view/com/util/moderation/PostHider.tsx:108 msgid "Hide" -msgstr "" +msgstr "Piilota" #: src/view/com/modals/ContentFilteringSettings.tsx:224 #: src/view/com/notifications/FeedItem.tsx:325 msgctxt "action" msgid "Hide" -msgstr "" +msgstr "Piilota" #: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Hide post" -msgstr "" +msgstr "Piilota viesti" #: src/view/com/util/moderation/ContentHider.tsx:67 #: src/view/com/util/moderation/PostHider.tsx:61 msgid "Hide the content" -msgstr "" +msgstr "Piilota sisältö" #: src/view/com/util/forms/PostDropdownBtn.tsx:236 msgid "Hide this post?" -msgstr "" +msgstr "Piilota tämä viesti?" #: src/view/com/notifications/FeedItem.tsx:315 msgid "Hide user list" -msgstr "" +msgstr "Piilota käyttäjäluettelo" #: src/view/com/profile/ProfileHeader.tsx:487 msgid "Hides posts from {0} in your feed" -msgstr "" +msgstr "Piilottaa viestit käyttäjältä {0} syötteessäsi" #: src/view/com/posts/FeedErrorMessage.tsx:111 msgid "Hmm, some kind of issue occurred when contacting the feed server. Please let the feed owner know about this issue." -msgstr "" +msgstr "Hmm, jokin ongelma ilmeni ottaessa yhteyttä syötteen palvelimeen. Ilmoita asiasta syötteen omistajalle." #: src/view/com/posts/FeedErrorMessage.tsx:99 msgid "Hmm, the feed server appears to be misconfigured. Please let the feed owner know about this issue." -msgstr "" +msgstr "Hmm, syötteen palvelin vaikuttaa olevan väärin konfiguroitu. Ilmoita asiasta syötteen omistajalle." #: src/view/com/posts/FeedErrorMessage.tsx:105 msgid "Hmm, the feed server appears to be offline. Please let the feed owner know about this issue." -msgstr "" +msgstr "Hmm, syötteen palvelin vaikuttaa olevan poissa käytöstä. Ilmoita asiasta syötteen omistajalle." #: src/view/com/posts/FeedErrorMessage.tsx:102 msgid "Hmm, the feed server gave a bad response. Please let the feed owner know about this issue." -msgstr "" +msgstr "Hmm, syötteen palvelin antoi virheellisen vastauksen. Ilmoita asiasta syötteen omistajalle." #: src/view/com/posts/FeedErrorMessage.tsx:96 msgid "Hmm, we're having trouble finding this feed. It may have been deleted." -msgstr "" +msgstr "Hmm, meillä on vaikeuksia löytää tätä syötettä. Se saattaa olla poistettu." #: src/Navigation.tsx:435 #: src/view/shell/bottom-bar/BottomBar.tsx:137 @@ -1828,124 +1828,124 @@ msgstr "" #: src/view/shell/Drawer.tsx:398 #: src/view/shell/Drawer.tsx:399 msgid "Home" -msgstr "" +msgstr "Koti" #: src/Navigation.tsx:247 #: src/view/com/pager/FeedsTabBarMobile.tsx:123 #: src/view/screens/PreferencesHomeFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 #~ msgid "Home Feed Preferences" -#~ msgstr "" +#~ msgstr "Aloitussivun syötteiden asetukset" #: src/view/com/auth/create/Step1.tsx:82 #: src/view/com/auth/login/ForgotPasswordForm.tsx:120 msgid "Hosting provider" -msgstr "" +msgstr "Hostingyritys" #: src/view/com/modals/InAppBrowserConsent.tsx:44 msgid "How should we open this link?" -msgstr "" +msgstr "Kuinka haluat avata tämän linkin?" #: src/view/com/modals/VerifyEmail.tsx:214 msgid "I have a code" -msgstr "" +msgstr "Minulla on koodi" #: src/view/com/modals/VerifyEmail.tsx:216 msgid "I have a confirmation code" -msgstr "" +msgstr "Minulla on vahvistuskoodi" #: src/view/com/modals/ChangeHandle.tsx:283 msgid "I have my own domain" -msgstr "" +msgstr "Minulla on oma verkkotunnus" #: src/view/com/lightbox/Lightbox.web.tsx:165 msgid "If alt text is long, toggles alt text expanded state" -msgstr "" +msgstr "Jos ALT-teksti on pitkä, vaihtaa ALT-tekstin laajennetun tilan" #: src/view/com/modals/SelfLabel.tsx:127 msgid "If none are selected, suitable for all ages." -msgstr "" +msgstr "Jos mitään ei ole valittu, sopii kaikenikäisille." #: src/view/com/modals/ChangePassword.tsx:146 msgid "If you want to change your password, we will send you a code to verify that this is your account." -msgstr "" +msgstr "Jos haluat vaihtaa salasanasi, lähetämme sinulle koodin varmistaaksemme, että tämä on tilisi." #: src/view/com/util/images/Gallery.tsx:38 msgid "Image" -msgstr "" +msgstr "Kuva" #: src/view/com/modals/AltImage.tsx:120 msgid "Image alt text" -msgstr "" +msgstr "Kuvan ALT-teksti" #: src/view/com/util/UserAvatar.tsx:311 #: src/view/com/util/UserBanner.tsx:118 msgid "Image options" -msgstr "" +msgstr "Kuva-asetukset" #: src/view/com/auth/login/SetNewPasswordForm.tsx:138 msgid "Input code sent to your email for password reset" -msgstr "" +msgstr "Syötä sähköpostiisi lähetetty koodi salasanan nollaamista varten" #: src/view/com/modals/DeleteAccount.tsx:184 msgid "Input confirmation code for account deletion" -msgstr "" +msgstr "Syötä vahvistuskoodi tilin poistoa varten" #: src/view/com/auth/create/Step1.tsx:200 msgid "Input email for Bluesky account" -msgstr "" +msgstr "Syötä sähköposti Bluesky-tiliä varten" #: src/view/com/auth/create/Step1.tsx:158 msgid "Input invite code to proceed" -msgstr "" +msgstr "Syötä kutsukoodi jatkaaksesi" #: src/view/com/modals/AddAppPasswords.tsx:180 msgid "Input name for app password" -msgstr "" +msgstr "Syötä nimi sovellussalasanaa varten" #: src/view/com/auth/login/SetNewPasswordForm.tsx:162 msgid "Input new password" -msgstr "" +msgstr "Syötä uusi salasana" #: src/view/com/modals/DeleteAccount.tsx:203 msgid "Input password for account deletion" -msgstr "" +msgstr "Syötä salasana tilin poistoa varten" #: src/view/com/auth/create/Step2.tsx:196 #~ msgid "Input phone number for SMS verification" -#~ msgstr "" +#~ msgstr "Syötä puhelinnumero SMS-varmennusta varten" #: src/view/com/auth/login/LoginForm.tsx:230 msgid "Input the password tied to {identifier}" -msgstr "" +msgstr "Syötä salasana, joka liittyy kohteeseen {identifier}" #: src/view/com/auth/login/LoginForm.tsx:197 msgid "Input the username or email address you used at signup" -msgstr "" +msgstr "Syötä käyttäjätunnus tai sähköpostiosoite, jonka käytit rekisteröityessäsi" #: src/view/com/auth/create/Step2.tsx:271 #~ msgid "Input the verification code we have texted to you" -#~ msgstr "" +#~ msgstr "Syötä sinulle tekstattu varmennuskoodi" #: src/view/com/modals/Waitlist.tsx:90 msgid "Input your email to get on the Bluesky waitlist" -msgstr "" +msgstr "Syötä sähköpostiosoitteesi päästäksesi Bluesky-jonoon" #: src/view/com/auth/login/LoginForm.tsx:229 msgid "Input your password" -msgstr "" +msgstr "Syötä salasanasi" #: src/view/com/auth/create/Step2.tsx:80 msgid "Input your user handle" -msgstr "" +msgstr "Syötä käyttäjätunnuksesi" #: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" -msgstr "" +msgstr "Virheellinen tai ei tuettu tietue" #: src/view/com/auth/login/LoginForm.tsx:113 msgid "Invalid username or password" -msgstr "" +msgstr "Virheellinen käyttäjätunnus tai salasana" #: src/view/screens/Settings.tsx:411 #~ msgid "Invite" @@ -1953,20 +1953,20 @@ msgstr "" #: src/view/com/modals/InviteCodes.tsx:93 msgid "Invite a Friend" -msgstr "" +msgstr "Kutsu ystävä" #: src/view/com/auth/create/Step1.tsx:148 #: src/view/com/auth/create/Step1.tsx:157 msgid "Invite code" -msgstr "" +msgstr "Kutsukoodi" #: src/view/com/auth/create/state.ts:158 msgid "Invite code not accepted. Check that you input it correctly and try again." -msgstr "" +msgstr "Kutsukoodia ei hyväksytty. Tarkista, että syötit sen oikein ja yritä uudelleen." #: src/view/com/modals/InviteCodes.tsx:170 msgid "Invite codes: {0} available" -msgstr "" +msgstr "Kutsukoodit: {0} saatavilla" #: src/view/shell/Drawer.tsx:645 #~ msgid "Invite codes: {invitesAvailable} available" @@ -1974,64 +1974,64 @@ msgstr "" #: src/view/com/modals/InviteCodes.tsx:169 msgid "Invite codes: 1 available" -msgstr "" +msgstr "Kutsukoodit: 1 saatavilla" #: src/screens/Onboarding/StepFollowingFeed.tsx:64 msgid "It shows posts from the people you follow as they happen." -msgstr "" +msgstr "Se näyttää viestejä seuraamiltasi ihmisiltä reaaliajassa." #: src/view/com/auth/HomeLoggedOutCTA.tsx:99 #: src/view/com/auth/SplashScreen.web.tsx:138 msgid "Jobs" -msgstr "" +msgstr "Työpaikat" #: src/view/com/modals/Waitlist.tsx:67 msgid "Join the waitlist" -msgstr "" +msgstr "Liity odotuslistalle" #: src/view/com/auth/create/Step1.tsx:174 #: src/view/com/auth/create/Step1.tsx:178 msgid "Join the waitlist." -msgstr "" +msgstr "Liity odotuslistalle." #: src/view/com/modals/Waitlist.tsx:128 msgid "Join Waitlist" -msgstr "" +msgstr "Liity odotuslistalle" #: src/screens/Onboarding/index.tsx:24 msgid "Journalism" -msgstr "" +msgstr "Journalismi" #: src/view/com/composer/select-language/SelectLangBtn.tsx:104 msgid "Language selection" -msgstr "" +msgstr "Kielen valinta" #: src/view/screens/Settings/index.tsx:594 msgid "Language settings" -msgstr "" +msgstr "Kielen asetukset" #: src/Navigation.tsx:140 #: src/view/screens/LanguageSettings.tsx:89 msgid "Language Settings" -msgstr "" +msgstr "Kielen asetukset" #: src/view/screens/Settings/index.tsx:603 msgid "Languages" -msgstr "" +msgstr "Kielet" #: src/view/com/auth/create/StepHeader.tsx:20 msgid "Last step!" -msgstr "" +msgstr "Viimeinen vaihe!" #: src/view/com/util/moderation/ContentHider.tsx:103 msgid "Learn more" -msgstr "" +msgstr "Lue lisää" #: src/view/com/util/moderation/PostAlerts.tsx:47 #: src/view/com/util/moderation/ProfileHeaderAlerts.tsx:65 #: src/view/com/util/moderation/ScreenHider.tsx:104 msgid "Learn More" -msgstr "" +msgstr "Lue lisää" #: src/view/com/util/moderation/ContentHider.tsx:85 #: src/view/com/util/moderation/PostAlerts.tsx:40 @@ -2039,123 +2039,123 @@ msgstr "" #: src/view/com/util/moderation/ProfileHeaderAlerts.tsx:49 #: src/view/com/util/moderation/ScreenHider.tsx:101 msgid "Learn more about this warning" -msgstr "" +msgstr "Lue lisää tästä varoituksesta" #: src/view/screens/Moderation.tsx:262 msgid "Learn more about what is public on Bluesky." -msgstr "" +msgstr "Lue lisää siitä, mikä on julkista Blueskyssa." #: src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx:82 msgid "Leave them all unchecked to see any language." -msgstr "" +msgstr "Jätä kaikki valitsematta nähdäksesi minkä tahansa kielen." #: src/view/com/modals/LinkWarning.tsx:51 msgid "Leaving Bluesky" -msgstr "" +msgstr "Poistuminen Blueskysta" #: src/screens/Deactivated.tsx:128 msgid "left to go." -msgstr "" +msgstr "jäljellä." #: src/view/screens/Settings/index.tsx:278 msgid "Legacy storage cleared, you need to restart the app now." -msgstr "" +msgstr "Legacy tietovarasto tyhjennetty, sinun on käynnistettävä sovellus uudelleen nyt." #: src/view/com/auth/login/Login.tsx:128 #: src/view/com/auth/login/Login.tsx:144 msgid "Let's get your password reset!" -msgstr "" +msgstr "Aloitetaan salasanasi nollaus!" #: src/screens/Onboarding/StepFinished.tsx:151 msgid "Let's go!" -msgstr "" +msgstr "Aloitetaan!" #: src/view/com/util/UserAvatar.tsx:248 #: src/view/com/util/UserBanner.tsx:62 msgid "Library" -msgstr "" +msgstr "Kirjasto" #: src/view/screens/Settings/index.tsx:479 msgid "Light" -msgstr "" +msgstr "Vaalea" #: src/view/com/util/post-ctrls/PostCtrls.tsx:182 #: src/view/com/util/post-ctrls/PostCtrls.tsx:216 msgid "Like" -msgstr "" +msgstr "Tykkää" #: src/view/screens/ProfileFeed.tsx:591 msgid "Like this feed" -msgstr "" +msgstr "Tykkää tästä syötteestä" #: src/Navigation.tsx:197 msgid "Liked by" -msgstr "" +msgstr "Tykänneet" #: src/view/screens/PostLikedBy.tsx:27 #: src/view/screens/ProfileFeedLikedBy.tsx:27 msgid "Liked By" -msgstr "" +msgstr "Tykänneet" #: src/view/com/feeds/FeedSourceCard.tsx:279 msgid "Liked by {0} {1}" -msgstr "" +msgstr "Tykänneet {0} {1}" #: src/view/screens/ProfileFeed.tsx:606 msgid "Liked by {likeCount} {0}" -msgstr "" +msgstr "Tykkäyksiä {likeCount} {0}" #: src/view/com/notifications/FeedItem.tsx:170 msgid "liked your custom feed" -msgstr "" +msgstr "tykkäsi mukautetusta syötteestäsi" #: src/view/com/notifications/FeedItem.tsx:155 msgid "liked your post" -msgstr "" +msgstr "tykkäsi viestistäsi" #: src/view/screens/Profile.tsx:183 msgid "Likes" -msgstr "" +msgstr "Tykkäykset" #: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" -msgstr "" +msgstr "Tykkäykset tässä viestissä" #: src/Navigation.tsx:166 msgid "List" -msgstr "" +msgstr "Lista" #: src/view/com/modals/CreateOrEditList.tsx:261 msgid "List Avatar" -msgstr "" +msgstr "Listan kuvake" #: src/view/screens/ProfileList.tsx:324 msgid "List blocked" -msgstr "" +msgstr "Lista estetty" #: src/view/com/feeds/FeedSourceCard.tsx:233 msgid "List by {0}" -msgstr "" +msgstr "Listan on luonut {0}" #: src/view/screens/ProfileList.tsx:378 msgid "List deleted" -msgstr "" +msgstr "Lista poistettu" #: src/view/screens/ProfileList.tsx:283 msgid "List muted" -msgstr "" +msgstr "Lista hiljennetty" #: src/view/com/modals/CreateOrEditList.tsx:275 msgid "List Name" -msgstr "" +msgstr "Listan nimi" #: src/view/screens/ProfileList.tsx:343 msgid "List unblocked" -msgstr "" +msgstr "Listaa estosta poistetut" #: src/view/screens/ProfileList.tsx:302 msgid "List unmuted" -msgstr "" +msgstr "Listaa hiljennyksestä poistetut" #: src/Navigation.tsx:110 #: src/view/screens/Profile.tsx:185 @@ -2163,27 +2163,27 @@ msgstr "" #: src/view/shell/Drawer.tsx:492 #: src/view/shell/Drawer.tsx:493 msgid "Lists" -msgstr "" +msgstr "Listat" #: src/view/com/post-thread/PostThread.tsx:333 #: src/view/com/post-thread/PostThread.tsx:341 msgid "Load more posts" -msgstr "" +msgstr "Lataa lisää viestejä" #: src/view/screens/Notifications.tsx:159 msgid "Load new notifications" -msgstr "" +msgstr "Lataa uusia ilmoituksia" #: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 #: src/view/screens/ProfileFeed.tsx:495 #: src/view/screens/ProfileList.tsx:681 msgid "Load new posts" -msgstr "" +msgstr "Lataa uusia viestejä" #: src/view/com/composer/text-input/mobile/Autocomplete.tsx:95 msgid "Loading..." -msgstr "" +msgstr "Ladataan..." #: src/view/com/modals/ServerInput.tsx:50 #~ msgid "Local dev server" @@ -2191,59 +2191,59 @@ msgstr "" #: src/Navigation.tsx:207 msgid "Log" -msgstr "" +msgstr "Loki" #: src/screens/Deactivated.tsx:149 #: src/screens/Deactivated.tsx:152 #: src/screens/Deactivated.tsx:178 #: src/screens/Deactivated.tsx:181 msgid "Log out" -msgstr "" +msgstr "Kirjaudu ulos" #: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" -msgstr "" +msgstr "Näkyvyys kirjautumattomana" #: src/view/com/auth/login/ChooseAccountForm.tsx:133 msgid "Login to account that is not listed" -msgstr "" +msgstr "Kirjaudu tiliin, joka ei ole luettelossa" #: src/view/com/modals/LinkWarning.tsx:65 msgid "Make sure this is where you intend to go!" -msgstr "" +msgstr "Varmista, että olet menossa oikeaan paikkaan!" #: src/components/dialogs/MutedWords.tsx:71 msgid "Manage your muted words and tags" -msgstr "" +msgstr "Hallinnoi hiljennettyjä sanojasi ja tunnisteitasi" #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" -msgstr "" +msgstr "Ei saa olla pidempi kuin 253 merkkiä" #: src/view/com/auth/create/Step2.tsx:109 msgid "May only contain letters and numbers" -msgstr "" +msgstr "Ei saa olla pidempi kuin 253 merkkiä" #: src/view/screens/Profile.tsx:182 msgid "Media" -msgstr "" +msgstr "Media" #: src/view/com/threadgate/WhoCanReply.tsx:139 msgid "mentioned users" -msgstr "" +msgstr "mainitut käyttäjät" #: src/view/com/modals/Threadgate.tsx:93 msgid "Mentioned users" -msgstr "" +msgstr "Mainitut käyttäjät" #: src/view/com/util/ViewHeader.tsx:81 -#: src/view/screens/Search/Search.tsx:646 +#: src/view/screens/Search/Search.tsx:623 msgid "Menu" -msgstr "" +msgstr "Valikko" #: src/view/com/posts/FeedErrorMessage.tsx:197 msgid "Message from server: {0}" -msgstr "" +msgstr "Viesti palvelimelta: {0}" #: src/Navigation.tsx:115 #: src/view/screens/Moderation.tsx:66 @@ -2252,183 +2252,182 @@ msgstr "" #: src/view/shell/Drawer.tsx:511 #: src/view/shell/Drawer.tsx:512 msgid "Moderation" -msgstr "" +msgstr "Moderointi" #: src/view/com/lists/ListCard.tsx:93 #: src/view/com/modals/UserAddRemoveLists.tsx:206 msgid "Moderation list by {0}" -msgstr "" +msgstr "Moderointilista käyttäjältä {0}" #: src/view/screens/ProfileList.tsx:774 msgid "Moderation list by <0/>" -msgstr "" +msgstr "Moderointilista käyttäjältä <0/>" #: src/view/com/lists/ListCard.tsx:91 #: src/view/com/modals/UserAddRemoveLists.tsx:204 #: src/view/screens/ProfileList.tsx:772 msgid "Moderation list by you" -msgstr "" +msgstr "Sinun moderointilistasi" #: src/view/com/modals/CreateOrEditList.tsx:197 msgid "Moderation list created" -msgstr "" +msgstr "Moderointilista luotu" #: src/view/com/modals/CreateOrEditList.tsx:183 msgid "Moderation list updated" -msgstr "" +msgstr "Moderointilista päivitetty" #: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" -msgstr "" +msgstr "Moderointilistat" #: src/Navigation.tsx:120 #: src/view/screens/ModerationModlists.tsx:58 msgid "Moderation Lists" -msgstr "" +msgstr "Moderointilistat" #: src/view/screens/Settings/index.tsx:619 msgid "Moderation settings" -msgstr "" +msgstr "Moderointiasetukset" #: src/view/com/modals/ModerationDetails.tsx:35 msgid "Moderator has chosen to set a general warning on the content." -msgstr "" +msgstr "Ylläpitäjä on asettanut yleisen varoituksen sisällölle." #: src/view/shell/desktop/Feeds.tsx:63 msgid "More feeds" -msgstr "" +msgstr "Lisää syötteitä" #: src/view/com/profile/ProfileHeader.tsx:523 #: src/view/screens/ProfileFeed.tsx:363 #: src/view/screens/ProfileList.tsx:617 msgid "More options" -msgstr "" +msgstr "Lisää asetuksia" #: src/view/com/util/forms/PostDropdownBtn.tsx:315 msgid "More post options" -msgstr "" +msgstr "Lisää viestiasetuksia" #: src/view/screens/PreferencesThreads.tsx:82 msgid "Most-liked replies first" -msgstr "" +msgstr "Eniten tykätyt vastaukset ensin" #: src/view/com/auth/create/Step2.tsx:122 msgid "Must be at least 3 characters" -msgstr "" +msgstr "Täytyy olla vähintään 3 merkkiä" #: src/components/TagMenu/index.tsx:253 msgid "Mute" -msgstr "" +msgstr "Hiljennä" #: src/components/TagMenu/index.web.tsx:91 msgid "Mute {truncatedTag}" -msgstr "" +msgstr "Hiljennä {truncatedTag}" #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" -msgstr "" +msgstr "Hiljennä käyttäjä" #: src/view/screens/ProfileList.tsx:544 msgid "Mute accounts" -msgstr "" - +msgstr "Hiljennä käyttäjät" #: src/components/TagMenu/index.tsx:211 msgid "Mute all {tag} posts" -msgstr "" +msgstr "Hiljennä kaikki {tag}-viestit" #: src/components/dialogs/MutedWords.tsx:131 msgid "Mute in tags only" -msgstr "" +msgstr "Hiljennä vain tunnisteissa" #: src/components/dialogs/MutedWords.tsx:116 msgid "Mute in text & tags" -msgstr "" +msgstr "Hiljennä tekstissä ja tunnisteissa" #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" -msgstr "" +msgstr "Hiljennä lista" #: src/view/screens/ProfileList.tsx:275 msgid "Mute these accounts?" -msgstr "" +msgstr "Hiljennä nämä käyttäjät?" #: src/view/screens/ProfileList.tsx:279 msgid "Mute this List" -msgstr "" +msgstr "Hiljennä tämä lista" #: src/components/dialogs/MutedWords.tsx:109 msgid "Mute this word in post text and tags" -msgstr "" +msgstr "Hiljennä tämä sana viesteissä ja tunnisteissa" #: src/components/dialogs/MutedWords.tsx:124 msgid "Mute this word in tags only" -msgstr "" +msgstr "Hiljennä tämä sana vain tunnisteissa" #: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Mute thread" -msgstr "" +msgstr "Hiljennä keskustelu" #: src/view/com/util/forms/PostDropdownBtn.tsx:216 msgid "Mute words & tags" -msgstr "" +msgstr "Hiljennä sanat ja tunnisteet" #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" -msgstr "" +msgstr "Hiljennetty" #: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" -msgstr "" +msgstr "Hiljennetyt käyttäjät" #: src/Navigation.tsx:125 #: src/view/screens/ModerationMutedAccounts.tsx:107 msgid "Muted Accounts" -msgstr "" +msgstr "Hiljennetyt käyttäjätilit" #: src/view/screens/ModerationMutedAccounts.tsx:115 msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." -msgstr "" +msgstr "Hiljennettyjen käyttäjien viestit poistetaan syötteestäsi ja ilmoituksistasi. Hiljennykset ovat täysin yksityisiä." #: src/view/screens/Moderation.tsx:100 msgid "Muted words & tags" -msgstr "" +msgstr "Hiljennetyt sanat ja tunnisteet" #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." -msgstr "" +msgstr "Hiljennys on yksityinen. Hiljennetyt käyttäjät voivat edelleen vuorovaikuttaa kanssasi, mutta et näe heidän viestejään tai saa ilmoituksia heiltä." #: src/view/com/modals/BirthDateSettings.tsx:56 msgid "My Birthday" -msgstr "" +msgstr "Syntymäpäiväni" #: src/view/screens/Feeds.tsx:663 msgid "My Feeds" -msgstr "" +msgstr "Omat syötteet" #: src/view/shell/desktop/LeftNav.tsx:65 msgid "My Profile" -msgstr "" +msgstr "Profiilini" #: src/view/screens/Settings/index.tsx:582 msgid "My Saved Feeds" -msgstr "" +msgstr "Omat tallennetut syötteet" #: src/view/com/auth/server-input/index.tsx:118 msgid "my-server.com" -msgstr "" +msgstr "oma-palvelimeni.com" #: src/view/com/modals/AddAppPasswords.tsx:179 #: src/view/com/modals/CreateOrEditList.tsx:290 msgid "Name" -msgstr "" +msgstr "Nimi" #: src/view/com/modals/CreateOrEditList.tsx:145 msgid "Name is required" -msgstr "" +msgstr "Nimi vaaditaan" #: src/screens/Onboarding/index.tsx:25 msgid "Nature" -msgstr "" +msgstr "Luonto" #: src/view/com/auth/login/ForgotPasswordForm.tsx:190 #: src/view/com/auth/login/ForgotPasswordForm.tsx:219 @@ -2436,55 +2435,55 @@ msgstr "" #: src/view/com/auth/login/SetNewPasswordForm.tsx:196 #: src/view/com/modals/ChangePassword.tsx:166 msgid "Navigates to the next screen" -msgstr "" +msgstr "Siirtyy seuraavalle näytölle" #: src/view/shell/Drawer.tsx:71 msgid "Navigates to your profile" -msgstr "" +msgstr "Siirtyy profiiliisi" #: src/view/com/modals/EmbedConsent.tsx:107 #: src/view/com/modals/EmbedConsent.tsx:123 msgid "Never load embeds from {0}" -msgstr "" +msgstr "Älä koskaan lataa upotuksia taholta {0}" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:72 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:72 msgid "Never lose access to your followers and data." -msgstr "" +msgstr "Älä koskaan menetä pääsyä seuraajiisi ja tietoihisi." #: src/screens/Onboarding/StepFinished.tsx:119 msgid "Never lose access to your followers or data." -msgstr "" +msgstr "Älä koskaan menetä pääsyä seuraajiisi tai tietoihisi." #: src/components/dialogs/MutedWords.tsx:244 msgid "Nevermind" -msgstr "" +msgstr "Ei väliä" #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" -msgstr "" +msgstr "Uusi" #: src/view/screens/ModerationModlists.tsx:78 msgid "New" -msgstr "" +msgstr "Uusi" #: src/view/com/modals/CreateOrEditList.tsx:252 msgid "New Moderation List" -msgstr "" +msgstr "Uusi moderointilista" #: src/view/com/auth/login/SetNewPasswordForm.tsx:150 msgid "New password" -msgstr "" +msgstr "Uusi salasana" #: src/view/com/modals/ChangePassword.tsx:215 msgid "New Password" -msgstr "" +msgstr "Uusi salasana" #: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" -msgstr "" +msgstr "Uusi viesti" #: src/view/screens/Feeds.tsx:555 #: src/view/screens/Notifications.tsx:168 @@ -2494,24 +2493,24 @@ msgstr "" #: src/view/screens/ProfileList.tsx:224 #: src/view/shell/desktop/LeftNav.tsx:248 msgid "New post" -msgstr "" +msgstr "Uusi viesti" #: src/view/shell/desktop/LeftNav.tsx:258 msgctxt "action" msgid "New Post" -msgstr "" +msgstr "Uusi viesti" #: src/view/com/modals/CreateOrEditList.tsx:247 msgid "New User List" -msgstr "" +msgstr "Uusi käyttäjälista" #: src/view/screens/PreferencesThreads.tsx:79 msgid "Newest replies first" -msgstr "" +msgstr "Uusimmat vastaukset ensin" #: src/screens/Onboarding/index.tsx:23 msgid "News" -msgstr "" +msgstr "Uutiset" #: src/view/com/auth/create/CreateAccount.tsx:172 #: src/view/com/auth/login/ForgotPasswordForm.tsx:182 @@ -2523,16 +2522,16 @@ msgstr "" #: src/view/com/modals/ChangePassword.tsx:251 #: src/view/com/modals/ChangePassword.tsx:253 msgid "Next" -msgstr "" +msgstr "Seuraava" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 msgctxt "action" msgid "Next" -msgstr "" +msgstr "Seuraava" #: src/view/com/lightbox/Lightbox.web.tsx:149 msgid "Next image" -msgstr "" +msgstr "Seuraava kuva" #: src/view/screens/PreferencesFollowingFeed.tsx:129 #: src/view/screens/PreferencesFollowingFeed.tsx:200 @@ -2541,61 +2540,61 @@ msgstr "" #: src/view/screens/PreferencesThreads.tsx:106 #: src/view/screens/PreferencesThreads.tsx:129 msgid "No" -msgstr "" +msgstr "Ei" #: src/view/screens/ProfileFeed.tsx:584 #: src/view/screens/ProfileList.tsx:754 msgid "No description" -msgstr "" +msgstr "Ei kuvausta" #: src/view/com/profile/ProfileHeader.tsx:170 msgid "No longer following {0}" -msgstr "" +msgstr "Et enää seuraa käyttäjää {0}" #: src/view/com/notifications/Feed.tsx:109 msgid "No notifications yet!" -msgstr "" +msgstr "Ei vielä ilmoituksia!" #: src/view/com/composer/text-input/mobile/Autocomplete.tsx:97 #: src/view/com/composer/text-input/web/Autocomplete.tsx:191 msgid "No result" -msgstr "" +msgstr "Ei tuloksia" #: src/view/screens/Feeds.tsx:495 msgid "No results found for \"{query}\"" -msgstr "" +msgstr "Ei tuloksia haulle \"{query}\"" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 #: src/view/screens/Search/Search.tsx:281 #: src/view/screens/Search/Search.tsx:309 msgid "No results found for {query}" -msgstr "" +msgstr "Ei tuloksia haulle {query}" #: src/view/com/modals/EmbedConsent.tsx:129 msgid "No thanks" -msgstr "" +msgstr "Ei kiitos" #: src/view/com/modals/Threadgate.tsx:82 msgid "Nobody" -msgstr "" +msgstr "Ei ketään" #: src/view/com/modals/SelfLabel.tsx:135 msgid "Not Applicable." -msgstr "" +msgstr "Ei sovellettavissa." #: src/Navigation.tsx:105 #: src/view/screens/Profile.tsx:106 msgid "Not Found" -msgstr "" +msgstr "Ei löytynyt" #: src/view/com/modals/VerifyEmail.tsx:246 #: src/view/com/modals/VerifyEmail.tsx:252 msgid "Not right now" -msgstr "" +msgstr "Ei juuri nyt" #: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." -msgstr "" +msgstr "Huomio: Bluesky on avoin ja julkinen verkosto. Tämä asetus rajoittaa vain sisältösi näkyvyyttä Bluesky-sovelluksessa ja -sivustolla, eikä muut sovellukset ehkä kunnioita tässä asetuksissaan. Sisältösi voi silti näkyä uloskirjautuneille käyttäjille muissa sovelluksissa ja verkkosivustoilla." #: src/Navigation.tsx:450 #: src/view/screens/Notifications.tsx:124 @@ -2605,117 +2604,117 @@ msgstr "" #: src/view/shell/Drawer.tsx:435 #: src/view/shell/Drawer.tsx:436 msgid "Notifications" -msgstr "" +msgstr "Ilmoitukset" #: src/view/com/modals/SelfLabel.tsx:103 msgid "Nudity" -msgstr "" +msgstr "Alastomuus" #: src/view/com/util/ErrorBoundary.tsx:35 msgid "Oh no!" -msgstr "" +msgstr "Voi ei!" #: src/screens/Onboarding/StepInterests/index.tsx:128 msgid "Oh no! Something went wrong." -msgstr "" +msgstr "Voi ei! Jokin meni pieleen." #: src/view/com/auth/login/PasswordUpdatedForm.tsx:41 msgid "Okay" -msgstr "" +msgstr "Selvä" #: src/view/screens/PreferencesThreads.tsx:78 msgid "Oldest replies first" -msgstr "" +msgstr "Vanhimmat vastaukset ensin" #: src/view/screens/Settings/index.tsx:234 msgid "Onboarding reset" -msgstr "" +msgstr "Käyttöönoton nollaus" #: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." -msgstr "" +msgstr "Yksi tai useampi kuva on ilman vaihtoehtoista Alt-tekstiä." #: src/view/com/threadgate/WhoCanReply.tsx:100 msgid "Only {0} can reply." -msgstr "" +msgstr "Vain {0} voi vastata." #: src/view/screens/AppPasswords.tsx:65 #: src/view/screens/Profile.tsx:106 msgid "Oops!" -msgstr "" +msgstr "Hups!" #: src/screens/Onboarding/StepFinished.tsx:115 msgid "Open" -msgstr "" +msgstr "Avaa" #: src/view/screens/Moderation.tsx:75 msgid "Open content filtering settings" -msgstr "" +msgstr "Avaa sisällönsuodatusasetukset" #: src/view/com/composer/Composer.tsx:477 #: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" -msgstr "" +msgstr "Avaa emoji-valitsin" #: src/view/screens/Settings/index.tsx:712 msgid "Open links with in-app browser" -msgstr "" +msgstr "Avaa linkit sovelluksen sisäisellä selaimella" #: src/view/screens/Moderation.tsx:92 msgid "Open muted words settings" -msgstr "" +msgstr "Avaa hiljennettyjen sanojen asetukset" #: src/view/com/home/HomeHeaderLayoutMobile.tsx:49 msgid "Open navigation" -msgstr "" +msgstr "Avaa navigointi" #: src/view/screens/Settings/index.tsx:804 msgid "Open storybook page" -msgstr "" +msgstr "Avaa storybook-sivu" #: src/view/com/util/forms/DropdownButton.tsx:154 msgid "Opens {numItems} options" -msgstr "" +msgstr "Avaa {numItems} asetusta" #: src/view/screens/Log.tsx:54 msgid "Opens additional details for a debug entry" -msgstr "" +msgstr "Avaa debug lisätiedot" #: src/view/com/notifications/FeedItem.tsx:348 msgid "Opens an expanded list of users in this notification" -msgstr "" +msgstr "Avaa laajennetun listan tämän ilmoituksen käyttäjistä" #: src/view/com/composer/photos/OpenCameraBtn.tsx:61 msgid "Opens camera on device" -msgstr "" +msgstr "Avaa laitteen kameran" #: src/view/com/composer/Prompt.tsx:25 msgid "Opens composer" -msgstr "" +msgstr "Avaa editorin" #: src/view/screens/Settings/index.tsx:595 msgid "Opens configurable language settings" -msgstr "" +msgstr "Avaa mukautettavat kielen asetukset" #: src/view/com/composer/photos/SelectPhotoBtn.tsx:44 msgid "Opens device photo gallery" -msgstr "" +msgstr "Avaa laitteen valokuvat" #: src/view/com/profile/ProfileHeader.tsx:420 msgid "Opens editor for profile display name, avatar, background image, and description" -msgstr "" +msgstr "Avaa editorin profiilin näyttönimeä, avataria, taustakuvaa ja kuvausta varten" #: src/view/screens/Settings/index.tsx:649 msgid "Opens external embeds settings" -msgstr "" +msgstr "Avaa ulkoiset upotusasetukset" #: src/view/com/profile/ProfileHeader.tsx:575 msgid "Opens followers list" -msgstr "" +msgstr "Avaa seuraajalistan" #: src/view/com/profile/ProfileHeader.tsx:594 msgid "Opens following list" -msgstr "" +msgstr "Avaa seurattavien listan" #: src/view/screens/Settings.tsx:412 #~ msgid "Opens invite code list" @@ -2723,64 +2722,64 @@ msgstr "" #: src/view/com/modals/InviteCodes.tsx:172 msgid "Opens list of invite codes" -msgstr "" +msgstr "Avaa kutsukoodien luettelon" #: src/view/screens/Settings/index.tsx:774 msgid "Opens modal for account deletion confirmation. Requires email code." -msgstr "" +msgstr "Avaa tilin poistovahvistuksen. Vaatii sähköpostikoodin." #: src/view/com/modals/ChangeHandle.tsx:281 msgid "Opens modal for using custom domain" -msgstr "" +msgstr "Avaa asetukset oman verkkotunnuksen käyttöönottoon" #: src/view/screens/Settings/index.tsx:620 msgid "Opens moderation settings" -msgstr "" +msgstr "Avaa moderointiasetukset" #: src/view/com/auth/login/LoginForm.tsx:239 msgid "Opens password reset form" -msgstr "" +msgstr "Avaa salasanan palautuslomakkeen" #: src/view/com/home/HomeHeaderLayout.web.tsx:60 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" -msgstr "" +msgstr "Avaa näkymän tallennettujen syötteiden muokkaamiseen" #: src/view/screens/Settings/index.tsx:576 msgid "Opens screen with all saved feeds" -msgstr "" +msgstr "Avaa näkymän kaikkiin tallennettuihin syötteisiin" #: src/view/screens/Settings/index.tsx:676 msgid "Opens the app password settings page" -msgstr "" +msgstr "Avaa sovellussalasanojen asetukset" #: src/view/screens/Settings/index.tsx:535 msgid "Opens the home feed preferences" -msgstr "" +msgstr "Avaa aloitussivun asetukset" #: src/view/screens/Settings/index.tsx:805 msgid "Opens the storybook page" -msgstr "" +msgstr "Avaa storybook-sivun" #: src/view/screens/Settings/index.tsx:793 msgid "Opens the system log page" -msgstr "" +msgstr "Avaa järjestelmän lokisivun" #: src/view/screens/Settings/index.tsx:556 msgid "Opens the threads preferences" -msgstr "" +msgstr "Avaa keskusteluasetukset" #: src/view/com/util/forms/DropdownButton.tsx:280 msgid "Option {0} of {numItems}" -msgstr "" +msgstr "Asetus {0}/{numItems}" #: src/view/com/modals/Threadgate.tsx:89 msgid "Or combine these options:" -msgstr "" +msgstr "Tai yhdistä nämä asetukset:" #: src/view/com/auth/login/ChooseAccountForm.tsx:138 msgid "Other account" -msgstr "" +msgstr "Toinen tili" #: src/view/com/modals/ServerInput.tsx:88 #~ msgid "Other service" @@ -2788,15 +2787,15 @@ msgstr "" #: src/view/com/composer/select-language/SelectLangBtn.tsx:91 msgid "Other..." -msgstr "" +msgstr "Muu..." #: src/view/screens/NotFound.tsx:45 msgid "Page not found" -msgstr "" +msgstr "Sivua ei löytynyt" #: src/view/screens/NotFound.tsx:42 msgid "Page Not Found" -msgstr "" +msgstr "Sivua ei löytynyt" #: src/view/com/auth/create/Step1.tsx:214 #: src/view/com/auth/create/Step1.tsx:224 @@ -2804,114 +2803,114 @@ msgstr "" #: src/view/com/auth/login/SetNewPasswordForm.tsx:161 #: src/view/com/modals/DeleteAccount.tsx:202 msgid "Password" -msgstr "" +msgstr "Salasana" #: src/view/com/auth/login/Login.tsx:157 msgid "Password updated" -msgstr "" +msgstr "Salasana päivitetty" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:28 msgid "Password updated!" -msgstr "" +msgstr "Salasana päivitetty!" #: src/Navigation.tsx:160 msgid "People followed by @{0}" -msgstr "" +msgstr "Henkilöt, joita @{0} seuraa" #: src/Navigation.tsx:153 msgid "People following @{0}" -msgstr "" +msgstr "Henkilöt, jotka seuraavat käyttäjää @{0}" #: src/view/com/lightbox/Lightbox.tsx:66 msgid "Permission to access camera roll is required." -msgstr "" +msgstr "Käyttöoikeus valokuviin tarvitaan." #: src/view/com/lightbox/Lightbox.tsx:72 msgid "Permission to access camera roll was denied. Please enable it in your system settings." -msgstr "" +msgstr "Lupa valokuviin evättiin. Anna lupa järjestelmäasetuksissa." #: src/screens/Onboarding/index.tsx:31 msgid "Pets" -msgstr "" +msgstr "Lemmikit" #: src/view/com/auth/create/Step2.tsx:183 #~ msgid "Phone number" -#~ msgstr "" +#~ msgstr "Puhelinnumero" #: src/view/com/modals/SelfLabel.tsx:121 msgid "Pictures meant for adults." -msgstr "" +msgstr "Aikuisille tarkoitetut kuvat." #: src/view/screens/ProfileFeed.tsx:354 #: src/view/screens/ProfileList.tsx:581 msgid "Pin to home" -msgstr "" +msgstr "Kiinnitä etusivulle" #: src/view/screens/SavedFeeds.tsx:88 msgid "Pinned Feeds" -msgstr "" +msgstr "Kiinnitetyt syötteet" #: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:111 msgid "Play {0}" -msgstr "" +msgstr "Toista {0}" #: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:54 #: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:55 msgid "Play Video" -msgstr "" +msgstr "Toista video" #: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:110 msgid "Plays the GIF" -msgstr "" +msgstr "Toistaa GIFin" #: src/view/com/auth/create/state.ts:124 msgid "Please choose your handle." -msgstr "" +msgstr "Valitse käyttäjätunnuksesi." #: src/view/com/auth/create/state.ts:117 msgid "Please choose your password." -msgstr "" +msgstr "Valitse salasanasi." #: src/view/com/auth/create/state.ts:131 msgid "Please complete the verification captcha." -msgstr "" +msgstr "Täydennä varmennus-captcha, ole hyvä." #: src/view/com/modals/ChangeEmail.tsx:67 msgid "Please confirm your email before changing it. This is a temporary requirement while email-updating tools are added, and it will soon be removed." -msgstr "" +msgstr "Vahvista sähköpostiosoitteesi ennen sen vaihtamista. Tämä on väliaikainen vaatimus, kunnes sähköpostin muokkaamisen liittyvät asetukset ovat lisätty ja se poistetaan piakkoin." #: src/view/com/modals/AddAppPasswords.tsx:90 msgid "Please enter a name for your app password. All spaces is not allowed." -msgstr "" +msgstr "Anna nimi sovellussalasanalle. Kaikki välilyönnit eivät ole sallittuja." #: src/view/com/auth/create/Step2.tsx:206 #~ msgid "Please enter a phone number that can receive SMS text messages." -#~ msgstr "" +#~ msgstr "Anna puhelinnumero, joka voi vastaanottaa tekstiviestejä." #: src/view/com/modals/AddAppPasswords.tsx:145 msgid "Please enter a unique name for this App Password or use our randomly generated one." -msgstr "" +msgstr "Anna uniikki nimi tälle sovellussalasanalle tai käytä satunnaisesti luotua." #: src/view/com/auth/create/state.ts:170 #~ msgid "Please enter the code you received by SMS." -#~ msgstr "" +#~ msgstr "Anna tekstiviestitse saamasi koodi." #: src/view/com/auth/create/Step2.tsx:282 #~ msgid "Please enter the verification code sent to {phoneNumberFormatted}." -#~ msgstr "" +#~ msgstr "Anna numeroon {phoneNumberFormatted} vastaanottamasi vahvistuskoodi." #: src/view/com/auth/create/state.ts:103 msgid "Please enter your email." -msgstr "" +msgstr "Anna sähköpostiosoitteesi." #: src/view/com/modals/DeleteAccount.tsx:191 msgid "Please enter your password as well:" -msgstr "" +msgstr "Anna myös salasanasi:" #: src/view/com/modals/AppealLabel.tsx:72 #: src/view/com/modals/AppealLabel.tsx:75 msgid "Please tell us why you think this content warning was incorrectly applied!" -msgstr "" +msgstr "Kerro meille, miksi luulet, että tämä sisältövaroitus on sovellettu virheellisesti!" #: src/view/com/modals/AppealLabel.tsx:72 #: src/view/com/modals/AppealLabel.tsx:75 @@ -2920,108 +2919,108 @@ msgstr "" #: src/view/com/modals/VerifyEmail.tsx:101 msgid "Please Verify Your Email" -msgstr "" +msgstr "Vahvista sähköpostiosoitteesi" #: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" -msgstr "" +msgstr "Odota, että linkkikortti latautuu kokonaan" #: src/screens/Onboarding/index.tsx:37 msgid "Politics" -msgstr "" +msgstr "Politiikka" #: src/view/com/modals/SelfLabel.tsx:111 msgid "Porn" -msgstr "" +msgstr "Porno" #: src/view/com/composer/Composer.tsx:357 #: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" -msgstr "" +msgstr "Lähetä" #: src/view/com/post-thread/PostThread.tsx:303 msgctxt "description" msgid "Post" -msgstr "" +msgstr "Viesti" #: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" -msgstr "" +msgstr "Lähettäjä {0}" #: src/Navigation.tsx:172 #: src/Navigation.tsx:179 #: src/Navigation.tsx:186 msgid "Post by @{0}" -msgstr "" +msgstr "Lähettäjä @{0}" #: src/view/com/util/forms/PostDropdownBtn.tsx:90 msgid "Post deleted" -msgstr "" +msgstr "Viesti poistettu" #: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" -msgstr "" +msgstr "Viesti piilotettu" #: src/view/com/composer/select-language/SelectLangBtn.tsx:87 msgid "Post language" -msgstr "" +msgstr "Lähetyskieli" #: src/view/com/modals/lang-settings/PostLanguagesSettings.tsx:75 msgid "Post Languages" -msgstr "" +msgstr "Lähetyskielet" #: src/view/com/post-thread/PostThread.tsx:514 msgid "Post not found" -msgstr "" +msgstr "Viestiä ei löydy" #: src/components/TagMenu/index.tsx:257 msgid "posts" -msgstr "" +msgstr "viestit" #: src/view/screens/Profile.tsx:180 msgid "Posts" -msgstr "" +msgstr "Viestit" #: src/components/dialogs/MutedWords.tsx:77 msgid "Posts can be muted based on their text, their tags, or both." -msgstr "" +msgstr "Viestejä voidaan hiljentää niiden tekstin, tunnisteiden tai molempien perusteella." #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" -msgstr "" +msgstr "Piilotetut viestit" #: src/view/com/modals/LinkWarning.tsx:46 msgid "Potentially Misleading Link" -msgstr "" +msgstr "Mahdollisesti harhaanjohtava linkki" #: src/view/com/lightbox/Lightbox.web.tsx:135 msgid "Previous image" -msgstr "" +msgstr "Edellinen kuva" #: src/view/screens/LanguageSettings.tsx:187 msgid "Primary Language" -msgstr "" +msgstr "Ensisijainen kieli" #: src/view/screens/PreferencesThreads.tsx:97 msgid "Prioritize Your Follows" -msgstr "" +msgstr "Aseta seurattavat tärkeysjärjestykseen" #: src/view/screens/Settings/index.tsx:632 #: src/view/shell/desktop/RightNav.tsx:72 msgid "Privacy" -msgstr "" +msgstr "Yksityisyys" #: src/Navigation.tsx:217 #: src/view/screens/PrivacyPolicy.tsx:29 #: src/view/screens/Settings/index.tsx:891 #: src/view/shell/Drawer.tsx:262 msgid "Privacy Policy" -msgstr "" +msgstr "Yksityisyydensuojakäytäntö" #: src/view/com/auth/login/ForgotPasswordForm.tsx:198 msgid "Processing..." -msgstr "" +msgstr "Käsitellään..." #: src/view/shell/bottom-bar/BottomBar.tsx:247 #: src/view/shell/desktop/LeftNav.tsx:415 @@ -3029,65 +3028,65 @@ msgstr "" #: src/view/shell/Drawer.tsx:546 #: src/view/shell/Drawer.tsx:547 msgid "Profile" -msgstr "" +msgstr "Profiili" #: src/view/com/modals/EditProfile.tsx:128 msgid "Profile updated" -msgstr "" +msgstr "Profiili päivitetty" #: src/view/screens/Settings/index.tsx:949 msgid "Protect your account by verifying your email." -msgstr "" +msgstr "Suojaa tilisi vahvistamalla sähköpostiosoitteesi." #: src/screens/Onboarding/StepFinished.tsx:101 msgid "Public" -msgstr "" +msgstr "Julkinen" #: src/view/screens/ModerationModlists.tsx:61 msgid "Public, shareable lists of users to mute or block in bulk." -msgstr "" +msgstr "Julkinen, jaettava käyttäjäluettelo hiljennettyjen tai estettyjen käyttäjien massamäärityksiä varten." #: src/view/screens/Lists.tsx:61 msgid "Public, shareable lists which can drive feeds." -msgstr "" +msgstr "Julkinen, jaettava lista, joka voi ohjata syötteitä." #: src/view/com/composer/Composer.tsx:342 msgid "Publish post" -msgstr "" +msgstr "Julkaise viesti" #: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" -msgstr "" +msgstr "Julkaise vastaus" #: src/view/com/modals/Repost.tsx:65 msgctxt "action" msgid "Quote post" -msgstr "" +msgstr "Lainaa viestiä" #: src/view/com/util/post-ctrls/RepostButton.web.tsx:58 msgid "Quote post" -msgstr "" +msgstr "Lainaa viestiä" #: src/view/com/modals/Repost.tsx:70 msgctxt "action" msgid "Quote Post" -msgstr "" +msgstr "Lainaa viestiä" #: src/view/screens/PreferencesThreads.tsx:86 msgid "Random (aka \"Poster's Roulette\")" -msgstr "" +msgstr "Satunnainen (tunnetaan myös nimellä \"Lähettäjän ruletti\")" #: src/view/com/modals/EditImage.tsx:236 msgid "Ratios" -msgstr "" +msgstr "Suhdeluvut" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:116 msgid "Recommended Feeds" -msgstr "" +msgstr "Suositellut syötteet" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:180 msgid "Recommended Users" -msgstr "" +msgstr "Suositellut käyttäjät" #: src/components/dialogs/MutedWords.tsx:249 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 @@ -3096,20 +3095,20 @@ msgstr "" #: src/view/com/util/UserAvatar.tsx:285 #: src/view/com/util/UserBanner.tsx:91 msgid "Remove" -msgstr "" +msgstr "Poista" #: src/view/com/feeds/FeedSourceCard.tsx:108 msgid "Remove {0} from my feeds?" -msgstr "" +msgstr "Poistetaanko {0} syötteistäni?" #: src/view/com/util/AccountDropdownBtn.tsx:22 msgid "Remove account" -msgstr "" +msgstr "Poista tili" #: src/view/com/posts/FeedErrorMessage.tsx:131 #: src/view/com/posts/FeedErrorMessage.tsx:166 msgid "Remove feed" -msgstr "" +msgstr "Poista syöte" #: src/view/com/feeds/FeedSourceCard.tsx:107 #: src/view/com/feeds/FeedSourceCard.tsx:169 @@ -3117,89 +3116,89 @@ msgstr "" #: src/view/com/feeds/FeedSourceCard.tsx:245 #: src/view/screens/ProfileFeed.tsx:273 msgid "Remove from my feeds" -msgstr "" +msgstr "Poista syötteistäni" #: src/view/com/composer/photos/Gallery.tsx:167 msgid "Remove image" -msgstr "" +msgstr "Poista kuva" #: src/view/com/composer/ExternalEmbed.tsx:70 msgid "Remove image preview" -msgstr "" +msgstr "Poista kuvan esikatselu" #: src/components/dialogs/MutedWords.tsx:294 msgid "Remove mute word from your list" -msgstr "" +msgstr "Poista hiljennetty sana listaltasi" #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" -msgstr "" +msgstr "Poista uudelleenjako" #: src/view/com/feeds/FeedSourceCard.tsx:175 msgid "Remove this feed from my feeds?" -msgstr "" +msgstr "Poistetaanko tämä syöte omista syötteistäni?" #: src/view/com/posts/FeedErrorMessage.tsx:132 msgid "Remove this feed from your saved feeds?" -msgstr "" +msgstr "Poistetaanko tämä syöte tallennetuista syötteistäsi?" #: src/view/com/modals/ListAddRemoveUsers.tsx:199 #: src/view/com/modals/UserAddRemoveLists.tsx:152 msgid "Removed from list" -msgstr "" +msgstr "Poistettu listalta" #: src/view/com/feeds/FeedSourceCard.tsx:113 #: src/view/com/feeds/FeedSourceCard.tsx:180 msgid "Removed from my feeds" -msgstr "" +msgstr "Poistettu syötteistäni" #: src/view/com/composer/ExternalEmbed.tsx:71 msgid "Removes default thumbnail from {0}" -msgstr "" +msgstr "Poistaa {0} oletuskuvakkeen" #: src/view/screens/Profile.tsx:181 msgid "Replies" -msgstr "" +msgstr "Vastaukset" #: src/view/com/threadgate/WhoCanReply.tsx:98 msgid "Replies to this thread are disabled" -msgstr "" +msgstr "Tähän keskusteluun vastaaminen on estetty" #: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" -msgstr "" +msgstr "Vastaa" #: src/view/screens/PreferencesFollowingFeed.tsx:144 msgid "Reply Filters" -msgstr "" +msgstr "Vastaussuodattimet" #: src/view/com/post/Post.tsx:167 #: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" -msgstr "" +msgstr "Vastaa käyttäjälle <0/>" #: src/view/com/modals/report/Modal.tsx:166 msgid "Report {collectionName}" -msgstr "" +msgstr "Raportoi {collectionName}" #: src/view/com/profile/ProfileHeader.tsx:361 msgid "Report Account" -msgstr "" +msgstr "Ilmoita tili" #: src/view/screens/ProfileFeed.tsx:293 msgid "Report feed" -msgstr "" +msgstr "Ilmoita syöte" #: src/view/screens/ProfileList.tsx:459 msgid "Report List" -msgstr "" +msgstr "Ilmoita luettelo" #: src/view/com/modals/report/SendReportButton.tsx:37 #: src/view/com/util/forms/PostDropdownBtn.tsx:255 msgid "Report post" -msgstr "" +msgstr "Ilmoita viesti" #: src/view/com/modals/Repost.tsx:43 #: src/view/com/modals/Repost.tsx:48 @@ -3207,104 +3206,104 @@ msgstr "" #: src/view/com/util/post-ctrls/RepostButton.tsx:61 msgctxt "action" msgid "Repost" -msgstr "" +msgstr "Uudelleenjaa" #: src/view/com/util/post-ctrls/RepostButton.web.tsx:48 msgid "Repost" -msgstr "" +msgstr "Uudelleenjaa" #: src/view/com/util/post-ctrls/RepostButton.web.tsx:94 #: src/view/com/util/post-ctrls/RepostButton.web.tsx:105 msgid "Repost or quote post" -msgstr "" +msgstr "Uudelleenjaa tai lainaa viestiä" #: src/view/screens/PostRepostedBy.tsx:27 msgid "Reposted By" -msgstr "" +msgstr "Uudelleenjakanut" #: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" -msgstr "" +msgstr "Uudelleenjakanut {0}" #: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" -msgstr "" +msgstr "Uudelleenjakanut <0/>" #: src/view/com/notifications/FeedItem.tsx:162 msgid "reposted your post" -msgstr "" +msgstr "uudelleenjakoi viestisi" #: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" -msgstr "" +msgstr "Tämän viestin uudelleenjulkaisut" #: src/view/com/modals/ChangeEmail.tsx:181 #: src/view/com/modals/ChangeEmail.tsx:183 msgid "Request Change" -msgstr "" +msgstr "Pyydä muutosta" #: src/view/com/auth/create/Step2.tsx:219 #~ msgid "Request code" -#~ msgstr "" +#~ msgstr "Pyydä koodia" #: src/view/com/modals/ChangePassword.tsx:239 #: src/view/com/modals/ChangePassword.tsx:241 msgid "Request Code" -msgstr "" +msgstr "Pyydä koodia" #: src/view/screens/Settings/index.tsx:456 msgid "Require alt text before posting" -msgstr "" +msgstr "Vaadi vaihtoehtoista ALT-tekstiä ennen julkaisua" #: src/view/com/auth/create/Step1.tsx:153 msgid "Required for this provider" -msgstr "" +msgstr "Vaaditaan tälle instanssille" #: src/view/com/auth/login/SetNewPasswordForm.tsx:124 #: src/view/com/auth/login/SetNewPasswordForm.tsx:136 msgid "Reset code" -msgstr "" +msgstr "Nollauskoodi" #: src/view/com/modals/ChangePassword.tsx:190 msgid "Reset Code" -msgstr "" +msgstr "Nollauskoodi" #: src/view/screens/Settings/index.tsx:824 msgid "Reset onboarding" -msgstr "" +msgstr "Nollaa käyttöönotto" #: src/view/screens/Settings/index.tsx:827 msgid "Reset onboarding state" -msgstr "" +msgstr "Nollaa käyttöönoton tila" #: src/view/com/auth/login/ForgotPasswordForm.tsx:104 msgid "Reset password" -msgstr "" +msgstr "Nollaa salasana" #: src/view/screens/Settings/index.tsx:814 msgid "Reset preferences" -msgstr "" +msgstr "Nollaa asetukset" #: src/view/screens/Settings/index.tsx:817 msgid "Reset preferences state" -msgstr "" +msgstr "Nollaa asetusten tila" #: src/view/screens/Settings/index.tsx:825 msgid "Resets the onboarding state" -msgstr "" +msgstr "Nollaa käyttöönoton tilan" #: src/view/screens/Settings/index.tsx:815 msgid "Resets the preferences state" -msgstr "" +msgstr "Nollaa asetusten tilan" #: src/view/com/auth/login/LoginForm.tsx:269 msgid "Retries login" -msgstr "" +msgstr "Yrittää uudelleen kirjautumista" #: src/view/com/util/error/ErrorMessage.tsx:57 #: src/view/com/util/error/ErrorScreen.tsx:74 msgid "Retries the last action, which errored out" -msgstr "" +msgstr "Yrittää uudelleen viimeisintä toimintoa, joka epäonnistui" #: src/screens/Onboarding/StepInterests/index.tsx:221 #: src/screens/Onboarding/StepInterests/index.tsx:224 @@ -3315,25 +3314,25 @@ msgstr "" #: src/view/com/util/error/ErrorMessage.tsx:55 #: src/view/com/util/error/ErrorScreen.tsx:72 msgid "Retry" -msgstr "" +msgstr "Yritä uudelleen" #: src/view/com/auth/create/Step2.tsx:247 #~ msgid "Retry." -#~ msgstr "" +#~ msgstr "Yritä uudelleen." #: src/view/screens/ProfileList.tsx:898 msgid "Return to previous page" -msgstr "" +msgstr "Palaa edelliselle sivulle" #: src/view/shell/desktop/RightNav.tsx:55 #~ msgid "SANDBOX. Posts and accounts are not permanent." -#~ msgstr "" +#~ msgstr "HIEKKALAATIKKO. Viestit ja tilit eivät ole pysyviä." #: src/view/com/lightbox/Lightbox.tsx:132 #: src/view/com/modals/CreateOrEditList.tsx:345 msgctxt "action" msgid "Save" -msgstr "" +msgstr "Tallenna" #: src/view/com/modals/BirthDateSettings.tsx:94 #: src/view/com/modals/BirthDateSettings.tsx:97 @@ -3342,43 +3341,43 @@ msgstr "" #: src/view/com/modals/EditProfile.tsx:224 #: src/view/screens/ProfileFeed.tsx:346 msgid "Save" -msgstr "" +msgstr "Tallenna" #: src/view/com/modals/AltImage.tsx:130 msgid "Save alt text" -msgstr "" +msgstr "Tallenna vaihtoehtoinen ALT-teksti" #: src/view/com/modals/EditProfile.tsx:232 msgid "Save Changes" -msgstr "" +msgstr "Tallenna muutokset" #: src/view/com/modals/ChangeHandle.tsx:170 msgid "Save handle change" -msgstr "" +msgstr "Tallenna käyttäjätunnuksen muutos" #: src/view/com/modals/crop-image/CropImage.web.tsx:144 msgid "Save image crop" -msgstr "" +msgstr "Tallenna kuvan rajaus" #: src/view/screens/SavedFeeds.tsx:122 msgid "Saved Feeds" -msgstr "" +msgstr "Tallennetut syötteet" #: src/view/com/modals/EditProfile.tsx:225 msgid "Saves any changes to your profile" -msgstr "" +msgstr "Tallentaa kaikki muutokset profiiliisi" #: src/view/com/modals/ChangeHandle.tsx:171 msgid "Saves handle change to {handle}" -msgstr "" +msgstr "Tallentaa käyttäjätunnuksen muutoksen muotoon {handle}" #: src/screens/Onboarding/index.tsx:36 msgid "Science" -msgstr "" +msgstr "Tiede" #: src/view/screens/ProfileList.tsx:854 msgid "Scroll to top" -msgstr "" +msgstr "Vieritä alkuun" #: src/Navigation.tsx:440 #: src/view/com/auth/LoggedOut.tsx:122 @@ -3395,58 +3394,58 @@ msgstr "" #: src/view/shell/Drawer.tsx:362 #: src/view/shell/Drawer.tsx:363 msgid "Search" -msgstr "" +msgstr "Haku" #: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" -msgstr "" +msgstr "Haku hakusanalla \"{query}\"" #: src/components/TagMenu/index.tsx:145 msgid "Search for all posts by @{authorHandle} with tag {tag}" -msgstr "" +msgstr "Etsi kaikki viestit käyttäjältä @{authorHandle} tunnisteella {tag}" #: src/components/TagMenu/index.tsx:90 msgid "Search for all posts with tag {tag}" -msgstr "" +msgstr "Etsi kaikki viestit tunnisteella {tag}" #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 msgid "Search for users" -msgstr "" +msgstr "Hae käyttäjiä" #: src/view/com/modals/ChangeEmail.tsx:110 msgid "Security Step Required" -msgstr "" +msgstr "Turvatarkistus vaaditaan" #: src/components/TagMenu/index.web.tsx:50 msgid "See {truncatedTag} posts" -msgstr "" +msgstr "Näytä {truncatedTag}-viestit" #: src/components/TagMenu/index.web.tsx:67 msgid "See {truncatedTag} posts by user" -msgstr "" +msgstr "Näytä käyttäjän {truncatedTag} viestit" #: src/components/TagMenu/index.tsx:128 msgid "See <0>{tag} posts" -msgstr "" +msgstr "Näytä <0>{tag}-viestit" #: src/components/TagMenu/index.tsx:189 msgid "See <0>{tag} posts by this user" -msgstr "" +msgstr "Näytä tämän käyttäjän <0>{tag}-viestit" #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" -msgstr "" +msgstr "Katso tämä opas" #: src/view/com/auth/HomeLoggedOutCTA.tsx:39 msgid "See what's next" -msgstr "" +msgstr "Katso, mitä seuraavaksi tapahtuu" #: src/view/com/util/Selector.tsx:106 msgid "Select {item}" -msgstr "" +msgstr "Valitse {item}" #: src/view/com/modals/ServerInput.tsx:75 #~ msgid "Select Bluesky Social" @@ -3454,24 +3453,24 @@ msgstr "" #: src/view/com/auth/login/Login.tsx:117 msgid "Select from an existing account" -msgstr "" +msgstr "Valitse olemassa olevalta tililtä" #: src/view/com/util/Selector.tsx:107 msgid "Select option {i} of {numItems}" -msgstr "" +msgstr "Valitse vaihtoehto {i} / {numItems}" #: src/view/com/auth/create/Step1.tsx:103 #: src/view/com/auth/login/LoginForm.tsx:150 msgid "Select service" -msgstr "" +msgstr "Valitse palvelu" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:52 msgid "Select some accounts below to follow" -msgstr "" +msgstr "Valitse alla olevista tileistä jotain seurattavaksi" #: src/view/com/auth/server-input/index.tsx:82 msgid "Select the service that hosts your data." -msgstr "" +msgstr "Valitse palvelu, joka hostaa tietojasi." #: src/screens/Onboarding/StepModeration/index.tsx:49 #~ msgid "Select the types of content that you want to see (or not see), and we'll handle the rest." @@ -3479,153 +3478,153 @@ msgstr "" #: src/screens/Onboarding/StepTopicalFeeds.tsx:96 msgid "Select topical feeds to follow from the list below" -msgstr "" +msgstr "Valitse ajankohtaisia syötteitä alla olevasta listasta" #: src/screens/Onboarding/StepModeration/index.tsx:75 msgid "Select what you want to see (or not see), and we’ll handle the rest." -msgstr "" +msgstr "Valitse, mitä haluat nähdä (tai olla näkemättä) ja me huolehdimme lopusta." #: src/view/screens/LanguageSettings.tsx:281 msgid "Select which languages you want your subscribed feeds to include. If none are selected, all languages will be shown." -msgstr "" +msgstr "Valitse, mitä kieliä haluat tilattujen syötteidesi sisältävän. Jos mitään ei ole valittu, kaikki kielet näytetään." #: src/view/screens/LanguageSettings.tsx:98 msgid "Select your app language for the default text to display in the app" -msgstr "" +msgstr "Valitse sovelluksen oletuskieli, joka näytetään sovelluksessa" #: src/screens/Onboarding/StepInterests/index.tsx:196 msgid "Select your interests from the options below" -msgstr "" +msgstr "Valitse kiinnostuksenkohteesi alla olevista vaihtoehdoista" #: src/view/com/auth/create/Step2.tsx:155 #~ msgid "Select your phone's country" -#~ msgstr "" +#~ msgstr "Valitse puhelinnumerosi maa" #: src/view/screens/LanguageSettings.tsx:190 msgid "Select your preferred language for translations in your feed." -msgstr "" +msgstr "Valitse haluamasi kieli käännöksille syötteessäsi." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:116 msgid "Select your primary algorithmic feeds" -msgstr "" +msgstr "Valitse ensisijaiset algoritmisyötteet" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:142 msgid "Select your secondary algorithmic feeds" -msgstr "" +msgstr "Valitse toissijaiset algoritmisyötteet" #: src/view/com/modals/VerifyEmail.tsx:202 #: src/view/com/modals/VerifyEmail.tsx:204 msgid "Send Confirmation Email" -msgstr "" +msgstr "Lähetä vahvistussähköposti" #: src/view/com/modals/DeleteAccount.tsx:131 msgid "Send email" -msgstr "" +msgstr "Lähetä sähköposti" #: src/view/com/modals/DeleteAccount.tsx:144 msgctxt "action" msgid "Send Email" -msgstr "" +msgstr "Lähetä sähköposti" #: src/view/shell/Drawer.tsx:295 #: src/view/shell/Drawer.tsx:316 msgid "Send feedback" -msgstr "" +msgstr "Lähetä palautetta" #: src/view/com/modals/report/SendReportButton.tsx:45 msgid "Send Report" -msgstr "" +msgstr "Lähetä raportti" #: src/view/com/modals/DeleteAccount.tsx:133 msgid "Sends email with confirmation code for account deletion" -msgstr "" +msgstr "Lähettää sähköpostin tilin poistamiseen tarvittavan vahvistuskoodin" #: src/view/com/auth/server-input/index.tsx:110 msgid "Server address" -msgstr "" +msgstr "Palvelimen osoite" #: src/view/com/modals/ContentFilteringSettings.tsx:311 msgid "Set {value} for {labelGroup} content moderation policy" -msgstr "" +msgstr "Aseta {value} {labelGroup} sisällön moderointisäännöksi" #: src/view/com/modals/ContentFilteringSettings.tsx:160 #: src/view/com/modals/ContentFilteringSettings.tsx:179 msgctxt "action" msgid "Set Age" -msgstr "" +msgstr "Aseta ikä" #: src/view/screens/Settings/index.tsx:488 msgid "Set color theme to dark" -msgstr "" +msgstr "Aseta väriteema tummaksi" #: src/view/screens/Settings/index.tsx:481 msgid "Set color theme to light" -msgstr "" +msgstr "Aseta väriteema vaaleaksi" #: src/view/screens/Settings/index.tsx:475 msgid "Set color theme to system setting" -msgstr "" +msgstr "Aseta väriteema järjestelmäasetuksiin" #: src/view/screens/Settings/index.tsx:514 msgid "Set dark theme to the dark theme" -msgstr "" +msgstr "Aseta tumma teema tummaksi" #: src/view/screens/Settings/index.tsx:507 msgid "Set dark theme to the dim theme" -msgstr "" +msgstr "Aseta tumma teema hämäräksi" #: src/view/com/auth/login/SetNewPasswordForm.tsx:104 msgid "Set new password" -msgstr "" +msgstr "Aseta uusi salasana" #: src/view/com/auth/create/Step1.tsx:225 msgid "Set password" -msgstr "" +msgstr "Aseta salasana" #: src/view/screens/PreferencesFollowingFeed.tsx:225 msgid "Set this setting to \"No\" to hide all quote posts from your feed. Reposts will still be visible." -msgstr "" +msgstr "Aseta tämä asetus \"Ei\"-tilaan piilottaaksesi kaikki lainaukset syötteestäsi. Uudelleenjulkaisut näkyvät silti." #: src/view/screens/PreferencesFollowingFeed.tsx:122 msgid "Set this setting to \"No\" to hide all replies from your feed." -msgstr "" +msgstr "Aseta tämä asetus \"Ei\"-tilaan piilottaaksesi kaikki vastaukset syötteestäsi." #: src/view/screens/PreferencesFollowingFeed.tsx:191 msgid "Set this setting to \"No\" to hide all reposts from your feed." -msgstr "" +msgstr "Aseta tämä asetus \"Ei\"-tilaan piilottaaksesi kaikki uudelleenjulkaisut syötteestäsi." #: src/view/screens/PreferencesThreads.tsx:122 msgid "Set this setting to \"Yes\" to show replies in a threaded view. This is an experimental feature." -msgstr "" +msgstr "Aseta tämä asetus \"Kyllä\" tilaan näyttääksesi vastaukset ketjumaisessa näkymässä. Tämä on kokeellinen ominaisuus." #: src/view/screens/PreferencesHomeFeed.tsx:261 #~ msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your following feed. This is an experimental feature." -#~ msgstr "" +#~ msgstr "Aseta tämä asetus \"Kyllä\"-tilaan nähdäksesi esimerkkejä tallennetuista syötteistäsi seuraamissasi syötteessäsi. Tämä on kokeellinen ominaisuus." #: src/view/screens/PreferencesFollowingFeed.tsx:261 msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your Following feed. This is an experimental feature." -msgstr "" +msgstr "Aseta tämä asetus \"Kyllä\"-tilaan nähdäksesi esimerkkejä tallennetuista syötteistäsi seuraamissasi syötteessäsi. Tämä on kokeellinen ominaisuus." #: src/screens/Onboarding/Layout.tsx:50 msgid "Set up your account" -msgstr "" +msgstr "Luo tili" #: src/view/com/modals/ChangeHandle.tsx:266 msgid "Sets Bluesky username" -msgstr "" +msgstr "Asettaa Bluesky-käyttäjätunnuksen" #: src/view/com/auth/login/ForgotPasswordForm.tsx:157 msgid "Sets email for password reset" -msgstr "" +msgstr "Asettaa sähköpostin salasanan palautusta varten" #: src/view/com/auth/login/ForgotPasswordForm.tsx:122 msgid "Sets hosting provider for password reset" -msgstr "" +msgstr "Asettaa palveluntarjoajan salasanan palautusta varten" #: src/view/com/auth/create/Step1.tsx:104 #: src/view/com/auth/login/LoginForm.tsx:151 msgid "Sets server for the Bluesky client" -msgstr "" +msgstr "Asettaa palvelimen Bluesky-ohjelmalle" #: src/Navigation.tsx:135 #: src/view/screens/Settings/index.tsx:294 @@ -3633,26 +3632,26 @@ msgstr "" #: src/view/shell/Drawer.tsx:567 #: src/view/shell/Drawer.tsx:568 msgid "Settings" -msgstr "" +msgstr "Asetukset" #: src/view/com/modals/SelfLabel.tsx:125 msgid "Sexual activity or erotic nudity." -msgstr "" +msgstr "Erotiikka tai muu aikuisviihde." #: src/view/com/lightbox/Lightbox.tsx:141 msgctxt "action" msgid "Share" -msgstr "" +msgstr "Jaa" #: src/view/com/profile/ProfileHeader.tsx:295 #: src/view/com/util/forms/PostDropdownBtn.tsx:184 #: src/view/screens/ProfileList.tsx:418 msgid "Share" -msgstr "" +msgstr "Jaa" #: src/view/screens/ProfileFeed.tsx:305 msgid "Share feed" -msgstr "" +msgstr "Jaa syöte" #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:43 #: src/view/com/modals/ContentFilteringSettings.tsx:266 @@ -3660,95 +3659,95 @@ msgstr "" #: src/view/com/util/moderation/PostHider.tsx:108 #: src/view/screens/Settings/index.tsx:344 msgid "Show" -msgstr "" +msgstr "Näytä" #: src/view/screens/PreferencesFollowingFeed.tsx:68 msgid "Show all replies" -msgstr "" +msgstr "Näytä kaikki vastaukset" #: src/view/com/util/moderation/ScreenHider.tsx:132 msgid "Show anyway" -msgstr "" +msgstr "Näytä silti" #: src/view/com/modals/EmbedConsent.tsx:87 msgid "Show embeds from {0}" -msgstr "" +msgstr "Näytä upotukset taholta {0}" #: src/view/com/profile/ProfileHeader.tsx:459 msgid "Show follows similar to {0}" -msgstr "" +msgstr "Näytä seurannat samankaltaisilta käyttäjiltä kuin {0}" #: src/view/com/post-thread/PostThreadItem.tsx:538 #: src/view/com/post/Post.tsx:198 #: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" -msgstr "" +msgstr "Näytä lisää" #: src/view/screens/PreferencesFollowingFeed.tsx:258 msgid "Show Posts from My Feeds" -msgstr "" +msgstr "Näytä viestit omista syötteistäni" #: src/view/screens/PreferencesFollowingFeed.tsx:222 msgid "Show Quote Posts" -msgstr "" +msgstr "Näytä lainatut viestit" #: src/screens/Onboarding/StepFollowingFeed.tsx:118 msgid "Show quote-posts in Following feed" -msgstr "" +msgstr "Näytä lainatut viestit seurattavien syötteessä" #: src/screens/Onboarding/StepFollowingFeed.tsx:134 msgid "Show quotes in Following" -msgstr "" +msgstr "Näytä lainaukset seurattavissa" #: src/screens/Onboarding/StepFollowingFeed.tsx:94 msgid "Show re-posts in Following feed" -msgstr "" +msgstr "Näytä uudelleenjulkaistut viestit seurattavissa" #: src/view/screens/PreferencesFollowingFeed.tsx:119 msgid "Show Replies" -msgstr "" +msgstr "Näytä vastaukset" #: src/view/screens/PreferencesThreads.tsx:100 msgid "Show replies by people you follow before all other replies." -msgstr "" +msgstr "Näytä seurattujen henkilöiden vastaukset ennen muita vastauksia." #: src/screens/Onboarding/StepFollowingFeed.tsx:86 msgid "Show replies in Following" -msgstr "" +msgstr "Näytä vastaukset seurattavissa" #: src/screens/Onboarding/StepFollowingFeed.tsx:70 msgid "Show replies in Following feed" -msgstr "" +msgstr "Näytä vastaukset seurattavissa" #: src/view/screens/PreferencesFollowingFeed.tsx:70 msgid "Show replies with at least {value} {0}" -msgstr "" +msgstr "Näytä vastaukset, joissa on vähintään {value} {0}" #: src/view/screens/PreferencesFollowingFeed.tsx:188 msgid "Show Reposts" -msgstr "" +msgstr "Näytä uudelleenjulkaisut" #: src/screens/Onboarding/StepFollowingFeed.tsx:110 msgid "Show reposts in Following" -msgstr "" +msgstr "Näytä uudelleenjulkaisut seurattavissa" #: src/view/com/util/moderation/ContentHider.tsx:67 #: src/view/com/util/moderation/PostHider.tsx:61 msgid "Show the content" -msgstr "" +msgstr "Näytä sisältö" #: src/view/com/notifications/FeedItem.tsx:346 msgid "Show users" -msgstr "" +msgstr "Näytä käyttäjät" #: src/view/com/profile/ProfileHeader.tsx:462 msgid "Shows a list of users similar to this user." -msgstr "" +msgstr "Näyttää luettelon käyttäjistä, jotka ovat samankaltaisia kuin tämä käyttäjä." #: src/view/com/post-thread/PostThreadFollowBtn.tsx:124 #: src/view/com/profile/ProfileHeader.tsx:506 msgid "Shows posts from {0} in your feed" -msgstr "" +msgstr "Näyttää viestit käyttäjältä {0} syötteessäsi" #: src/view/com/auth/HomeLoggedOutCTA.tsx:70 #: src/view/com/auth/login/Login.tsx:98 @@ -3762,33 +3761,33 @@ msgstr "" #: src/view/shell/NavSignupCard.tsx:58 #: src/view/shell/NavSignupCard.tsx:59 msgid "Sign in" -msgstr "" +msgstr "Kirjaudu sisään" #: src/view/com/auth/HomeLoggedOutCTA.tsx:78 #: src/view/com/auth/SplashScreen.tsx:82 #: src/view/com/auth/SplashScreen.web.tsx:91 msgid "Sign In" -msgstr "" +msgstr "Kirjaudu sisään" #: src/view/com/auth/login/ChooseAccountForm.tsx:44 msgid "Sign in as {0}" -msgstr "" +msgstr "Kirjaudu sisään nimellä {0}" #: src/view/com/auth/login/ChooseAccountForm.tsx:118 #: src/view/com/auth/login/Login.tsx:116 msgid "Sign in as..." -msgstr "" +msgstr "Kirjaudu sisään nimellä..." #: src/view/com/auth/login/LoginForm.tsx:137 msgid "Sign into" -msgstr "" +msgstr "Kirjaudu sisään" #: src/view/com/modals/SwitchAccount.tsx:64 #: src/view/com/modals/SwitchAccount.tsx:69 #: src/view/screens/Settings/index.tsx:100 #: src/view/screens/Settings/index.tsx:103 msgid "Sign out" -msgstr "" +msgstr "Kirjaudu ulos" #: src/view/shell/bottom-bar/BottomBar.tsx:275 #: src/view/shell/bottom-bar/BottomBar.tsx:276 @@ -3800,45 +3799,45 @@ msgstr "" #: src/view/shell/NavSignupCard.tsx:50 #: src/view/shell/NavSignupCard.tsx:52 msgid "Sign up" -msgstr "" +msgstr "Rekisteröidy" #: src/view/shell/NavSignupCard.tsx:42 msgid "Sign up or sign in to join the conversation" -msgstr "" +msgstr "Rekisteröidy tai kirjaudu sisään liittyäksesi keskusteluun" #: src/view/com/util/moderation/ScreenHider.tsx:76 msgid "Sign-in Required" -msgstr "" +msgstr "Sisäänkirjautuminen vaaditaan" #: src/view/screens/Settings/index.tsx:355 msgid "Signed in as" -msgstr "" +msgstr "Kirjautunut sisään nimellä" #: src/view/com/auth/login/ChooseAccountForm.tsx:103 msgid "Signed in as @{0}" -msgstr "" +msgstr "Kirjautunut sisään käyttäjätunnuksella @{0}" #: src/view/com/modals/SwitchAccount.tsx:66 msgid "Signs {0} out of Bluesky" -msgstr "" +msgstr "{0} kirjautuu ulos Blueskysta" #: src/screens/Onboarding/StepInterests/index.tsx:235 #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:195 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:33 msgid "Skip" -msgstr "" +msgstr "Ohita" #: src/screens/Onboarding/StepInterests/index.tsx:232 msgid "Skip this flow" -msgstr "" +msgstr "Ohita tämä vaihe" #: src/view/com/auth/create/Step2.tsx:82 #~ msgid "SMS verification" -#~ msgstr "" +#~ msgstr "SMS-varmennus" #: src/screens/Onboarding/index.tsx:40 msgid "Software Dev" -msgstr "" +msgstr "Ohjelmistokehitys" #: src/view/com/modals/ProfilePreview.tsx:62 #~ msgid "Something went wrong and we're not sure what." @@ -3846,27 +3845,27 @@ msgstr "" #: src/view/com/modals/Waitlist.tsx:51 msgid "Something went wrong. Check your email and try again." -msgstr "" +msgstr "Jotain meni pieleen. Tarkista sähköpostisi ja yritä uudelleen." #: src/App.native.tsx:63 msgid "Sorry! Your session expired. Please log in again." -msgstr "" +msgstr "Pahoittelut! Istuntosi on vanhentunut. Kirjaudu sisään uudelleen." #: src/view/screens/PreferencesThreads.tsx:69 msgid "Sort Replies" -msgstr "" +msgstr "Lajittele vastaukset" #: src/view/screens/PreferencesThreads.tsx:72 msgid "Sort replies to the same post by:" -msgstr "" +msgstr "Lajittele saman viestin vastaukset seuraavasti:" #: src/screens/Onboarding/index.tsx:30 msgid "Sports" -msgstr "" +msgstr "Urheilu" #: src/view/com/modals/crop-image/CropImage.web.tsx:122 msgid "Square" -msgstr "" +msgstr "Neliö" #: src/view/com/modals/ServerInput.tsx:62 #~ msgid "Staging" @@ -3874,55 +3873,55 @@ msgstr "" #: src/view/screens/Settings/index.tsx:871 msgid "Status page" -msgstr "" +msgstr "Tilasivu" #: src/view/com/auth/create/StepHeader.tsx:22 msgid "Step {0} of {numSteps}" -msgstr "" +msgstr "Vaihe {0}/{numSteps}" #: src/view/screens/Settings/index.tsx:274 msgid "Storage cleared, you need to restart the app now." -msgstr "" +msgstr "Tallennustila tyhjennetty, sinun on käynnistettävä sovellus uudelleen." #: src/Navigation.tsx:202 #: src/view/screens/Settings/index.tsx:807 msgid "Storybook" -msgstr "" +msgstr "Storybook" #: src/view/com/modals/AppealLabel.tsx:101 msgid "Submit" -msgstr "Submit" +msgstr "Lähetä" #: src/view/screens/ProfileList.tsx:608 msgid "Subscribe" -msgstr "" +msgstr "Tilaa" #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:173 #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:307 msgid "Subscribe to the {0} feed" -msgstr "" +msgstr "Tilaa {0}-syöte" #: src/view/screens/ProfileList.tsx:604 msgid "Subscribe to this list" -msgstr "" +msgstr "Tilaa tämä lista" #: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" -msgstr "" +msgstr "Ehdotetut seurattavat" #: src/view/com/profile/ProfileHeaderSuggestedFollows.tsx:64 msgid "Suggested for you" -msgstr "" +msgstr "Suositeltua sinulle" #: src/view/com/modals/SelfLabel.tsx:95 msgid "Suggestive" -msgstr "" +msgstr "Viittaava" #: src/Navigation.tsx:212 #: src/view/screens/Support.tsx:30 #: src/view/screens/Support.tsx:33 msgid "Support" -msgstr "" +msgstr "Tuki" #: src/view/com/modals/ProfilePreview.tsx:110 #~ msgid "Swipe up to see more" @@ -3930,117 +3929,117 @@ msgstr "" #: src/view/com/modals/SwitchAccount.tsx:117 msgid "Switch Account" -msgstr "" +msgstr "Vaihda tiliä" #: src/view/com/modals/SwitchAccount.tsx:97 #: src/view/screens/Settings/index.tsx:130 msgid "Switch to {0}" -msgstr "" +msgstr "Vaihda käyttäjään {0}" #: src/view/com/modals/SwitchAccount.tsx:98 #: src/view/screens/Settings/index.tsx:131 msgid "Switches the account you are logged in to" -msgstr "" +msgstr "Vaihtaa sisäänkirjautuneen käyttäjän tilin" #: src/view/screens/Settings/index.tsx:472 msgid "System" -msgstr "" +msgstr "Järjestelmä" #: src/view/screens/Settings/index.tsx:795 msgid "System log" -msgstr "" +msgstr "Järjestelmäloki" #: src/components/dialogs/MutedWords.tsx:288 msgid "tag" -msgstr "" +msgstr "tunniste" #: src/components/TagMenu/index.tsx:74 msgid "Tag menu: {tag}" -msgstr "" +msgstr "Tunnistevalikko: {tag}" #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" -msgstr "" +msgstr "Pitkä" #: src/view/com/util/images/AutoSizedImage.tsx:70 msgid "Tap to view fully" -msgstr "" +msgstr "Napauta nähdäksesi kokonaan" #: src/screens/Onboarding/index.tsx:39 msgid "Tech" -msgstr "" +msgstr "Teknologia" #: src/view/shell/desktop/RightNav.tsx:81 msgid "Terms" -msgstr "" +msgstr "Ehdot" #: src/Navigation.tsx:222 #: src/view/screens/Settings/index.tsx:885 #: src/view/screens/TermsOfService.tsx:29 #: src/view/shell/Drawer.tsx:256 msgid "Terms of Service" -msgstr "" +msgstr "Käyttöehdot" #: src/components/dialogs/MutedWords.tsx:288 msgid "text" -msgstr "" +msgstr "teksti" #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" -msgstr "" +msgstr "Tekstikenttä" #: src/view/com/auth/create/CreateAccount.tsx:94 msgid "That handle is already taken." -msgstr "" +msgstr "Tuo käyttätunnus on jo käytössä." #: src/view/com/profile/ProfileHeader.tsx:263 msgid "The account will be able to interact with you after unblocking." -msgstr "" +msgstr "Tili voi olla vuorovaikutuksessa kanssasi, kun estäminen on poistettu." #: src/view/screens/CommunityGuidelines.tsx:36 msgid "The Community Guidelines have been moved to <0/>" -msgstr "" +msgstr "Yhteisöohjeet on siirretty kohtaan <0/>" #: src/view/screens/CopyrightPolicy.tsx:33 msgid "The Copyright Policy has been moved to <0/>" -msgstr "" +msgstr "Tekijänoikeuskäytäntö on siirretty kohtaan <0/>" #: src/screens/Onboarding/Layout.tsx:60 msgid "The following steps will help customize your Bluesky experience." -msgstr "" +msgstr "Seuraavat vaiheet auttavat mukauttamaan Bluesky-kokemustasi." #: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." -msgstr "" +msgstr "Viesti saattaa olla poistettu." #: src/view/screens/PrivacyPolicy.tsx:33 msgid "The Privacy Policy has been moved to <0/>" -msgstr "" +msgstr "Tietosuojakäytäntö on siirretty kohtaan <0/>" #: src/view/screens/Support.tsx:36 msgid "The support form has been moved. If you need help, please <0/> or visit {HELP_DESK_URL} to get in touch with us." -msgstr "" +msgstr "Tukilomake on siirretty. Jos tarvitset apua, käy osoitteessa <0/> tai vieraile {HELP_DESK_URL} ottaaksesi meihin yhteyttä." #: src/view/screens/TermsOfService.tsx:33 msgid "The Terms of Service have been moved to" -msgstr "" +msgstr "Käyttöehdot on siirretty kohtaan" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:150 msgid "There are many feeds to try:" -msgstr "" +msgstr "On monia syötteitä kokeiltavaksi:" #: src/view/screens/ProfileFeed.tsx:550 msgid "There was an an issue contacting the server, please check your internet connection and try again." -msgstr "" +msgstr "Emme saaneet yhteyttä palvelimeen, tarkista internetyhteytesi ja yritä uudelleen." #: src/view/com/posts/FeedErrorMessage.tsx:139 msgid "There was an an issue removing this feed. Please check your internet connection and try again." -msgstr "" +msgstr "Syötteen poistossa on ongelmia. Tarkista internetyhteytesi ja yritä uudelleen." #: src/view/screens/ProfileFeed.tsx:210 msgid "There was an an issue updating your feeds, please check your internet connection and try again." -msgstr "" +msgstr "Syötteiden päivittämisessä on ongelmia, tarkista internetyhteytesi ja yritä uudelleen." #: src/view/screens/ProfileFeed.tsx:237 #: src/view/screens/ProfileList.tsx:267 @@ -4048,7 +4047,7 @@ msgstr "" #: src/view/screens/SavedFeeds.tsx:231 #: src/view/screens/SavedFeeds.tsx:252 msgid "There was an issue contacting the server" -msgstr "" +msgstr "Yhteydenotto palvelimeen epäonnistui" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:57 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:66 @@ -4056,33 +4055,33 @@ msgstr "" #: src/view/com/feeds/FeedSourceCard.tsx:129 #: src/view/com/feeds/FeedSourceCard.tsx:183 msgid "There was an issue contacting your server" -msgstr "" +msgstr "Yhteydenotto palvelimeen epäonnistui" #: src/view/com/notifications/Feed.tsx:117 msgid "There was an issue fetching notifications. Tap here to try again." -msgstr "" +msgstr "Ongelma ilmoitusten hakemisessa. Napauta tästä yrittääksesi uudelleen." #: src/view/com/posts/Feed.tsx:263 msgid "There was an issue fetching posts. Tap here to try again." -msgstr "" +msgstr "Ongelma viestien hakemisessa. Napauta tästä yrittääksesi uudelleen." #: src/view/com/lists/ListMembers.tsx:172 msgid "There was an issue fetching the list. Tap here to try again." -msgstr "" +msgstr "Ongelma listan hakemisessa. Napauta tästä yrittääksesi uudelleen." #: src/view/com/feeds/ProfileFeedgens.tsx:148 #: src/view/com/lists/ProfileLists.tsx:155 msgid "There was an issue fetching your lists. Tap here to try again." -msgstr "" +msgstr "Ongelma listojesi hakemisessa. Napauta tästä yrittääksesi uudelleen." #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:63 #: src/view/com/modals/ContentFilteringSettings.tsx:126 msgid "There was an issue syncing your preferences with the server" -msgstr "" +msgstr "Ongelma asetuksiesi synkronoinnissa palvelimelle" #: src/view/screens/AppPasswords.tsx:66 msgid "There was an issue with fetching your app passwords" -msgstr "" +msgstr "Sovellussalasanojen hakemisessa tapahtui virhe" #: src/view/com/post-thread/PostThreadFollowBtn.tsx:93 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:105 @@ -4093,104 +4092,104 @@ msgstr "" #: src/view/com/profile/ProfileHeader.tsx:250 #: src/view/com/profile/ProfileHeader.tsx:272 msgid "There was an issue! {0}" -msgstr "" +msgstr "Ilmeni ongelma! {0}" #: src/view/screens/ProfileList.tsx:288 #: src/view/screens/ProfileList.tsx:307 #: src/view/screens/ProfileList.tsx:329 #: src/view/screens/ProfileList.tsx:348 msgid "There was an issue. Please check your internet connection and try again." -msgstr "" +msgstr "Ilmeni joku ongelma. Tarkista internet-yhteys ja yritä uudelleen." #: src/view/com/util/ErrorBoundary.tsx:36 msgid "There was an unexpected issue in the application. Please let us know if this happened to you!" -msgstr "" +msgstr "Sovelluksessa ilmeni odottamaton ongelma. Kerro meille, jos tämä tapahtui sinulle!" #: src/screens/Deactivated.tsx:106 msgid "There's been a rush of new users to Bluesky! We'll activate your account as soon as we can." -msgstr "" +msgstr "Blueskyyn on tullut paljon uusia käyttäjiä! Aktivoimme tilisi niin pian kuin mahdollista." #: src/view/com/auth/create/Step2.tsx:55 #~ msgid "There's something wrong with this number. Please choose your country and enter your full phone number!" -#~ msgstr "" +#~ msgstr "Tässä numerossa on jotain vikaa. Valitse maasi ja syötä koko puhelinnumerosi!" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:138 msgid "These are popular accounts you might like:" -msgstr "" +msgstr "Nämä ovat suosittuja tilejä, joista saatat pitää:" #: src/view/com/util/moderation/ScreenHider.tsx:88 msgid "This {screenDescription} has been flagged:" -msgstr "" +msgstr "Tämä {screenDescription} on liputettu:" #: src/view/com/util/moderation/ScreenHider.tsx:83 msgid "This account has requested that users sign in to view their profile." -msgstr "" +msgstr "Tämä tili pyytää käyttäjiä kirjautumaan sisään nähdäkseen profiilinsa." #: src/view/com/modals/EmbedConsent.tsx:68 msgid "This content is hosted by {0}. Do you want to enable external media?" -msgstr "" +msgstr "Tämä sisältö on hostattu palvelussa {0}. Haluatko sallia ulkoisen median?" #: src/view/com/modals/ModerationDetails.tsx:67 msgid "This content is not available because one of the users involved has blocked the other." -msgstr "" +msgstr "Tämä sisältö ei ole saatavilla, koska toinen käyttäjistä on estänyt toisen." #: src/view/com/posts/FeedErrorMessage.tsx:108 msgid "This content is not viewable without a Bluesky account." -msgstr "" +msgstr "Tätä sisältöä ei voi katsoa ilman Bluesky-tiliä." #: src/view/screens/Settings/ExportCarDialog.tsx:75 msgid "This feature is in beta. You can read more about repository exports in <0>this blogpost." -msgstr "" +msgstr "Tämä ominaisuus on betavaiheessa. Voit lukea lisää pakettivarastojen vientitoiminnosta <0>tässä blogikirjoituksessa." #: src/view/com/posts/FeedErrorMessage.tsx:114 msgid "This feed is currently receiving high traffic and is temporarily unavailable. Please try again later." -msgstr "" +msgstr "Tämä syöte saa tällä hetkellä paljon liikennettä ja on tilapäisesti pois käytöstä. Yritä uudelleen myöhemmin." #: src/view/screens/Profile.tsx:420 #: src/view/screens/ProfileFeed.tsx:476 #: src/view/screens/ProfileList.tsx:661 msgid "This feed is empty!" -msgstr "" +msgstr "Tämä syöte on tyhjä!" #: src/view/com/posts/CustomFeedEmptyState.tsx:37 msgid "This feed is empty! You may need to follow more users or tune your language settings." -msgstr "" +msgstr "Tämä syöte on tyhjä! Sinun on ehkä seurattava useampia käyttäjiä tai säädettävä kieliasetuksiasi." #: src/view/com/modals/BirthDateSettings.tsx:61 msgid "This information is not shared with other users." -msgstr "" +msgstr "Tätä tietoa ei jaeta muiden käyttäjien kanssa." #: src/view/com/modals/VerifyEmail.tsx:119 msgid "This is important in case you ever need to change your email or reset your password." -msgstr "" +msgstr "Tämä on tärkeää, jos sinun tarvitsee vaihtaa sähköpostiosoitteesi tai palauttaa salasanasi." #: src/view/com/modals/LinkWarning.tsx:58 msgid "This link is taking you to the following website:" -msgstr "" +msgstr "Tämä linkki vie sinut tälle verkkosivustolle:" #: src/view/screens/ProfileList.tsx:834 msgid "This list is empty!" -msgstr "" +msgstr "Tämä lista on tyhjä!" #: src/view/com/modals/AddAppPasswords.tsx:106 msgid "This name is already in use" -msgstr "" +msgstr "Tämä nimi on jo käytössä" #: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." -msgstr "" +msgstr "Tämä viesti on poistettu." #: src/view/com/modals/ModerationDetails.tsx:62 msgid "This user has blocked you. You cannot view their content." -msgstr "" +msgstr "Tämä käyttäjä on estänyt sinut. Et voi nähdä heidän sisältöään." #: src/view/com/modals/ModerationDetails.tsx:42 msgid "This user is included in the <0/> list which you have blocked." -msgstr "" +msgstr "Tämä käyttäjä on <0/>-listassa, jonka olet estänyt." #: src/view/com/modals/ModerationDetails.tsx:74 msgid "This user is included in the <0/> list which you have muted." -msgstr "" +msgstr "Tämä käyttäjä on <0/>-listassa, jonka olet hiljentänyt." #: src/view/com/modals/ModerationDetails.tsx:74 #~ msgid "This user is included the <0/> list which you have muted." @@ -4198,59 +4197,59 @@ msgstr "" #: src/view/com/modals/SelfLabel.tsx:137 msgid "This warning is only available for posts with media attached." -msgstr "" +msgstr "Tämä varoitus on saatavilla vain viesteille, joihin on liitetty mediatiedosto." #: src/components/dialogs/MutedWords.tsx:236 msgid "This will delete {0} from your muted words. You can always add it back later." -msgstr "" +msgstr "Tämä poistaa {0}:n hiljennetyistä sanoistasi. Voit lisätä sen takaisin myöhemmin." #: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "This will hide this post from your feeds." -msgstr "" +msgstr "Tämä piilottaa tämän viestin syötteistäsi." #: src/view/screens/PreferencesThreads.tsx:53 #: src/view/screens/Settings/index.tsx:565 msgid "Thread Preferences" -msgstr "" +msgstr "Keskusteluketjun asetukset" #: src/view/screens/PreferencesThreads.tsx:119 msgid "Threaded Mode" -msgstr "" +msgstr "Ketjumainen näkymä" #: src/Navigation.tsx:255 msgid "Threads Preferences" -msgstr "" +msgstr "Keskusteluketjujen asetukset" #: src/components/dialogs/MutedWords.tsx:95 msgid "Toggle between muted word options." -msgstr "" +msgstr "Vaihda hiljennysvaihtoehtojen välillä." #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" -msgstr "" +msgstr "Vaihda pudotusvalikko" #: src/view/com/modals/EditImage.tsx:271 msgid "Transformations" -msgstr "" +msgstr "Muutokset" #: src/view/com/post-thread/PostThreadItem.tsx:685 #: src/view/com/post-thread/PostThreadItem.tsx:687 #: src/view/com/util/forms/PostDropdownBtn.tsx:156 msgid "Translate" -msgstr "" +msgstr "Käännä" #: src/view/com/util/error/ErrorScreen.tsx:82 msgctxt "action" msgid "Try again" -msgstr "" +msgstr "Yritä uudelleen" #: src/view/screens/ProfileList.tsx:506 msgid "Un-block list" -msgstr "" +msgstr "Poista listan esto" #: src/view/screens/ProfileList.tsx:491 msgid "Un-mute list" -msgstr "" +msgstr "Poista listan hiljennys" #: src/view/com/auth/create/CreateAccount.tsx:58 #: src/view/com/auth/login/ForgotPasswordForm.tsx:87 @@ -4258,119 +4257,119 @@ msgstr "" #: src/view/com/auth/login/LoginForm.tsx:118 #: src/view/com/modals/ChangePassword.tsx:70 msgid "Unable to contact your service. Please check your Internet connection." -msgstr "" +msgstr "Yhteys palveluusi ei onnistu. Tarkista internet-yhteytesi." #: src/view/com/profile/ProfileHeader.tsx:433 #: src/view/screens/ProfileList.tsx:590 msgid "Unblock" -msgstr "" +msgstr "Poista esto" -#: src/view/com/profile/ProfileHeader.tsx:436 +#: src/view/com/profile/ProfileHeader.tsx:435 msgctxt "action" msgid "Unblock" -msgstr "" +msgstr "Poista esto" #: src/view/com/profile/ProfileHeader.tsx:261 #: src/view/com/profile/ProfileHeader.tsx:345 msgid "Unblock Account" -msgstr "" +msgstr "Poista tilin esto" #: src/view/com/modals/Repost.tsx:42 #: src/view/com/modals/Repost.tsx:55 #: src/view/com/util/post-ctrls/RepostButton.tsx:60 #: src/view/com/util/post-ctrls/RepostButton.web.tsx:48 msgid "Undo repost" -msgstr "" +msgstr "Kumoa uudelleenjako" #: src/view/com/profile/FollowButton.tsx:55 msgctxt "action" msgid "Unfollow" -msgstr "" +msgstr "Lopeta seuraaminen" #: src/view/com/profile/ProfileHeader.tsx:485 msgid "Unfollow {0}" -msgstr "" +msgstr "Lopeta seuraaminen {0}" #: src/view/com/auth/create/state.ts:262 msgid "Unfortunately, you do not meet the requirements to create an account." -msgstr "" +msgstr "Valitettavasti et täytä tilin luomisen vaatimuksia." #: src/view/com/util/post-ctrls/PostCtrls.tsx:182 #: src/view/com/util/post-ctrls/PostCtrls.tsx:216 msgid "Unlike" -msgstr "" +msgstr "En tykkää" #: src/components/TagMenu/index.tsx:253 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" -msgstr "" +msgstr "Poista hiljennys" #: src/components/TagMenu/index.web.tsx:90 msgid "Unmute {truncatedTag}" -msgstr "" +msgstr "Poista hiljennys {truncatedTag}" #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" -msgstr "" +msgstr "Poista tilin hiljennys" #: src/components/TagMenu/index.tsx:210 msgid "Unmute all {tag} posts" -msgstr "" +msgstr "Poista hiljennys kaikista {tag}-viesteistä" #: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Unmute thread" -msgstr "" +msgstr "Poista keskusteluketjun hiljennys" -#: src/view/screens/ProfileFeed.tsx:354 -#: src/view/screens/ProfileList.tsx:581 +#: src/view/screens/ProfileFeed.tsx:353 +#: src/view/screens/ProfileList.tsx:580 msgid "Unpin" -msgstr "" +msgstr "Poista kiinnitys" #: src/view/screens/ProfileList.tsx:474 msgid "Unpin moderation list" -msgstr "" +msgstr "Poista moderointilistan kiinnitys" #: src/view/screens/ProfileFeed.tsx:346 msgid "Unsave" -msgstr "" +msgstr "Poista tallennus" #: src/view/com/modals/UserAddRemoveLists.tsx:70 msgid "Update {displayName} in Lists" -msgstr "" +msgstr "Päivitä {displayName} listoissa" #: src/lib/hooks/useOTAUpdate.ts:15 msgid "Update Available" -msgstr "" +msgstr "Päivitys saatavilla" #: src/view/com/auth/login/SetNewPasswordForm.tsx:204 msgid "Updating..." -msgstr "" +msgstr "Päivitetään..." #: src/view/com/modals/ChangeHandle.tsx:455 msgid "Upload a text file to:" -msgstr "" +msgstr "Lataa tekstitiedosto kohteeseen:" #: src/view/screens/AppPasswords.tsx:195 msgid "Use app passwords to login to other Bluesky clients without giving full access to your account or password." -msgstr "" +msgstr "Käytä sovellussalasanoja kirjautuaksesi muihin Bluesky-sovelluksiin antamatta niille täyttä hallintaa tilillesi tai salasanallesi." #: src/view/com/modals/ChangeHandle.tsx:515 msgid "Use default provider" -msgstr "" +msgstr "Käytä oletustoimittajaa" #: src/view/com/modals/InAppBrowserConsent.tsx:56 #: src/view/com/modals/InAppBrowserConsent.tsx:58 msgid "Use in-app browser" -msgstr "" +msgstr "Käytä sovelluksen sisäistä selainta" #: src/view/com/modals/InAppBrowserConsent.tsx:66 #: src/view/com/modals/InAppBrowserConsent.tsx:68 msgid "Use my default browser" -msgstr "" +msgstr "Käytä oletusselaintani" #: src/view/com/modals/AddAppPasswords.tsx:155 msgid "Use this to sign into the other app along with your handle." -msgstr "" +msgstr "Käytä tätä kirjautuaksesi toiseen sovellukseen käyttäjätunnuksellasi." #: src/view/com/modals/ServerInput.tsx:105 #~ msgid "Use your domain as your Bluesky client service provider" @@ -4378,141 +4377,141 @@ msgstr "" #: src/view/com/modals/InviteCodes.tsx:200 msgid "Used by:" -msgstr "" +msgstr "Käyttänyt:" #: src/view/com/modals/ModerationDetails.tsx:54 msgid "User Blocked" -msgstr "" +msgstr "Käyttäjä estetty" #: src/view/com/modals/ModerationDetails.tsx:40 msgid "User Blocked by List" -msgstr "" +msgstr "Käyttäjä estetty listan vuoksi" #: src/view/com/modals/ModerationDetails.tsx:60 msgid "User Blocks You" -msgstr "" +msgstr "Käyttäjä on estänyt sinut" #: src/view/com/auth/create/Step2.tsx:79 msgid "User handle" -msgstr "" +msgstr "Käyttäjätunnus" #: src/view/com/lists/ListCard.tsx:85 #: src/view/com/modals/UserAddRemoveLists.tsx:198 msgid "User list by {0}" -msgstr "" +msgstr "Käyttäjälistan on tehnyt {0}" #: src/view/screens/ProfileList.tsx:762 msgid "User list by <0/>" -msgstr "" +msgstr "Käyttäjälistan on tehnyt <0/>" #: src/view/com/lists/ListCard.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:196 #: src/view/screens/ProfileList.tsx:760 msgid "User list by you" -msgstr "" +msgstr "Sinun käyttäjälistasi" #: src/view/com/modals/CreateOrEditList.tsx:196 msgid "User list created" -msgstr "" +msgstr "Käyttäjälista luotu" #: src/view/com/modals/CreateOrEditList.tsx:182 msgid "User list updated" -msgstr "" +msgstr "Käyttäjälista päivitetty" #: src/view/screens/Lists.tsx:58 msgid "User Lists" -msgstr "" +msgstr "Käyttäjälistat" #: src/view/com/auth/login/LoginForm.tsx:177 #: src/view/com/auth/login/LoginForm.tsx:195 msgid "Username or email address" -msgstr "" +msgstr "Käyttäjätunnus tai sähköpostiosoite" #: src/view/screens/ProfileList.tsx:796 msgid "Users" -msgstr "" +msgstr "Käyttäjät" #: src/view/com/threadgate/WhoCanReply.tsx:143 msgid "users followed by <0/>" -msgstr "" +msgstr "käyttäjät, joita <0/> seuraa" #: src/view/com/modals/Threadgate.tsx:106 msgid "Users in \"{0}\"" -msgstr "" +msgstr "Käyttäjät ryhmässä \"{0}\"" #: src/view/com/auth/create/Step2.tsx:243 #~ msgid "Verification code" -#~ msgstr "" +#~ msgstr "Varmistuskoodi" #: src/view/screens/Settings/index.tsx:910 msgid "Verify email" -msgstr "" +msgstr "Varmista sähköposti" #: src/view/screens/Settings/index.tsx:935 msgid "Verify my email" -msgstr "" +msgstr "Vahvista sähköpostini" #: src/view/screens/Settings/index.tsx:944 msgid "Verify My Email" -msgstr "" +msgstr "Vahvista sähköpostini" #: src/view/com/modals/ChangeEmail.tsx:205 #: src/view/com/modals/ChangeEmail.tsx:207 msgid "Verify New Email" -msgstr "" +msgstr "Vahvista uusi sähköposti" #: src/view/com/modals/VerifyEmail.tsx:103 msgid "Verify Your Email" -msgstr "" +msgstr "Vahvista sähköpostisi" #: src/screens/Onboarding/index.tsx:42 msgid "Video Games" -msgstr "" +msgstr "Videopelit" #: src/view/com/profile/ProfileHeader.tsx:662 msgid "View {0}'s avatar" -msgstr "" +msgstr "Katso {0}:n avatar" #: src/view/screens/Log.tsx:52 msgid "View debug entry" -msgstr "" +msgstr "Katso vianmääritystietue" #: src/view/com/posts/FeedSlice.tsx:103 msgid "View full thread" -msgstr "" +msgstr "Katso koko keskusteluketju" #: src/view/com/posts/FeedErrorMessage.tsx:172 msgid "View profile" -msgstr "" +msgstr "Katso profiilia" #: src/view/com/profile/ProfileSubpageHeader.tsx:128 msgid "View the avatar" -msgstr "" +msgstr "Katso avatar" #: src/view/com/modals/LinkWarning.tsx:75 msgid "Visit Site" -msgstr "" +msgstr "Vieraile sivustolla" #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:42 #: src/view/com/modals/ContentFilteringSettings.tsx:259 msgid "Warn" -msgstr "" +msgstr "Varoita" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:134 msgid "We also think you'll like \"For You\" by Skygaze:" -msgstr "" +msgstr "Uskomme myös, että pitäisit Skygazen \"For You\" -syötteestä:" #: src/screens/Deactivated.tsx:133 msgid "We estimate {estimatedTime} until your account is ready." -msgstr "" +msgstr "Arvioimme, että tilisi valmistumiseen on {estimatedTime} aikaa." #: src/screens/Onboarding/StepFinished.tsx:93 msgid "We hope you have a wonderful time. Remember, Bluesky is:" -msgstr "" +msgstr "Toivomme sinulle ihania hetkiä. Muista, että Bluesky on:" #: src/view/com/posts/DiscoverFallbackHeader.tsx:29 msgid "We ran out of posts from your follows. Here's the latest from <0/>." -msgstr "" +msgstr "Emme enää löytäneet viestejä seurattavilta. Tässä on uusin tekijältä <0/>." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:118 #~ msgid "We recommend \"For You\" by Skygaze:" @@ -4520,98 +4519,98 @@ msgstr "" #: src/components/dialogs/MutedWords.tsx:161 msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." -msgstr "" +msgstr "Suosittelemme välttämään yleisiä sanoja, jotka esiintyvät monissa viesteissä. Se voi johtaa siihen, ettei viestejä näytetä." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" -msgstr "" +msgstr "Suosittelemme \"Tutustu\"-syötettämme:" #: src/screens/Onboarding/StepInterests/index.tsx:133 msgid "We weren't able to connect. Please try again to continue setting up your account. If it continues to fail, you can skip this flow." -msgstr "" +msgstr "Yhteyden muodostaminen ei onnistunut. Yritä uudelleen jatkaaksesi tilisi määritystä. Jos ongelma jatkuu, voit ohittaa tämän vaiheen." #: src/screens/Deactivated.tsx:137 msgid "We will let you know when your account is ready." -msgstr "" +msgstr "Ilmoitamme sinulle, kun tilisi on valmis." #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." -msgstr "" +msgstr "Käsittelemme vetoomuksesi pikaisesti." #: src/screens/Onboarding/StepInterests/index.tsx:138 msgid "We'll use this to help customize your experience." -msgstr "" +msgstr "Käytämme tätä mukauttaaksemme kokemustasi." #: src/view/com/auth/create/CreateAccount.tsx:134 msgid "We're so excited to have you join us!" -msgstr "" +msgstr "Olemme innoissamme, että liityt joukkoomme!" #: src/view/screens/ProfileList.tsx:86 msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." -msgstr "" +msgstr "Pahoittelemme, emme saaneet avattua tätä listaa. Jos ongelma jatkuu, ota yhteyttä listan tekijään: @{handleOrDid}." #: src/components/dialogs/MutedWords.tsx:182 msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." -msgstr "" +msgstr "Pahoittelemme, emme pystyneet lataamaan hiljennettyjä sanojasi tällä hetkellä. Yritä uudelleen." #: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." -msgstr "" +msgstr "Pahoittelemme, hakuasi ei voitu suorittaa loppuun. Yritä uudelleen muutaman minuutin kuluttua." #: src/view/screens/NotFound.tsx:48 msgid "We're sorry! We can't find the page you were looking for." -msgstr "" +msgstr "Pahoittelut! Emme löydä etsimääsi sivua." #: src/view/com/auth/onboarding/WelcomeMobile.tsx:46 msgid "Welcome to <0>Bluesky" -msgstr "" +msgstr "Tervetuloa <0>Bluesky:iin" #: src/screens/Onboarding/StepInterests/index.tsx:130 msgid "What are your interests?" -msgstr "" +msgstr "Mitkä ovat kiinnostuksenkohteesi?" #: src/view/com/modals/report/Modal.tsx:169 msgid "What is the issue with this {collectionName}?" -msgstr "" +msgstr "Mikä on ongelma tämän {collectionName} kanssa?" #: src/view/com/auth/SplashScreen.tsx:59 #: src/view/com/composer/Composer.tsx:286 msgid "What's up?" -msgstr "" +msgstr "Mitä kuuluu?" #: src/view/com/modals/lang-settings/PostLanguagesSettings.tsx:78 msgid "Which languages are used in this post?" -msgstr "" +msgstr "Mitä kieliä tässä viestissä käytetään?" #: src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx:77 msgid "Which languages would you like to see in your algorithmic feeds?" -msgstr "" +msgstr "Mitä kieliä haluaisit nähdä algoritmisissä syötteissä?" #: src/view/com/composer/threadgate/ThreadgateBtn.tsx:47 #: src/view/com/modals/Threadgate.tsx:66 msgid "Who can reply" -msgstr "" +msgstr "Kuka voi vastata" #: src/view/com/modals/crop-image/CropImage.web.tsx:102 msgid "Wide" -msgstr "" +msgstr "Leveä" #: src/view/com/composer/Composer.tsx:422 msgid "Write post" -msgstr "" +msgstr "Kirjoita viesti" #: src/view/com/composer/Composer.tsx:285 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" -msgstr "" +msgstr "Kirjoita vastauksesi" #: src/screens/Onboarding/index.tsx:28 msgid "Writers" -msgstr "" +msgstr "Kirjoittajat" #: src/view/com/auth/create/Step2.tsx:263 #~ msgid "XXXXXX" -#~ msgstr "" +#~ msgstr "XXXXXX" #: src/view/com/composer/select-language/SuggestedLanguage.tsx:77 #: src/view/screens/PreferencesFollowingFeed.tsx:129 @@ -4621,7 +4620,7 @@ msgstr "" #: src/view/screens/PreferencesThreads.tsx:106 #: src/view/screens/PreferencesThreads.tsx:129 msgid "Yes" -msgstr "" +msgstr "Kyllä" #: src/screens/Onboarding/StepModeration/index.tsx:46 #~ msgid "You are in control" @@ -4629,12 +4628,12 @@ msgstr "" #: src/screens/Deactivated.tsx:130 msgid "You are in line." -msgstr "" +msgstr "Olet jonossa." #: src/view/com/posts/FollowingEmptyState.tsx:67 #: src/view/com/posts/FollowingEndOfFeed.tsx:68 msgid "You can also discover new Custom Feeds to follow." -msgstr "" +msgstr "Voit myös selata uusia mukautettuja syötteitä seurattavaksi." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:123 #~ msgid "You can also try our \"Discover\" algorithm:" @@ -4642,164 +4641,164 @@ msgstr "" #: src/screens/Onboarding/StepFollowingFeed.tsx:142 msgid "You can change these settings later." -msgstr "" +msgstr "Voit muuttaa näitä asetuksia myöhemmin." #: src/view/com/auth/login/Login.tsx:158 #: src/view/com/auth/login/PasswordUpdatedForm.tsx:31 msgid "You can now sign in with your new password." -msgstr "" +msgstr "Voit nyt kirjautua sisään uudella salasanallasi." #: src/view/com/modals/InviteCodes.tsx:66 msgid "You don't have any invite codes yet! We'll send you some when you've been on Bluesky for a little longer." -msgstr "" +msgstr "Sinulla ei ole vielä kutsukoodia! Lähetämme sinulle sellaisen, kun olet ollut Bluesky-palvelussa hieman pidempään." #: src/view/screens/SavedFeeds.tsx:102 msgid "You don't have any pinned feeds." -msgstr "" +msgstr "Sinulla ei ole kiinnitettyjä syötteitä." #: src/view/screens/Feeds.tsx:452 msgid "You don't have any saved feeds!" -msgstr "" +msgstr "Sinulla ei ole tallennettuja syötteitä!" #: src/view/screens/SavedFeeds.tsx:135 msgid "You don't have any saved feeds." -msgstr "" +msgstr "Sinulla ei ole tallennettuja syötteitä." #: src/view/com/post-thread/PostThread.tsx:465 msgid "You have blocked the author or you have been blocked by the author." -msgstr "" +msgstr "Olet estänyt tekijän tai sinut on estetty tekijän toimesta." #: src/view/com/modals/ModerationDetails.tsx:56 msgid "You have blocked this user. You cannot view their content." -msgstr "" +msgstr "Olet estänyt tämän käyttäjän. Et voi nähdä heidän sisältöään." #: src/view/com/auth/login/SetNewPasswordForm.tsx:57 #: src/view/com/auth/login/SetNewPasswordForm.tsx:92 #: src/view/com/modals/ChangePassword.tsx:87 #: src/view/com/modals/ChangePassword.tsx:121 msgid "You have entered an invalid code. It should look like XXXXX-XXXXX." -msgstr "" +msgstr "Olet syöttänyt virheellisen koodin. Sen tulisi näyttää muodoltaan XXXXX-XXXXX." #: src/view/com/modals/ModerationDetails.tsx:87 msgid "You have muted this user." -msgstr "" +msgstr "Olet hiljentänyt tämän käyttäjän." #: src/view/com/feeds/ProfileFeedgens.tsx:136 msgid "You have no feeds." -msgstr "" +msgstr "Sinulla ei ole syötteitä." #: src/view/com/lists/MyLists.tsx:89 #: src/view/com/lists/ProfileLists.tsx:140 msgid "You have no lists." -msgstr "" +msgstr "Sinulla ei ole listoja." #: src/view/screens/ModerationBlockedAccounts.tsx:132 msgid "You have not blocked any accounts yet. To block an account, go to their profile and selected \"Block account\" from the menu on their account." -msgstr "" +msgstr "Et ole vielä estänyt yhtään käyttäjää. Estääksesi käyttäjän, siirry heidän profiiliinsa ja valitse \"Estä käyttäjä\"-vaihtoehto heidän tilinsä valikosta." #: src/view/screens/AppPasswords.tsx:87 msgid "You have not created any app passwords yet. You can create one by pressing the button below." -msgstr "" +msgstr "Et ole vielä luonut yhtään sovelluksen salasanaa. Voit luoda sellaisen painamalla alla olevaa painiketta." #: src/view/screens/ModerationMutedAccounts.tsx:131 msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." -msgstr "" +msgstr "Et ole vielä hiljentänyt yhtään käyttäjää. Hiljentääksesi käyttäjän, siirry heidän profiiliinsa ja valitse \"Hiljennä käyttäjä\"-vaihtoehto heidän tilinsä valikosta." #: src/components/dialogs/MutedWords.tsx:202 msgid "You haven't muted any words or tags yet" -msgstr "" +msgstr "Et ole vielä hiljentänyt yhtään sanaa tai tunnistetta" #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." -msgstr "" +msgstr "Sinun on oltava vähintään 18-vuotias katsoaksesi aikuissisältöä." #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:103 msgid "You must be 18 years or older to enable adult content" -msgstr "" +msgstr "Sinun on oltava vähintään 18-vuotias katsoaksesi aikuissisältöä" #: src/view/com/util/forms/PostDropdownBtn.tsx:129 msgid "You will no longer receive notifications for this thread" -msgstr "" +msgstr "Et enää saa ilmoituksia tästä keskustelusta" #: src/view/com/util/forms/PostDropdownBtn.tsx:132 msgid "You will now receive notifications for this thread" -msgstr "" +msgstr "Saat nyt ilmoituksia tästä keskustelusta" #: src/view/com/auth/login/SetNewPasswordForm.tsx:107 msgid "You will receive an email with a \"reset code.\" Enter that code here, then enter your new password." -msgstr "" +msgstr "Saat sähköpostin \"nollauskoodin\". Syötä koodi tähän ja syötä sitten uusi salasanasi." #: src/screens/Onboarding/StepModeration/index.tsx:72 msgid "You're in control" -msgstr "" +msgstr "Sinulla on ohjat" #: src/screens/Deactivated.tsx:87 #: src/screens/Deactivated.tsx:88 #: src/screens/Deactivated.tsx:103 msgid "You're in line" -msgstr "" +msgstr "Olet jonossa" #: src/screens/Onboarding/StepFinished.tsx:90 msgid "You're ready to go!" -msgstr "" +msgstr "Olet valmis aloittamaan!" #: src/view/com/posts/FollowingEndOfFeed.tsx:48 msgid "You've reached the end of your feed! Find some more accounts to follow." -msgstr "" +msgstr "Olet saavuttanut syötteesi lopun! Etsi lisää käyttäjiä seurattavaksi." #: src/view/com/auth/create/Step1.tsx:74 msgid "Your account" -msgstr "" +msgstr "Tilisi" #: src/view/com/modals/DeleteAccount.tsx:67 msgid "Your account has been deleted" -msgstr "" +msgstr "Tilisi on poistettu" #: src/view/screens/Settings/ExportCarDialog.tsx:47 msgid "Your account repository, containing all public data records, can be downloaded as a \"CAR\" file. This file does not include media embeds, such as images, or your private data, which must be fetched separately." -msgstr "" +msgstr "Tilisi arkisto, joka sisältää kaikki julkiset tietueet, voidaan ladata \"CAR\"-tiedostona. Tämä tiedosto ei sisällä upotettuja mediaelementtejä, kuten kuvia, tai yksityisiä tietojasi, jotka on haettava erikseen." #: src/view/com/auth/create/Step1.tsx:238 msgid "Your birth date" -msgstr "" +msgstr "Syntymäaikasi" #: src/view/com/modals/InAppBrowserConsent.tsx:47 msgid "Your choice will be saved, but can be changed later in settings." -msgstr "" +msgstr "Valintasi tallennetaan, mutta sitä voit muuttaa myöhemmin asetuksissa." #: src/screens/Onboarding/StepFollowingFeed.tsx:61 msgid "Your default feed is \"Following\"" -msgstr "" +msgstr "Oletussyötteesi on \"Following\"" #: src/view/com/auth/create/state.ts:110 #: src/view/com/auth/login/ForgotPasswordForm.tsx:70 #: src/view/com/modals/ChangePassword.tsx:54 msgid "Your email appears to be invalid." -msgstr "" +msgstr "Sähköpostiosoitteesi näyttää olevan virheellinen." #: src/view/com/modals/Waitlist.tsx:109 msgid "Your email has been saved! We'll be in touch soon." -msgstr "" +msgstr "Sähköpostiosoitteesi on tallennettu! Olemme pian yhteydessä." #: src/view/com/modals/ChangeEmail.tsx:125 msgid "Your email has been updated but not verified. As a next step, please verify your new email." -msgstr "" +msgstr "Sähköpostiosoitteesi on päivitetty, mutta sitä ei ole vielä vahvistettu. Seuraavana vaiheena vahvista uusi sähköpostiosoitteesi." #: src/view/com/modals/VerifyEmail.tsx:114 msgid "Your email has not yet been verified. This is an important security step which we recommend." -msgstr "" +msgstr "Sähköpostiosoitettasi ei ole vielä vahvistettu. Tämä on tärkeä turvatoimi, jonka suosittelemme suorittamaan." #: src/view/com/posts/FollowingEmptyState.tsx:47 msgid "Your following feed is empty! Follow more users to see what's happening." -msgstr "" +msgstr "Seuraamiesi syöte on tyhjä! Seuraa lisää käyttäjiä nähdäksesi, mitä tapahtuu." #: src/view/com/auth/create/Step2.tsx:83 msgid "Your full handle will be" -msgstr "" +msgstr "Käyttäjätunnuksesi tulee olemaan" #: src/view/com/modals/ChangeHandle.tsx:270 msgid "Your full handle will be <0>@{0}" -msgstr "" +msgstr "Käyttäjätunnuksesi tulee olemaan <0>@{0}" #: src/view/screens/Settings.tsx:430 #: src/view/shell/desktop/RightNav.tsx:137 @@ -4809,31 +4808,31 @@ msgstr "" #: src/components/dialogs/MutedWords.tsx:173 msgid "Your muted words" -msgstr "" +msgstr "Hiljentämäsi sanat" #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" -msgstr "" +msgstr "Salasanasi on vaihdettu onnistuneesti!" #: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" -msgstr "" +msgstr "Viestisi on julkaistu" #: src/screens/Onboarding/StepFinished.tsx:105 #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:59 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:59 msgid "Your posts, likes, and blocks are public. Mutes are private." -msgstr "" +msgstr "Julkaisusi, tykkäyksesi ja estosi ovat julkisia. Hiljennykset ovat yksityisiä." #: src/view/com/modals/SwitchAccount.tsx:84 #: src/view/screens/Settings/index.tsx:118 msgid "Your profile" -msgstr "" +msgstr "Profiilisi" #: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" -msgstr "" +msgstr "Vastauksesi on julkaistu" #: src/view/com/auth/create/Step2.tsx:65 msgid "Your user handle" -msgstr "" +msgstr "Käyttäjätunnuksesi" From c52635c578c7f4663dd59c7135a43869a5fbae60 Mon Sep 17 00:00:00 2001 From: Jan-Olof Eriksson Date: Mon, 4 Mar 2024 19:04:04 +0200 Subject: [PATCH 053/109] Update messages.po --- src/locale/locales/en/messages.po | 2109 +++++++++++++++-------------- 1 file changed, 1055 insertions(+), 1054 deletions(-) diff --git a/src/locale/locales/en/messages.po b/src/locale/locales/en/messages.po index f5b40f4214..ec1b71cf29 100644 --- a/src/locale/locales/en/messages.po +++ b/src/locale/locales/en/messages.po @@ -5,17 +5,17 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: @lingui/cli\n" -"Language: fi\n" +"Language: en\n" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: \n" -"Last-Translator:@jaoler.fi\n" -"Language-Team: @pekka.bsky.social,@jaoler.fi,@rahi.bsky.social\n" +"Last-Translator: \n" +"Language-Team: \n" "Plural-Forms: \n" #: src/view/com/modals/VerifyEmail.tsx:142 msgid "(no email)" -msgstr "(ei sähköpostiosoitetta)" +msgstr "" #: src/view/shell/desktop/RightNav.tsx:168 #~ msgid "{0, plural, one {# invite code available} other {# invite codes available}}" @@ -23,7 +23,7 @@ msgstr "(ei sähköpostiosoitetta)" #: src/view/com/profile/ProfileHeader.tsx:593 msgid "{following} following" -msgstr "{following} seuraajaa" +msgstr "" #: src/view/shell/desktop/RightNav.tsx:151 #~ msgid "{invitesAvailable, plural, one {Invite codes: # available} other {Invite codes: # available}}" @@ -41,91 +41,91 @@ msgstr "{following} seuraajaa" #: src/view/shell/Drawer.tsx:440 msgid "{numUnreadNotifications} unread" -msgstr "{numUnreadNotifications} lukematonta" +msgstr "" #: src/view/com/threadgate/WhoCanReply.tsx:158 msgid "<0/> members" -msgstr "<0/> jäsentä" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:595 msgid "<0>{following} <1>following" -msgstr "<0>{following} <1>seuraajaa" +msgstr "" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:30 msgid "<0>Choose your<1>Recommended<2>Feeds" -msgstr "<0>Valitse<1>Suositellut<2>syötteet" +msgstr "" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:37 msgid "<0>Follow some<1>Recommended<2>Users" -msgstr "<0>Seuraa joitakin<1>suositeltuja<2>käyttäjiä" +msgstr "" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:21 msgid "<0>Welcome to<1>Bluesky" -msgstr "<0>Tervetuloa<1>Blueskyhin" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:558 msgid "⚠Invalid Handle" -msgstr "⚠Virheellinen käyttäjätunnus" +msgstr "" #: src/view/com/util/moderation/LabelInfo.tsx:45 msgid "A content warning has been applied to this {0}." -msgstr "Tämä {0} sisältää sisältövaroituksen." +msgstr "" #: src/lib/hooks/useOTAUpdate.ts:16 msgid "A new version of the app is available. Please update to continue using the app." -msgstr "Sovelluksen uusi versio on saatavilla. Päivitä jatkaaksesi sovelluksen käyttöä." +msgstr "" #: src/view/com/util/ViewHeader.tsx:83 #: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" -msgstr "Siirry navigointilinkkeihin ja asetuksiin" +msgstr "" #: src/view/com/home/HomeHeaderLayoutMobile.tsx:51 msgid "Access profile and other navigation links" -msgstr "Siirry profiiliin ja muihin navigointilinkkeihin" +msgstr "" #: src/view/com/modals/EditImage.tsx:299 #: src/view/screens/Settings/index.tsx:451 msgid "Accessibility" -msgstr "Saavutettavuus" +msgstr "" #: src/view/com/auth/login/LoginForm.tsx:166 #: src/view/screens/Settings/index.tsx:308 #: src/view/screens/Settings/index.tsx:721 msgid "Account" -msgstr "Tili" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:246 msgid "Account blocked" -msgstr "Tili on estetty" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:213 msgid "Account muted" -msgstr "Tili on hiljennetty" +msgstr "" #: src/view/com/modals/ModerationDetails.tsx:86 msgid "Account Muted" -msgstr "Tili on hiljennetty" +msgstr "" #: src/view/com/modals/ModerationDetails.tsx:72 msgid "Account Muted by List" -msgstr "Tili on hiljennetty listalla" +msgstr "" #: src/view/com/util/AccountDropdownBtn.tsx:41 msgid "Account options" -msgstr "Tilin asetukset" +msgstr "" #: src/view/com/util/AccountDropdownBtn.tsx:25 msgid "Account removed from quick access" -msgstr "Tili poistettu pikalinkeistä" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:268 msgid "Account unblocked" -msgstr "Tilin esto poistettu" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:226 msgid "Account unmuted" -msgstr "Tilin hiljennys poistettu" +msgstr "" #: src/components/dialogs/MutedWords.tsx:147 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 @@ -133,95 +133,95 @@ msgstr "Tilin hiljennys poistettu" #: src/view/com/modals/UserAddRemoveLists.tsx:219 #: src/view/screens/ProfileList.tsx:812 msgid "Add" -msgstr "Lisää" +msgstr "" #: src/view/com/modals/SelfLabel.tsx:56 msgid "Add a content warning" -msgstr "Lisää sisältövaroitus" +msgstr "" #: src/view/screens/ProfileList.tsx:802 msgid "Add a user to this list" -msgstr "Lisää käyttäjä tähän listaan" +msgstr "" #: src/view/screens/Settings/index.tsx:383 #: src/view/screens/Settings/index.tsx:392 msgid "Add account" -msgstr "Lisää tili" +msgstr "" #: src/view/com/composer/photos/Gallery.tsx:119 #: src/view/com/composer/photos/Gallery.tsx:180 #: src/view/com/modals/AltImage.tsx:116 msgid "Add alt text" -msgstr "Lisää ALT-teksti" +msgstr "" #: src/view/screens/AppPasswords.tsx:102 #: src/view/screens/AppPasswords.tsx:143 #: src/view/screens/AppPasswords.tsx:156 msgid "Add App Password" -msgstr "Lisää sovelluksen salasana" +msgstr "" #: src/view/com/modals/report/InputIssueDetails.tsx:41 #: src/view/com/modals/report/Modal.tsx:191 msgid "Add details" -msgstr "Lisää tiedot" +msgstr "" #: src/view/com/modals/report/Modal.tsx:194 msgid "Add details to report" -msgstr "Lisää tiedot raporttiin" +msgstr "" #: src/view/com/composer/Composer.tsx:453 msgid "Add link card" -msgstr "Lisää linkkikortti" +msgstr "" #: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" -msgstr "Lisää linkkikortti:" +msgstr "" #: src/components/dialogs/MutedWords.tsx:140 msgid "Add mute word for configured settings" -msgstr "Lisää hiljennetty sana määritettyihin asetuksiin" +msgstr "" #: src/components/dialogs/MutedWords.tsx:74 msgid "Add muted words and tags" -msgstr "Lisää hiljennetyt sanat ja tunnisteet" +msgstr "" #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" -msgstr "Lisää seuraava DNS-merkintä verkkotunnukseesi:" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:310 msgid "Add to Lists" -msgstr "Lisää listoihin" +msgstr "" #: src/view/com/feeds/FeedSourceCard.tsx:245 #: src/view/screens/ProfileFeed.tsx:273 msgid "Add to my feeds" -msgstr "Lisää syötteisiini" +msgstr "" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:139 msgid "Added" -msgstr "Lisätty" +msgstr "" #: src/view/com/modals/ListAddRemoveUsers.tsx:191 #: src/view/com/modals/UserAddRemoveLists.tsx:144 msgid "Added to list" -msgstr "Lisätty listaan" +msgstr "" #: src/view/com/feeds/FeedSourceCard.tsx:127 msgid "Added to my feeds" -msgstr "Lisätty syötteisiini" +msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:173 msgid "Adjust the number of likes a reply must have to be shown in your feed." -msgstr "Säädä, kuinka monta tykkäystä vastauksen on saatava näkyäkseen syötteessäsi." +msgstr "" #: src/view/com/modals/SelfLabel.tsx:75 msgid "Adult Content" -msgstr "Aikuissisältöä" +msgstr "" #: src/view/com/modals/ContentFilteringSettings.tsx:141 msgid "Adult content can only be enabled via the Web at <0/>." -msgstr "Aikuissisältö voidaan ottaa käyttöön vain verkon kautta osoitteessa <0/>." +msgstr "" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:78 #~ msgid "Adult content can only be enabled via the Web at <0>bsky.app." @@ -229,74 +229,74 @@ msgstr "Aikuissisältö voidaan ottaa käyttöön vain verkon kautta osoitteessa #: src/view/screens/Settings/index.tsx:664 msgid "Advanced" -msgstr "Edistynyt" +msgstr "" #: src/view/screens/Feeds.tsx:666 msgid "All the feeds you've saved, right in one place." -msgstr "Kaikki tallentamasi syötteet yhdessä paikassa." +msgstr "" #: src/view/com/auth/login/ForgotPasswordForm.tsx:221 #: src/view/com/modals/ChangePassword.tsx:168 msgid "Already have a code?" -msgstr "Onko sinulla jo koodi?" +msgstr "" #: src/view/com/auth/login/ChooseAccountForm.tsx:98 msgid "Already signed in as @{0}" -msgstr "Kirjautuneena sisään nimellä @{0}" +msgstr "" #: src/view/com/composer/photos/Gallery.tsx:130 msgid "ALT" -msgstr "ALT" +msgstr "" #: src/view/com/modals/EditImage.tsx:315 msgid "Alt text" -msgstr "ALT-teksti" +msgstr "" #: src/view/com/composer/photos/Gallery.tsx:209 msgid "Alt text describes images for blind and low-vision users, and helps give context to everyone." -msgstr "ALT-teksti kuvailee kuvia sokeille ja heikkonäköisille käyttäjille sekä lisää kontekstia kaikille." +msgstr "" #: src/view/com/modals/VerifyEmail.tsx:124 msgid "An email has been sent to {0}. It includes a confirmation code which you can enter below." -msgstr "Sähköposti on lähetetty osoitteeseen {0}. Siinä on vahvistuskoodi, jonka voit syöttää alla." +msgstr "" #: src/view/com/modals/ChangeEmail.tsx:119 msgid "An email has been sent to your previous address, {0}. It includes a confirmation code which you can enter below." -msgstr "Sähköposti on lähetetty aiempaan osoitteeseesi, {0}. Siinä on vahvistuskoodi, jonka voit syöttää alla." +msgstr "" #: src/view/com/profile/FollowButton.tsx:30 #: src/view/com/profile/FollowButton.tsx:40 msgid "An issue occurred, please try again." -msgstr "Tapahtui virhe, yritä uudelleen." +msgstr "" #: src/view/com/notifications/FeedItem.tsx:236 #: src/view/com/threadgate/WhoCanReply.tsx:178 msgid "and" -msgstr "ja" +msgstr "" #: src/screens/Onboarding/index.tsx:32 msgid "Animals" -msgstr "Eläimet" +msgstr "" #: src/view/screens/LanguageSettings.tsx:95 msgid "App Language" -msgstr "Sovelluksen kieli" +msgstr "" #: src/view/screens/AppPasswords.tsx:228 msgid "App password deleted" -msgstr "Sovelluksen salasana poistettu" +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:134 msgid "App Password names can only contain letters, numbers, spaces, dashes, and underscores." -msgstr "Sovelluksen salasanan nimet voivat sisältää vain kirjaimia, numeroita, välilyöntejä, viivoja ja alaviivoja." +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:99 msgid "App Password names must be at least 4 characters long." -msgstr "Sovelluksen salasanojen nimien on oltava vähintään 4 merkkiä pitkiä." +msgstr "" #: src/view/screens/Settings/index.tsx:675 msgid "App password settings" -msgstr "Sovelluksen salasanan asetukset" +msgstr "" #: src/view/screens/Settings.tsx:650 #~ msgid "App passwords" @@ -306,56 +306,56 @@ msgstr "Sovelluksen salasanan asetukset" #: src/view/screens/AppPasswords.tsx:187 #: src/view/screens/Settings/index.tsx:684 msgid "App Passwords" -msgstr "Sovellussalasanat" +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:295 msgid "Appeal content warning" -msgstr "Valita sisältövaroituksesta" +msgstr "" #: src/view/com/modals/AppealLabel.tsx:65 msgid "Appeal Content Warning" -msgstr "Valita sisältövaroituksesta" +msgstr "" #: src/view/com/util/moderation/LabelInfo.tsx:52 msgid "Appeal this decision" -msgstr "Valita tästä päätöksestä" +msgstr "" #: src/view/com/util/moderation/LabelInfo.tsx:56 msgid "Appeal this decision." -msgstr "Valita tästä päätöksestä." +msgstr "" #: src/view/screens/Settings/index.tsx:466 msgid "Appearance" -msgstr "Ulkonäkö" +msgstr "" #: src/view/screens/AppPasswords.tsx:224 msgid "Are you sure you want to delete the app password \"{name}\"?" -msgstr "Haluatko varmasti poistaa sovellussalasanan \"{name}\"?" +msgstr "" #: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" -msgstr "Haluatko varmasti hylätä tämän luonnoksen?" +msgstr "" #: src/components/dialogs/MutedWords.tsx:233 #: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" -msgstr "Oletko varma?" +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Are you sure? This cannot be undone." -msgstr "Oletko varma? Tätä ei voi perua." +msgstr "" #: src/view/com/composer/select-language/SuggestedLanguage.tsx:60 msgid "Are you writing in <0>{0}?" -msgstr "Onko viestisi kieli <0>{0}?" +msgstr "" #: src/screens/Onboarding/index.tsx:26 msgid "Art" -msgstr "Taide" +msgstr "" #: src/view/com/modals/SelfLabel.tsx:123 msgid "Artistic or non-erotic nudity." -msgstr "Taiteellinen tai ei-eroottinen alastomuus." +msgstr "" #: src/view/com/auth/create/CreateAccount.tsx:158 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 @@ -369,118 +369,118 @@ msgstr "Taiteellinen tai ei-eroottinen alastomuus." #: src/view/com/profile/ProfileHeader.tsx:649 #: src/view/com/util/ViewHeader.tsx:81 msgid "Back" -msgstr "Takaisin" +msgstr "" #: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" -msgstr "Takaisin" +msgstr "" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:136 msgid "Based on your interest in {interestsText}" -msgstr "Perustuen kiinnostukseesi {interestsText}" +msgstr "" #: src/view/screens/Settings/index.tsx:523 msgid "Basics" -msgstr "Perusasiat" +msgstr "" #: src/view/com/auth/create/Step1.tsx:250 #: src/view/com/modals/BirthDateSettings.tsx:73 msgid "Birthday" -msgstr "Syntymäpäivä" +msgstr "" #: src/view/screens/Settings/index.tsx:340 msgid "Birthday:" -msgstr "Syntymäpäivä:" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:239 #: src/view/com/profile/ProfileHeader.tsx:346 msgid "Block Account" -msgstr "Estä käyttäjä" +msgstr "" #: src/view/screens/ProfileList.tsx:556 msgid "Block accounts" -msgstr "Estä käyttäjät" +msgstr "" #: src/view/screens/ProfileList.tsx:506 msgid "Block list" -msgstr "Estettyjen lista" +msgstr "" #: src/view/screens/ProfileList.tsx:316 msgid "Block these accounts?" -msgstr "Estetäänkö nämä käyttäjät?" +msgstr "" #: src/view/screens/ProfileList.tsx:320 msgid "Block this List" -msgstr "Estä tämä lista" +msgstr "" #: src/view/com/lists/ListCard.tsx:110 #: src/view/com/util/post-embeds/QuoteEmbed.tsx:61 msgid "Blocked" -msgstr "Estetty" +msgstr "" #: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" -msgstr "Estetyt käyttäjät" +msgstr "" #: src/Navigation.tsx:130 #: src/view/screens/ModerationBlockedAccounts.tsx:107 msgid "Blocked Accounts" -msgstr "Estetyt käyttäjät" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:241 msgid "Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you." -msgstr "Estetyt käyttäjät eivät voi vastata viesteihisi, mainita sinua tai muuten olla vuorovaikutuksessa kanssasi." +msgstr "" #: src/view/screens/ModerationBlockedAccounts.tsx:115 msgid "Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you. You will not see their content and they will be prevented from seeing yours." -msgstr "Estetyt käyttäjät eivät voi vastata viesteihisi, mainita sinua tai muuten olla vuorovaikutuksessa kanssasi. Et näe heidän sisältöään ja he eivät näe sinun sisältöäsi." +msgstr "" #: src/view/com/post-thread/PostThread.tsx:324 msgid "Blocked post." -msgstr "Estetty viesti." +msgstr "" #: src/view/screens/ProfileList.tsx:318 msgid "Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you." -msgstr "Estäminen on julkista. Estetyt käyttäjät eivät voi vastata viesteihisi, mainita sinua tai muuten olla vuorovaikutuksessa kanssasi." +msgstr "" #: src/view/com/auth/HomeLoggedOutCTA.tsx:93 #: src/view/com/auth/SplashScreen.web.tsx:133 msgid "Blog" -msgstr "Blogi" +msgstr "" #: src/view/com/auth/HomeLoggedOutCTA.tsx:31 #: src/view/com/auth/server-input/index.tsx:89 #: src/view/com/auth/server-input/index.tsx:90 msgid "Bluesky" -msgstr "Bluesky" +msgstr "" #: src/view/com/auth/server-input/index.tsx:150 msgid "Bluesky is an open network where you can choose your hosting provider. Custom hosting is now available in beta for developers." -msgstr "Bluesky on avoin verkko, jossa voit valita palveluntarjoajasi. Räätälöity palveluntarjoajan määritys on nyt saatavilla betavaiheen kehittäjille." +msgstr "" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:80 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:80 msgid "Bluesky is flexible." -msgstr "Bluesky on joustava." +msgstr "" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:69 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:69 msgid "Bluesky is open." -msgstr "Bluesky on avoin." +msgstr "" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:56 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:56 msgid "Bluesky is public." -msgstr "Bluesky on julkinen." +msgstr "" #: src/view/com/modals/Waitlist.tsx:70 msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." -msgstr "Bluesky käyttää kutsuja rakentaakseen terveellisemmän yhteisön. Jos et tunne ketään, jolla on kutsu, voit ilmoittautua odotuslistalle, niin lähetämme sinulle pian yhden." +msgstr "" #: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." -msgstr "Bluesky ei näytä profiiliasi ja viestejäsi kirjautumattomille käyttäjille. Toiset sovellukset eivät ehkä noudata tätä asetusta. Tämä ei tee tilistäsi yksityistä." +msgstr "" #: src/view/com/modals/ServerInput.tsx:78 #~ msgid "Bluesky.Social" @@ -488,16 +488,16 @@ msgstr "Bluesky ei näytä profiiliasi ja viestejäsi kirjautumattomille käytt #: src/screens/Onboarding/index.tsx:33 msgid "Books" -msgstr "Kirjat" +msgstr "" #: src/view/screens/Settings/index.tsx:859 msgid "Build version {0} {1}" -msgstr "Versio {0} {1}" +msgstr "" #: src/view/com/auth/HomeLoggedOutCTA.tsx:87 #: src/view/com/auth/SplashScreen.web.tsx:128 msgid "Business" -msgstr "Yritys" +msgstr "" #: src/view/com/modals/ServerInput.tsx:115 #~ msgid "Button disabled. Input custom domain to proceed." @@ -505,29 +505,29 @@ msgstr "Yritys" #: src/view/com/profile/ProfileSubpageHeader.tsx:157 msgid "by —" -msgstr "käyttäjä —" +msgstr "" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:100 msgid "by {0}" -msgstr "käyttäjältä {0}" +msgstr "" #: src/view/com/profile/ProfileSubpageHeader.tsx:161 msgid "by <0/>" -msgstr "käyttäjältä <0/>" +msgstr "" #: src/view/com/profile/ProfileSubpageHeader.tsx:159 msgid "by you" -msgstr "sinulta" +msgstr "" #: src/view/com/composer/photos/OpenCameraBtn.tsx:60 #: src/view/com/util/UserAvatar.tsx:224 #: src/view/com/util/UserBanner.tsx:40 msgid "Camera" -msgstr "Kamera" +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:216 msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must be at least 4 characters long, but no more than 32 characters long." -msgstr "Voi sisältää vain kirjaimia, numeroita, välilyöntejä, viivoja ja alaviivoja. Täytyy olla vähintään 4 merkkiä pitkä, mutta enintään 32 merkkiä pitkä." +msgstr "" #: src/components/Prompt.tsx:91 #: src/view/com/composer/Composer.tsx:307 @@ -545,10 +545,10 @@ msgstr "Voi sisältää vain kirjaimia, numeroita, välilyöntejä, viivoja ja a #: src/view/com/modals/VerifyEmail.tsx:247 #: src/view/com/modals/VerifyEmail.tsx:253 #: src/view/com/modals/Waitlist.tsx:142 -#: src/view/screens/Search/Search.tsx:693 +#: src/view/screens/Search/Search.tsx:716 #: src/view/shell/desktop/Search.tsx:238 msgid "Cancel" -msgstr "Peruuta" +msgstr "" #: src/view/com/modals/Confirm.tsx:88 #: src/view/com/modals/Confirm.tsx:91 @@ -557,113 +557,113 @@ msgstr "Peruuta" #: src/view/com/modals/DeleteAccount.tsx:234 msgctxt "action" msgid "Cancel" -msgstr "Peruuta" +msgstr "" #: src/view/com/modals/DeleteAccount.tsx:152 #: src/view/com/modals/DeleteAccount.tsx:230 msgid "Cancel account deletion" -msgstr "Peruuta tilin poisto" +msgstr "" #: src/view/com/modals/ChangeHandle.tsx:149 msgid "Cancel change handle" -msgstr "Peruuta käyttäjätunnuksen vaihto" +msgstr "" #: src/view/com/modals/crop-image/CropImage.web.tsx:134 msgid "Cancel image crop" -msgstr "Peruuta kuvan rajaus" +msgstr "" #: src/view/com/modals/EditProfile.tsx:244 msgid "Cancel profile editing" -msgstr "Peruuta profiilin muokkaus" +msgstr "" #: src/view/com/modals/Repost.tsx:78 msgid "Cancel quote post" -msgstr "Peruuta uudelleenpostaus" +msgstr "" #: src/view/com/modals/ListAddRemoveUsers.tsx:87 #: src/view/shell/desktop/Search.tsx:234 msgid "Cancel search" -msgstr "Peruuta haku" +msgstr "" #: src/view/com/modals/Waitlist.tsx:136 msgid "Cancel waitlist signup" -msgstr "Peruuta odotuslistalle liittyminen" +msgstr "" #: src/view/screens/Settings/index.tsx:334 msgctxt "action" msgid "Change" -msgstr "Vaihda" +msgstr "" #: src/view/screens/Settings/index.tsx:696 msgid "Change handle" -msgstr "Vaihda käyttäjätunnus" +msgstr "" #: src/view/com/modals/ChangeHandle.tsx:161 #: src/view/screens/Settings/index.tsx:705 msgid "Change Handle" -msgstr "Vaihda käyttäjätunnus" +msgstr "" #: src/view/com/modals/VerifyEmail.tsx:147 msgid "Change my email" -msgstr "Vaihda sähköpostiosoitteeni" +msgstr "" #: src/view/screens/Settings/index.tsx:732 msgid "Change password" -msgstr "Vaihda salasana" +msgstr "" #: src/view/screens/Settings/index.tsx:741 msgid "Change Password" -msgstr "Vaihda salasana" +msgstr "" #: src/view/com/composer/select-language/SuggestedLanguage.tsx:73 msgid "Change post language to {0}" -msgstr "Vaihda julkaisun kieleksi {0}" +msgstr "" #: src/view/screens/Settings/index.tsx:733 msgid "Change your Bluesky password" -msgstr "Vaihda Bluesky-salasanasi" +msgstr "" #: src/view/com/modals/ChangeEmail.tsx:109 msgid "Change Your Email" -msgstr "Vaihda sähköpostiosoitteesi" +msgstr "" #: src/screens/Deactivated.tsx:72 #: src/screens/Deactivated.tsx:76 msgid "Check my status" -msgstr "Tarkista tilani" +msgstr "" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:121 msgid "Check out some recommended feeds. Tap + to add them to your list of pinned feeds." -msgstr "Katso joitakin suositeltuja syötteitä. Napauta + lisätäksesi ne kiinnitettyjen syötteiden luetteloon." +msgstr "" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:185 msgid "Check out some recommended users. Follow them to see similar users." -msgstr "Tutustu suositeltuihin käyttäjiin. Seuraa heitä löytääksesi samankaltaisia käyttäjiä." +msgstr "" #: src/view/com/modals/DeleteAccount.tsx:169 msgid "Check your inbox for an email with the confirmation code to enter below:" -msgstr "Tarkista sähköpostisi ja syötä saamasi vahvistuskoodi alle:" +msgstr "" #: src/view/com/modals/Threadgate.tsx:72 msgid "Choose \"Everybody\" or \"Nobody\"" -msgstr "Valitse \"Kaikki\" tai \"Ei kukaan\"" +msgstr "" #: src/view/screens/Settings/index.tsx:697 msgid "Choose a new Bluesky username or create" -msgstr "Valitse uusi Bluesky-käyttäjätunnus tai luo" +msgstr "" #: src/view/com/auth/server-input/index.tsx:79 msgid "Choose Service" -msgstr "Valitse palvelu" +msgstr "" #: src/screens/Onboarding/StepFinished.tsx:135 msgid "Choose the algorithms that power your custom feeds." -msgstr "Valitse algoritmit, jotka ohjaavat mukautettuja syötteitäsi." +msgstr "" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:83 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:83 msgid "Choose the algorithms that power your experience with custom feeds." -msgstr "Valitse algoritmit, jotka ohjaavat kokemustasi mukautettujen syötteiden kanssa." +msgstr "" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 #~ msgid "Choose your algorithmic feeds" @@ -671,134 +671,134 @@ msgstr "Valitse algoritmit, jotka ohjaavat kokemustasi mukautettujen syötteiden #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 msgid "Choose your main feeds" -msgstr "Valitse pääsyötteet" +msgstr "" #: src/view/com/auth/create/Step1.tsx:219 msgid "Choose your password" -msgstr "Valitse salasanasi" +msgstr "" #: src/view/screens/Settings/index.tsx:834 #: src/view/screens/Settings/index.tsx:835 msgid "Clear all legacy storage data" -msgstr "Tyhjennä kaikki vanhan tietomallin mukaiset tiedot" +msgstr "" #: src/view/screens/Settings/index.tsx:837 msgid "Clear all legacy storage data (restart after this)" -msgstr "Tyhjennä kaikki vanhan tietomallin tiedot (käynnistä uudelleen tämän jälkeen)" +msgstr "" #: src/view/screens/Settings/index.tsx:846 #: src/view/screens/Settings/index.tsx:847 msgid "Clear all storage data" -msgstr "Tyhjennä kaikki tallennukset" +msgstr "" #: src/view/screens/Settings/index.tsx:849 msgid "Clear all storage data (restart after this)" -msgstr "Tyhjennä kaikki tallennukset (käynnistä uudelleen tämän jälkeen)" +msgstr "" #: src/view/com/util/forms/SearchInput.tsx:88 #: src/view/screens/Search/Search.tsx:697 msgid "Clear search query" -msgstr "Tyhjennä hakukysely" +msgstr "" #: src/view/screens/Support.tsx:40 msgid "click here" -msgstr "klikkaa tästä" +msgstr "" #: src/components/RichText.tsx:189 #: src/components/TagMenu/index.web.tsx:125 msgid "Click here to open tag menu for {tag}" -msgstr "Avaa tästä valikko tunnisteelle {tag}" +msgstr "" #: src/screens/Onboarding/index.tsx:35 msgid "Climate" -msgstr "Ilmasto" +msgstr "" #: src/view/com/modals/ChangePassword.tsx:265 #: src/view/com/modals/ChangePassword.tsx:268 msgid "Close" -msgstr "Sulje" +msgstr "" #: src/components/Dialog/index.web.tsx:80 #: src/components/Dialog/index.web.tsx:194 msgid "Close active dialog" -msgstr "Sulje aktiivinen ikkuna" +msgstr "" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:38 msgid "Close alert" -msgstr "Sulje hälytys" +msgstr "" #: src/view/com/util/BottomSheetCustomBackdrop.tsx:33 msgid "Close bottom drawer" -msgstr "Sulje alavalinnat" +msgstr "" #: src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx:26 msgid "Close image" -msgstr "Sulje kuva" +msgstr "" #: src/view/com/lightbox/Lightbox.web.tsx:119 msgid "Close image viewer" -msgstr "Sulje kuvankatselu" +msgstr "" #: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" -msgstr "Sulje alanavigointi" +msgstr "" #: src/components/TagMenu/index.tsx:266 msgid "Close this dialog" -msgstr "Sulje tämä valintaikkuna" +msgstr "" #: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" -msgstr "Sulkee alanavigaation" +msgstr "" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:39 msgid "Closes password update alert" -msgstr "Sulkee salasanan päivitysilmoituksen" +msgstr "" #: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" -msgstr "Sulkee editorin ja hylkää luonnoksen" +msgstr "" #: src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx:27 msgid "Closes viewer for header image" -msgstr "Sulkee kuvan katseluohjelman" +msgstr "" #: src/view/com/notifications/FeedItem.tsx:317 msgid "Collapses list of users for a given notification" -msgstr "Pienentää käyttäjäluettelon annetulle ilmoitukselle" +msgstr "" #: src/screens/Onboarding/index.tsx:41 msgid "Comedy" -msgstr "Komedia" +msgstr "" #: src/screens/Onboarding/index.tsx:27 msgid "Comics" -msgstr "Sarjakuvat" +msgstr "" #: src/Navigation.tsx:227 #: src/view/screens/CommunityGuidelines.tsx:32 msgid "Community Guidelines" -msgstr "Yhteisöohjeet" +msgstr "" #: src/screens/Onboarding/StepFinished.tsx:148 msgid "Complete onboarding and start using your account" -msgstr "Suorita käyttöönotto loppuun ja aloita tilisi käyttö" +msgstr "" #: src/view/com/auth/create/Step3.tsx:73 msgid "Complete the challenge" -msgstr "Tee haaste loppuun" +msgstr "" #: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" -msgstr "Laadi viestejä, joiden pituus on enintään {MAX_GRAPHEME_LENGTH} merkkiä" +msgstr "" #: src/view/com/composer/Prompt.tsx:24 msgid "Compose reply" -msgstr "Kirjoita vastaus" +msgstr "" #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:67 msgid "Configure content filtering setting for category: {0}" -msgstr "Määritä sisällönsuodatusasetus aiheille: {0}" +msgstr "" #: src/components/Prompt.tsx:113 #: src/view/com/modals/AppealLabel.tsx:98 @@ -808,75 +808,75 @@ msgstr "Määritä sisällönsuodatusasetus aiheille: {0}" #: src/view/screens/PreferencesFollowingFeed.tsx:308 #: src/view/screens/PreferencesThreads.tsx:159 msgid "Confirm" -msgstr "Vahvista" +msgstr "" #: src/view/com/modals/Confirm.tsx:75 #: src/view/com/modals/Confirm.tsx:78 msgctxt "action" msgid "Confirm" -msgstr "Vahvista" +msgstr "" #: src/view/com/modals/ChangeEmail.tsx:193 #: src/view/com/modals/ChangeEmail.tsx:195 msgid "Confirm Change" -msgstr "Vahvista muutos" +msgstr "" #: src/view/com/modals/lang-settings/ConfirmLanguagesButton.tsx:34 msgid "Confirm content language settings" -msgstr "Vahvista sisällön kieliasetukset" +msgstr "" #: src/view/com/modals/DeleteAccount.tsx:220 msgid "Confirm delete account" -msgstr "Vahvista tilin poisto" +msgstr "" #: src/view/com/modals/ContentFilteringSettings.tsx:156 msgid "Confirm your age to enable adult content." -msgstr "Vahvista ikäsi nähdäksesi ikärajarajoitettua sisältöä" +msgstr "" #: src/view/com/modals/ChangeEmail.tsx:157 #: src/view/com/modals/DeleteAccount.tsx:182 #: src/view/com/modals/VerifyEmail.tsx:165 msgid "Confirmation code" -msgstr "Vahvistuskoodi" +msgstr "" #: src/view/com/modals/Waitlist.tsx:120 msgid "Confirms signing up {email} to the waitlist" -msgstr "Vahvistaa sähköpostiosoitteen {email} - rekisteröinnin odotuslistalle" +msgstr "" #: src/view/com/auth/create/CreateAccount.tsx:193 #: src/view/com/auth/login/LoginForm.tsx:278 msgid "Connecting..." -msgstr "Yhdistetään..." +msgstr "" #: src/view/com/auth/create/CreateAccount.tsx:213 msgid "Contact support" -msgstr "Ota yhteyttä tukeen" +msgstr "" #: src/view/screens/Moderation.tsx:83 msgid "Content filtering" -msgstr "Sisällönsuodatus" +msgstr "" #: src/view/com/modals/ContentFilteringSettings.tsx:44 msgid "Content Filtering" -msgstr "Sisällönsuodatus" +msgstr "" #: src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx:74 #: src/view/screens/LanguageSettings.tsx:278 msgid "Content Languages" -msgstr "Sisältöjen kielet" +msgstr "" #: src/view/com/modals/ModerationDetails.tsx:65 msgid "Content Not Available" -msgstr "Sisältö ei ole saatavilla" +msgstr "" #: src/view/com/modals/ModerationDetails.tsx:33 #: src/view/com/util/moderation/ScreenHider.tsx:78 msgid "Content Warning" -msgstr "Sisältövaroitus" +msgstr "" #: src/view/com/composer/labels/LabelsBtn.tsx:31 msgid "Content warnings" -msgstr "Sisältövaroitukset" +msgstr "" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:170 #: src/screens/Onboarding/StepFollowingFeed.tsx:153 @@ -886,143 +886,143 @@ msgstr "Sisältövaroitukset" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:148 #: src/view/com/auth/onboarding/RecommendedFollows.tsx:209 msgid "Continue" -msgstr "Jatka" +msgstr "" #: src/screens/Onboarding/StepFollowingFeed.tsx:150 #: src/screens/Onboarding/StepInterests/index.tsx:245 #: src/screens/Onboarding/StepModeration/index.tsx:115 #: src/screens/Onboarding/StepTopicalFeeds.tsx:111 msgid "Continue to next step" -msgstr "Jatka seuraavaan vaiheeseen" +msgstr "" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:167 msgid "Continue to the next step" -msgstr "Jatka seuraavaan vaiheeseen" +msgstr "" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:191 msgid "Continue to the next step without following any accounts" -msgstr "Jatka seuraavaan vaiheeseen seuraamatta yhtään tiliä" +msgstr "" #: src/screens/Onboarding/index.tsx:44 msgid "Cooking" -msgstr "Ruoanlaitto" +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:195 #: src/view/com/modals/InviteCodes.tsx:182 msgid "Copied" -msgstr "Kopioitu" +msgstr "" #: src/view/screens/Settings/index.tsx:241 msgid "Copied build version to clipboard" -msgstr "Ohjelmiston versio kopioitu leikepöydälle" +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 #: src/view/com/util/forms/PostDropdownBtn.tsx:143 msgid "Copied to clipboard" -msgstr "Kopioitu leikepöydälle" +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:189 msgid "Copies app password" -msgstr "Kopioi sovellussalasanan" +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:188 msgid "Copy" -msgstr "Kopioi" +msgstr "" #: src/view/screens/ProfileList.tsx:418 msgid "Copy link to list" -msgstr "Kopioi listan linkki" +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:184 msgid "Copy link to post" -msgstr "Kopioi julkaisun linkki" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:295 msgid "Copy link to profile" -msgstr "Kopioi linkki profiiliin" +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:170 msgid "Copy post text" -msgstr "Kopioi viestin teksti" +msgstr "" #: src/Navigation.tsx:232 #: src/view/screens/CopyrightPolicy.tsx:29 msgid "Copyright Policy" -msgstr "Tekijänoikeuskäytäntö" +msgstr "" #: src/view/screens/ProfileFeed.tsx:97 msgid "Could not load feed" -msgstr "Syötettä ei voitu ladata" +msgstr "" #: src/view/screens/ProfileList.tsx:888 msgid "Could not load list" -msgstr "Listaa ei voitu ladata" +msgstr "" #: src/view/com/auth/create/Step2.tsx:91 #~ msgid "Country" -#~ msgstr "Maa" +#~ msgstr "" #: src/view/com/auth/HomeLoggedOutCTA.tsx:62 #: src/view/com/auth/SplashScreen.tsx:71 #: src/view/com/auth/SplashScreen.web.tsx:81 msgid "Create a new account" -msgstr "Luo uusi tili" +msgstr "" #: src/view/screens/Settings/index.tsx:384 msgid "Create a new Bluesky account" -msgstr "Luo uusi Bluesky-tili" +msgstr "" #: src/view/com/auth/create/CreateAccount.tsx:133 msgid "Create Account" -msgstr "Luo tili" +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:226 msgid "Create App Password" -msgstr "Luo sovellussalasana" +msgstr "" #: src/view/com/auth/HomeLoggedOutCTA.tsx:54 #: src/view/com/auth/SplashScreen.tsx:68 msgid "Create new account" -msgstr "Luo uusi tili" +msgstr "" #: src/view/screens/AppPasswords.tsx:249 msgid "Created {0}" -msgstr "{0} luotu" +msgstr "" #: src/view/screens/ProfileFeed.tsx:616 msgid "Created by <0/>" -msgstr "Luonut <0/>" +msgstr "" #: src/view/screens/ProfileFeed.tsx:614 msgid "Created by you" -msgstr "Sinun luoma sisältö" +msgstr "" #: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" -msgstr "Luo kortin pikkukuvan kanssa. Kortti linkittyy osoitteeseen {url}" +msgstr "" #: src/screens/Onboarding/index.tsx:29 msgid "Culture" -msgstr "Kulttuuri" +msgstr "" #: src/view/com/auth/server-input/index.tsx:95 #: src/view/com/auth/server-input/index.tsx:96 msgid "Custom" -msgstr "Mukautettu" +msgstr "" #: src/view/com/modals/ChangeHandle.tsx:389 msgid "Custom domain" -msgstr "Mukautettu verkkotunnus" +msgstr "" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 #: src/view/screens/Feeds.tsx:692 msgid "Custom feeds built by the community bring you new experiences and help you find the content you love." -msgstr "Yhteisön rakentamat mukautetut syötteet tuovat sinulle uusia kokemuksia ja auttavat löytämään sinulle mieluisaa sisältöä." +msgstr "" #: src/view/screens/PreferencesExternalEmbeds.tsx:55 msgid "Customize media from external sites." -msgstr "Muokkaa mediaa ulkoisista sivustoista." +msgstr "" #: src/view/screens/Settings.tsx:687 #~ msgid "Danger Zone" @@ -1031,41 +1031,41 @@ msgstr "Muokkaa mediaa ulkoisista sivustoista." #: src/view/screens/Settings/index.tsx:485 #: src/view/screens/Settings/index.tsx:511 msgid "Dark" -msgstr "Tumma" +msgstr "" #: src/view/screens/Debug.tsx:63 msgid "Dark mode" -msgstr "Tumma ulkoasu" +msgstr "" #: src/view/screens/Settings/index.tsx:498 msgid "Dark Theme" -msgstr "Tumma teema" +msgstr "" #: src/view/screens/Debug.tsx:83 msgid "Debug panel" -msgstr "Vianetsintäpaneeli" +msgstr "" #: src/view/screens/Settings/index.tsx:772 msgid "Delete account" -msgstr "Poista käyttäjätili" +msgstr "" #: src/view/com/modals/DeleteAccount.tsx:87 msgid "Delete Account" -msgstr "Poista käyttäjätili" +msgstr "" #: src/view/screens/AppPasswords.tsx:222 #: src/view/screens/AppPasswords.tsx:242 msgid "Delete app password" -msgstr "Poista sovellussalasana" +msgstr "" #: src/view/screens/ProfileList.tsx:364 #: src/view/screens/ProfileList.tsx:445 msgid "Delete List" -msgstr "Poista lista" +msgstr "" #: src/view/com/modals/DeleteAccount.tsx:223 msgid "Delete my account" -msgstr "Poista käyttäjätilini" +msgstr "" #: src/view/screens/Settings.tsx:706 #~ msgid "Delete my account…" @@ -1073,30 +1073,30 @@ msgstr "Poista käyttäjätilini" #: src/view/screens/Settings/index.tsx:784 msgid "Delete My Account…" -msgstr "Poista tilini…" +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:273 msgid "Delete post" -msgstr "Poista viesti" +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:277 msgid "Delete this post?" -msgstr "Poista tämä viesti?" +msgstr "" #: src/view/com/util/post-embeds/QuoteEmbed.tsx:70 msgid "Deleted" -msgstr "Poistettu" +msgstr "" #: src/view/com/post-thread/PostThread.tsx:316 msgid "Deleted post." -msgstr "Poistettu viesti." +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:300 #: src/view/com/modals/CreateOrEditList.tsx:321 #: src/view/com/modals/EditProfile.tsx:198 #: src/view/com/modals/EditProfile.tsx:210 msgid "Description" -msgstr "Kuvaus" +msgstr "" #: src/view/screens/Settings.tsx:760 #~ msgid "Developer Tools" @@ -1104,28 +1104,28 @@ msgstr "Kuvaus" #: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" -msgstr "Haluatko sanoa jotain?" +msgstr "" #: src/view/screens/Settings/index.tsx:504 msgid "Dim" -msgstr "Himmeä" +msgstr "" #: src/view/com/composer/Composer.tsx:151 msgid "Discard" -msgstr "Hylkää" +msgstr "" #: src/view/com/composer/Composer.tsx:145 msgid "Discard draft" -msgstr "Hylkää luonnos" +msgstr "" #: src/view/screens/Moderation.tsx:226 msgid "Discourage apps from showing my account to logged-out users" -msgstr "Estä sovelluksia näyttämästä tiliäni kirjautumattomille käyttäjille" +msgstr "" #: src/view/com/posts/FollowingEmptyState.tsx:74 #: src/view/com/posts/FollowingEndOfFeed.tsx:75 msgid "Discover new custom feeds" -msgstr "Löydä uusia mukautettuja syötteitä" +msgstr "" #: src/view/screens/Feeds.tsx:473 #~ msgid "Discover new feeds" @@ -1133,23 +1133,23 @@ msgstr "Löydä uusia mukautettuja syötteitä" #: src/view/screens/Feeds.tsx:689 msgid "Discover New Feeds" -msgstr "Löydä uusia syötteitä" +msgstr "" #: src/view/com/modals/EditProfile.tsx:192 msgid "Display name" -msgstr "Näyttönimi" +msgstr "" #: src/view/com/modals/EditProfile.tsx:180 msgid "Display Name" -msgstr "Näyttönimi" +msgstr "" #: src/view/com/modals/ChangeHandle.tsx:487 msgid "Domain verified!" -msgstr "Verkkotunnus vahvistettu!" +msgstr "" #: src/view/com/auth/create/Step1.tsx:170 msgid "Don't have an invite code?" -msgstr "Eikö sinulla ole kutsukoodia?" +msgstr "" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:86 #: src/view/com/modals/EditImage.tsx:333 @@ -1162,7 +1162,7 @@ msgstr "Eikö sinulla ole kutsukoodia?" #: src/view/screens/PreferencesThreads.tsx:162 msgctxt "action" msgid "Done" -msgstr "Valmis" +msgstr "" #: src/view/com/auth/server-input/index.tsx:165 #: src/view/com/auth/server-input/index.tsx:166 @@ -1178,336 +1178,336 @@ msgstr "Valmis" #: src/view/screens/Settings/ExportCarDialog.tsx:93 #: src/view/screens/Settings/ExportCarDialog.tsx:94 msgid "Done" -msgstr "Valmis" +msgstr "" #: src/view/com/modals/lang-settings/ConfirmLanguagesButton.tsx:42 msgid "Done{extraText}" -msgstr "Valmis{extraText}" +msgstr "" #: src/view/com/auth/login/ChooseAccountForm.tsx:45 msgid "Double tap to sign in" -msgstr "Kaksoisnapauta kirjautuaksesi sisään" +msgstr "" #: src/view/screens/Settings/index.tsx:755 msgid "Download Bluesky account data (repository)" -msgstr "Lataa Bluesky-tilin tiedot (repository)" +msgstr "" #: src/view/screens/Settings/ExportCarDialog.tsx:59 #: src/view/screens/Settings/ExportCarDialog.tsx:63 msgid "Download CAR file" -msgstr "Lataa CAR tiedosto" +msgstr "" #: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" -msgstr "Raahaa tähän lisätäksesi kuvia" +msgstr "" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:111 msgid "Due to Apple policies, adult content can only be enabled on the web after completing sign up." -msgstr "Applen sääntöjen vuoksi aikuisviihde voidaan ottaa käyttöön vasta rekisteröitymisen jälkeen." +msgstr "" #: src/view/com/modals/EditProfile.tsx:185 msgid "e.g. Alice Roberts" -msgstr "esim. Mikko Mallikas" +msgstr "" #: src/view/com/modals/EditProfile.tsx:203 msgid "e.g. Artist, dog-lover, and avid reader." -msgstr "esim. Taiteilija, koiraharrastaja ja innokas lukija." +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:283 msgid "e.g. Great Posters" -msgstr "esim. Loistavat kirjoittajat" +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:284 msgid "e.g. Spammers" -msgstr "esim. Roskapostittajat" +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:312 msgid "e.g. The posters who never miss." -msgstr "esim. Julkaisijat, jotka osuvat maaliin aina." +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:313 msgid "e.g. Users that repeatedly reply with ads." -msgstr "esim. Käyttäjät, jotka vastaavat toistuvasti mainoksilla." +msgstr "" #: src/view/com/modals/InviteCodes.tsx:96 msgid "Each code works once. You'll receive more invite codes periodically." -msgstr "Jokainen koodi toimii vain kerran. Saat lisää kutsukoodeja säännöllisin väliajoin." +msgstr "" #: src/view/com/lists/ListMembers.tsx:149 msgctxt "action" msgid "Edit" -msgstr "Muokkaa" +msgstr "" #: src/view/com/composer/photos/Gallery.tsx:144 #: src/view/com/modals/EditImage.tsx:207 msgid "Edit image" -msgstr "Muokkaa kuvaa" +msgstr "" #: src/view/screens/ProfileList.tsx:433 msgid "Edit list details" -msgstr "Muokkaa listan tietoja" +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:250 msgid "Edit Moderation List" -msgstr "Muokkaa moderaatiolistaa" +msgstr "" #: src/Navigation.tsx:242 #: src/view/screens/Feeds.tsx:434 #: src/view/screens/SavedFeeds.tsx:84 msgid "Edit My Feeds" -msgstr "Muokkaa syötteitäni" +msgstr "" #: src/view/com/modals/EditProfile.tsx:152 msgid "Edit my profile" -msgstr "Muokkaa profiiliani" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:418 msgid "Edit profile" -msgstr "Muokkaa profiilia" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:423 msgid "Edit Profile" -msgstr "Muokkaa profiilia" +msgstr "" #: src/view/com/home/HomeHeaderLayout.web.tsx:59 #: src/view/screens/Feeds.tsx:355 msgid "Edit Saved Feeds" -msgstr "Muokkaa tallennettuja syötteitä" +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:245 msgid "Edit User List" -msgstr "Muokkaa käyttäjälistaa" +msgstr "" #: src/view/com/modals/EditProfile.tsx:193 msgid "Edit your display name" -msgstr "Muokkaa näyttönimeäsi" +msgstr "" #: src/view/com/modals/EditProfile.tsx:211 msgid "Edit your profile description" -msgstr "Muokkaa profiilin kuvausta" +msgstr "" #: src/screens/Onboarding/index.tsx:34 msgid "Education" -msgstr "Koulutus" +msgstr "" #: src/view/com/auth/create/Step1.tsx:199 #: src/view/com/auth/login/ForgotPasswordForm.tsx:156 #: src/view/com/modals/ChangeEmail.tsx:141 #: src/view/com/modals/Waitlist.tsx:88 msgid "Email" -msgstr "Sähköposti" +msgstr "" #: src/view/com/auth/create/Step1.tsx:190 #: src/view/com/auth/login/ForgotPasswordForm.tsx:147 msgid "Email address" -msgstr "Sähköpostiosoite" +msgstr "" #: src/view/com/modals/ChangeEmail.tsx:56 #: src/view/com/modals/ChangeEmail.tsx:88 msgid "Email updated" -msgstr "Sähköpostiosoite päivitetty" +msgstr "" #: src/view/com/modals/ChangeEmail.tsx:111 msgid "Email Updated" -msgstr "Sähköpostiosoite päivitetty" +msgstr "" #: src/view/com/modals/VerifyEmail.tsx:78 msgid "Email verified" -msgstr "Sähköpostiosoite vahvistettu" +msgstr "" #: src/view/screens/Settings/index.tsx:312 msgid "Email:" -msgstr "Sähköpostiosoite:" +msgstr "" #: src/view/com/modals/EmbedConsent.tsx:113 msgid "Enable {0} only" -msgstr "Ota käyttöön vain {0}" +msgstr "" #: src/view/com/modals/ContentFilteringSettings.tsx:167 msgid "Enable Adult Content" -msgstr "Ota aikuissisältö käyttöön" +msgstr "" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:76 #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:77 msgid "Enable adult content in your feeds" -msgstr "Näytä aikuissisältöä syötteissäsi" +msgstr "" #: src/view/com/modals/EmbedConsent.tsx:97 msgid "Enable External Media" -msgstr "Ota ulkoinen media käyttöön" +msgstr "" #: src/view/screens/PreferencesExternalEmbeds.tsx:75 msgid "Enable media players for" -msgstr "Ota mediatoistimet käyttöön kohteille" +msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:147 msgid "Enable this setting to only see replies between people you follow." -msgstr "Ota tämä asetus käyttöön nähdäksesi vastaukset vain seuraamiltasi ihmisiltä." +msgstr "" #: src/view/screens/Profile.tsx:455 msgid "End of feed" -msgstr "Syötteen loppu" +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:166 msgid "Enter a name for this App Password" -msgstr "Anna sovellusalasanalle nimi" +msgstr "" #: src/components/dialogs/MutedWords.tsx:87 #: src/components/dialogs/MutedWords.tsx:88 msgid "Enter a word or tag" -msgstr "Kirjoita sana tai tunniste" +msgstr "" #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" -msgstr "Syötä vahvistuskoodi" +msgstr "" #: src/view/com/modals/ChangePassword.tsx:151 msgid "Enter the code you received to change your password." -msgstr "Anna saamasi koodi vaihtaaksesi salasanasi." +msgstr "" #: src/view/com/modals/ChangeHandle.tsx:371 msgid "Enter the domain you want to use" -msgstr "Anna verkkotunnus, jota haluat käyttää" +msgstr "" #: src/view/com/auth/login/ForgotPasswordForm.tsx:107 msgid "Enter the email you used to create your account. We'll send you a \"reset code\" so you can set a new password." -msgstr "Anna sähköpostiosoite, jotaa käytit tilin luomiseen. Lähetämme sinulle \"nollauskoodin\", jotta voit määritellä uuden salasanan." +msgstr "" #: src/view/com/auth/create/Step1.tsx:251 #: src/view/com/modals/BirthDateSettings.tsx:74 msgid "Enter your birth date" -msgstr "Syötä syntymäaikasi" +msgstr "" #: src/view/com/modals/Waitlist.tsx:78 msgid "Enter your email" -msgstr "Syötä sähköpostiosoitteesi" +msgstr "" #: src/view/com/auth/create/Step1.tsx:195 msgid "Enter your email address" -msgstr "Syötä sähköpostiosoitteesi" +msgstr "" #: src/view/com/modals/ChangeEmail.tsx:41 msgid "Enter your new email above" -msgstr "Syötä uusi sähköpostiosoitteesi yläpuolelle" +msgstr "" #: src/view/com/modals/ChangeEmail.tsx:117 msgid "Enter your new email address below." -msgstr "Syötä uusi sähköpostiosoitteesi alle" +msgstr "" #: src/view/com/auth/create/Step2.tsx:188 #~ msgid "Enter your phone number" -msgstr "Syötä puhelinnumerosi" +#~ msgstr "" #: src/view/com/auth/login/Login.tsx:99 msgid "Enter your username and password" -msgstr "Syötä käyttäjätunnuksesi ja salasanasi" +msgstr "" #: src/view/com/auth/create/Step3.tsx:67 msgid "Error receiving captcha response." -msgstr "Virhe captcha-vastauksen vastaanottamisessa." +msgstr "" #: src/view/screens/Search/Search.tsx:110 msgid "Error:" -msgstr "Virhe:" +msgstr "" #: src/view/com/modals/Threadgate.tsx:76 msgid "Everybody" -msgstr "Kaikki" +msgstr "" #: src/view/com/modals/ChangeHandle.tsx:150 msgid "Exits handle change process" -msgstr "Peruuttaa käyttäjätunnuksen vaihtamisen" +msgstr "" #: src/view/com/lightbox/Lightbox.web.tsx:120 msgid "Exits image view" -msgstr "Poistuu kuvan katselutilasta" +msgstr "" #: src/view/com/modals/ListAddRemoveUsers.tsx:88 #: src/view/shell/desktop/Search.tsx:235 msgid "Exits inputting search query" -msgstr "Poistuu hakukyselyn kirjoittamisesta" +msgstr "" #: src/view/com/modals/Waitlist.tsx:138 msgid "Exits signing up for waitlist with {email}" -msgstr "Poistuu odotuslistalle liittymisestä sähköpostilla {email}" +msgstr "" #: src/view/com/lightbox/Lightbox.web.tsx:163 msgid "Expand alt text" -msgstr "Laajenna ALT-teksti" +msgstr "" #: src/view/com/composer/ComposerReplyTo.tsx:81 #: src/view/com/composer/ComposerReplyTo.tsx:84 msgid "Expand or collapse the full post you are replying to" -msgstr "Laajenna tai pienennä viesti johon olit vastaamassa" +msgstr "" #: src/view/screens/Settings/index.tsx:753 msgid "Export my data" -msgstr "Vie tietoni" +msgstr "" #: src/view/screens/Settings/ExportCarDialog.tsx:44 #: src/view/screens/Settings/index.tsx:764 msgid "Export My Data" -msgstr "Vie tietoni" +msgstr "" #: src/view/com/modals/EmbedConsent.tsx:64 msgid "External Media" -msgstr "Ulkoiset mediat" +msgstr "" #: src/view/com/modals/EmbedConsent.tsx:75 #: src/view/screens/PreferencesExternalEmbeds.tsx:66 msgid "External media may allow websites to collect information about you and your device. No information is sent or requested until you press the \"play\" button." -msgstr "Ulkoiset mediat voivat sallia verkkosivustojen kerätä tietoja sinusta ja laitteestasi. Tietoja ei lähetetä eikä pyydetä, ennen kuin painat \"toista\"-painiketta." +msgstr "" #: src/Navigation.tsx:261 #: src/view/screens/PreferencesExternalEmbeds.tsx:52 #: src/view/screens/Settings/index.tsx:657 msgid "External Media Preferences" -msgstr "Ulkoisten medioiden asetukset" +msgstr "" #: src/view/screens/Settings/index.tsx:648 msgid "External media settings" -msgstr "Ulkoisten medioiden asetukset" +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:115 #: src/view/com/modals/AddAppPasswords.tsx:119 msgid "Failed to create app password." -msgstr "Sovellussalasanan luominen epäonnistui." +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:206 msgid "Failed to create the list. Check your internet connection and try again." -msgstr "Listan luominen epäonnistui. Tarkista internetyhteytesi ja yritä uudelleen." +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Failed to delete post, please try again" -msgstr "Viestin poistaminen epäonnistui, yritä uudelleen" +msgstr "" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:109 #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:141 msgid "Failed to load recommended feeds" -msgstr "Suositeltujen syötteiden lataaminen epäonnistui" +msgstr "" #: src/Navigation.tsx:192 msgid "Feed" -msgstr "Syöte" +msgstr "" #: src/view/com/feeds/FeedSourceCard.tsx:231 msgid "Feed by {0}" -msgstr "Syöte käyttäjältä {0}" +msgstr "" #: src/view/screens/Feeds.tsx:605 msgid "Feed offline" -msgstr "Syöte ei ole käytettävissä" +msgstr "" #: src/view/com/feeds/FeedPage.tsx:143 #~ msgid "Feed Preferences" -#~ msgstr "Syötteen asetukset" +#~ msgstr "" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 msgid "Feedback" -msgstr "Palaute" +msgstr "" -#: src/Navigation.tsx:442 +#: src/Navigation.tsx:445 #: src/view/screens/Feeds.tsx:419 #: src/view/screens/Feeds.tsx:524 #: src/view/screens/Profile.tsx:184 @@ -1516,7 +1516,7 @@ msgstr "Palaute" #: src/view/shell/Drawer.tsx:476 #: src/view/shell/Drawer.tsx:477 msgid "Feeds" -msgstr "Syötteet" +msgstr "" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 #~ msgid "Feeds are created by users and can give you entirely new experiences." @@ -1528,125 +1528,125 @@ msgstr "Syötteet" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:57 msgid "Feeds are created by users to curate content. Choose some feeds that you find interesting." -msgstr "Käyttäjät luovat syötteitä sisällön kuratointiin. Valitse joitakin syötteitä, jotka koet mielenkiintoisiksi." +msgstr "" #: src/view/screens/SavedFeeds.tsx:156 msgid "Feeds are custom algorithms that users build with a little coding expertise. <0/> for more information." -msgstr "Syötteet ovat käyttäjien rakentamia mukautettuja algoritmeja, jotka vaativat vain vähän koodaustaitoja. <0/> lisätietoa varten." +msgstr "" #: src/screens/Onboarding/StepTopicalFeeds.tsx:76 msgid "Feeds can be topical as well!" -msgstr "Syötteet voivat olla myös aihepiirikohtaisia!" +msgstr "" #: src/screens/Onboarding/StepFinished.tsx:151 msgid "Finalizing" -msgstr "Viimeistely" +msgstr "" #: src/view/com/posts/CustomFeedEmptyState.tsx:47 #: src/view/com/posts/FollowingEmptyState.tsx:57 #: src/view/com/posts/FollowingEndOfFeed.tsx:58 msgid "Find accounts to follow" -msgstr "Etsi seurattavia tilejä" +msgstr "" #: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" -msgstr "Etsi käyttäjiä Bluesky-palvelusta" +msgstr "" #: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" -msgstr "Etsi käyttäjiä oikealla olevan hakutyökalun avulla" +msgstr "" #: src/view/com/auth/onboarding/RecommendedFollowsItem.tsx:150 msgid "Finding similar accounts..." -msgstr "Etsitään samankaltaisia käyttäjätilejä" +msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:111 msgid "Fine-tune the content you see on your Following feed." -msgstr "Hienosäädä näkemääsi sisältöä Seuraavat-syötteessäsi." +msgstr "" #: src/view/screens/PreferencesHomeFeed.tsx:111 #~ msgid "Fine-tune the content you see on your home screen." -#~ msgstr "Hienosäädä näkemääsi sisältöä pääsivulla." +#~ msgstr "" #: src/view/screens/PreferencesThreads.tsx:60 msgid "Fine-tune the discussion threads." -msgstr "Hienosäädä keskusteluketjuja." +msgstr "" #: src/screens/Onboarding/index.tsx:38 msgid "Fitness" -msgstr "Kuntoilu" +msgstr "" #: src/screens/Onboarding/StepFinished.tsx:131 msgid "Flexible" -msgstr "Joustava" +msgstr "" #: src/view/com/modals/EditImage.tsx:115 msgid "Flip horizontal" -msgstr "Käännä vaakasuunnassa" +msgstr "" #: src/view/com/modals/EditImage.tsx:120 #: src/view/com/modals/EditImage.tsx:287 msgid "Flip vertically" -msgstr "Käännä pystysuunnassa" +msgstr "" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:181 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:136 #: src/view/com/profile/ProfileHeader.tsx:513 msgid "Follow" -msgstr "Seuraa" +msgstr "" #: src/view/com/profile/FollowButton.tsx:64 msgctxt "action" msgid "Follow" -msgstr "Seuraa" +msgstr "" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:58 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:122 #: src/view/com/profile/ProfileHeader.tsx:504 msgid "Follow {0}" -msgstr "Seuraa {0}" +msgstr "" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:179 msgid "Follow All" -msgstr "Seuraa kaikkia" +msgstr "" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:174 msgid "Follow selected accounts and continue to the next step" -msgstr "Seuraa valittuja tilejä ja siirry seuraavaan vaiheeseen" +msgstr "" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:64 msgid "Follow some users to get started. We can recommend you more users based on who you find interesting." -msgstr "Seuraa joitakin käyttäjiä aloittaaksesi. Suosittelemme sinulle lisää käyttäjiä sen perusteella, ketä pidät mielenkiintoisena." +msgstr "" #: src/view/com/profile/ProfileCard.tsx:194 msgid "Followed by {0}" -msgstr "Seuraajina {0}" +msgstr "" #: src/view/com/modals/Threadgate.tsx:98 msgid "Followed users" -msgstr "Seuratut käyttäjät" +msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:154 msgid "Followed users only" -msgstr "Vain seuratut käyttäjät" +msgstr "" #: src/view/com/notifications/FeedItem.tsx:166 msgid "followed you" -msgstr "seurasi sinua" +msgstr "" #: src/view/screens/ProfileFollowers.tsx:25 msgid "Followers" -msgstr "Seuraajat" +msgstr "" #: src/view/com/post-thread/PostThreadFollowBtn.tsx:136 #: src/view/com/profile/ProfileHeader.tsx:495 #: src/view/screens/ProfileFollows.tsx:25 msgid "Following" -msgstr "Seuraa" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:149 msgid "Following {0}" -msgstr "Seuraa {0}" +msgstr "" #: src/Navigation.tsx:248 #: src/view/com/home/HomeHeaderLayout.web.tsx:45 @@ -1654,78 +1654,78 @@ msgstr "Seuraa {0}" #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 msgid "Following Feed Preferences" -msgstr "Seuratut -syötteen asetukset" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:546 msgid "Follows you" -msgstr "Seuraa sinua" +msgstr "" #: src/view/com/profile/ProfileCard.tsx:141 msgid "Follows You" -msgstr "Seuraa sinua" +msgstr "" #: src/screens/Onboarding/index.tsx:43 msgid "Food" -msgstr "Ruoka" +msgstr "" #: src/view/com/modals/DeleteAccount.tsx:111 msgid "For security reasons, we'll need to send a confirmation code to your email address." -msgstr "Turvallisuussyistä meidän on lähetettävä vahvistuskoodi sähköpostiosoitteeseesi." +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:209 msgid "For security reasons, you won't be able to view this again. If you lose this password, you'll need to generate a new one." -msgstr "Turvallisuussyistä et näe tätä uudelleen. Jos unohdat tämän salasanan, sinun on luotava uusi." +msgstr "" #: src/view/com/auth/login/LoginForm.tsx:241 msgid "Forgot" -msgstr "Unohtui" +msgstr "" #: src/view/com/auth/login/LoginForm.tsx:238 msgid "Forgot password" -msgstr "Unohtunut salasana" +msgstr "" #: src/view/com/auth/login/Login.tsx:127 #: src/view/com/auth/login/Login.tsx:143 msgid "Forgot Password" -msgstr "Unohtunut salasana" +msgstr "" #: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" -msgstr "Lähde: <0/>" +msgstr "" #: src/view/com/composer/photos/SelectPhotoBtn.tsx:43 msgid "Gallery" -msgstr "Galleria" +msgstr "" #: src/view/com/modals/VerifyEmail.tsx:189 #: src/view/com/modals/VerifyEmail.tsx:191 msgid "Get Started" -msgstr "Aloita tästä" +msgstr "" #: src/view/com/auth/LoggedOut.tsx:81 #: src/view/com/auth/LoggedOut.tsx:82 #: src/view/com/util/moderation/ScreenHider.tsx:123 #: src/view/shell/desktop/LeftNav.tsx:104 msgid "Go back" -msgstr "Palaa takaisin" +msgstr "" #: src/view/screens/ProfileFeed.tsx:106 #: src/view/screens/ProfileFeed.tsx:111 #: src/view/screens/ProfileList.tsx:897 #: src/view/screens/ProfileList.tsx:902 msgid "Go Back" -msgstr "Palaa takaisin" +msgstr "" #: src/screens/Onboarding/Layout.tsx:104 #: src/screens/Onboarding/Layout.tsx:193 msgid "Go back to previous step" -msgstr "Palaa edelliseen vaiheeseen" +msgstr "" #: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" -msgstr "Siirry @{queryMaybeHandle}" +msgstr "" #: src/view/com/auth/login/ForgotPasswordForm.tsx:189 #: src/view/com/auth/login/ForgotPasswordForm.tsx:218 @@ -1733,94 +1733,94 @@ msgstr "Siirry @{queryMaybeHandle}" #: src/view/com/auth/login/SetNewPasswordForm.tsx:195 #: src/view/com/modals/ChangePassword.tsx:165 msgid "Go to next" -msgstr "Siirry seuraavaan" +msgstr "" #: src/view/com/modals/ChangeHandle.tsx:265 msgid "Handle" -msgstr "Käyttäjätunnus" +msgstr "" #: src/components/RichText.tsx:188 msgid "Hashtag: {tag}" -msgstr "Tunniste: {tag}" +msgstr "" #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" -msgstr "Ongelmia?" +msgstr "" #: src/view/shell/desktop/RightNav.tsx:90 #: src/view/shell/Drawer.tsx:321 msgid "Help" -msgstr "Ohje" +msgstr "" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:132 msgid "Here are some accounts for you to follow" -msgstr "Tässä on joitakin tilejä seurattavaksi" +msgstr "" #: src/screens/Onboarding/StepTopicalFeeds.tsx:85 msgid "Here are some popular topical feeds. You can choose to follow as many as you like." -msgstr "Tässä on joitakin suosittuja aihepiirikohtaisia syötteitä. Voit valita seurattavaksi niin monta kuin haluat." +msgstr "" #: src/screens/Onboarding/StepTopicalFeeds.tsx:80 msgid "Here are some topical feeds based on your interests: {interestsText}. You can choose to follow as many as you like." -msgstr "Tässä on joitakin aihepiirikohtaisia syötteitä kiinnostuksiesi perusteella: {interestsText}. Voit valita seurata niin montaa kuin haluat." +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:153 msgid "Here is your app password." -msgstr "Tässä on sovelluksesi salasana." +msgstr "" #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:41 #: src/view/com/modals/ContentFilteringSettings.tsx:251 #: src/view/com/util/moderation/ContentHider.tsx:105 #: src/view/com/util/moderation/PostHider.tsx:108 msgid "Hide" -msgstr "Piilota" +msgstr "" #: src/view/com/modals/ContentFilteringSettings.tsx:224 #: src/view/com/notifications/FeedItem.tsx:325 msgctxt "action" msgid "Hide" -msgstr "Piilota" +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Hide post" -msgstr "Piilota viesti" +msgstr "" #: src/view/com/util/moderation/ContentHider.tsx:67 #: src/view/com/util/moderation/PostHider.tsx:61 msgid "Hide the content" -msgstr "Piilota sisältö" +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:236 msgid "Hide this post?" -msgstr "Piilota tämä viesti?" +msgstr "" #: src/view/com/notifications/FeedItem.tsx:315 msgid "Hide user list" -msgstr "Piilota käyttäjäluettelo" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:487 msgid "Hides posts from {0} in your feed" -msgstr "Piilottaa viestit käyttäjältä {0} syötteessäsi" +msgstr "" #: src/view/com/posts/FeedErrorMessage.tsx:111 msgid "Hmm, some kind of issue occurred when contacting the feed server. Please let the feed owner know about this issue." -msgstr "Hmm, jokin ongelma ilmeni ottaessa yhteyttä syötteen palvelimeen. Ilmoita asiasta syötteen omistajalle." +msgstr "" #: src/view/com/posts/FeedErrorMessage.tsx:99 msgid "Hmm, the feed server appears to be misconfigured. Please let the feed owner know about this issue." -msgstr "Hmm, syötteen palvelin vaikuttaa olevan väärin konfiguroitu. Ilmoita asiasta syötteen omistajalle." +msgstr "" #: src/view/com/posts/FeedErrorMessage.tsx:105 msgid "Hmm, the feed server appears to be offline. Please let the feed owner know about this issue." -msgstr "Hmm, syötteen palvelin vaikuttaa olevan poissa käytöstä. Ilmoita asiasta syötteen omistajalle." +msgstr "" #: src/view/com/posts/FeedErrorMessage.tsx:102 msgid "Hmm, the feed server gave a bad response. Please let the feed owner know about this issue." -msgstr "Hmm, syötteen palvelin antoi virheellisen vastauksen. Ilmoita asiasta syötteen omistajalle." +msgstr "" #: src/view/com/posts/FeedErrorMessage.tsx:96 msgid "Hmm, we're having trouble finding this feed. It may have been deleted." -msgstr "Hmm, meillä on vaikeuksia löytää tätä syötettä. Se saattaa olla poistettu." +msgstr "" #: src/Navigation.tsx:435 #: src/view/shell/bottom-bar/BottomBar.tsx:137 @@ -1828,124 +1828,124 @@ msgstr "Hmm, meillä on vaikeuksia löytää tätä syötettä. Se saattaa olla #: src/view/shell/Drawer.tsx:398 #: src/view/shell/Drawer.tsx:399 msgid "Home" -msgstr "Koti" +msgstr "" #: src/Navigation.tsx:247 #: src/view/com/pager/FeedsTabBarMobile.tsx:123 #: src/view/screens/PreferencesHomeFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 #~ msgid "Home Feed Preferences" -#~ msgstr "Aloitussivun syötteiden asetukset" +#~ msgstr "" #: src/view/com/auth/create/Step1.tsx:82 #: src/view/com/auth/login/ForgotPasswordForm.tsx:120 msgid "Hosting provider" -msgstr "Hostingyritys" +msgstr "" #: src/view/com/modals/InAppBrowserConsent.tsx:44 msgid "How should we open this link?" -msgstr "Kuinka haluat avata tämän linkin?" +msgstr "" #: src/view/com/modals/VerifyEmail.tsx:214 msgid "I have a code" -msgstr "Minulla on koodi" +msgstr "" #: src/view/com/modals/VerifyEmail.tsx:216 msgid "I have a confirmation code" -msgstr "Minulla on vahvistuskoodi" +msgstr "" #: src/view/com/modals/ChangeHandle.tsx:283 msgid "I have my own domain" -msgstr "Minulla on oma verkkotunnus" +msgstr "" #: src/view/com/lightbox/Lightbox.web.tsx:165 msgid "If alt text is long, toggles alt text expanded state" -msgstr "Jos ALT-teksti on pitkä, vaihtaa ALT-tekstin laajennetun tilan" +msgstr "" #: src/view/com/modals/SelfLabel.tsx:127 msgid "If none are selected, suitable for all ages." -msgstr "Jos mitään ei ole valittu, sopii kaikenikäisille." +msgstr "" #: src/view/com/modals/ChangePassword.tsx:146 msgid "If you want to change your password, we will send you a code to verify that this is your account." -msgstr "Jos haluat vaihtaa salasanasi, lähetämme sinulle koodin varmistaaksemme, että tämä on tilisi." +msgstr "" #: src/view/com/util/images/Gallery.tsx:38 msgid "Image" -msgstr "Kuva" +msgstr "" #: src/view/com/modals/AltImage.tsx:120 msgid "Image alt text" -msgstr "Kuvan ALT-teksti" +msgstr "" #: src/view/com/util/UserAvatar.tsx:311 #: src/view/com/util/UserBanner.tsx:118 msgid "Image options" -msgstr "Kuva-asetukset" +msgstr "" #: src/view/com/auth/login/SetNewPasswordForm.tsx:138 msgid "Input code sent to your email for password reset" -msgstr "Syötä sähköpostiisi lähetetty koodi salasanan nollaamista varten" +msgstr "" #: src/view/com/modals/DeleteAccount.tsx:184 msgid "Input confirmation code for account deletion" -msgstr "Syötä vahvistuskoodi tilin poistoa varten" +msgstr "" #: src/view/com/auth/create/Step1.tsx:200 msgid "Input email for Bluesky account" -msgstr "Syötä sähköposti Bluesky-tiliä varten" +msgstr "" #: src/view/com/auth/create/Step1.tsx:158 msgid "Input invite code to proceed" -msgstr "Syötä kutsukoodi jatkaaksesi" +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:180 msgid "Input name for app password" -msgstr "Syötä nimi sovellussalasanaa varten" +msgstr "" #: src/view/com/auth/login/SetNewPasswordForm.tsx:162 msgid "Input new password" -msgstr "Syötä uusi salasana" +msgstr "" #: src/view/com/modals/DeleteAccount.tsx:203 msgid "Input password for account deletion" -msgstr "Syötä salasana tilin poistoa varten" +msgstr "" #: src/view/com/auth/create/Step2.tsx:196 #~ msgid "Input phone number for SMS verification" -#~ msgstr "Syötä puhelinnumero SMS-varmennusta varten" +#~ msgstr "" #: src/view/com/auth/login/LoginForm.tsx:230 msgid "Input the password tied to {identifier}" -msgstr "Syötä salasana, joka liittyy kohteeseen {identifier}" +msgstr "" #: src/view/com/auth/login/LoginForm.tsx:197 msgid "Input the username or email address you used at signup" -msgstr "Syötä käyttäjätunnus tai sähköpostiosoite, jonka käytit rekisteröityessäsi" +msgstr "" #: src/view/com/auth/create/Step2.tsx:271 #~ msgid "Input the verification code we have texted to you" -#~ msgstr "Syötä sinulle tekstattu varmennuskoodi" +#~ msgstr "" #: src/view/com/modals/Waitlist.tsx:90 msgid "Input your email to get on the Bluesky waitlist" -msgstr "Syötä sähköpostiosoitteesi päästäksesi Bluesky-jonoon" +msgstr "" #: src/view/com/auth/login/LoginForm.tsx:229 msgid "Input your password" -msgstr "Syötä salasanasi" +msgstr "" #: src/view/com/auth/create/Step2.tsx:80 msgid "Input your user handle" -msgstr "Syötä käyttäjätunnuksesi" +msgstr "" #: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" -msgstr "Virheellinen tai ei tuettu tietue" +msgstr "" #: src/view/com/auth/login/LoginForm.tsx:113 msgid "Invalid username or password" -msgstr "Virheellinen käyttäjätunnus tai salasana" +msgstr "" #: src/view/screens/Settings.tsx:411 #~ msgid "Invite" @@ -1953,20 +1953,20 @@ msgstr "Virheellinen käyttäjätunnus tai salasana" #: src/view/com/modals/InviteCodes.tsx:93 msgid "Invite a Friend" -msgstr "Kutsu ystävä" +msgstr "" #: src/view/com/auth/create/Step1.tsx:148 #: src/view/com/auth/create/Step1.tsx:157 msgid "Invite code" -msgstr "Kutsukoodi" +msgstr "" #: src/view/com/auth/create/state.ts:158 msgid "Invite code not accepted. Check that you input it correctly and try again." -msgstr "Kutsukoodia ei hyväksytty. Tarkista, että syötit sen oikein ja yritä uudelleen." +msgstr "" #: src/view/com/modals/InviteCodes.tsx:170 msgid "Invite codes: {0} available" -msgstr "Kutsukoodit: {0} saatavilla" +msgstr "" #: src/view/shell/Drawer.tsx:645 #~ msgid "Invite codes: {invitesAvailable} available" @@ -1974,64 +1974,64 @@ msgstr "Kutsukoodit: {0} saatavilla" #: src/view/com/modals/InviteCodes.tsx:169 msgid "Invite codes: 1 available" -msgstr "Kutsukoodit: 1 saatavilla" +msgstr "" #: src/screens/Onboarding/StepFollowingFeed.tsx:64 msgid "It shows posts from the people you follow as they happen." -msgstr "Se näyttää viestejä seuraamiltasi ihmisiltä reaaliajassa." +msgstr "" #: src/view/com/auth/HomeLoggedOutCTA.tsx:99 #: src/view/com/auth/SplashScreen.web.tsx:138 msgid "Jobs" -msgstr "Työpaikat" +msgstr "" #: src/view/com/modals/Waitlist.tsx:67 msgid "Join the waitlist" -msgstr "Liity odotuslistalle" +msgstr "" #: src/view/com/auth/create/Step1.tsx:174 #: src/view/com/auth/create/Step1.tsx:178 msgid "Join the waitlist." -msgstr "Liity odotuslistalle." +msgstr "" #: src/view/com/modals/Waitlist.tsx:128 msgid "Join Waitlist" -msgstr "Liity odotuslistalle" +msgstr "" #: src/screens/Onboarding/index.tsx:24 msgid "Journalism" -msgstr "Journalismi" +msgstr "" #: src/view/com/composer/select-language/SelectLangBtn.tsx:104 msgid "Language selection" -msgstr "Kielen valinta" +msgstr "" #: src/view/screens/Settings/index.tsx:594 msgid "Language settings" -msgstr "Kielen asetukset" +msgstr "" #: src/Navigation.tsx:140 #: src/view/screens/LanguageSettings.tsx:89 msgid "Language Settings" -msgstr "Kielen asetukset" +msgstr "" #: src/view/screens/Settings/index.tsx:603 msgid "Languages" -msgstr "Kielet" +msgstr "" #: src/view/com/auth/create/StepHeader.tsx:20 msgid "Last step!" -msgstr "Viimeinen vaihe!" +msgstr "" #: src/view/com/util/moderation/ContentHider.tsx:103 msgid "Learn more" -msgstr "Lue lisää" +msgstr "" #: src/view/com/util/moderation/PostAlerts.tsx:47 #: src/view/com/util/moderation/ProfileHeaderAlerts.tsx:65 #: src/view/com/util/moderation/ScreenHider.tsx:104 msgid "Learn More" -msgstr "Lue lisää" +msgstr "" #: src/view/com/util/moderation/ContentHider.tsx:85 #: src/view/com/util/moderation/PostAlerts.tsx:40 @@ -2039,123 +2039,123 @@ msgstr "Lue lisää" #: src/view/com/util/moderation/ProfileHeaderAlerts.tsx:49 #: src/view/com/util/moderation/ScreenHider.tsx:101 msgid "Learn more about this warning" -msgstr "Lue lisää tästä varoituksesta" +msgstr "" #: src/view/screens/Moderation.tsx:262 msgid "Learn more about what is public on Bluesky." -msgstr "Lue lisää siitä, mikä on julkista Blueskyssa." +msgstr "" #: src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx:82 msgid "Leave them all unchecked to see any language." -msgstr "Jätä kaikki valitsematta nähdäksesi minkä tahansa kielen." +msgstr "" #: src/view/com/modals/LinkWarning.tsx:51 msgid "Leaving Bluesky" -msgstr "Poistuminen Blueskysta" +msgstr "" #: src/screens/Deactivated.tsx:128 msgid "left to go." -msgstr "jäljellä." +msgstr "" #: src/view/screens/Settings/index.tsx:278 msgid "Legacy storage cleared, you need to restart the app now." -msgstr "Legacy tietovarasto tyhjennetty, sinun on käynnistettävä sovellus uudelleen nyt." +msgstr "" #: src/view/com/auth/login/Login.tsx:128 #: src/view/com/auth/login/Login.tsx:144 msgid "Let's get your password reset!" -msgstr "Aloitetaan salasanasi nollaus!" +msgstr "" #: src/screens/Onboarding/StepFinished.tsx:151 msgid "Let's go!" -msgstr "Aloitetaan!" +msgstr "" #: src/view/com/util/UserAvatar.tsx:248 #: src/view/com/util/UserBanner.tsx:62 msgid "Library" -msgstr "Kirjasto" +msgstr "" #: src/view/screens/Settings/index.tsx:479 msgid "Light" -msgstr "Vaalea" +msgstr "" #: src/view/com/util/post-ctrls/PostCtrls.tsx:182 #: src/view/com/util/post-ctrls/PostCtrls.tsx:216 msgid "Like" -msgstr "Tykkää" +msgstr "" #: src/view/screens/ProfileFeed.tsx:591 msgid "Like this feed" -msgstr "Tykkää tästä syötteestä" +msgstr "" #: src/Navigation.tsx:197 msgid "Liked by" -msgstr "Tykänneet" +msgstr "" #: src/view/screens/PostLikedBy.tsx:27 #: src/view/screens/ProfileFeedLikedBy.tsx:27 msgid "Liked By" -msgstr "Tykänneet" +msgstr "" #: src/view/com/feeds/FeedSourceCard.tsx:279 msgid "Liked by {0} {1}" -msgstr "Tykänneet {0} {1}" +msgstr "" #: src/view/screens/ProfileFeed.tsx:606 msgid "Liked by {likeCount} {0}" -msgstr "Tykkäyksiä {likeCount} {0}" +msgstr "" #: src/view/com/notifications/FeedItem.tsx:170 msgid "liked your custom feed" -msgstr "tykkäsi mukautetusta syötteestäsi" +msgstr "" #: src/view/com/notifications/FeedItem.tsx:155 msgid "liked your post" -msgstr "tykkäsi viestistäsi" +msgstr "" #: src/view/screens/Profile.tsx:183 msgid "Likes" -msgstr "Tykkäykset" +msgstr "" #: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" -msgstr "Tykkäykset tässä viestissä" +msgstr "" #: src/Navigation.tsx:166 msgid "List" -msgstr "Lista" +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:261 msgid "List Avatar" -msgstr "Listan kuvake" +msgstr "" #: src/view/screens/ProfileList.tsx:324 msgid "List blocked" -msgstr "Lista estetty" +msgstr "" #: src/view/com/feeds/FeedSourceCard.tsx:233 msgid "List by {0}" -msgstr "Listan on luonut {0}" +msgstr "" #: src/view/screens/ProfileList.tsx:378 msgid "List deleted" -msgstr "Lista poistettu" +msgstr "" #: src/view/screens/ProfileList.tsx:283 msgid "List muted" -msgstr "Lista hiljennetty" +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:275 msgid "List Name" -msgstr "Listan nimi" +msgstr "" #: src/view/screens/ProfileList.tsx:343 msgid "List unblocked" -msgstr "Listaa estosta poistetut" +msgstr "" #: src/view/screens/ProfileList.tsx:302 msgid "List unmuted" -msgstr "Listaa hiljennyksestä poistetut" +msgstr "" #: src/Navigation.tsx:110 #: src/view/screens/Profile.tsx:185 @@ -2163,27 +2163,27 @@ msgstr "Listaa hiljennyksestä poistetut" #: src/view/shell/Drawer.tsx:492 #: src/view/shell/Drawer.tsx:493 msgid "Lists" -msgstr "Listat" +msgstr "" #: src/view/com/post-thread/PostThread.tsx:333 #: src/view/com/post-thread/PostThread.tsx:341 msgid "Load more posts" -msgstr "Lataa lisää viestejä" +msgstr "" #: src/view/screens/Notifications.tsx:159 msgid "Load new notifications" -msgstr "Lataa uusia ilmoituksia" +msgstr "" #: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 #: src/view/screens/ProfileFeed.tsx:495 #: src/view/screens/ProfileList.tsx:681 msgid "Load new posts" -msgstr "Lataa uusia viestejä" +msgstr "" #: src/view/com/composer/text-input/mobile/Autocomplete.tsx:95 msgid "Loading..." -msgstr "Ladataan..." +msgstr "" #: src/view/com/modals/ServerInput.tsx:50 #~ msgid "Local dev server" @@ -2191,59 +2191,59 @@ msgstr "Ladataan..." #: src/Navigation.tsx:207 msgid "Log" -msgstr "Loki" +msgstr "" #: src/screens/Deactivated.tsx:149 #: src/screens/Deactivated.tsx:152 #: src/screens/Deactivated.tsx:178 #: src/screens/Deactivated.tsx:181 msgid "Log out" -msgstr "Kirjaudu ulos" +msgstr "" #: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" -msgstr "Näkyvyys kirjautumattomana" +msgstr "" #: src/view/com/auth/login/ChooseAccountForm.tsx:133 msgid "Login to account that is not listed" -msgstr "Kirjaudu tiliin, joka ei ole luettelossa" +msgstr "" #: src/view/com/modals/LinkWarning.tsx:65 msgid "Make sure this is where you intend to go!" -msgstr "Varmista, että olet menossa oikeaan paikkaan!" +msgstr "" #: src/components/dialogs/MutedWords.tsx:71 msgid "Manage your muted words and tags" -msgstr "Hallinnoi hiljennettyjä sanojasi ja tunnisteitasi" +msgstr "" #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" -msgstr "Ei saa olla pidempi kuin 253 merkkiä" +msgstr "" #: src/view/com/auth/create/Step2.tsx:109 msgid "May only contain letters and numbers" -msgstr "Ei saa olla pidempi kuin 253 merkkiä" +msgstr "" #: src/view/screens/Profile.tsx:182 msgid "Media" -msgstr "Media" +msgstr "" #: src/view/com/threadgate/WhoCanReply.tsx:139 msgid "mentioned users" -msgstr "mainitut käyttäjät" +msgstr "" #: src/view/com/modals/Threadgate.tsx:93 msgid "Mentioned users" -msgstr "Mainitut käyttäjät" +msgstr "" #: src/view/com/util/ViewHeader.tsx:81 -#: src/view/screens/Search/Search.tsx:623 +#: src/view/screens/Search/Search.tsx:646 msgid "Menu" -msgstr "Valikko" +msgstr "" #: src/view/com/posts/FeedErrorMessage.tsx:197 msgid "Message from server: {0}" -msgstr "Viesti palvelimelta: {0}" +msgstr "" #: src/Navigation.tsx:115 #: src/view/screens/Moderation.tsx:66 @@ -2252,182 +2252,183 @@ msgstr "Viesti palvelimelta: {0}" #: src/view/shell/Drawer.tsx:511 #: src/view/shell/Drawer.tsx:512 msgid "Moderation" -msgstr "Moderointi" +msgstr "" #: src/view/com/lists/ListCard.tsx:93 #: src/view/com/modals/UserAddRemoveLists.tsx:206 msgid "Moderation list by {0}" -msgstr "Moderointilista käyttäjältä {0}" +msgstr "" #: src/view/screens/ProfileList.tsx:774 msgid "Moderation list by <0/>" -msgstr "Moderointilista käyttäjältä <0/>" +msgstr "" #: src/view/com/lists/ListCard.tsx:91 #: src/view/com/modals/UserAddRemoveLists.tsx:204 #: src/view/screens/ProfileList.tsx:772 msgid "Moderation list by you" -msgstr "Sinun moderointilistasi" +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:197 msgid "Moderation list created" -msgstr "Moderointilista luotu" +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:183 msgid "Moderation list updated" -msgstr "Moderointilista päivitetty" +msgstr "" #: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" -msgstr "Moderointilistat" +msgstr "" #: src/Navigation.tsx:120 #: src/view/screens/ModerationModlists.tsx:58 msgid "Moderation Lists" -msgstr "Moderointilistat" +msgstr "" #: src/view/screens/Settings/index.tsx:619 msgid "Moderation settings" -msgstr "Moderointiasetukset" +msgstr "" #: src/view/com/modals/ModerationDetails.tsx:35 msgid "Moderator has chosen to set a general warning on the content." -msgstr "Ylläpitäjä on asettanut yleisen varoituksen sisällölle." +msgstr "" #: src/view/shell/desktop/Feeds.tsx:63 msgid "More feeds" -msgstr "Lisää syötteitä" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:523 #: src/view/screens/ProfileFeed.tsx:363 #: src/view/screens/ProfileList.tsx:617 msgid "More options" -msgstr "Lisää asetuksia" +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:315 msgid "More post options" -msgstr "Lisää viestiasetuksia" +msgstr "" #: src/view/screens/PreferencesThreads.tsx:82 msgid "Most-liked replies first" -msgstr "Eniten tykätyt vastaukset ensin" +msgstr "" #: src/view/com/auth/create/Step2.tsx:122 msgid "Must be at least 3 characters" -msgstr "Täytyy olla vähintään 3 merkkiä" +msgstr "" #: src/components/TagMenu/index.tsx:253 msgid "Mute" -msgstr "Hiljennä" +msgstr "" #: src/components/TagMenu/index.web.tsx:91 msgid "Mute {truncatedTag}" -msgstr "Hiljennä {truncatedTag}" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" -msgstr "Hiljennä käyttäjä" +msgstr "" #: src/view/screens/ProfileList.tsx:544 msgid "Mute accounts" -msgstr "Hiljennä käyttäjät" +msgstr "" + #: src/components/TagMenu/index.tsx:211 msgid "Mute all {tag} posts" -msgstr "Hiljennä kaikki {tag}-viestit" +msgstr "" #: src/components/dialogs/MutedWords.tsx:131 msgid "Mute in tags only" -msgstr "Hiljennä vain tunnisteissa" +msgstr "" #: src/components/dialogs/MutedWords.tsx:116 msgid "Mute in text & tags" -msgstr "Hiljennä tekstissä ja tunnisteissa" +msgstr "" #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" -msgstr "Hiljennä lista" +msgstr "" #: src/view/screens/ProfileList.tsx:275 msgid "Mute these accounts?" -msgstr "Hiljennä nämä käyttäjät?" +msgstr "" #: src/view/screens/ProfileList.tsx:279 msgid "Mute this List" -msgstr "Hiljennä tämä lista" +msgstr "" #: src/components/dialogs/MutedWords.tsx:109 msgid "Mute this word in post text and tags" -msgstr "Hiljennä tämä sana viesteissä ja tunnisteissa" +msgstr "" #: src/components/dialogs/MutedWords.tsx:124 msgid "Mute this word in tags only" -msgstr "Hiljennä tämä sana vain tunnisteissa" +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Mute thread" -msgstr "Hiljennä keskustelu" +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:216 msgid "Mute words & tags" -msgstr "Hiljennä sanat ja tunnisteet" +msgstr "" #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" -msgstr "Hiljennetty" +msgstr "" #: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" -msgstr "Hiljennetyt käyttäjät" +msgstr "" #: src/Navigation.tsx:125 #: src/view/screens/ModerationMutedAccounts.tsx:107 msgid "Muted Accounts" -msgstr "Hiljennetyt käyttäjätilit" +msgstr "" #: src/view/screens/ModerationMutedAccounts.tsx:115 msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." -msgstr "Hiljennettyjen käyttäjien viestit poistetaan syötteestäsi ja ilmoituksistasi. Hiljennykset ovat täysin yksityisiä." +msgstr "" #: src/view/screens/Moderation.tsx:100 msgid "Muted words & tags" -msgstr "Hiljennetyt sanat ja tunnisteet" +msgstr "" #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." -msgstr "Hiljennys on yksityinen. Hiljennetyt käyttäjät voivat edelleen vuorovaikuttaa kanssasi, mutta et näe heidän viestejään tai saa ilmoituksia heiltä." +msgstr "" #: src/view/com/modals/BirthDateSettings.tsx:56 msgid "My Birthday" -msgstr "Syntymäpäiväni" +msgstr "" #: src/view/screens/Feeds.tsx:663 msgid "My Feeds" -msgstr "Omat syötteet" +msgstr "" #: src/view/shell/desktop/LeftNav.tsx:65 msgid "My Profile" -msgstr "Profiilini" +msgstr "" #: src/view/screens/Settings/index.tsx:582 msgid "My Saved Feeds" -msgstr "Omat tallennetut syötteet" +msgstr "" #: src/view/com/auth/server-input/index.tsx:118 msgid "my-server.com" -msgstr "oma-palvelimeni.com" +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:179 #: src/view/com/modals/CreateOrEditList.tsx:290 msgid "Name" -msgstr "Nimi" +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:145 msgid "Name is required" -msgstr "Nimi vaaditaan" +msgstr "" #: src/screens/Onboarding/index.tsx:25 msgid "Nature" -msgstr "Luonto" +msgstr "" #: src/view/com/auth/login/ForgotPasswordForm.tsx:190 #: src/view/com/auth/login/ForgotPasswordForm.tsx:219 @@ -2435,55 +2436,55 @@ msgstr "Luonto" #: src/view/com/auth/login/SetNewPasswordForm.tsx:196 #: src/view/com/modals/ChangePassword.tsx:166 msgid "Navigates to the next screen" -msgstr "Siirtyy seuraavalle näytölle" +msgstr "" #: src/view/shell/Drawer.tsx:71 msgid "Navigates to your profile" -msgstr "Siirtyy profiiliisi" +msgstr "" #: src/view/com/modals/EmbedConsent.tsx:107 #: src/view/com/modals/EmbedConsent.tsx:123 msgid "Never load embeds from {0}" -msgstr "Älä koskaan lataa upotuksia taholta {0}" +msgstr "" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:72 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:72 msgid "Never lose access to your followers and data." -msgstr "Älä koskaan menetä pääsyä seuraajiisi ja tietoihisi." +msgstr "" #: src/screens/Onboarding/StepFinished.tsx:119 msgid "Never lose access to your followers or data." -msgstr "Älä koskaan menetä pääsyä seuraajiisi tai tietoihisi." +msgstr "" #: src/components/dialogs/MutedWords.tsx:244 msgid "Nevermind" -msgstr "Ei väliä" +msgstr "" #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" -msgstr "Uusi" +msgstr "" #: src/view/screens/ModerationModlists.tsx:78 msgid "New" -msgstr "Uusi" +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:252 msgid "New Moderation List" -msgstr "Uusi moderointilista" +msgstr "" #: src/view/com/auth/login/SetNewPasswordForm.tsx:150 msgid "New password" -msgstr "Uusi salasana" +msgstr "" #: src/view/com/modals/ChangePassword.tsx:215 msgid "New Password" -msgstr "Uusi salasana" +msgstr "" #: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" -msgstr "Uusi viesti" +msgstr "" #: src/view/screens/Feeds.tsx:555 #: src/view/screens/Notifications.tsx:168 @@ -2493,24 +2494,24 @@ msgstr "Uusi viesti" #: src/view/screens/ProfileList.tsx:224 #: src/view/shell/desktop/LeftNav.tsx:248 msgid "New post" -msgstr "Uusi viesti" +msgstr "" #: src/view/shell/desktop/LeftNav.tsx:258 msgctxt "action" msgid "New Post" -msgstr "Uusi viesti" +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:247 msgid "New User List" -msgstr "Uusi käyttäjälista" +msgstr "" #: src/view/screens/PreferencesThreads.tsx:79 msgid "Newest replies first" -msgstr "Uusimmat vastaukset ensin" +msgstr "" #: src/screens/Onboarding/index.tsx:23 msgid "News" -msgstr "Uutiset" +msgstr "" #: src/view/com/auth/create/CreateAccount.tsx:172 #: src/view/com/auth/login/ForgotPasswordForm.tsx:182 @@ -2522,16 +2523,16 @@ msgstr "Uutiset" #: src/view/com/modals/ChangePassword.tsx:251 #: src/view/com/modals/ChangePassword.tsx:253 msgid "Next" -msgstr "Seuraava" +msgstr "" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 msgctxt "action" msgid "Next" -msgstr "Seuraava" +msgstr "" #: src/view/com/lightbox/Lightbox.web.tsx:149 msgid "Next image" -msgstr "Seuraava kuva" +msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:129 #: src/view/screens/PreferencesFollowingFeed.tsx:200 @@ -2540,61 +2541,61 @@ msgstr "Seuraava kuva" #: src/view/screens/PreferencesThreads.tsx:106 #: src/view/screens/PreferencesThreads.tsx:129 msgid "No" -msgstr "Ei" +msgstr "" #: src/view/screens/ProfileFeed.tsx:584 #: src/view/screens/ProfileList.tsx:754 msgid "No description" -msgstr "Ei kuvausta" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:170 msgid "No longer following {0}" -msgstr "Et enää seuraa käyttäjää {0}" +msgstr "" #: src/view/com/notifications/Feed.tsx:109 msgid "No notifications yet!" -msgstr "Ei vielä ilmoituksia!" +msgstr "" #: src/view/com/composer/text-input/mobile/Autocomplete.tsx:97 #: src/view/com/composer/text-input/web/Autocomplete.tsx:191 msgid "No result" -msgstr "Ei tuloksia" +msgstr "" #: src/view/screens/Feeds.tsx:495 msgid "No results found for \"{query}\"" -msgstr "Ei tuloksia haulle \"{query}\"" +msgstr "" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 #: src/view/screens/Search/Search.tsx:281 #: src/view/screens/Search/Search.tsx:309 msgid "No results found for {query}" -msgstr "Ei tuloksia haulle {query}" +msgstr "" #: src/view/com/modals/EmbedConsent.tsx:129 msgid "No thanks" -msgstr "Ei kiitos" +msgstr "" #: src/view/com/modals/Threadgate.tsx:82 msgid "Nobody" -msgstr "Ei ketään" +msgstr "" #: src/view/com/modals/SelfLabel.tsx:135 msgid "Not Applicable." -msgstr "Ei sovellettavissa." +msgstr "" #: src/Navigation.tsx:105 #: src/view/screens/Profile.tsx:106 msgid "Not Found" -msgstr "Ei löytynyt" +msgstr "" #: src/view/com/modals/VerifyEmail.tsx:246 #: src/view/com/modals/VerifyEmail.tsx:252 msgid "Not right now" -msgstr "Ei juuri nyt" +msgstr "" #: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." -msgstr "Huomio: Bluesky on avoin ja julkinen verkosto. Tämä asetus rajoittaa vain sisältösi näkyvyyttä Bluesky-sovelluksessa ja -sivustolla, eikä muut sovellukset ehkä kunnioita tässä asetuksissaan. Sisältösi voi silti näkyä uloskirjautuneille käyttäjille muissa sovelluksissa ja verkkosivustoilla." +msgstr "" #: src/Navigation.tsx:450 #: src/view/screens/Notifications.tsx:124 @@ -2604,117 +2605,117 @@ msgstr "Huomio: Bluesky on avoin ja julkinen verkosto. Tämä asetus rajoittaa v #: src/view/shell/Drawer.tsx:435 #: src/view/shell/Drawer.tsx:436 msgid "Notifications" -msgstr "Ilmoitukset" +msgstr "" #: src/view/com/modals/SelfLabel.tsx:103 msgid "Nudity" -msgstr "Alastomuus" +msgstr "" #: src/view/com/util/ErrorBoundary.tsx:35 msgid "Oh no!" -msgstr "Voi ei!" +msgstr "" #: src/screens/Onboarding/StepInterests/index.tsx:128 msgid "Oh no! Something went wrong." -msgstr "Voi ei! Jokin meni pieleen." +msgstr "" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:41 msgid "Okay" -msgstr "Selvä" +msgstr "" #: src/view/screens/PreferencesThreads.tsx:78 msgid "Oldest replies first" -msgstr "Vanhimmat vastaukset ensin" +msgstr "" #: src/view/screens/Settings/index.tsx:234 msgid "Onboarding reset" -msgstr "Käyttöönoton nollaus" +msgstr "" #: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." -msgstr "Yksi tai useampi kuva on ilman vaihtoehtoista Alt-tekstiä." +msgstr "" #: src/view/com/threadgate/WhoCanReply.tsx:100 msgid "Only {0} can reply." -msgstr "Vain {0} voi vastata." +msgstr "" #: src/view/screens/AppPasswords.tsx:65 #: src/view/screens/Profile.tsx:106 msgid "Oops!" -msgstr "Hups!" +msgstr "" #: src/screens/Onboarding/StepFinished.tsx:115 msgid "Open" -msgstr "Avaa" +msgstr "" #: src/view/screens/Moderation.tsx:75 msgid "Open content filtering settings" -msgstr "Avaa sisällönsuodatusasetukset" +msgstr "" #: src/view/com/composer/Composer.tsx:477 #: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" -msgstr "Avaa emoji-valitsin" +msgstr "" #: src/view/screens/Settings/index.tsx:712 msgid "Open links with in-app browser" -msgstr "Avaa linkit sovelluksen sisäisellä selaimella" +msgstr "" #: src/view/screens/Moderation.tsx:92 msgid "Open muted words settings" -msgstr "Avaa hiljennettyjen sanojen asetukset" +msgstr "" #: src/view/com/home/HomeHeaderLayoutMobile.tsx:49 msgid "Open navigation" -msgstr "Avaa navigointi" +msgstr "" #: src/view/screens/Settings/index.tsx:804 msgid "Open storybook page" -msgstr "Avaa storybook-sivu" +msgstr "" #: src/view/com/util/forms/DropdownButton.tsx:154 msgid "Opens {numItems} options" -msgstr "Avaa {numItems} asetusta" +msgstr "" #: src/view/screens/Log.tsx:54 msgid "Opens additional details for a debug entry" -msgstr "Avaa debug lisätiedot" +msgstr "" #: src/view/com/notifications/FeedItem.tsx:348 msgid "Opens an expanded list of users in this notification" -msgstr "Avaa laajennetun listan tämän ilmoituksen käyttäjistä" +msgstr "" #: src/view/com/composer/photos/OpenCameraBtn.tsx:61 msgid "Opens camera on device" -msgstr "Avaa laitteen kameran" +msgstr "" #: src/view/com/composer/Prompt.tsx:25 msgid "Opens composer" -msgstr "Avaa editorin" +msgstr "" #: src/view/screens/Settings/index.tsx:595 msgid "Opens configurable language settings" -msgstr "Avaa mukautettavat kielen asetukset" +msgstr "" #: src/view/com/composer/photos/SelectPhotoBtn.tsx:44 msgid "Opens device photo gallery" -msgstr "Avaa laitteen valokuvat" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:420 msgid "Opens editor for profile display name, avatar, background image, and description" -msgstr "Avaa editorin profiilin näyttönimeä, avataria, taustakuvaa ja kuvausta varten" +msgstr "" #: src/view/screens/Settings/index.tsx:649 msgid "Opens external embeds settings" -msgstr "Avaa ulkoiset upotusasetukset" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:575 msgid "Opens followers list" -msgstr "Avaa seuraajalistan" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:594 msgid "Opens following list" -msgstr "Avaa seurattavien listan" +msgstr "" #: src/view/screens/Settings.tsx:412 #~ msgid "Opens invite code list" @@ -2722,64 +2723,64 @@ msgstr "Avaa seurattavien listan" #: src/view/com/modals/InviteCodes.tsx:172 msgid "Opens list of invite codes" -msgstr "Avaa kutsukoodien luettelon" +msgstr "" #: src/view/screens/Settings/index.tsx:774 msgid "Opens modal for account deletion confirmation. Requires email code." -msgstr "Avaa tilin poistovahvistuksen. Vaatii sähköpostikoodin." +msgstr "" #: src/view/com/modals/ChangeHandle.tsx:281 msgid "Opens modal for using custom domain" -msgstr "Avaa asetukset oman verkkotunnuksen käyttöönottoon" +msgstr "" #: src/view/screens/Settings/index.tsx:620 msgid "Opens moderation settings" -msgstr "Avaa moderointiasetukset" +msgstr "" #: src/view/com/auth/login/LoginForm.tsx:239 msgid "Opens password reset form" -msgstr "Avaa salasanan palautuslomakkeen" +msgstr "" #: src/view/com/home/HomeHeaderLayout.web.tsx:60 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" -msgstr "Avaa näkymän tallennettujen syötteiden muokkaamiseen" +msgstr "" #: src/view/screens/Settings/index.tsx:576 msgid "Opens screen with all saved feeds" -msgstr "Avaa näkymän kaikkiin tallennettuihin syötteisiin" +msgstr "" #: src/view/screens/Settings/index.tsx:676 msgid "Opens the app password settings page" -msgstr "Avaa sovellussalasanojen asetukset" +msgstr "" #: src/view/screens/Settings/index.tsx:535 msgid "Opens the home feed preferences" -msgstr "Avaa aloitussivun asetukset" +msgstr "" #: src/view/screens/Settings/index.tsx:805 msgid "Opens the storybook page" -msgstr "Avaa storybook-sivun" +msgstr "" #: src/view/screens/Settings/index.tsx:793 msgid "Opens the system log page" -msgstr "Avaa järjestelmän lokisivun" +msgstr "" #: src/view/screens/Settings/index.tsx:556 msgid "Opens the threads preferences" -msgstr "Avaa keskusteluasetukset" +msgstr "" #: src/view/com/util/forms/DropdownButton.tsx:280 msgid "Option {0} of {numItems}" -msgstr "Asetus {0}/{numItems}" +msgstr "" #: src/view/com/modals/Threadgate.tsx:89 msgid "Or combine these options:" -msgstr "Tai yhdistä nämä asetukset:" +msgstr "" #: src/view/com/auth/login/ChooseAccountForm.tsx:138 msgid "Other account" -msgstr "Toinen tili" +msgstr "" #: src/view/com/modals/ServerInput.tsx:88 #~ msgid "Other service" @@ -2787,15 +2788,15 @@ msgstr "Toinen tili" #: src/view/com/composer/select-language/SelectLangBtn.tsx:91 msgid "Other..." -msgstr "Muu..." +msgstr "" #: src/view/screens/NotFound.tsx:45 msgid "Page not found" -msgstr "Sivua ei löytynyt" +msgstr "" #: src/view/screens/NotFound.tsx:42 msgid "Page Not Found" -msgstr "Sivua ei löytynyt" +msgstr "" #: src/view/com/auth/create/Step1.tsx:214 #: src/view/com/auth/create/Step1.tsx:224 @@ -2803,114 +2804,114 @@ msgstr "Sivua ei löytynyt" #: src/view/com/auth/login/SetNewPasswordForm.tsx:161 #: src/view/com/modals/DeleteAccount.tsx:202 msgid "Password" -msgstr "Salasana" +msgstr "" #: src/view/com/auth/login/Login.tsx:157 msgid "Password updated" -msgstr "Salasana päivitetty" +msgstr "" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:28 msgid "Password updated!" -msgstr "Salasana päivitetty!" +msgstr "" #: src/Navigation.tsx:160 msgid "People followed by @{0}" -msgstr "Henkilöt, joita @{0} seuraa" +msgstr "" #: src/Navigation.tsx:153 msgid "People following @{0}" -msgstr "Henkilöt, jotka seuraavat käyttäjää @{0}" +msgstr "" #: src/view/com/lightbox/Lightbox.tsx:66 msgid "Permission to access camera roll is required." -msgstr "Käyttöoikeus valokuviin tarvitaan." +msgstr "" #: src/view/com/lightbox/Lightbox.tsx:72 msgid "Permission to access camera roll was denied. Please enable it in your system settings." -msgstr "Lupa valokuviin evättiin. Anna lupa järjestelmäasetuksissa." +msgstr "" #: src/screens/Onboarding/index.tsx:31 msgid "Pets" -msgstr "Lemmikit" +msgstr "" #: src/view/com/auth/create/Step2.tsx:183 #~ msgid "Phone number" -#~ msgstr "Puhelinnumero" +#~ msgstr "" #: src/view/com/modals/SelfLabel.tsx:121 msgid "Pictures meant for adults." -msgstr "Aikuisille tarkoitetut kuvat." +msgstr "" #: src/view/screens/ProfileFeed.tsx:354 #: src/view/screens/ProfileList.tsx:581 msgid "Pin to home" -msgstr "Kiinnitä etusivulle" +msgstr "" #: src/view/screens/SavedFeeds.tsx:88 msgid "Pinned Feeds" -msgstr "Kiinnitetyt syötteet" +msgstr "" #: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:111 msgid "Play {0}" -msgstr "Toista {0}" +msgstr "" #: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:54 #: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:55 msgid "Play Video" -msgstr "Toista video" +msgstr "" #: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:110 msgid "Plays the GIF" -msgstr "Toistaa GIFin" +msgstr "" #: src/view/com/auth/create/state.ts:124 msgid "Please choose your handle." -msgstr "Valitse käyttäjätunnuksesi." +msgstr "" #: src/view/com/auth/create/state.ts:117 msgid "Please choose your password." -msgstr "Valitse salasanasi." +msgstr "" #: src/view/com/auth/create/state.ts:131 msgid "Please complete the verification captcha." -msgstr "Täydennä varmennus-captcha, ole hyvä." +msgstr "" #: src/view/com/modals/ChangeEmail.tsx:67 msgid "Please confirm your email before changing it. This is a temporary requirement while email-updating tools are added, and it will soon be removed." -msgstr "Vahvista sähköpostiosoitteesi ennen sen vaihtamista. Tämä on väliaikainen vaatimus, kunnes sähköpostin muokkaamisen liittyvät asetukset ovat lisätty ja se poistetaan piakkoin." +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:90 msgid "Please enter a name for your app password. All spaces is not allowed." -msgstr "Anna nimi sovellussalasanalle. Kaikki välilyönnit eivät ole sallittuja." +msgstr "" #: src/view/com/auth/create/Step2.tsx:206 #~ msgid "Please enter a phone number that can receive SMS text messages." -#~ msgstr "Anna puhelinnumero, joka voi vastaanottaa tekstiviestejä." +#~ msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:145 msgid "Please enter a unique name for this App Password or use our randomly generated one." -msgstr "Anna uniikki nimi tälle sovellussalasanalle tai käytä satunnaisesti luotua." +msgstr "" #: src/view/com/auth/create/state.ts:170 #~ msgid "Please enter the code you received by SMS." -#~ msgstr "Anna tekstiviestitse saamasi koodi." +#~ msgstr "" #: src/view/com/auth/create/Step2.tsx:282 #~ msgid "Please enter the verification code sent to {phoneNumberFormatted}." -#~ msgstr "Anna numeroon {phoneNumberFormatted} vastaanottamasi vahvistuskoodi." +#~ msgstr "" #: src/view/com/auth/create/state.ts:103 msgid "Please enter your email." -msgstr "Anna sähköpostiosoitteesi." +msgstr "" #: src/view/com/modals/DeleteAccount.tsx:191 msgid "Please enter your password as well:" -msgstr "Anna myös salasanasi:" +msgstr "" #: src/view/com/modals/AppealLabel.tsx:72 #: src/view/com/modals/AppealLabel.tsx:75 msgid "Please tell us why you think this content warning was incorrectly applied!" -msgstr "Kerro meille, miksi luulet, että tämä sisältövaroitus on sovellettu virheellisesti!" +msgstr "" #: src/view/com/modals/AppealLabel.tsx:72 #: src/view/com/modals/AppealLabel.tsx:75 @@ -2919,108 +2920,108 @@ msgstr "Kerro meille, miksi luulet, että tämä sisältövaroitus on sovellettu #: src/view/com/modals/VerifyEmail.tsx:101 msgid "Please Verify Your Email" -msgstr "Vahvista sähköpostiosoitteesi" +msgstr "" #: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" -msgstr "Odota, että linkkikortti latautuu kokonaan" +msgstr "" #: src/screens/Onboarding/index.tsx:37 msgid "Politics" -msgstr "Politiikka" +msgstr "" #: src/view/com/modals/SelfLabel.tsx:111 msgid "Porn" -msgstr "Porno" +msgstr "" #: src/view/com/composer/Composer.tsx:357 #: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" -msgstr "Lähetä" +msgstr "" #: src/view/com/post-thread/PostThread.tsx:303 msgctxt "description" msgid "Post" -msgstr "Viesti" +msgstr "" #: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" -msgstr "Lähettäjä {0}" +msgstr "" #: src/Navigation.tsx:172 #: src/Navigation.tsx:179 #: src/Navigation.tsx:186 msgid "Post by @{0}" -msgstr "Lähettäjä @{0}" +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:90 msgid "Post deleted" -msgstr "Viesti poistettu" +msgstr "" #: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" -msgstr "Viesti piilotettu" +msgstr "" #: src/view/com/composer/select-language/SelectLangBtn.tsx:87 msgid "Post language" -msgstr "Lähetyskieli" +msgstr "" #: src/view/com/modals/lang-settings/PostLanguagesSettings.tsx:75 msgid "Post Languages" -msgstr "Lähetyskielet" +msgstr "" #: src/view/com/post-thread/PostThread.tsx:514 msgid "Post not found" -msgstr "Viestiä ei löydy" +msgstr "" #: src/components/TagMenu/index.tsx:257 msgid "posts" -msgstr "viestit" +msgstr "" #: src/view/screens/Profile.tsx:180 msgid "Posts" -msgstr "Viestit" +msgstr "" #: src/components/dialogs/MutedWords.tsx:77 msgid "Posts can be muted based on their text, their tags, or both." -msgstr "Viestejä voidaan hiljentää niiden tekstin, tunnisteiden tai molempien perusteella." +msgstr "" #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" -msgstr "Piilotetut viestit" +msgstr "" #: src/view/com/modals/LinkWarning.tsx:46 msgid "Potentially Misleading Link" -msgstr "Mahdollisesti harhaanjohtava linkki" +msgstr "" #: src/view/com/lightbox/Lightbox.web.tsx:135 msgid "Previous image" -msgstr "Edellinen kuva" +msgstr "" #: src/view/screens/LanguageSettings.tsx:187 msgid "Primary Language" -msgstr "Ensisijainen kieli" +msgstr "" #: src/view/screens/PreferencesThreads.tsx:97 msgid "Prioritize Your Follows" -msgstr "Aseta seurattavat tärkeysjärjestykseen" +msgstr "" #: src/view/screens/Settings/index.tsx:632 #: src/view/shell/desktop/RightNav.tsx:72 msgid "Privacy" -msgstr "Yksityisyys" +msgstr "" #: src/Navigation.tsx:217 #: src/view/screens/PrivacyPolicy.tsx:29 #: src/view/screens/Settings/index.tsx:891 #: src/view/shell/Drawer.tsx:262 msgid "Privacy Policy" -msgstr "Yksityisyydensuojakäytäntö" +msgstr "" #: src/view/com/auth/login/ForgotPasswordForm.tsx:198 msgid "Processing..." -msgstr "Käsitellään..." +msgstr "" #: src/view/shell/bottom-bar/BottomBar.tsx:247 #: src/view/shell/desktop/LeftNav.tsx:415 @@ -3028,65 +3029,65 @@ msgstr "Käsitellään..." #: src/view/shell/Drawer.tsx:546 #: src/view/shell/Drawer.tsx:547 msgid "Profile" -msgstr "Profiili" +msgstr "" #: src/view/com/modals/EditProfile.tsx:128 msgid "Profile updated" -msgstr "Profiili päivitetty" +msgstr "" #: src/view/screens/Settings/index.tsx:949 msgid "Protect your account by verifying your email." -msgstr "Suojaa tilisi vahvistamalla sähköpostiosoitteesi." +msgstr "" #: src/screens/Onboarding/StepFinished.tsx:101 msgid "Public" -msgstr "Julkinen" +msgstr "" #: src/view/screens/ModerationModlists.tsx:61 msgid "Public, shareable lists of users to mute or block in bulk." -msgstr "Julkinen, jaettava käyttäjäluettelo hiljennettyjen tai estettyjen käyttäjien massamäärityksiä varten." +msgstr "" #: src/view/screens/Lists.tsx:61 msgid "Public, shareable lists which can drive feeds." -msgstr "Julkinen, jaettava lista, joka voi ohjata syötteitä." +msgstr "" #: src/view/com/composer/Composer.tsx:342 msgid "Publish post" -msgstr "Julkaise viesti" +msgstr "" #: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" -msgstr "Julkaise vastaus" +msgstr "" #: src/view/com/modals/Repost.tsx:65 msgctxt "action" msgid "Quote post" -msgstr "Lainaa viestiä" +msgstr "" #: src/view/com/util/post-ctrls/RepostButton.web.tsx:58 msgid "Quote post" -msgstr "Lainaa viestiä" +msgstr "" #: src/view/com/modals/Repost.tsx:70 msgctxt "action" msgid "Quote Post" -msgstr "Lainaa viestiä" +msgstr "" #: src/view/screens/PreferencesThreads.tsx:86 msgid "Random (aka \"Poster's Roulette\")" -msgstr "Satunnainen (tunnetaan myös nimellä \"Lähettäjän ruletti\")" +msgstr "" #: src/view/com/modals/EditImage.tsx:236 msgid "Ratios" -msgstr "Suhdeluvut" +msgstr "" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:116 msgid "Recommended Feeds" -msgstr "Suositellut syötteet" +msgstr "" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:180 msgid "Recommended Users" -msgstr "Suositellut käyttäjät" +msgstr "" #: src/components/dialogs/MutedWords.tsx:249 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 @@ -3095,20 +3096,20 @@ msgstr "Suositellut käyttäjät" #: src/view/com/util/UserAvatar.tsx:285 #: src/view/com/util/UserBanner.tsx:91 msgid "Remove" -msgstr "Poista" +msgstr "" #: src/view/com/feeds/FeedSourceCard.tsx:108 msgid "Remove {0} from my feeds?" -msgstr "Poistetaanko {0} syötteistäni?" +msgstr "" #: src/view/com/util/AccountDropdownBtn.tsx:22 msgid "Remove account" -msgstr "Poista tili" +msgstr "" #: src/view/com/posts/FeedErrorMessage.tsx:131 #: src/view/com/posts/FeedErrorMessage.tsx:166 msgid "Remove feed" -msgstr "Poista syöte" +msgstr "" #: src/view/com/feeds/FeedSourceCard.tsx:107 #: src/view/com/feeds/FeedSourceCard.tsx:169 @@ -3116,89 +3117,89 @@ msgstr "Poista syöte" #: src/view/com/feeds/FeedSourceCard.tsx:245 #: src/view/screens/ProfileFeed.tsx:273 msgid "Remove from my feeds" -msgstr "Poista syötteistäni" +msgstr "" #: src/view/com/composer/photos/Gallery.tsx:167 msgid "Remove image" -msgstr "Poista kuva" +msgstr "" #: src/view/com/composer/ExternalEmbed.tsx:70 msgid "Remove image preview" -msgstr "Poista kuvan esikatselu" +msgstr "" #: src/components/dialogs/MutedWords.tsx:294 msgid "Remove mute word from your list" -msgstr "Poista hiljennetty sana listaltasi" +msgstr "" #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" -msgstr "Poista uudelleenjako" +msgstr "" #: src/view/com/feeds/FeedSourceCard.tsx:175 msgid "Remove this feed from my feeds?" -msgstr "Poistetaanko tämä syöte omista syötteistäni?" +msgstr "" #: src/view/com/posts/FeedErrorMessage.tsx:132 msgid "Remove this feed from your saved feeds?" -msgstr "Poistetaanko tämä syöte tallennetuista syötteistäsi?" +msgstr "" #: src/view/com/modals/ListAddRemoveUsers.tsx:199 #: src/view/com/modals/UserAddRemoveLists.tsx:152 msgid "Removed from list" -msgstr "Poistettu listalta" +msgstr "" #: src/view/com/feeds/FeedSourceCard.tsx:113 #: src/view/com/feeds/FeedSourceCard.tsx:180 msgid "Removed from my feeds" -msgstr "Poistettu syötteistäni" +msgstr "" #: src/view/com/composer/ExternalEmbed.tsx:71 msgid "Removes default thumbnail from {0}" -msgstr "Poistaa {0} oletuskuvakkeen" +msgstr "" #: src/view/screens/Profile.tsx:181 msgid "Replies" -msgstr "Vastaukset" +msgstr "" #: src/view/com/threadgate/WhoCanReply.tsx:98 msgid "Replies to this thread are disabled" -msgstr "Tähän keskusteluun vastaaminen on estetty" +msgstr "" #: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" -msgstr "Vastaa" +msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:144 msgid "Reply Filters" -msgstr "Vastaussuodattimet" +msgstr "" #: src/view/com/post/Post.tsx:167 #: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" -msgstr "Vastaa käyttäjälle <0/>" +msgstr "" #: src/view/com/modals/report/Modal.tsx:166 msgid "Report {collectionName}" -msgstr "Raportoi {collectionName}" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:361 msgid "Report Account" -msgstr "Ilmoita tili" +msgstr "" #: src/view/screens/ProfileFeed.tsx:293 msgid "Report feed" -msgstr "Ilmoita syöte" +msgstr "" #: src/view/screens/ProfileList.tsx:459 msgid "Report List" -msgstr "Ilmoita luettelo" +msgstr "" #: src/view/com/modals/report/SendReportButton.tsx:37 #: src/view/com/util/forms/PostDropdownBtn.tsx:255 msgid "Report post" -msgstr "Ilmoita viesti" +msgstr "" #: src/view/com/modals/Repost.tsx:43 #: src/view/com/modals/Repost.tsx:48 @@ -3206,104 +3207,104 @@ msgstr "Ilmoita viesti" #: src/view/com/util/post-ctrls/RepostButton.tsx:61 msgctxt "action" msgid "Repost" -msgstr "Uudelleenjaa" +msgstr "" #: src/view/com/util/post-ctrls/RepostButton.web.tsx:48 msgid "Repost" -msgstr "Uudelleenjaa" +msgstr "" #: src/view/com/util/post-ctrls/RepostButton.web.tsx:94 #: src/view/com/util/post-ctrls/RepostButton.web.tsx:105 msgid "Repost or quote post" -msgstr "Uudelleenjaa tai lainaa viestiä" +msgstr "" #: src/view/screens/PostRepostedBy.tsx:27 msgid "Reposted By" -msgstr "Uudelleenjakanut" +msgstr "" #: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" -msgstr "Uudelleenjakanut {0}" +msgstr "" #: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" -msgstr "Uudelleenjakanut <0/>" +msgstr "" #: src/view/com/notifications/FeedItem.tsx:162 msgid "reposted your post" -msgstr "uudelleenjakoi viestisi" +msgstr "" #: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" -msgstr "Tämän viestin uudelleenjulkaisut" +msgstr "" #: src/view/com/modals/ChangeEmail.tsx:181 #: src/view/com/modals/ChangeEmail.tsx:183 msgid "Request Change" -msgstr "Pyydä muutosta" +msgstr "" #: src/view/com/auth/create/Step2.tsx:219 #~ msgid "Request code" -#~ msgstr "Pyydä koodia" +#~ msgstr "" #: src/view/com/modals/ChangePassword.tsx:239 #: src/view/com/modals/ChangePassword.tsx:241 msgid "Request Code" -msgstr "Pyydä koodia" +msgstr "" #: src/view/screens/Settings/index.tsx:456 msgid "Require alt text before posting" -msgstr "Vaadi vaihtoehtoista ALT-tekstiä ennen julkaisua" +msgstr "" #: src/view/com/auth/create/Step1.tsx:153 msgid "Required for this provider" -msgstr "Vaaditaan tälle instanssille" +msgstr "" #: src/view/com/auth/login/SetNewPasswordForm.tsx:124 #: src/view/com/auth/login/SetNewPasswordForm.tsx:136 msgid "Reset code" -msgstr "Nollauskoodi" +msgstr "" #: src/view/com/modals/ChangePassword.tsx:190 msgid "Reset Code" -msgstr "Nollauskoodi" +msgstr "" #: src/view/screens/Settings/index.tsx:824 msgid "Reset onboarding" -msgstr "Nollaa käyttöönotto" +msgstr "" #: src/view/screens/Settings/index.tsx:827 msgid "Reset onboarding state" -msgstr "Nollaa käyttöönoton tila" +msgstr "" #: src/view/com/auth/login/ForgotPasswordForm.tsx:104 msgid "Reset password" -msgstr "Nollaa salasana" +msgstr "" #: src/view/screens/Settings/index.tsx:814 msgid "Reset preferences" -msgstr "Nollaa asetukset" +msgstr "" #: src/view/screens/Settings/index.tsx:817 msgid "Reset preferences state" -msgstr "Nollaa asetusten tila" +msgstr "" #: src/view/screens/Settings/index.tsx:825 msgid "Resets the onboarding state" -msgstr "Nollaa käyttöönoton tilan" +msgstr "" #: src/view/screens/Settings/index.tsx:815 msgid "Resets the preferences state" -msgstr "Nollaa asetusten tilan" +msgstr "" #: src/view/com/auth/login/LoginForm.tsx:269 msgid "Retries login" -msgstr "Yrittää uudelleen kirjautumista" +msgstr "" #: src/view/com/util/error/ErrorMessage.tsx:57 #: src/view/com/util/error/ErrorScreen.tsx:74 msgid "Retries the last action, which errored out" -msgstr "Yrittää uudelleen viimeisintä toimintoa, joka epäonnistui" +msgstr "" #: src/screens/Onboarding/StepInterests/index.tsx:221 #: src/screens/Onboarding/StepInterests/index.tsx:224 @@ -3314,25 +3315,25 @@ msgstr "Yrittää uudelleen viimeisintä toimintoa, joka epäonnistui" #: src/view/com/util/error/ErrorMessage.tsx:55 #: src/view/com/util/error/ErrorScreen.tsx:72 msgid "Retry" -msgstr "Yritä uudelleen" +msgstr "" #: src/view/com/auth/create/Step2.tsx:247 #~ msgid "Retry." -#~ msgstr "Yritä uudelleen." +#~ msgstr "" #: src/view/screens/ProfileList.tsx:898 msgid "Return to previous page" -msgstr "Palaa edelliselle sivulle" +msgstr "" #: src/view/shell/desktop/RightNav.tsx:55 #~ msgid "SANDBOX. Posts and accounts are not permanent." -#~ msgstr "HIEKKALAATIKKO. Viestit ja tilit eivät ole pysyviä." +#~ msgstr "" #: src/view/com/lightbox/Lightbox.tsx:132 #: src/view/com/modals/CreateOrEditList.tsx:345 msgctxt "action" msgid "Save" -msgstr "Tallenna" +msgstr "" #: src/view/com/modals/BirthDateSettings.tsx:94 #: src/view/com/modals/BirthDateSettings.tsx:97 @@ -3341,43 +3342,43 @@ msgstr "Tallenna" #: src/view/com/modals/EditProfile.tsx:224 #: src/view/screens/ProfileFeed.tsx:346 msgid "Save" -msgstr "Tallenna" +msgstr "" #: src/view/com/modals/AltImage.tsx:130 msgid "Save alt text" -msgstr "Tallenna vaihtoehtoinen ALT-teksti" +msgstr "" #: src/view/com/modals/EditProfile.tsx:232 msgid "Save Changes" -msgstr "Tallenna muutokset" +msgstr "" #: src/view/com/modals/ChangeHandle.tsx:170 msgid "Save handle change" -msgstr "Tallenna käyttäjätunnuksen muutos" +msgstr "" #: src/view/com/modals/crop-image/CropImage.web.tsx:144 msgid "Save image crop" -msgstr "Tallenna kuvan rajaus" +msgstr "" #: src/view/screens/SavedFeeds.tsx:122 msgid "Saved Feeds" -msgstr "Tallennetut syötteet" +msgstr "" #: src/view/com/modals/EditProfile.tsx:225 msgid "Saves any changes to your profile" -msgstr "Tallentaa kaikki muutokset profiiliisi" +msgstr "" #: src/view/com/modals/ChangeHandle.tsx:171 msgid "Saves handle change to {handle}" -msgstr "Tallentaa käyttäjätunnuksen muutoksen muotoon {handle}" +msgstr "" #: src/screens/Onboarding/index.tsx:36 msgid "Science" -msgstr "Tiede" +msgstr "" #: src/view/screens/ProfileList.tsx:854 msgid "Scroll to top" -msgstr "Vieritä alkuun" +msgstr "" #: src/Navigation.tsx:440 #: src/view/com/auth/LoggedOut.tsx:122 @@ -3394,58 +3395,58 @@ msgstr "Vieritä alkuun" #: src/view/shell/Drawer.tsx:362 #: src/view/shell/Drawer.tsx:363 msgid "Search" -msgstr "Haku" +msgstr "" #: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" -msgstr "Haku hakusanalla \"{query}\"" +msgstr "" #: src/components/TagMenu/index.tsx:145 msgid "Search for all posts by @{authorHandle} with tag {tag}" -msgstr "Etsi kaikki viestit käyttäjältä @{authorHandle} tunnisteella {tag}" +msgstr "" #: src/components/TagMenu/index.tsx:90 msgid "Search for all posts with tag {tag}" -msgstr "Etsi kaikki viestit tunnisteella {tag}" +msgstr "" #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 msgid "Search for users" -msgstr "Hae käyttäjiä" +msgstr "" #: src/view/com/modals/ChangeEmail.tsx:110 msgid "Security Step Required" -msgstr "Turvatarkistus vaaditaan" +msgstr "" #: src/components/TagMenu/index.web.tsx:50 msgid "See {truncatedTag} posts" -msgstr "Näytä {truncatedTag}-viestit" +msgstr "" #: src/components/TagMenu/index.web.tsx:67 msgid "See {truncatedTag} posts by user" -msgstr "Näytä käyttäjän {truncatedTag} viestit" +msgstr "" #: src/components/TagMenu/index.tsx:128 msgid "See <0>{tag} posts" -msgstr "Näytä <0>{tag}-viestit" +msgstr "" #: src/components/TagMenu/index.tsx:189 msgid "See <0>{tag} posts by this user" -msgstr "Näytä tämän käyttäjän <0>{tag}-viestit" +msgstr "" #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" -msgstr "Katso tämä opas" +msgstr "" #: src/view/com/auth/HomeLoggedOutCTA.tsx:39 msgid "See what's next" -msgstr "Katso, mitä seuraavaksi tapahtuu" +msgstr "" #: src/view/com/util/Selector.tsx:106 msgid "Select {item}" -msgstr "Valitse {item}" +msgstr "" #: src/view/com/modals/ServerInput.tsx:75 #~ msgid "Select Bluesky Social" @@ -3453,24 +3454,24 @@ msgstr "Valitse {item}" #: src/view/com/auth/login/Login.tsx:117 msgid "Select from an existing account" -msgstr "Valitse olemassa olevalta tililtä" +msgstr "" #: src/view/com/util/Selector.tsx:107 msgid "Select option {i} of {numItems}" -msgstr "Valitse vaihtoehto {i} / {numItems}" +msgstr "" #: src/view/com/auth/create/Step1.tsx:103 #: src/view/com/auth/login/LoginForm.tsx:150 msgid "Select service" -msgstr "Valitse palvelu" +msgstr "" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:52 msgid "Select some accounts below to follow" -msgstr "Valitse alla olevista tileistä jotain seurattavaksi" +msgstr "" #: src/view/com/auth/server-input/index.tsx:82 msgid "Select the service that hosts your data." -msgstr "Valitse palvelu, joka hostaa tietojasi." +msgstr "" #: src/screens/Onboarding/StepModeration/index.tsx:49 #~ msgid "Select the types of content that you want to see (or not see), and we'll handle the rest." @@ -3478,153 +3479,153 @@ msgstr "Valitse palvelu, joka hostaa tietojasi." #: src/screens/Onboarding/StepTopicalFeeds.tsx:96 msgid "Select topical feeds to follow from the list below" -msgstr "Valitse ajankohtaisia syötteitä alla olevasta listasta" +msgstr "" #: src/screens/Onboarding/StepModeration/index.tsx:75 msgid "Select what you want to see (or not see), and we’ll handle the rest." -msgstr "Valitse, mitä haluat nähdä (tai olla näkemättä) ja me huolehdimme lopusta." +msgstr "" #: src/view/screens/LanguageSettings.tsx:281 msgid "Select which languages you want your subscribed feeds to include. If none are selected, all languages will be shown." -msgstr "Valitse, mitä kieliä haluat tilattujen syötteidesi sisältävän. Jos mitään ei ole valittu, kaikki kielet näytetään." +msgstr "" #: src/view/screens/LanguageSettings.tsx:98 msgid "Select your app language for the default text to display in the app" -msgstr "Valitse sovelluksen oletuskieli, joka näytetään sovelluksessa" +msgstr "" #: src/screens/Onboarding/StepInterests/index.tsx:196 msgid "Select your interests from the options below" -msgstr "Valitse kiinnostuksenkohteesi alla olevista vaihtoehdoista" +msgstr "" #: src/view/com/auth/create/Step2.tsx:155 #~ msgid "Select your phone's country" -#~ msgstr "Valitse puhelinnumerosi maa" +#~ msgstr "" #: src/view/screens/LanguageSettings.tsx:190 msgid "Select your preferred language for translations in your feed." -msgstr "Valitse haluamasi kieli käännöksille syötteessäsi." +msgstr "" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:116 msgid "Select your primary algorithmic feeds" -msgstr "Valitse ensisijaiset algoritmisyötteet" +msgstr "" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:142 msgid "Select your secondary algorithmic feeds" -msgstr "Valitse toissijaiset algoritmisyötteet" +msgstr "" #: src/view/com/modals/VerifyEmail.tsx:202 #: src/view/com/modals/VerifyEmail.tsx:204 msgid "Send Confirmation Email" -msgstr "Lähetä vahvistussähköposti" +msgstr "" #: src/view/com/modals/DeleteAccount.tsx:131 msgid "Send email" -msgstr "Lähetä sähköposti" +msgstr "" #: src/view/com/modals/DeleteAccount.tsx:144 msgctxt "action" msgid "Send Email" -msgstr "Lähetä sähköposti" +msgstr "" #: src/view/shell/Drawer.tsx:295 #: src/view/shell/Drawer.tsx:316 msgid "Send feedback" -msgstr "Lähetä palautetta" +msgstr "" #: src/view/com/modals/report/SendReportButton.tsx:45 msgid "Send Report" -msgstr "Lähetä raportti" +msgstr "" #: src/view/com/modals/DeleteAccount.tsx:133 msgid "Sends email with confirmation code for account deletion" -msgstr "Lähettää sähköpostin tilin poistamiseen tarvittavan vahvistuskoodin" +msgstr "" #: src/view/com/auth/server-input/index.tsx:110 msgid "Server address" -msgstr "Palvelimen osoite" +msgstr "" #: src/view/com/modals/ContentFilteringSettings.tsx:311 msgid "Set {value} for {labelGroup} content moderation policy" -msgstr "Aseta {value} {labelGroup} sisällön moderointisäännöksi" +msgstr "" #: src/view/com/modals/ContentFilteringSettings.tsx:160 #: src/view/com/modals/ContentFilteringSettings.tsx:179 msgctxt "action" msgid "Set Age" -msgstr "Aseta ikä" +msgstr "" #: src/view/screens/Settings/index.tsx:488 msgid "Set color theme to dark" -msgstr "Aseta väriteema tummaksi" +msgstr "" #: src/view/screens/Settings/index.tsx:481 msgid "Set color theme to light" -msgstr "Aseta väriteema vaaleaksi" +msgstr "" #: src/view/screens/Settings/index.tsx:475 msgid "Set color theme to system setting" -msgstr "Aseta väriteema järjestelmäasetuksiin" +msgstr "" #: src/view/screens/Settings/index.tsx:514 msgid "Set dark theme to the dark theme" -msgstr "Aseta tumma teema tummaksi" +msgstr "" #: src/view/screens/Settings/index.tsx:507 msgid "Set dark theme to the dim theme" -msgstr "Aseta tumma teema hämäräksi" +msgstr "" #: src/view/com/auth/login/SetNewPasswordForm.tsx:104 msgid "Set new password" -msgstr "Aseta uusi salasana" +msgstr "" #: src/view/com/auth/create/Step1.tsx:225 msgid "Set password" -msgstr "Aseta salasana" +msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:225 msgid "Set this setting to \"No\" to hide all quote posts from your feed. Reposts will still be visible." -msgstr "Aseta tämä asetus \"Ei\"-tilaan piilottaaksesi kaikki lainaukset syötteestäsi. Uudelleenjulkaisut näkyvät silti." +msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:122 msgid "Set this setting to \"No\" to hide all replies from your feed." -msgstr "Aseta tämä asetus \"Ei\"-tilaan piilottaaksesi kaikki vastaukset syötteestäsi." +msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:191 msgid "Set this setting to \"No\" to hide all reposts from your feed." -msgstr "Aseta tämä asetus \"Ei\"-tilaan piilottaaksesi kaikki uudelleenjulkaisut syötteestäsi." +msgstr "" #: src/view/screens/PreferencesThreads.tsx:122 msgid "Set this setting to \"Yes\" to show replies in a threaded view. This is an experimental feature." -msgstr "Aseta tämä asetus \"Kyllä\" tilaan näyttääksesi vastaukset ketjumaisessa näkymässä. Tämä on kokeellinen ominaisuus." +msgstr "" #: src/view/screens/PreferencesHomeFeed.tsx:261 #~ msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your following feed. This is an experimental feature." -#~ msgstr "Aseta tämä asetus \"Kyllä\"-tilaan nähdäksesi esimerkkejä tallennetuista syötteistäsi seuraamissasi syötteessäsi. Tämä on kokeellinen ominaisuus." +#~ msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:261 msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your Following feed. This is an experimental feature." -msgstr "Aseta tämä asetus \"Kyllä\"-tilaan nähdäksesi esimerkkejä tallennetuista syötteistäsi seuraamissasi syötteessäsi. Tämä on kokeellinen ominaisuus." +msgstr "" #: src/screens/Onboarding/Layout.tsx:50 msgid "Set up your account" -msgstr "Luo tili" +msgstr "" #: src/view/com/modals/ChangeHandle.tsx:266 msgid "Sets Bluesky username" -msgstr "Asettaa Bluesky-käyttäjätunnuksen" +msgstr "" #: src/view/com/auth/login/ForgotPasswordForm.tsx:157 msgid "Sets email for password reset" -msgstr "Asettaa sähköpostin salasanan palautusta varten" +msgstr "" #: src/view/com/auth/login/ForgotPasswordForm.tsx:122 msgid "Sets hosting provider for password reset" -msgstr "Asettaa palveluntarjoajan salasanan palautusta varten" +msgstr "" #: src/view/com/auth/create/Step1.tsx:104 #: src/view/com/auth/login/LoginForm.tsx:151 msgid "Sets server for the Bluesky client" -msgstr "Asettaa palvelimen Bluesky-ohjelmalle" +msgstr "" #: src/Navigation.tsx:135 #: src/view/screens/Settings/index.tsx:294 @@ -3632,26 +3633,26 @@ msgstr "Asettaa palvelimen Bluesky-ohjelmalle" #: src/view/shell/Drawer.tsx:567 #: src/view/shell/Drawer.tsx:568 msgid "Settings" -msgstr "Asetukset" +msgstr "" #: src/view/com/modals/SelfLabel.tsx:125 msgid "Sexual activity or erotic nudity." -msgstr "Erotiikka tai muu aikuisviihde." +msgstr "" #: src/view/com/lightbox/Lightbox.tsx:141 msgctxt "action" msgid "Share" -msgstr "Jaa" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:295 #: src/view/com/util/forms/PostDropdownBtn.tsx:184 #: src/view/screens/ProfileList.tsx:418 msgid "Share" -msgstr "Jaa" +msgstr "" #: src/view/screens/ProfileFeed.tsx:305 msgid "Share feed" -msgstr "Jaa syöte" +msgstr "" #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:43 #: src/view/com/modals/ContentFilteringSettings.tsx:266 @@ -3659,95 +3660,95 @@ msgstr "Jaa syöte" #: src/view/com/util/moderation/PostHider.tsx:108 #: src/view/screens/Settings/index.tsx:344 msgid "Show" -msgstr "Näytä" +msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:68 msgid "Show all replies" -msgstr "Näytä kaikki vastaukset" +msgstr "" #: src/view/com/util/moderation/ScreenHider.tsx:132 msgid "Show anyway" -msgstr "Näytä silti" +msgstr "" #: src/view/com/modals/EmbedConsent.tsx:87 msgid "Show embeds from {0}" -msgstr "Näytä upotukset taholta {0}" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:459 msgid "Show follows similar to {0}" -msgstr "Näytä seurannat samankaltaisilta käyttäjiltä kuin {0}" +msgstr "" #: src/view/com/post-thread/PostThreadItem.tsx:538 #: src/view/com/post/Post.tsx:198 #: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" -msgstr "Näytä lisää" +msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:258 msgid "Show Posts from My Feeds" -msgstr "Näytä viestit omista syötteistäni" +msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:222 msgid "Show Quote Posts" -msgstr "Näytä lainatut viestit" +msgstr "" #: src/screens/Onboarding/StepFollowingFeed.tsx:118 msgid "Show quote-posts in Following feed" -msgstr "Näytä lainatut viestit seurattavien syötteessä" +msgstr "" #: src/screens/Onboarding/StepFollowingFeed.tsx:134 msgid "Show quotes in Following" -msgstr "Näytä lainaukset seurattavissa" +msgstr "" #: src/screens/Onboarding/StepFollowingFeed.tsx:94 msgid "Show re-posts in Following feed" -msgstr "Näytä uudelleenjulkaistut viestit seurattavissa" +msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:119 msgid "Show Replies" -msgstr "Näytä vastaukset" +msgstr "" #: src/view/screens/PreferencesThreads.tsx:100 msgid "Show replies by people you follow before all other replies." -msgstr "Näytä seurattujen henkilöiden vastaukset ennen muita vastauksia." +msgstr "" #: src/screens/Onboarding/StepFollowingFeed.tsx:86 msgid "Show replies in Following" -msgstr "Näytä vastaukset seurattavissa" +msgstr "" #: src/screens/Onboarding/StepFollowingFeed.tsx:70 msgid "Show replies in Following feed" -msgstr "Näytä vastaukset seurattavissa" +msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:70 msgid "Show replies with at least {value} {0}" -msgstr "Näytä vastaukset, joissa on vähintään {value} {0}" +msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:188 msgid "Show Reposts" -msgstr "Näytä uudelleenjulkaisut" +msgstr "" #: src/screens/Onboarding/StepFollowingFeed.tsx:110 msgid "Show reposts in Following" -msgstr "Näytä uudelleenjulkaisut seurattavissa" +msgstr "" #: src/view/com/util/moderation/ContentHider.tsx:67 #: src/view/com/util/moderation/PostHider.tsx:61 msgid "Show the content" -msgstr "Näytä sisältö" +msgstr "" #: src/view/com/notifications/FeedItem.tsx:346 msgid "Show users" -msgstr "Näytä käyttäjät" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:462 msgid "Shows a list of users similar to this user." -msgstr "Näyttää luettelon käyttäjistä, jotka ovat samankaltaisia kuin tämä käyttäjä." +msgstr "" #: src/view/com/post-thread/PostThreadFollowBtn.tsx:124 #: src/view/com/profile/ProfileHeader.tsx:506 msgid "Shows posts from {0} in your feed" -msgstr "Näyttää viestit käyttäjältä {0} syötteessäsi" +msgstr "" #: src/view/com/auth/HomeLoggedOutCTA.tsx:70 #: src/view/com/auth/login/Login.tsx:98 @@ -3761,33 +3762,33 @@ msgstr "Näyttää viestit käyttäjältä {0} syötteessäsi" #: src/view/shell/NavSignupCard.tsx:58 #: src/view/shell/NavSignupCard.tsx:59 msgid "Sign in" -msgstr "Kirjaudu sisään" +msgstr "" #: src/view/com/auth/HomeLoggedOutCTA.tsx:78 #: src/view/com/auth/SplashScreen.tsx:82 #: src/view/com/auth/SplashScreen.web.tsx:91 msgid "Sign In" -msgstr "Kirjaudu sisään" +msgstr "" #: src/view/com/auth/login/ChooseAccountForm.tsx:44 msgid "Sign in as {0}" -msgstr "Kirjaudu sisään nimellä {0}" +msgstr "" #: src/view/com/auth/login/ChooseAccountForm.tsx:118 #: src/view/com/auth/login/Login.tsx:116 msgid "Sign in as..." -msgstr "Kirjaudu sisään nimellä..." +msgstr "" #: src/view/com/auth/login/LoginForm.tsx:137 msgid "Sign into" -msgstr "Kirjaudu sisään" +msgstr "" #: src/view/com/modals/SwitchAccount.tsx:64 #: src/view/com/modals/SwitchAccount.tsx:69 #: src/view/screens/Settings/index.tsx:100 #: src/view/screens/Settings/index.tsx:103 msgid "Sign out" -msgstr "Kirjaudu ulos" +msgstr "" #: src/view/shell/bottom-bar/BottomBar.tsx:275 #: src/view/shell/bottom-bar/BottomBar.tsx:276 @@ -3799,45 +3800,45 @@ msgstr "Kirjaudu ulos" #: src/view/shell/NavSignupCard.tsx:50 #: src/view/shell/NavSignupCard.tsx:52 msgid "Sign up" -msgstr "Rekisteröidy" +msgstr "" #: src/view/shell/NavSignupCard.tsx:42 msgid "Sign up or sign in to join the conversation" -msgstr "Rekisteröidy tai kirjaudu sisään liittyäksesi keskusteluun" +msgstr "" #: src/view/com/util/moderation/ScreenHider.tsx:76 msgid "Sign-in Required" -msgstr "Sisäänkirjautuminen vaaditaan" +msgstr "" #: src/view/screens/Settings/index.tsx:355 msgid "Signed in as" -msgstr "Kirjautunut sisään nimellä" +msgstr "" #: src/view/com/auth/login/ChooseAccountForm.tsx:103 msgid "Signed in as @{0}" -msgstr "Kirjautunut sisään käyttäjätunnuksella @{0}" +msgstr "" #: src/view/com/modals/SwitchAccount.tsx:66 msgid "Signs {0} out of Bluesky" -msgstr "{0} kirjautuu ulos Blueskysta" +msgstr "" #: src/screens/Onboarding/StepInterests/index.tsx:235 #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:195 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:33 msgid "Skip" -msgstr "Ohita" +msgstr "" #: src/screens/Onboarding/StepInterests/index.tsx:232 msgid "Skip this flow" -msgstr "Ohita tämä vaihe" +msgstr "" #: src/view/com/auth/create/Step2.tsx:82 #~ msgid "SMS verification" -#~ msgstr "SMS-varmennus" +#~ msgstr "" #: src/screens/Onboarding/index.tsx:40 msgid "Software Dev" -msgstr "Ohjelmistokehitys" +msgstr "" #: src/view/com/modals/ProfilePreview.tsx:62 #~ msgid "Something went wrong and we're not sure what." @@ -3845,27 +3846,27 @@ msgstr "Ohjelmistokehitys" #: src/view/com/modals/Waitlist.tsx:51 msgid "Something went wrong. Check your email and try again." -msgstr "Jotain meni pieleen. Tarkista sähköpostisi ja yritä uudelleen." +msgstr "" #: src/App.native.tsx:63 msgid "Sorry! Your session expired. Please log in again." -msgstr "Pahoittelut! Istuntosi on vanhentunut. Kirjaudu sisään uudelleen." +msgstr "" #: src/view/screens/PreferencesThreads.tsx:69 msgid "Sort Replies" -msgstr "Lajittele vastaukset" +msgstr "" #: src/view/screens/PreferencesThreads.tsx:72 msgid "Sort replies to the same post by:" -msgstr "Lajittele saman viestin vastaukset seuraavasti:" +msgstr "" #: src/screens/Onboarding/index.tsx:30 msgid "Sports" -msgstr "Urheilu" +msgstr "" #: src/view/com/modals/crop-image/CropImage.web.tsx:122 msgid "Square" -msgstr "Neliö" +msgstr "" #: src/view/com/modals/ServerInput.tsx:62 #~ msgid "Staging" @@ -3873,55 +3874,55 @@ msgstr "Neliö" #: src/view/screens/Settings/index.tsx:871 msgid "Status page" -msgstr "Tilasivu" +msgstr "" #: src/view/com/auth/create/StepHeader.tsx:22 msgid "Step {0} of {numSteps}" -msgstr "Vaihe {0}/{numSteps}" +msgstr "" #: src/view/screens/Settings/index.tsx:274 msgid "Storage cleared, you need to restart the app now." -msgstr "Tallennustila tyhjennetty, sinun on käynnistettävä sovellus uudelleen." +msgstr "" #: src/Navigation.tsx:202 #: src/view/screens/Settings/index.tsx:807 msgid "Storybook" -msgstr "Storybook" +msgstr "" #: src/view/com/modals/AppealLabel.tsx:101 msgid "Submit" -msgstr "Lähetä" +msgstr "Submit" #: src/view/screens/ProfileList.tsx:608 msgid "Subscribe" -msgstr "Tilaa" +msgstr "" #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:173 #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:307 msgid "Subscribe to the {0} feed" -msgstr "Tilaa {0}-syöte" +msgstr "" #: src/view/screens/ProfileList.tsx:604 msgid "Subscribe to this list" -msgstr "Tilaa tämä lista" +msgstr "" #: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" -msgstr "Ehdotetut seurattavat" +msgstr "" #: src/view/com/profile/ProfileHeaderSuggestedFollows.tsx:64 msgid "Suggested for you" -msgstr "Suositeltua sinulle" +msgstr "" #: src/view/com/modals/SelfLabel.tsx:95 msgid "Suggestive" -msgstr "Viittaava" +msgstr "" #: src/Navigation.tsx:212 #: src/view/screens/Support.tsx:30 #: src/view/screens/Support.tsx:33 msgid "Support" -msgstr "Tuki" +msgstr "" #: src/view/com/modals/ProfilePreview.tsx:110 #~ msgid "Swipe up to see more" @@ -3929,117 +3930,117 @@ msgstr "Tuki" #: src/view/com/modals/SwitchAccount.tsx:117 msgid "Switch Account" -msgstr "Vaihda tiliä" +msgstr "" #: src/view/com/modals/SwitchAccount.tsx:97 #: src/view/screens/Settings/index.tsx:130 msgid "Switch to {0}" -msgstr "Vaihda käyttäjään {0}" +msgstr "" #: src/view/com/modals/SwitchAccount.tsx:98 #: src/view/screens/Settings/index.tsx:131 msgid "Switches the account you are logged in to" -msgstr "Vaihtaa sisäänkirjautuneen käyttäjän tilin" +msgstr "" #: src/view/screens/Settings/index.tsx:472 msgid "System" -msgstr "Järjestelmä" +msgstr "" #: src/view/screens/Settings/index.tsx:795 msgid "System log" -msgstr "Järjestelmäloki" +msgstr "" #: src/components/dialogs/MutedWords.tsx:288 msgid "tag" -msgstr "tunniste" +msgstr "" #: src/components/TagMenu/index.tsx:74 msgid "Tag menu: {tag}" -msgstr "Tunnistevalikko: {tag}" +msgstr "" #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" -msgstr "Pitkä" +msgstr "" #: src/view/com/util/images/AutoSizedImage.tsx:70 msgid "Tap to view fully" -msgstr "Napauta nähdäksesi kokonaan" +msgstr "" #: src/screens/Onboarding/index.tsx:39 msgid "Tech" -msgstr "Teknologia" +msgstr "" #: src/view/shell/desktop/RightNav.tsx:81 msgid "Terms" -msgstr "Ehdot" +msgstr "" #: src/Navigation.tsx:222 #: src/view/screens/Settings/index.tsx:885 #: src/view/screens/TermsOfService.tsx:29 #: src/view/shell/Drawer.tsx:256 msgid "Terms of Service" -msgstr "Käyttöehdot" +msgstr "" #: src/components/dialogs/MutedWords.tsx:288 msgid "text" -msgstr "teksti" +msgstr "" #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" -msgstr "Tekstikenttä" +msgstr "" #: src/view/com/auth/create/CreateAccount.tsx:94 msgid "That handle is already taken." -msgstr "Tuo käyttätunnus on jo käytössä." +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:263 msgid "The account will be able to interact with you after unblocking." -msgstr "Tili voi olla vuorovaikutuksessa kanssasi, kun estäminen on poistettu." +msgstr "" #: src/view/screens/CommunityGuidelines.tsx:36 msgid "The Community Guidelines have been moved to <0/>" -msgstr "Yhteisöohjeet on siirretty kohtaan <0/>" +msgstr "" #: src/view/screens/CopyrightPolicy.tsx:33 msgid "The Copyright Policy has been moved to <0/>" -msgstr "Tekijänoikeuskäytäntö on siirretty kohtaan <0/>" +msgstr "" #: src/screens/Onboarding/Layout.tsx:60 msgid "The following steps will help customize your Bluesky experience." -msgstr "Seuraavat vaiheet auttavat mukauttamaan Bluesky-kokemustasi." +msgstr "" #: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." -msgstr "Viesti saattaa olla poistettu." +msgstr "" #: src/view/screens/PrivacyPolicy.tsx:33 msgid "The Privacy Policy has been moved to <0/>" -msgstr "Tietosuojakäytäntö on siirretty kohtaan <0/>" +msgstr "" #: src/view/screens/Support.tsx:36 msgid "The support form has been moved. If you need help, please <0/> or visit {HELP_DESK_URL} to get in touch with us." -msgstr "Tukilomake on siirretty. Jos tarvitset apua, käy osoitteessa <0/> tai vieraile {HELP_DESK_URL} ottaaksesi meihin yhteyttä." +msgstr "" #: src/view/screens/TermsOfService.tsx:33 msgid "The Terms of Service have been moved to" -msgstr "Käyttöehdot on siirretty kohtaan" +msgstr "" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:150 msgid "There are many feeds to try:" -msgstr "On monia syötteitä kokeiltavaksi:" +msgstr "" #: src/view/screens/ProfileFeed.tsx:550 msgid "There was an an issue contacting the server, please check your internet connection and try again." -msgstr "Emme saaneet yhteyttä palvelimeen, tarkista internetyhteytesi ja yritä uudelleen." +msgstr "" #: src/view/com/posts/FeedErrorMessage.tsx:139 msgid "There was an an issue removing this feed. Please check your internet connection and try again." -msgstr "Syötteen poistossa on ongelmia. Tarkista internetyhteytesi ja yritä uudelleen." +msgstr "" #: src/view/screens/ProfileFeed.tsx:210 msgid "There was an an issue updating your feeds, please check your internet connection and try again." -msgstr "Syötteiden päivittämisessä on ongelmia, tarkista internetyhteytesi ja yritä uudelleen." +msgstr "" #: src/view/screens/ProfileFeed.tsx:237 #: src/view/screens/ProfileList.tsx:267 @@ -4047,7 +4048,7 @@ msgstr "Syötteiden päivittämisessä on ongelmia, tarkista internetyhteytesi j #: src/view/screens/SavedFeeds.tsx:231 #: src/view/screens/SavedFeeds.tsx:252 msgid "There was an issue contacting the server" -msgstr "Yhteydenotto palvelimeen epäonnistui" +msgstr "" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:57 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:66 @@ -4055,33 +4056,33 @@ msgstr "Yhteydenotto palvelimeen epäonnistui" #: src/view/com/feeds/FeedSourceCard.tsx:129 #: src/view/com/feeds/FeedSourceCard.tsx:183 msgid "There was an issue contacting your server" -msgstr "Yhteydenotto palvelimeen epäonnistui" +msgstr "" #: src/view/com/notifications/Feed.tsx:117 msgid "There was an issue fetching notifications. Tap here to try again." -msgstr "Ongelma ilmoitusten hakemisessa. Napauta tästä yrittääksesi uudelleen." +msgstr "" #: src/view/com/posts/Feed.tsx:263 msgid "There was an issue fetching posts. Tap here to try again." -msgstr "Ongelma viestien hakemisessa. Napauta tästä yrittääksesi uudelleen." +msgstr "" #: src/view/com/lists/ListMembers.tsx:172 msgid "There was an issue fetching the list. Tap here to try again." -msgstr "Ongelma listan hakemisessa. Napauta tästä yrittääksesi uudelleen." +msgstr "" #: src/view/com/feeds/ProfileFeedgens.tsx:148 #: src/view/com/lists/ProfileLists.tsx:155 msgid "There was an issue fetching your lists. Tap here to try again." -msgstr "Ongelma listojesi hakemisessa. Napauta tästä yrittääksesi uudelleen." +msgstr "" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:63 #: src/view/com/modals/ContentFilteringSettings.tsx:126 msgid "There was an issue syncing your preferences with the server" -msgstr "Ongelma asetuksiesi synkronoinnissa palvelimelle" +msgstr "" #: src/view/screens/AppPasswords.tsx:66 msgid "There was an issue with fetching your app passwords" -msgstr "Sovellussalasanojen hakemisessa tapahtui virhe" +msgstr "" #: src/view/com/post-thread/PostThreadFollowBtn.tsx:93 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:105 @@ -4092,104 +4093,104 @@ msgstr "Sovellussalasanojen hakemisessa tapahtui virhe" #: src/view/com/profile/ProfileHeader.tsx:250 #: src/view/com/profile/ProfileHeader.tsx:272 msgid "There was an issue! {0}" -msgstr "Ilmeni ongelma! {0}" +msgstr "" #: src/view/screens/ProfileList.tsx:288 #: src/view/screens/ProfileList.tsx:307 #: src/view/screens/ProfileList.tsx:329 #: src/view/screens/ProfileList.tsx:348 msgid "There was an issue. Please check your internet connection and try again." -msgstr "Ilmeni joku ongelma. Tarkista internet-yhteys ja yritä uudelleen." +msgstr "" #: src/view/com/util/ErrorBoundary.tsx:36 msgid "There was an unexpected issue in the application. Please let us know if this happened to you!" -msgstr "Sovelluksessa ilmeni odottamaton ongelma. Kerro meille, jos tämä tapahtui sinulle!" +msgstr "" #: src/screens/Deactivated.tsx:106 msgid "There's been a rush of new users to Bluesky! We'll activate your account as soon as we can." -msgstr "Blueskyyn on tullut paljon uusia käyttäjiä! Aktivoimme tilisi niin pian kuin mahdollista." +msgstr "" #: src/view/com/auth/create/Step2.tsx:55 #~ msgid "There's something wrong with this number. Please choose your country and enter your full phone number!" -#~ msgstr "Tässä numerossa on jotain vikaa. Valitse maasi ja syötä koko puhelinnumerosi!" +#~ msgstr "" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:138 msgid "These are popular accounts you might like:" -msgstr "Nämä ovat suosittuja tilejä, joista saatat pitää:" +msgstr "" #: src/view/com/util/moderation/ScreenHider.tsx:88 msgid "This {screenDescription} has been flagged:" -msgstr "Tämä {screenDescription} on liputettu:" +msgstr "" #: src/view/com/util/moderation/ScreenHider.tsx:83 msgid "This account has requested that users sign in to view their profile." -msgstr "Tämä tili pyytää käyttäjiä kirjautumaan sisään nähdäkseen profiilinsa." +msgstr "" #: src/view/com/modals/EmbedConsent.tsx:68 msgid "This content is hosted by {0}. Do you want to enable external media?" -msgstr "Tämä sisältö on hostattu palvelussa {0}. Haluatko sallia ulkoisen median?" +msgstr "" #: src/view/com/modals/ModerationDetails.tsx:67 msgid "This content is not available because one of the users involved has blocked the other." -msgstr "Tämä sisältö ei ole saatavilla, koska toinen käyttäjistä on estänyt toisen." +msgstr "" #: src/view/com/posts/FeedErrorMessage.tsx:108 msgid "This content is not viewable without a Bluesky account." -msgstr "Tätä sisältöä ei voi katsoa ilman Bluesky-tiliä." +msgstr "" #: src/view/screens/Settings/ExportCarDialog.tsx:75 msgid "This feature is in beta. You can read more about repository exports in <0>this blogpost." -msgstr "Tämä ominaisuus on betavaiheessa. Voit lukea lisää pakettivarastojen vientitoiminnosta <0>tässä blogikirjoituksessa." +msgstr "" #: src/view/com/posts/FeedErrorMessage.tsx:114 msgid "This feed is currently receiving high traffic and is temporarily unavailable. Please try again later." -msgstr "Tämä syöte saa tällä hetkellä paljon liikennettä ja on tilapäisesti pois käytöstä. Yritä uudelleen myöhemmin." +msgstr "" #: src/view/screens/Profile.tsx:420 #: src/view/screens/ProfileFeed.tsx:476 #: src/view/screens/ProfileList.tsx:661 msgid "This feed is empty!" -msgstr "Tämä syöte on tyhjä!" +msgstr "" #: src/view/com/posts/CustomFeedEmptyState.tsx:37 msgid "This feed is empty! You may need to follow more users or tune your language settings." -msgstr "Tämä syöte on tyhjä! Sinun on ehkä seurattava useampia käyttäjiä tai säädettävä kieliasetuksiasi." +msgstr "" #: src/view/com/modals/BirthDateSettings.tsx:61 msgid "This information is not shared with other users." -msgstr "Tätä tietoa ei jaeta muiden käyttäjien kanssa." +msgstr "" #: src/view/com/modals/VerifyEmail.tsx:119 msgid "This is important in case you ever need to change your email or reset your password." -msgstr "Tämä on tärkeää, jos sinun tarvitsee vaihtaa sähköpostiosoitteesi tai palauttaa salasanasi." +msgstr "" #: src/view/com/modals/LinkWarning.tsx:58 msgid "This link is taking you to the following website:" -msgstr "Tämä linkki vie sinut tälle verkkosivustolle:" +msgstr "" #: src/view/screens/ProfileList.tsx:834 msgid "This list is empty!" -msgstr "Tämä lista on tyhjä!" +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:106 msgid "This name is already in use" -msgstr "Tämä nimi on jo käytössä" +msgstr "" #: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." -msgstr "Tämä viesti on poistettu." +msgstr "" #: src/view/com/modals/ModerationDetails.tsx:62 msgid "This user has blocked you. You cannot view their content." -msgstr "Tämä käyttäjä on estänyt sinut. Et voi nähdä heidän sisältöään." +msgstr "" #: src/view/com/modals/ModerationDetails.tsx:42 msgid "This user is included in the <0/> list which you have blocked." -msgstr "Tämä käyttäjä on <0/>-listassa, jonka olet estänyt." +msgstr "" #: src/view/com/modals/ModerationDetails.tsx:74 msgid "This user is included in the <0/> list which you have muted." -msgstr "Tämä käyttäjä on <0/>-listassa, jonka olet hiljentänyt." +msgstr "" #: src/view/com/modals/ModerationDetails.tsx:74 #~ msgid "This user is included the <0/> list which you have muted." @@ -4197,59 +4198,59 @@ msgstr "Tämä käyttäjä on <0/>-listassa, jonka olet hiljentänyt." #: src/view/com/modals/SelfLabel.tsx:137 msgid "This warning is only available for posts with media attached." -msgstr "Tämä varoitus on saatavilla vain viesteille, joihin on liitetty mediatiedosto." +msgstr "" #: src/components/dialogs/MutedWords.tsx:236 msgid "This will delete {0} from your muted words. You can always add it back later." -msgstr "Tämä poistaa {0}:n hiljennetyistä sanoistasi. Voit lisätä sen takaisin myöhemmin." +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "This will hide this post from your feeds." -msgstr "Tämä piilottaa tämän viestin syötteistäsi." +msgstr "" #: src/view/screens/PreferencesThreads.tsx:53 #: src/view/screens/Settings/index.tsx:565 msgid "Thread Preferences" -msgstr "Keskusteluketjun asetukset" +msgstr "" #: src/view/screens/PreferencesThreads.tsx:119 msgid "Threaded Mode" -msgstr "Ketjumainen näkymä" +msgstr "" #: src/Navigation.tsx:255 msgid "Threads Preferences" -msgstr "Keskusteluketjujen asetukset" +msgstr "" #: src/components/dialogs/MutedWords.tsx:95 msgid "Toggle between muted word options." -msgstr "Vaihda hiljennysvaihtoehtojen välillä." +msgstr "" #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" -msgstr "Vaihda pudotusvalikko" +msgstr "" #: src/view/com/modals/EditImage.tsx:271 msgid "Transformations" -msgstr "Muutokset" +msgstr "" #: src/view/com/post-thread/PostThreadItem.tsx:685 #: src/view/com/post-thread/PostThreadItem.tsx:687 #: src/view/com/util/forms/PostDropdownBtn.tsx:156 msgid "Translate" -msgstr "Käännä" +msgstr "" #: src/view/com/util/error/ErrorScreen.tsx:82 msgctxt "action" msgid "Try again" -msgstr "Yritä uudelleen" +msgstr "" #: src/view/screens/ProfileList.tsx:506 msgid "Un-block list" -msgstr "Poista listan esto" +msgstr "" #: src/view/screens/ProfileList.tsx:491 msgid "Un-mute list" -msgstr "Poista listan hiljennys" +msgstr "" #: src/view/com/auth/create/CreateAccount.tsx:58 #: src/view/com/auth/login/ForgotPasswordForm.tsx:87 @@ -4257,119 +4258,119 @@ msgstr "Poista listan hiljennys" #: src/view/com/auth/login/LoginForm.tsx:118 #: src/view/com/modals/ChangePassword.tsx:70 msgid "Unable to contact your service. Please check your Internet connection." -msgstr "Yhteys palveluusi ei onnistu. Tarkista internet-yhteytesi." +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:433 #: src/view/screens/ProfileList.tsx:590 msgid "Unblock" -msgstr "Poista esto" +msgstr "" -#: src/view/com/profile/ProfileHeader.tsx:435 +#: src/view/com/profile/ProfileHeader.tsx:436 msgctxt "action" msgid "Unblock" -msgstr "Poista esto" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:261 #: src/view/com/profile/ProfileHeader.tsx:345 msgid "Unblock Account" -msgstr "Poista tilin esto" +msgstr "" #: src/view/com/modals/Repost.tsx:42 #: src/view/com/modals/Repost.tsx:55 #: src/view/com/util/post-ctrls/RepostButton.tsx:60 #: src/view/com/util/post-ctrls/RepostButton.web.tsx:48 msgid "Undo repost" -msgstr "Kumoa uudelleenjako" +msgstr "" #: src/view/com/profile/FollowButton.tsx:55 msgctxt "action" msgid "Unfollow" -msgstr "Lopeta seuraaminen" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:485 msgid "Unfollow {0}" -msgstr "Lopeta seuraaminen {0}" +msgstr "" #: src/view/com/auth/create/state.ts:262 msgid "Unfortunately, you do not meet the requirements to create an account." -msgstr "Valitettavasti et täytä tilin luomisen vaatimuksia." +msgstr "" #: src/view/com/util/post-ctrls/PostCtrls.tsx:182 #: src/view/com/util/post-ctrls/PostCtrls.tsx:216 msgid "Unlike" -msgstr "En tykkää" +msgstr "" #: src/components/TagMenu/index.tsx:253 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" -msgstr "Poista hiljennys" +msgstr "" #: src/components/TagMenu/index.web.tsx:90 msgid "Unmute {truncatedTag}" -msgstr "Poista hiljennys {truncatedTag}" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" -msgstr "Poista tilin hiljennys" +msgstr "" #: src/components/TagMenu/index.tsx:210 msgid "Unmute all {tag} posts" -msgstr "Poista hiljennys kaikista {tag}-viesteistä" +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Unmute thread" -msgstr "Poista keskusteluketjun hiljennys" +msgstr "" #: src/view/screens/ProfileFeed.tsx:353 #: src/view/screens/ProfileList.tsx:580 msgid "Unpin" -msgstr "Poista kiinnitys" +msgstr "" #: src/view/screens/ProfileList.tsx:474 msgid "Unpin moderation list" -msgstr "Poista moderointilistan kiinnitys" +msgstr "" #: src/view/screens/ProfileFeed.tsx:346 msgid "Unsave" -msgstr "Poista tallennus" +msgstr "" #: src/view/com/modals/UserAddRemoveLists.tsx:70 msgid "Update {displayName} in Lists" -msgstr "Päivitä {displayName} listoissa" +msgstr "" #: src/lib/hooks/useOTAUpdate.ts:15 msgid "Update Available" -msgstr "Päivitys saatavilla" +msgstr "" #: src/view/com/auth/login/SetNewPasswordForm.tsx:204 msgid "Updating..." -msgstr "Päivitetään..." +msgstr "" #: src/view/com/modals/ChangeHandle.tsx:455 msgid "Upload a text file to:" -msgstr "Lataa tekstitiedosto kohteeseen:" +msgstr "" #: src/view/screens/AppPasswords.tsx:195 msgid "Use app passwords to login to other Bluesky clients without giving full access to your account or password." -msgstr "Käytä sovellussalasanoja kirjautuaksesi muihin Bluesky-sovelluksiin antamatta niille täyttä hallintaa tilillesi tai salasanallesi." +msgstr "" #: src/view/com/modals/ChangeHandle.tsx:515 msgid "Use default provider" -msgstr "Käytä oletustoimittajaa" +msgstr "" #: src/view/com/modals/InAppBrowserConsent.tsx:56 #: src/view/com/modals/InAppBrowserConsent.tsx:58 msgid "Use in-app browser" -msgstr "Käytä sovelluksen sisäistä selainta" +msgstr "" #: src/view/com/modals/InAppBrowserConsent.tsx:66 #: src/view/com/modals/InAppBrowserConsent.tsx:68 msgid "Use my default browser" -msgstr "Käytä oletusselaintani" +msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:155 msgid "Use this to sign into the other app along with your handle." -msgstr "Käytä tätä kirjautuaksesi toiseen sovellukseen käyttäjätunnuksellasi." +msgstr "" #: src/view/com/modals/ServerInput.tsx:105 #~ msgid "Use your domain as your Bluesky client service provider" @@ -4377,141 +4378,141 @@ msgstr "Käytä tätä kirjautuaksesi toiseen sovellukseen käyttäjätunnuksell #: src/view/com/modals/InviteCodes.tsx:200 msgid "Used by:" -msgstr "Käyttänyt:" +msgstr "" #: src/view/com/modals/ModerationDetails.tsx:54 msgid "User Blocked" -msgstr "Käyttäjä estetty" +msgstr "" #: src/view/com/modals/ModerationDetails.tsx:40 msgid "User Blocked by List" -msgstr "Käyttäjä estetty listan vuoksi" +msgstr "" #: src/view/com/modals/ModerationDetails.tsx:60 msgid "User Blocks You" -msgstr "Käyttäjä on estänyt sinut" +msgstr "" #: src/view/com/auth/create/Step2.tsx:79 msgid "User handle" -msgstr "Käyttäjätunnus" +msgstr "" #: src/view/com/lists/ListCard.tsx:85 #: src/view/com/modals/UserAddRemoveLists.tsx:198 msgid "User list by {0}" -msgstr "Käyttäjälistan on tehnyt {0}" +msgstr "" #: src/view/screens/ProfileList.tsx:762 msgid "User list by <0/>" -msgstr "Käyttäjälistan on tehnyt <0/>" +msgstr "" #: src/view/com/lists/ListCard.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:196 #: src/view/screens/ProfileList.tsx:760 msgid "User list by you" -msgstr "Sinun käyttäjälistasi" +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:196 msgid "User list created" -msgstr "Käyttäjälista luotu" +msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:182 msgid "User list updated" -msgstr "Käyttäjälista päivitetty" +msgstr "" #: src/view/screens/Lists.tsx:58 msgid "User Lists" -msgstr "Käyttäjälistat" +msgstr "" #: src/view/com/auth/login/LoginForm.tsx:177 #: src/view/com/auth/login/LoginForm.tsx:195 msgid "Username or email address" -msgstr "Käyttäjätunnus tai sähköpostiosoite" +msgstr "" #: src/view/screens/ProfileList.tsx:796 msgid "Users" -msgstr "Käyttäjät" +msgstr "" #: src/view/com/threadgate/WhoCanReply.tsx:143 msgid "users followed by <0/>" -msgstr "käyttäjät, joita <0/> seuraa" +msgstr "" #: src/view/com/modals/Threadgate.tsx:106 msgid "Users in \"{0}\"" -msgstr "Käyttäjät ryhmässä \"{0}\"" +msgstr "" #: src/view/com/auth/create/Step2.tsx:243 #~ msgid "Verification code" -#~ msgstr "Varmistuskoodi" +#~ msgstr "" #: src/view/screens/Settings/index.tsx:910 msgid "Verify email" -msgstr "Varmista sähköposti" +msgstr "" #: src/view/screens/Settings/index.tsx:935 msgid "Verify my email" -msgstr "Vahvista sähköpostini" +msgstr "" #: src/view/screens/Settings/index.tsx:944 msgid "Verify My Email" -msgstr "Vahvista sähköpostini" +msgstr "" #: src/view/com/modals/ChangeEmail.tsx:205 #: src/view/com/modals/ChangeEmail.tsx:207 msgid "Verify New Email" -msgstr "Vahvista uusi sähköposti" +msgstr "" #: src/view/com/modals/VerifyEmail.tsx:103 msgid "Verify Your Email" -msgstr "Vahvista sähköpostisi" +msgstr "" #: src/screens/Onboarding/index.tsx:42 msgid "Video Games" -msgstr "Videopelit" +msgstr "" #: src/view/com/profile/ProfileHeader.tsx:662 msgid "View {0}'s avatar" -msgstr "Katso {0}:n avatar" +msgstr "" #: src/view/screens/Log.tsx:52 msgid "View debug entry" -msgstr "Katso vianmääritystietue" +msgstr "" #: src/view/com/posts/FeedSlice.tsx:103 msgid "View full thread" -msgstr "Katso koko keskusteluketju" +msgstr "" #: src/view/com/posts/FeedErrorMessage.tsx:172 msgid "View profile" -msgstr "Katso profiilia" +msgstr "" #: src/view/com/profile/ProfileSubpageHeader.tsx:128 msgid "View the avatar" -msgstr "Katso avatar" +msgstr "" #: src/view/com/modals/LinkWarning.tsx:75 msgid "Visit Site" -msgstr "Vieraile sivustolla" +msgstr "" #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:42 #: src/view/com/modals/ContentFilteringSettings.tsx:259 msgid "Warn" -msgstr "Varoita" +msgstr "" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:134 msgid "We also think you'll like \"For You\" by Skygaze:" -msgstr "Uskomme myös, että pitäisit Skygazen \"For You\" -syötteestä:" +msgstr "" #: src/screens/Deactivated.tsx:133 msgid "We estimate {estimatedTime} until your account is ready." -msgstr "Arvioimme, että tilisi valmistumiseen on {estimatedTime} aikaa." +msgstr "" #: src/screens/Onboarding/StepFinished.tsx:93 msgid "We hope you have a wonderful time. Remember, Bluesky is:" -msgstr "Toivomme sinulle ihania hetkiä. Muista, että Bluesky on:" +msgstr "" #: src/view/com/posts/DiscoverFallbackHeader.tsx:29 msgid "We ran out of posts from your follows. Here's the latest from <0/>." -msgstr "Emme enää löytäneet viestejä seurattavilta. Tässä on uusin tekijältä <0/>." +msgstr "" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:118 #~ msgid "We recommend \"For You\" by Skygaze:" @@ -4519,98 +4520,98 @@ msgstr "Emme enää löytäneet viestejä seurattavilta. Tässä on uusin tekij #: src/components/dialogs/MutedWords.tsx:161 msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." -msgstr "Suosittelemme välttämään yleisiä sanoja, jotka esiintyvät monissa viesteissä. Se voi johtaa siihen, ettei viestejä näytetä." +msgstr "" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" -msgstr "Suosittelemme \"Tutustu\"-syötettämme:" +msgstr "" #: src/screens/Onboarding/StepInterests/index.tsx:133 msgid "We weren't able to connect. Please try again to continue setting up your account. If it continues to fail, you can skip this flow." -msgstr "Yhteyden muodostaminen ei onnistunut. Yritä uudelleen jatkaaksesi tilisi määritystä. Jos ongelma jatkuu, voit ohittaa tämän vaiheen." +msgstr "" #: src/screens/Deactivated.tsx:137 msgid "We will let you know when your account is ready." -msgstr "Ilmoitamme sinulle, kun tilisi on valmis." +msgstr "" #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." -msgstr "Käsittelemme vetoomuksesi pikaisesti." +msgstr "" #: src/screens/Onboarding/StepInterests/index.tsx:138 msgid "We'll use this to help customize your experience." -msgstr "Käytämme tätä mukauttaaksemme kokemustasi." +msgstr "" #: src/view/com/auth/create/CreateAccount.tsx:134 msgid "We're so excited to have you join us!" -msgstr "Olemme innoissamme, että liityt joukkoomme!" +msgstr "" #: src/view/screens/ProfileList.tsx:86 msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." -msgstr "Pahoittelemme, emme saaneet avattua tätä listaa. Jos ongelma jatkuu, ota yhteyttä listan tekijään: @{handleOrDid}." +msgstr "" #: src/components/dialogs/MutedWords.tsx:182 msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." -msgstr "Pahoittelemme, emme pystyneet lataamaan hiljennettyjä sanojasi tällä hetkellä. Yritä uudelleen." +msgstr "" #: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." -msgstr "Pahoittelemme, hakuasi ei voitu suorittaa loppuun. Yritä uudelleen muutaman minuutin kuluttua." +msgstr "" #: src/view/screens/NotFound.tsx:48 msgid "We're sorry! We can't find the page you were looking for." -msgstr "Pahoittelut! Emme löydä etsimääsi sivua." +msgstr "" #: src/view/com/auth/onboarding/WelcomeMobile.tsx:46 msgid "Welcome to <0>Bluesky" -msgstr "Tervetuloa <0>Bluesky:iin" +msgstr "" #: src/screens/Onboarding/StepInterests/index.tsx:130 msgid "What are your interests?" -msgstr "Mitkä ovat kiinnostuksenkohteesi?" +msgstr "" #: src/view/com/modals/report/Modal.tsx:169 msgid "What is the issue with this {collectionName}?" -msgstr "Mikä on ongelma tämän {collectionName} kanssa?" +msgstr "" #: src/view/com/auth/SplashScreen.tsx:59 #: src/view/com/composer/Composer.tsx:286 msgid "What's up?" -msgstr "Mitä kuuluu?" +msgstr "" #: src/view/com/modals/lang-settings/PostLanguagesSettings.tsx:78 msgid "Which languages are used in this post?" -msgstr "Mitä kieliä tässä viestissä käytetään?" +msgstr "" #: src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx:77 msgid "Which languages would you like to see in your algorithmic feeds?" -msgstr "Mitä kieliä haluaisit nähdä algoritmisissä syötteissä?" +msgstr "" #: src/view/com/composer/threadgate/ThreadgateBtn.tsx:47 #: src/view/com/modals/Threadgate.tsx:66 msgid "Who can reply" -msgstr "Kuka voi vastata" +msgstr "" #: src/view/com/modals/crop-image/CropImage.web.tsx:102 msgid "Wide" -msgstr "Leveä" +msgstr "" #: src/view/com/composer/Composer.tsx:422 msgid "Write post" -msgstr "Kirjoita viesti" +msgstr "" #: src/view/com/composer/Composer.tsx:285 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" -msgstr "Kirjoita vastauksesi" +msgstr "" #: src/screens/Onboarding/index.tsx:28 msgid "Writers" -msgstr "Kirjoittajat" +msgstr "" #: src/view/com/auth/create/Step2.tsx:263 #~ msgid "XXXXXX" -#~ msgstr "XXXXXX" +#~ msgstr "" #: src/view/com/composer/select-language/SuggestedLanguage.tsx:77 #: src/view/screens/PreferencesFollowingFeed.tsx:129 @@ -4620,7 +4621,7 @@ msgstr "Kirjoittajat" #: src/view/screens/PreferencesThreads.tsx:106 #: src/view/screens/PreferencesThreads.tsx:129 msgid "Yes" -msgstr "Kyllä" +msgstr "" #: src/screens/Onboarding/StepModeration/index.tsx:46 #~ msgid "You are in control" @@ -4628,12 +4629,12 @@ msgstr "Kyllä" #: src/screens/Deactivated.tsx:130 msgid "You are in line." -msgstr "Olet jonossa." +msgstr "" #: src/view/com/posts/FollowingEmptyState.tsx:67 #: src/view/com/posts/FollowingEndOfFeed.tsx:68 msgid "You can also discover new Custom Feeds to follow." -msgstr "Voit myös selata uusia mukautettuja syötteitä seurattavaksi." +msgstr "" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:123 #~ msgid "You can also try our \"Discover\" algorithm:" @@ -4641,164 +4642,164 @@ msgstr "Voit myös selata uusia mukautettuja syötteitä seurattavaksi." #: src/screens/Onboarding/StepFollowingFeed.tsx:142 msgid "You can change these settings later." -msgstr "Voit muuttaa näitä asetuksia myöhemmin." +msgstr "" #: src/view/com/auth/login/Login.tsx:158 #: src/view/com/auth/login/PasswordUpdatedForm.tsx:31 msgid "You can now sign in with your new password." -msgstr "Voit nyt kirjautua sisään uudella salasanallasi." +msgstr "" #: src/view/com/modals/InviteCodes.tsx:66 msgid "You don't have any invite codes yet! We'll send you some when you've been on Bluesky for a little longer." -msgstr "Sinulla ei ole vielä kutsukoodia! Lähetämme sinulle sellaisen, kun olet ollut Bluesky-palvelussa hieman pidempään." +msgstr "" #: src/view/screens/SavedFeeds.tsx:102 msgid "You don't have any pinned feeds." -msgstr "Sinulla ei ole kiinnitettyjä syötteitä." +msgstr "" #: src/view/screens/Feeds.tsx:452 msgid "You don't have any saved feeds!" -msgstr "Sinulla ei ole tallennettuja syötteitä!" +msgstr "" #: src/view/screens/SavedFeeds.tsx:135 msgid "You don't have any saved feeds." -msgstr "Sinulla ei ole tallennettuja syötteitä." +msgstr "" #: src/view/com/post-thread/PostThread.tsx:465 msgid "You have blocked the author or you have been blocked by the author." -msgstr "Olet estänyt tekijän tai sinut on estetty tekijän toimesta." +msgstr "" #: src/view/com/modals/ModerationDetails.tsx:56 msgid "You have blocked this user. You cannot view their content." -msgstr "Olet estänyt tämän käyttäjän. Et voi nähdä heidän sisältöään." +msgstr "" #: src/view/com/auth/login/SetNewPasswordForm.tsx:57 #: src/view/com/auth/login/SetNewPasswordForm.tsx:92 #: src/view/com/modals/ChangePassword.tsx:87 #: src/view/com/modals/ChangePassword.tsx:121 msgid "You have entered an invalid code. It should look like XXXXX-XXXXX." -msgstr "Olet syöttänyt virheellisen koodin. Sen tulisi näyttää muodoltaan XXXXX-XXXXX." +msgstr "" #: src/view/com/modals/ModerationDetails.tsx:87 msgid "You have muted this user." -msgstr "Olet hiljentänyt tämän käyttäjän." +msgstr "" #: src/view/com/feeds/ProfileFeedgens.tsx:136 msgid "You have no feeds." -msgstr "Sinulla ei ole syötteitä." +msgstr "" #: src/view/com/lists/MyLists.tsx:89 #: src/view/com/lists/ProfileLists.tsx:140 msgid "You have no lists." -msgstr "Sinulla ei ole listoja." +msgstr "" #: src/view/screens/ModerationBlockedAccounts.tsx:132 msgid "You have not blocked any accounts yet. To block an account, go to their profile and selected \"Block account\" from the menu on their account." -msgstr "Et ole vielä estänyt yhtään käyttäjää. Estääksesi käyttäjän, siirry heidän profiiliinsa ja valitse \"Estä käyttäjä\"-vaihtoehto heidän tilinsä valikosta." +msgstr "" #: src/view/screens/AppPasswords.tsx:87 msgid "You have not created any app passwords yet. You can create one by pressing the button below." -msgstr "Et ole vielä luonut yhtään sovelluksen salasanaa. Voit luoda sellaisen painamalla alla olevaa painiketta." +msgstr "" #: src/view/screens/ModerationMutedAccounts.tsx:131 msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." -msgstr "Et ole vielä hiljentänyt yhtään käyttäjää. Hiljentääksesi käyttäjän, siirry heidän profiiliinsa ja valitse \"Hiljennä käyttäjä\"-vaihtoehto heidän tilinsä valikosta." +msgstr "" #: src/components/dialogs/MutedWords.tsx:202 msgid "You haven't muted any words or tags yet" -msgstr "Et ole vielä hiljentänyt yhtään sanaa tai tunnistetta" +msgstr "" #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." -msgstr "Sinun on oltava vähintään 18-vuotias katsoaksesi aikuissisältöä." +msgstr "" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:103 msgid "You must be 18 years or older to enable adult content" -msgstr "Sinun on oltava vähintään 18-vuotias katsoaksesi aikuissisältöä" +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:129 msgid "You will no longer receive notifications for this thread" -msgstr "Et enää saa ilmoituksia tästä keskustelusta" +msgstr "" #: src/view/com/util/forms/PostDropdownBtn.tsx:132 msgid "You will now receive notifications for this thread" -msgstr "Saat nyt ilmoituksia tästä keskustelusta" +msgstr "" #: src/view/com/auth/login/SetNewPasswordForm.tsx:107 msgid "You will receive an email with a \"reset code.\" Enter that code here, then enter your new password." -msgstr "Saat sähköpostin \"nollauskoodin\". Syötä koodi tähän ja syötä sitten uusi salasanasi." +msgstr "" #: src/screens/Onboarding/StepModeration/index.tsx:72 msgid "You're in control" -msgstr "Sinulla on ohjat" +msgstr "" #: src/screens/Deactivated.tsx:87 #: src/screens/Deactivated.tsx:88 #: src/screens/Deactivated.tsx:103 msgid "You're in line" -msgstr "Olet jonossa" +msgstr "" #: src/screens/Onboarding/StepFinished.tsx:90 msgid "You're ready to go!" -msgstr "Olet valmis aloittamaan!" +msgstr "" #: src/view/com/posts/FollowingEndOfFeed.tsx:48 msgid "You've reached the end of your feed! Find some more accounts to follow." -msgstr "Olet saavuttanut syötteesi lopun! Etsi lisää käyttäjiä seurattavaksi." +msgstr "" #: src/view/com/auth/create/Step1.tsx:74 msgid "Your account" -msgstr "Tilisi" +msgstr "" #: src/view/com/modals/DeleteAccount.tsx:67 msgid "Your account has been deleted" -msgstr "Tilisi on poistettu" +msgstr "" #: src/view/screens/Settings/ExportCarDialog.tsx:47 msgid "Your account repository, containing all public data records, can be downloaded as a \"CAR\" file. This file does not include media embeds, such as images, or your private data, which must be fetched separately." -msgstr "Tilisi arkisto, joka sisältää kaikki julkiset tietueet, voidaan ladata \"CAR\"-tiedostona. Tämä tiedosto ei sisällä upotettuja mediaelementtejä, kuten kuvia, tai yksityisiä tietojasi, jotka on haettava erikseen." +msgstr "" #: src/view/com/auth/create/Step1.tsx:238 msgid "Your birth date" -msgstr "Syntymäaikasi" +msgstr "" #: src/view/com/modals/InAppBrowserConsent.tsx:47 msgid "Your choice will be saved, but can be changed later in settings." -msgstr "Valintasi tallennetaan, mutta sitä voit muuttaa myöhemmin asetuksissa." +msgstr "" #: src/screens/Onboarding/StepFollowingFeed.tsx:61 msgid "Your default feed is \"Following\"" -msgstr "Oletussyötteesi on \"Following\"" +msgstr "" #: src/view/com/auth/create/state.ts:110 #: src/view/com/auth/login/ForgotPasswordForm.tsx:70 #: src/view/com/modals/ChangePassword.tsx:54 msgid "Your email appears to be invalid." -msgstr "Sähköpostiosoitteesi näyttää olevan virheellinen." +msgstr "" #: src/view/com/modals/Waitlist.tsx:109 msgid "Your email has been saved! We'll be in touch soon." -msgstr "Sähköpostiosoitteesi on tallennettu! Olemme pian yhteydessä." +msgstr "" #: src/view/com/modals/ChangeEmail.tsx:125 msgid "Your email has been updated but not verified. As a next step, please verify your new email." -msgstr "Sähköpostiosoitteesi on päivitetty, mutta sitä ei ole vielä vahvistettu. Seuraavana vaiheena vahvista uusi sähköpostiosoitteesi." +msgstr "" #: src/view/com/modals/VerifyEmail.tsx:114 msgid "Your email has not yet been verified. This is an important security step which we recommend." -msgstr "Sähköpostiosoitettasi ei ole vielä vahvistettu. Tämä on tärkeä turvatoimi, jonka suosittelemme suorittamaan." +msgstr "" #: src/view/com/posts/FollowingEmptyState.tsx:47 msgid "Your following feed is empty! Follow more users to see what's happening." -msgstr "Seuraamiesi syöte on tyhjä! Seuraa lisää käyttäjiä nähdäksesi, mitä tapahtuu." +msgstr "" #: src/view/com/auth/create/Step2.tsx:83 msgid "Your full handle will be" -msgstr "Käyttäjätunnuksesi tulee olemaan" +msgstr "" #: src/view/com/modals/ChangeHandle.tsx:270 msgid "Your full handle will be <0>@{0}" -msgstr "Käyttäjätunnuksesi tulee olemaan <0>@{0}" +msgstr "" #: src/view/screens/Settings.tsx:430 #: src/view/shell/desktop/RightNav.tsx:137 @@ -4808,31 +4809,31 @@ msgstr "Käyttäjätunnuksesi tulee olemaan <0>@{0}" #: src/components/dialogs/MutedWords.tsx:173 msgid "Your muted words" -msgstr "Hiljentämäsi sanat" +msgstr "" #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" -msgstr "Salasanasi on vaihdettu onnistuneesti!" +msgstr "" #: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" -msgstr "Viestisi on julkaistu" +msgstr "" #: src/screens/Onboarding/StepFinished.tsx:105 #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:59 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:59 msgid "Your posts, likes, and blocks are public. Mutes are private." -msgstr "Julkaisusi, tykkäyksesi ja estosi ovat julkisia. Hiljennykset ovat yksityisiä." +msgstr "" #: src/view/com/modals/SwitchAccount.tsx:84 #: src/view/screens/Settings/index.tsx:118 msgid "Your profile" -msgstr "Profiilisi" +msgstr "" #: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" -msgstr "Vastauksesi on julkaistu" +msgstr "" #: src/view/com/auth/create/Step2.tsx:65 msgid "Your user handle" -msgstr "Käyttäjätunnuksesi" +msgstr "" From 521530eeb67dc7b3f2697a153f28dc9af4bf49dd Mon Sep 17 00:00:00 2001 From: Jan-Olof Eriksson Date: Mon, 4 Mar 2024 19:05:03 +0200 Subject: [PATCH 054/109] Update messages.po Updated latest strings --- src/locale/locales/fi/messages.po | 768 +++++++++++++++++++----------- 1 file changed, 480 insertions(+), 288 deletions(-) diff --git a/src/locale/locales/fi/messages.po b/src/locale/locales/fi/messages.po index be89f18f56..f5b40f4214 100644 --- a/src/locale/locales/fi/messages.po +++ b/src/locale/locales/fi/messages.po @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: \n" -"Last-Translator: @pekka.bsky.social\n" +"Last-Translator:@jaoler.fi\n" "Language-Team: @pekka.bsky.social,@jaoler.fi,@rahi.bsky.social\n" "Plural-Forms: \n" @@ -21,7 +21,7 @@ msgstr "(ei sähköpostiosoitetta)" #~ msgid "{0, plural, one {# invite code available} other {# invite codes available}}" #~ msgstr "" -#: src/view/com/profile/ProfileHeader.tsx:592 +#: src/view/com/profile/ProfileHeader.tsx:593 msgid "{following} following" msgstr "{following} seuraajaa" @@ -47,7 +47,7 @@ msgstr "{numUnreadNotifications} lukematonta" msgid "<0/> members" msgstr "<0/> jäsentä" -#: src/view/com/profile/ProfileHeader.tsx:594 +#: src/view/com/profile/ProfileHeader.tsx:595 msgid "<0>{following} <1>following" msgstr "<0>{following} <1>seuraajaa" @@ -63,7 +63,7 @@ msgstr "<0>Seuraa joitakin<1>suositeltuja<2>käyttäjiä" msgid "<0>Welcome to<1>Bluesky" msgstr "<0>Tervetuloa<1>Blueskyhin" -#: src/view/com/profile/ProfileHeader.tsx:557 +#: src/view/com/profile/ProfileHeader.tsx:558 msgid "⚠Invalid Handle" msgstr "⚠Virheellinen käyttäjätunnus" @@ -76,11 +76,11 @@ msgid "A new version of the app is available. Please update to continue using th msgstr "Sovelluksen uusi versio on saatavilla. Päivitä jatkaaksesi sovelluksen käyttöä." #: src/view/com/util/ViewHeader.tsx:83 -#: src/view/screens/Search/Search.tsx:624 +#: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" msgstr "Siirry navigointilinkkeihin ja asetuksiin" -#: src/view/com/pager/FeedsTabBarMobile.tsx:89 +#: src/view/com/home/HomeHeaderLayoutMobile.tsx:51 msgid "Access profile and other navigation links" msgstr "Siirry profiiliin ja muihin navigointilinkkeihin" @@ -95,11 +95,11 @@ msgstr "Saavutettavuus" msgid "Account" msgstr "Tili" -#: src/view/com/profile/ProfileHeader.tsx:245 +#: src/view/com/profile/ProfileHeader.tsx:246 msgid "Account blocked" msgstr "Tili on estetty" -#: src/view/com/profile/ProfileHeader.tsx:212 +#: src/view/com/profile/ProfileHeader.tsx:213 msgid "Account muted" msgstr "Tili on hiljennetty" @@ -119,14 +119,15 @@ msgstr "Tilin asetukset" msgid "Account removed from quick access" msgstr "Tili poistettu pikalinkeistä" -#: src/view/com/profile/ProfileHeader.tsx:267 +#: src/view/com/profile/ProfileHeader.tsx:268 msgid "Account unblocked" msgstr "Tilin esto poistettu" -#: src/view/com/profile/ProfileHeader.tsx:225 +#: src/view/com/profile/ProfileHeader.tsx:226 msgid "Account unmuted" msgstr "Tilin hiljennys poistettu" +#: src/components/dialogs/MutedWords.tsx:147 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -168,24 +169,32 @@ msgstr "Lisää tiedot" msgid "Add details to report" msgstr "Lisää tiedot raporttiin" -#: src/view/com/composer/Composer.tsx:446 +#: src/view/com/composer/Composer.tsx:453 msgid "Add link card" msgstr "Lisää linkkikortti" -#: src/view/com/composer/Composer.tsx:451 +#: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" msgstr "Lisää linkkikortti:" +#: src/components/dialogs/MutedWords.tsx:140 +msgid "Add mute word for configured settings" +msgstr "Lisää hiljennetty sana määritettyihin asetuksiin" + +#: src/components/dialogs/MutedWords.tsx:74 +msgid "Add muted words and tags" +msgstr "Lisää hiljennetyt sanat ja tunnisteet" + #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" msgstr "Lisää seuraava DNS-merkintä verkkotunnukseesi:" -#: src/view/com/profile/ProfileHeader.tsx:309 +#: src/view/com/profile/ProfileHeader.tsx:310 msgid "Add to Lists" msgstr "Lisää listoihin" -#: src/view/com/feeds/FeedSourceCard.tsx:243 -#: src/view/screens/ProfileFeed.tsx:272 +#: src/view/com/feeds/FeedSourceCard.tsx:245 +#: src/view/screens/ProfileFeed.tsx:273 msgid "Add to my feeds" msgstr "Lisää syötteisiini" @@ -198,11 +207,11 @@ msgstr "Lisätty" msgid "Added to list" msgstr "Lisätty listaan" -#: src/view/com/feeds/FeedSourceCard.tsx:125 +#: src/view/com/feeds/FeedSourceCard.tsx:127 msgid "Added to my feeds" msgstr "Lisätty syötteisiini" -#: src/view/screens/PreferencesHomeFeed.tsx:173 +#: src/view/screens/PreferencesFollowingFeed.tsx:173 msgid "Adjust the number of likes a reply must have to be shown in your feed." msgstr "Säädä, kuinka monta tykkäystä vastauksen on saatava näkyäkseen syötteessäsi." @@ -299,7 +308,7 @@ msgstr "Sovelluksen salasanan asetukset" msgid "App Passwords" msgstr "Sovellussalasanat" -#: src/view/com/util/forms/PostDropdownBtn.tsx:250 +#: src/view/com/util/forms/PostDropdownBtn.tsx:295 msgid "Appeal content warning" msgstr "Valita sisältövaroituksesta" @@ -323,15 +332,16 @@ msgstr "Ulkonäkö" msgid "Are you sure you want to delete the app password \"{name}\"?" msgstr "Haluatko varmasti poistaa sovellussalasanan \"{name}\"?" -#: src/view/com/composer/Composer.tsx:143 +#: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" msgstr "Haluatko varmasti hylätä tämän luonnoksen?" -#: src/view/screens/ProfileList.tsx:364 +#: src/components/dialogs/MutedWords.tsx:233 +#: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" msgstr "Oletko varma?" -#: src/view/com/util/forms/PostDropdownBtn.tsx:233 +#: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Are you sure? This cannot be undone." msgstr "Oletko varma? Tätä ei voi perua." @@ -347,21 +357,21 @@ msgstr "Taide" msgid "Artistic or non-erotic nudity." msgstr "Taiteellinen tai ei-eroottinen alastomuus." -#: src/view/com/auth/create/CreateAccount.tsx:154 +#: src/view/com/auth/create/CreateAccount.tsx:158 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 #: src/view/com/auth/login/ForgotPasswordForm.tsx:174 #: src/view/com/auth/login/LoginForm.tsx:259 #: src/view/com/auth/login/SetNewPasswordForm.tsx:179 #: src/view/com/modals/report/InputIssueDetails.tsx:46 -#: src/view/com/post-thread/PostThread.tsx:471 -#: src/view/com/post-thread/PostThread.tsx:521 -#: src/view/com/post-thread/PostThread.tsx:529 -#: src/view/com/profile/ProfileHeader.tsx:648 +#: src/view/com/post-thread/PostThread.tsx:472 +#: src/view/com/post-thread/PostThread.tsx:522 +#: src/view/com/post-thread/PostThread.tsx:530 +#: src/view/com/profile/ProfileHeader.tsx:649 #: src/view/com/util/ViewHeader.tsx:81 msgid "Back" msgstr "Takaisin" -#: src/view/com/post-thread/PostThread.tsx:479 +#: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" msgstr "Takaisin" @@ -383,33 +393,33 @@ msgstr "Syntymäpäivä" msgid "Birthday:" msgstr "Syntymäpäivä:" -#: src/view/com/profile/ProfileHeader.tsx:238 -#: src/view/com/profile/ProfileHeader.tsx:345 +#: src/view/com/profile/ProfileHeader.tsx:239 +#: src/view/com/profile/ProfileHeader.tsx:346 msgid "Block Account" msgstr "Estä käyttäjä" -#: src/view/screens/ProfileList.tsx:555 +#: src/view/screens/ProfileList.tsx:556 msgid "Block accounts" msgstr "Estä käyttäjät" -#: src/view/screens/ProfileList.tsx:505 +#: src/view/screens/ProfileList.tsx:506 msgid "Block list" msgstr "Estettyjen lista" -#: src/view/screens/ProfileList.tsx:315 +#: src/view/screens/ProfileList.tsx:316 msgid "Block these accounts?" msgstr "Estetäänkö nämä käyttäjät?" -#: src/view/screens/ProfileList.tsx:319 +#: src/view/screens/ProfileList.tsx:320 msgid "Block this List" msgstr "Estä tämä lista" -#: src/view/com/lists/ListCard.tsx:109 -#: src/view/com/util/post-embeds/QuoteEmbed.tsx:60 +#: src/view/com/lists/ListCard.tsx:110 +#: src/view/com/util/post-embeds/QuoteEmbed.tsx:61 msgid "Blocked" msgstr "Estetty" -#: src/view/screens/Moderation.tsx:123 +#: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" msgstr "Estetyt käyttäjät" @@ -418,7 +428,7 @@ msgstr "Estetyt käyttäjät" msgid "Blocked Accounts" msgstr "Estetyt käyttäjät" -#: src/view/com/profile/ProfileHeader.tsx:240 +#: src/view/com/profile/ProfileHeader.tsx:241 msgid "Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you." msgstr "Estetyt käyttäjät eivät voi vastata viesteihisi, mainita sinua tai muuten olla vuorovaikutuksessa kanssasi." @@ -430,7 +440,7 @@ msgstr "Estetyt käyttäjät eivät voi vastata viesteihisi, mainita sinua tai m msgid "Blocked post." msgstr "Estetty viesti." -#: src/view/screens/ProfileList.tsx:317 +#: src/view/screens/ProfileList.tsx:318 msgid "Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you." msgstr "Estäminen on julkista. Estetyt käyttäjät eivät voi vastata viesteihisi, mainita sinua tai muuten olla vuorovaikutuksessa kanssasi." @@ -468,7 +478,7 @@ msgstr "Bluesky on julkinen." msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." msgstr "Bluesky käyttää kutsuja rakentaakseen terveellisemmän yhteisön. Jos et tunne ketään, jolla on kutsu, voit ilmoittautua odotuslistalle, niin lähetämme sinulle pian yhden." -#: src/view/screens/Moderation.tsx:226 +#: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "Bluesky ei näytä profiiliasi ja viestejäsi kirjautumattomille käyttäjille. Toiset sovellukset eivät ehkä noudata tätä asetusta. Tämä ei tee tilistäsi yksityistä." @@ -520,8 +530,8 @@ msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must msgstr "Voi sisältää vain kirjaimia, numeroita, välilyöntejä, viivoja ja alaviivoja. Täytyy olla vähintään 4 merkkiä pitkä, mutta enintään 32 merkkiä pitkä." #: src/components/Prompt.tsx:91 -#: src/view/com/composer/Composer.tsx:300 -#: src/view/com/composer/Composer.tsx:305 +#: src/view/com/composer/Composer.tsx:307 +#: src/view/com/composer/Composer.tsx:312 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 #: src/view/com/modals/ChangePassword.tsx:265 @@ -686,7 +696,7 @@ msgid "Clear all storage data (restart after this)" msgstr "Tyhjennä kaikki tallennukset (käynnistä uudelleen tämän jälkeen)" #: src/view/com/util/forms/SearchInput.tsx:88 -#: src/view/screens/Search/Search.tsx:674 +#: src/view/screens/Search/Search.tsx:697 msgid "Clear search query" msgstr "Tyhjennä hakukysely" @@ -694,6 +704,11 @@ msgstr "Tyhjennä hakukysely" msgid "click here" msgstr "klikkaa tästä" +#: src/components/RichText.tsx:189 +#: src/components/TagMenu/index.web.tsx:125 +msgid "Click here to open tag menu for {tag}" +msgstr "Avaa tästä valikko tunnisteelle {tag}" + #: src/screens/Onboarding/index.tsx:35 msgid "Climate" msgstr "Ilmasto" @@ -703,7 +718,8 @@ msgstr "Ilmasto" msgid "Close" msgstr "Sulje" -#: src/components/Dialog/index.web.tsx:78 +#: src/components/Dialog/index.web.tsx:80 +#: src/components/Dialog/index.web.tsx:194 msgid "Close active dialog" msgstr "Sulje aktiivinen ikkuna" @@ -723,11 +739,15 @@ msgstr "Sulje kuva" msgid "Close image viewer" msgstr "Sulje kuvankatselu" -#: src/view/shell/index.web.tsx:49 +#: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" msgstr "Sulje alanavigointi" -#: src/view/shell/index.web.tsx:50 +#: src/components/TagMenu/index.tsx:266 +msgid "Close this dialog" +msgstr "Sulje tämä valintaikkuna" + +#: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" msgstr "Sulkee alanavigaation" @@ -735,7 +755,7 @@ msgstr "Sulkee alanavigaation" msgid "Closes password update alert" msgstr "Sulkee salasanan päivitysilmoituksen" -#: src/view/com/composer/Composer.tsx:302 +#: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" msgstr "Sulkee editorin ja hylkää luonnoksen" @@ -768,7 +788,7 @@ msgstr "Suorita käyttöönotto loppuun ja aloita tilisi käyttö" msgid "Complete the challenge" msgstr "Tee haaste loppuun" -#: src/view/com/composer/Composer.tsx:417 +#: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" msgstr "Laadi viestejä, joiden pituus on enintään {MAX_GRAPHEME_LENGTH} merkkiä" @@ -785,7 +805,7 @@ msgstr "Määritä sisällönsuodatusasetus aiheille: {0}" #: src/view/com/modals/SelfLabel.tsx:154 #: src/view/com/modals/VerifyEmail.tsx:231 #: src/view/com/modals/VerifyEmail.tsx:233 -#: src/view/screens/PreferencesHomeFeed.tsx:308 +#: src/view/screens/PreferencesFollowingFeed.tsx:308 #: src/view/screens/PreferencesThreads.tsx:159 msgid "Confirm" msgstr "Vahvista" @@ -823,16 +843,16 @@ msgstr "Vahvistuskoodi" msgid "Confirms signing up {email} to the waitlist" msgstr "Vahvistaa sähköpostiosoitteen {email} - rekisteröinnin odotuslistalle" -#: src/view/com/auth/create/CreateAccount.tsx:189 +#: src/view/com/auth/create/CreateAccount.tsx:193 #: src/view/com/auth/login/LoginForm.tsx:278 msgid "Connecting..." msgstr "Yhdistetään..." -#: src/view/com/auth/create/CreateAccount.tsx:209 +#: src/view/com/auth/create/CreateAccount.tsx:213 msgid "Contact support" msgstr "Ota yhteyttä tukeen" -#: src/view/screens/Moderation.tsx:81 +#: src/view/screens/Moderation.tsx:83 msgid "Content filtering" msgstr "Sisällönsuodatus" @@ -862,7 +882,7 @@ msgstr "Sisältövaroitukset" #: src/screens/Onboarding/StepFollowingFeed.tsx:153 #: src/screens/Onboarding/StepInterests/index.tsx:248 #: src/screens/Onboarding/StepModeration/index.tsx:118 -#: src/screens/Onboarding/StepTopicalFeeds.tsx:108 +#: src/screens/Onboarding/StepTopicalFeeds.tsx:114 #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:148 #: src/view/com/auth/onboarding/RecommendedFollows.tsx:209 msgid "Continue" @@ -871,7 +891,7 @@ msgstr "Jatka" #: src/screens/Onboarding/StepFollowingFeed.tsx:150 #: src/screens/Onboarding/StepInterests/index.tsx:245 #: src/screens/Onboarding/StepModeration/index.tsx:115 -#: src/screens/Onboarding/StepTopicalFeeds.tsx:105 +#: src/screens/Onboarding/StepTopicalFeeds.tsx:111 msgid "Continue to next step" msgstr "Jatka seuraavaan vaiheeseen" @@ -898,7 +918,7 @@ msgstr "Ohjelmiston versio kopioitu leikepöydälle" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 -#: src/view/com/util/forms/PostDropdownBtn.tsx:112 +#: src/view/com/util/forms/PostDropdownBtn.tsx:143 msgid "Copied to clipboard" msgstr "Kopioitu leikepöydälle" @@ -910,19 +930,19 @@ msgstr "Kopioi sovellussalasanan" msgid "Copy" msgstr "Kopioi" -#: src/view/screens/ProfileList.tsx:417 +#: src/view/screens/ProfileList.tsx:418 msgid "Copy link to list" msgstr "Kopioi listan linkki" -#: src/view/com/util/forms/PostDropdownBtn.tsx:153 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 msgid "Copy link to post" msgstr "Kopioi julkaisun linkki" -#: src/view/com/profile/ProfileHeader.tsx:294 +#: src/view/com/profile/ProfileHeader.tsx:295 msgid "Copy link to profile" msgstr "Kopioi linkki profiiliin" -#: src/view/com/util/forms/PostDropdownBtn.tsx:139 +#: src/view/com/util/forms/PostDropdownBtn.tsx:170 msgid "Copy post text" msgstr "Kopioi viestin teksti" @@ -931,7 +951,7 @@ msgstr "Kopioi viestin teksti" msgid "Copyright Policy" msgstr "Tekijänoikeuskäytäntö" -#: src/view/screens/ProfileFeed.tsx:96 +#: src/view/screens/ProfileFeed.tsx:97 msgid "Could not load feed" msgstr "Syötettä ei voitu ladata" @@ -953,7 +973,7 @@ msgstr "Luo uusi tili" msgid "Create a new Bluesky account" msgstr "Luo uusi Bluesky-tili" -#: src/view/com/auth/create/CreateAccount.tsx:129 +#: src/view/com/auth/create/CreateAccount.tsx:133 msgid "Create Account" msgstr "Luo tili" @@ -978,7 +998,7 @@ msgstr "Luonut <0/>" msgid "Created by you" msgstr "Sinun luoma sisältö" -#: src/view/com/composer/Composer.tsx:448 +#: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" msgstr "Luo kortin pikkukuvan kanssa. Kortti linkittyy osoitteeseen {url}" @@ -1038,8 +1058,8 @@ msgstr "Poista käyttäjätili" msgid "Delete app password" msgstr "Poista sovellussalasana" -#: src/view/screens/ProfileList.tsx:363 -#: src/view/screens/ProfileList.tsx:444 +#: src/view/screens/ProfileList.tsx:364 +#: src/view/screens/ProfileList.tsx:445 msgid "Delete List" msgstr "Poista lista" @@ -1055,15 +1075,15 @@ msgstr "Poista käyttäjätilini" msgid "Delete My Account…" msgstr "Poista tilini…" -#: src/view/com/util/forms/PostDropdownBtn.tsx:228 +#: src/view/com/util/forms/PostDropdownBtn.tsx:273 msgid "Delete post" msgstr "Poista viesti" -#: src/view/com/util/forms/PostDropdownBtn.tsx:232 +#: src/view/com/util/forms/PostDropdownBtn.tsx:277 msgid "Delete this post?" msgstr "Poista tämä viesti?" -#: src/view/com/util/post-embeds/QuoteEmbed.tsx:69 +#: src/view/com/util/post-embeds/QuoteEmbed.tsx:70 msgid "Deleted" msgstr "Poistettu" @@ -1082,7 +1102,7 @@ msgstr "Kuvaus" #~ msgid "Developer Tools" #~ msgstr "" -#: src/view/com/composer/Composer.tsx:211 +#: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" msgstr "Haluatko sanoa jotain?" @@ -1090,15 +1110,15 @@ msgstr "Haluatko sanoa jotain?" msgid "Dim" msgstr "Himmeä" -#: src/view/com/composer/Composer.tsx:144 +#: src/view/com/composer/Composer.tsx:151 msgid "Discard" msgstr "Hylkää" -#: src/view/com/composer/Composer.tsx:138 +#: src/view/com/composer/Composer.tsx:145 msgid "Discard draft" msgstr "Hylkää luonnos" -#: src/view/screens/Moderation.tsx:207 +#: src/view/screens/Moderation.tsx:226 msgid "Discourage apps from showing my account to logged-out users" msgstr "Estä sovelluksia näyttämästä tiliäni kirjautumattomille käyttäjille" @@ -1154,7 +1174,7 @@ msgstr "Valmis" #: src/view/com/modals/InviteCodes.tsx:80 #: src/view/com/modals/InviteCodes.tsx:123 #: src/view/com/modals/ListAddRemoveUsers.tsx:142 -#: src/view/screens/PreferencesHomeFeed.tsx:311 +#: src/view/screens/PreferencesFollowingFeed.tsx:311 #: src/view/screens/Settings/ExportCarDialog.tsx:93 #: src/view/screens/Settings/ExportCarDialog.tsx:94 msgid "Done" @@ -1177,7 +1197,7 @@ msgstr "Lataa Bluesky-tilin tiedot (repository)" msgid "Download CAR file" msgstr "Lataa CAR tiedosto" -#: src/view/com/composer/text-input/TextInput.web.tsx:247 +#: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" msgstr "Raahaa tähän lisätäksesi kuvia" @@ -1223,7 +1243,7 @@ msgstr "Muokkaa" msgid "Edit image" msgstr "Muokkaa kuvaa" -#: src/view/screens/ProfileList.tsx:432 +#: src/view/screens/ProfileList.tsx:433 msgid "Edit list details" msgstr "Muokkaa listan tietoja" @@ -1241,14 +1261,15 @@ msgstr "Muokkaa syötteitäni" msgid "Edit my profile" msgstr "Muokkaa profiiliani" -#: src/view/com/profile/ProfileHeader.tsx:417 +#: src/view/com/profile/ProfileHeader.tsx:418 msgid "Edit profile" msgstr "Muokkaa profiilia" -#: src/view/com/profile/ProfileHeader.tsx:422 +#: src/view/com/profile/ProfileHeader.tsx:423 msgid "Edit Profile" msgstr "Muokkaa profiilia" +#: src/view/com/home/HomeHeaderLayout.web.tsx:59 #: src/view/screens/Feeds.tsx:355 msgid "Edit Saved Feeds" msgstr "Muokkaa tallennettuja syötteitä" @@ -1319,7 +1340,7 @@ msgstr "Ota ulkoinen media käyttöön" msgid "Enable media players for" msgstr "Ota mediatoistimet käyttöön kohteille" -#: src/view/screens/PreferencesHomeFeed.tsx:147 +#: src/view/screens/PreferencesFollowingFeed.tsx:147 msgid "Enable this setting to only see replies between people you follow." msgstr "Ota tämä asetus käyttöön nähdäksesi vastaukset vain seuraamiltasi ihmisiltä." @@ -1329,7 +1350,12 @@ msgstr "Syötteen loppu" #: src/view/com/modals/AddAppPasswords.tsx:166 msgid "Enter a name for this App Password" -msgstr "Anna nimi tälle sovellussalasanalle" +msgstr "Anna sovellusalasanalle nimi" + +#: src/components/dialogs/MutedWords.tsx:87 +#: src/components/dialogs/MutedWords.tsx:88 +msgid "Enter a word or tag" +msgstr "Kirjoita sana tai tunniste" #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" @@ -1380,7 +1406,7 @@ msgstr "Syötä käyttäjätunnuksesi ja salasanasi" msgid "Error receiving captcha response." msgstr "Virhe captcha-vastauksen vastaanottamisessa." -#: src/view/screens/Search/Search.tsx:109 +#: src/view/screens/Search/Search.tsx:110 msgid "Error:" msgstr "Virhe:" @@ -1432,7 +1458,7 @@ msgstr "Ulkoiset mediat" msgid "External media may allow websites to collect information about you and your device. No information is sent or requested until you press the \"play\" button." msgstr "Ulkoiset mediat voivat sallia verkkosivustojen kerätä tietoja sinusta ja laitteestasi. Tietoja ei lähetetä eikä pyydetä, ennen kuin painat \"toista\"-painiketta." -#: src/Navigation.tsx:258 +#: src/Navigation.tsx:261 #: src/view/screens/PreferencesExternalEmbeds.tsx:52 #: src/view/screens/Settings/index.tsx:657 msgid "External Media Preferences" @@ -1451,7 +1477,7 @@ msgstr "Sovellussalasanan luominen epäonnistui." msgid "Failed to create the list. Check your internet connection and try again." msgstr "Listan luominen epäonnistui. Tarkista internetyhteytesi ja yritä uudelleen." -#: src/view/com/util/forms/PostDropdownBtn.tsx:88 +#: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Failed to delete post, please try again" msgstr "Viestin poistaminen epäonnistui, yritä uudelleen" @@ -1464,7 +1490,7 @@ msgstr "Suositeltujen syötteiden lataaminen epäonnistui" msgid "Feed" msgstr "Syöte" -#: src/view/com/feeds/FeedSourceCard.tsx:229 +#: src/view/com/feeds/FeedSourceCard.tsx:231 msgid "Feed by {0}" msgstr "Syöte käyttäjältä {0}" @@ -1473,8 +1499,8 @@ msgid "Feed offline" msgstr "Syöte ei ole käytettävissä" #: src/view/com/feeds/FeedPage.tsx:143 -msgid "Feed Preferences" -msgstr "Syötteen asetukset" +#~ msgid "Feed Preferences" +#~ msgstr "Syötteen asetukset" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 @@ -1508,7 +1534,7 @@ msgstr "Käyttäjät luovat syötteitä sisällön kuratointiin. Valitse joitaki msgid "Feeds are custom algorithms that users build with a little coding expertise. <0/> for more information." msgstr "Syötteet ovat käyttäjien rakentamia mukautettuja algoritmeja, jotka vaativat vain vähän koodaustaitoja. <0/> lisätietoa varten." -#: src/screens/Onboarding/StepTopicalFeeds.tsx:70 +#: src/screens/Onboarding/StepTopicalFeeds.tsx:76 msgid "Feeds can be topical as well!" msgstr "Syötteet voivat olla myös aihepiirikohtaisia!" @@ -1522,21 +1548,25 @@ msgstr "Viimeistely" msgid "Find accounts to follow" msgstr "Etsi seurattavia tilejä" -#: src/view/screens/Search/Search.tsx:439 +#: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" msgstr "Etsi käyttäjiä Bluesky-palvelusta" -#: src/view/screens/Search/Search.tsx:437 +#: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" msgstr "Etsi käyttäjiä oikealla olevan hakutyökalun avulla" #: src/view/com/auth/onboarding/RecommendedFollowsItem.tsx:150 msgid "Finding similar accounts..." -msgstr "Etsitään samankaltaisia tilejä..." +msgstr "Etsitään samankaltaisia käyttäjätilejä" + +#: src/view/screens/PreferencesFollowingFeed.tsx:111 +msgid "Fine-tune the content you see on your Following feed." +msgstr "Hienosäädä näkemääsi sisältöä Seuraavat-syötteessäsi." #: src/view/screens/PreferencesHomeFeed.tsx:111 -msgid "Fine-tune the content you see on your home screen." -msgstr "Hienosäädä näkemääsi sisältöä pääsivulla." +#~ msgid "Fine-tune the content you see on your home screen." +#~ msgstr "Hienosäädä näkemääsi sisältöä pääsivulla." #: src/view/screens/PreferencesThreads.tsx:60 msgid "Fine-tune the discussion threads." @@ -1561,7 +1591,7 @@ msgstr "Käännä pystysuunnassa" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:181 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:136 -#: src/view/com/profile/ProfileHeader.tsx:512 +#: src/view/com/profile/ProfileHeader.tsx:513 msgid "Follow" msgstr "Seuraa" @@ -1572,7 +1602,7 @@ msgstr "Seuraa" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:58 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:122 -#: src/view/com/profile/ProfileHeader.tsx:503 +#: src/view/com/profile/ProfileHeader.tsx:504 msgid "Follow {0}" msgstr "Seuraa {0}" @@ -1596,7 +1626,7 @@ msgstr "Seuraajina {0}" msgid "Followed users" msgstr "Seuratut käyttäjät" -#: src/view/screens/PreferencesHomeFeed.tsx:154 +#: src/view/screens/PreferencesFollowingFeed.tsx:154 msgid "Followed users only" msgstr "Vain seuratut käyttäjät" @@ -1609,16 +1639,24 @@ msgid "Followers" msgstr "Seuraajat" #: src/view/com/post-thread/PostThreadFollowBtn.tsx:136 -#: src/view/com/profile/ProfileHeader.tsx:494 +#: src/view/com/profile/ProfileHeader.tsx:495 #: src/view/screens/ProfileFollows.tsx:25 msgid "Following" msgstr "Seuraa" -#: src/view/com/profile/ProfileHeader.tsx:148 +#: src/view/com/profile/ProfileHeader.tsx:149 msgid "Following {0}" msgstr "Seuraa {0}" -#: src/view/com/profile/ProfileHeader.tsx:545 +#: src/Navigation.tsx:248 +#: src/view/com/home/HomeHeaderLayout.web.tsx:45 +#: src/view/com/home/HomeHeaderLayoutMobile.tsx:83 +#: src/view/screens/PreferencesFollowingFeed.tsx:104 +#: src/view/screens/Settings/index.tsx:543 +msgid "Following Feed Preferences" +msgstr "Seuratut -syötteen asetukset" + +#: src/view/com/profile/ProfileHeader.tsx:546 msgid "Follows you" msgstr "Seuraa sinua" @@ -1651,7 +1689,7 @@ msgstr "Unohtunut salasana" msgid "Forgot Password" msgstr "Unohtunut salasana" -#: src/view/com/posts/FeedItem.tsx:186 +#: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" msgstr "Lähde: <0/>" @@ -1672,8 +1710,8 @@ msgstr "Aloita tästä" msgid "Go back" msgstr "Palaa takaisin" -#: src/view/screens/ProfileFeed.tsx:105 -#: src/view/screens/ProfileFeed.tsx:110 +#: src/view/screens/ProfileFeed.tsx:106 +#: src/view/screens/ProfileFeed.tsx:111 #: src/view/screens/ProfileList.tsx:897 #: src/view/screens/ProfileList.tsx:902 msgid "Go Back" @@ -1684,7 +1722,7 @@ msgstr "Palaa takaisin" msgid "Go back to previous step" msgstr "Palaa edelliseen vaiheeseen" -#: src/view/screens/Search/Search.tsx:724 +#: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" msgstr "Siirry @{queryMaybeHandle}" @@ -1701,7 +1739,11 @@ msgstr "Siirry seuraavaan" msgid "Handle" msgstr "Käyttäjätunnus" -#: src/view/com/auth/create/CreateAccount.tsx:204 +#: src/components/RichText.tsx:188 +msgid "Hashtag: {tag}" +msgstr "Tunniste: {tag}" + +#: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" msgstr "Ongelmia?" @@ -1714,11 +1756,11 @@ msgstr "Ohje" msgid "Here are some accounts for you to follow" msgstr "Tässä on joitakin tilejä seurattavaksi" -#: src/screens/Onboarding/StepTopicalFeeds.tsx:79 +#: src/screens/Onboarding/StepTopicalFeeds.tsx:85 msgid "Here are some popular topical feeds. You can choose to follow as many as you like." msgstr "Tässä on joitakin suosittuja aihepiirikohtaisia syötteitä. Voit valita seurattavaksi niin monta kuin haluat." -#: src/screens/Onboarding/StepTopicalFeeds.tsx:74 +#: src/screens/Onboarding/StepTopicalFeeds.tsx:80 msgid "Here are some topical feeds based on your interests: {interestsText}. You can choose to follow as many as you like." msgstr "Tässä on joitakin aihepiirikohtaisia syötteitä kiinnostuksiesi perusteella: {interestsText}. Voit valita seurata niin montaa kuin haluat." @@ -1739,7 +1781,7 @@ msgctxt "action" msgid "Hide" msgstr "Piilota" -#: src/view/com/util/forms/PostDropdownBtn.tsx:187 +#: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Hide post" msgstr "Piilota viesti" @@ -1748,7 +1790,7 @@ msgstr "Piilota viesti" msgid "Hide the content" msgstr "Piilota sisältö" -#: src/view/com/util/forms/PostDropdownBtn.tsx:191 +#: src/view/com/util/forms/PostDropdownBtn.tsx:236 msgid "Hide this post?" msgstr "Piilota tämä viesti?" @@ -1756,7 +1798,7 @@ msgstr "Piilota tämä viesti?" msgid "Hide user list" msgstr "Piilota käyttäjäluettelo" -#: src/view/com/profile/ProfileHeader.tsx:486 +#: src/view/com/profile/ProfileHeader.tsx:487 msgid "Hides posts from {0} in your feed" msgstr "Piilottaa viestit käyttäjältä {0} syötteessäsi" @@ -1780,7 +1822,7 @@ msgstr "Hmm, syötteen palvelin antoi virheellisen vastauksen. Ilmoita asiasta s msgid "Hmm, we're having trouble finding this feed. It may have been deleted." msgstr "Hmm, meillä on vaikeuksia löytää tätä syötettä. Se saattaa olla poistettu." -#: src/Navigation.tsx:432 +#: src/Navigation.tsx:435 #: src/view/shell/bottom-bar/BottomBar.tsx:137 #: src/view/shell/desktop/LeftNav.tsx:306 #: src/view/shell/Drawer.tsx:398 @@ -1792,8 +1834,8 @@ msgstr "Koti" #: src/view/com/pager/FeedsTabBarMobile.tsx:123 #: src/view/screens/PreferencesHomeFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 -msgid "Home Feed Preferences" -msgstr "Aloitussivun syötteiden asetukset" +#~ msgid "Home Feed Preferences" +#~ msgstr "Aloitussivun syötteiden asetukset" #: src/view/com/auth/create/Step1.tsx:82 #: src/view/com/auth/login/ForgotPasswordForm.tsx:120 @@ -1893,11 +1935,11 @@ msgstr "Syötä sähköpostiosoitteesi päästäksesi Bluesky-jonoon" msgid "Input your password" msgstr "Syötä salasanasi" -#: src/view/com/auth/create/Step2.tsx:45 +#: src/view/com/auth/create/Step2.tsx:80 msgid "Input your user handle" msgstr "Syötä käyttäjätunnuksesi" -#: src/view/com/post-thread/PostThreadItem.tsx:223 +#: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" msgstr "Virheellinen tai ei tuettu tietue" @@ -1999,7 +2041,7 @@ msgstr "Lue lisää" msgid "Learn more about this warning" msgstr "Lue lisää tästä varoituksesta" -#: src/view/screens/Moderation.tsx:243 +#: src/view/screens/Moderation.tsx:262 msgid "Learn more about what is public on Bluesky." msgstr "Lue lisää siitä, mikä on julkista Blueskyssa." @@ -2055,7 +2097,7 @@ msgstr "Tykänneet" msgid "Liked By" msgstr "Tykänneet" -#: src/view/com/feeds/FeedSourceCard.tsx:277 +#: src/view/com/feeds/FeedSourceCard.tsx:279 msgid "Liked by {0} {1}" msgstr "Tykänneet {0} {1}" @@ -2075,7 +2117,7 @@ msgstr "tykkäsi viestistäsi" msgid "Likes" msgstr "Tykkäykset" -#: src/view/com/post-thread/PostThreadItem.tsx:180 +#: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" msgstr "Tykkäykset tässä viestissä" @@ -2087,19 +2129,19 @@ msgstr "Lista" msgid "List Avatar" msgstr "Listan kuvake" -#: src/view/screens/ProfileList.tsx:323 +#: src/view/screens/ProfileList.tsx:324 msgid "List blocked" msgstr "Lista estetty" -#: src/view/com/feeds/FeedSourceCard.tsx:231 +#: src/view/com/feeds/FeedSourceCard.tsx:233 msgid "List by {0}" msgstr "Listan on luonut {0}" -#: src/view/screens/ProfileList.tsx:377 +#: src/view/screens/ProfileList.tsx:378 msgid "List deleted" msgstr "Lista poistettu" -#: src/view/screens/ProfileList.tsx:282 +#: src/view/screens/ProfileList.tsx:283 msgid "List muted" msgstr "Lista hiljennetty" @@ -2107,11 +2149,11 @@ msgstr "Lista hiljennetty" msgid "List Name" msgstr "Listan nimi" -#: src/view/screens/ProfileList.tsx:342 +#: src/view/screens/ProfileList.tsx:343 msgid "List unblocked" msgstr "Listaa estosta poistetut" -#: src/view/screens/ProfileList.tsx:301 +#: src/view/screens/ProfileList.tsx:302 msgid "List unmuted" msgstr "Listaa hiljennyksestä poistetut" @@ -2132,10 +2174,10 @@ msgstr "Lataa lisää viestejä" msgid "Load new notifications" msgstr "Lataa uusia ilmoituksia" -#: src/view/com/feeds/FeedPage.tsx:181 +#: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 -#: src/view/screens/ProfileFeed.tsx:494 -#: src/view/screens/ProfileList.tsx:680 +#: src/view/screens/ProfileFeed.tsx:495 +#: src/view/screens/ProfileList.tsx:681 msgid "Load new posts" msgstr "Lataa uusia viestejä" @@ -2158,7 +2200,7 @@ msgstr "Loki" msgid "Log out" msgstr "Kirjaudu ulos" -#: src/view/screens/Moderation.tsx:136 +#: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" msgstr "Näkyvyys kirjautumattomana" @@ -2170,6 +2212,18 @@ msgstr "Kirjaudu tiliin, joka ei ole luettelossa" msgid "Make sure this is where you intend to go!" msgstr "Varmista, että olet menossa oikeaan paikkaan!" +#: src/components/dialogs/MutedWords.tsx:71 +msgid "Manage your muted words and tags" +msgstr "Hallinnoi hiljennettyjä sanojasi ja tunnisteitasi" + +#: src/view/com/auth/create/Step2.tsx:118 +msgid "May not be longer than 253 characters" +msgstr "Ei saa olla pidempi kuin 253 merkkiä" + +#: src/view/com/auth/create/Step2.tsx:109 +msgid "May only contain letters and numbers" +msgstr "Ei saa olla pidempi kuin 253 merkkiä" + #: src/view/screens/Profile.tsx:182 msgid "Media" msgstr "Media" @@ -2192,7 +2246,7 @@ msgid "Message from server: {0}" msgstr "Viesti palvelimelta: {0}" #: src/Navigation.tsx:115 -#: src/view/screens/Moderation.tsx:64 +#: src/view/screens/Moderation.tsx:66 #: src/view/screens/Settings/index.tsx:625 #: src/view/shell/desktop/LeftNav.tsx:397 #: src/view/shell/Drawer.tsx:511 @@ -2200,7 +2254,7 @@ msgstr "Viesti palvelimelta: {0}" msgid "Moderation" msgstr "Moderointi" -#: src/view/com/lists/ListCard.tsx:92 +#: src/view/com/lists/ListCard.tsx:93 #: src/view/com/modals/UserAddRemoveLists.tsx:206 msgid "Moderation list by {0}" msgstr "Moderointilista käyttäjältä {0}" @@ -2209,7 +2263,7 @@ msgstr "Moderointilista käyttäjältä {0}" msgid "Moderation list by <0/>" msgstr "Moderointilista käyttäjältä <0/>" -#: src/view/com/lists/ListCard.tsx:90 +#: src/view/com/lists/ListCard.tsx:91 #: src/view/com/modals/UserAddRemoveLists.tsx:204 #: src/view/screens/ProfileList.tsx:772 msgid "Moderation list by you" @@ -2223,7 +2277,7 @@ msgstr "Moderointilista luotu" msgid "Moderation list updated" msgstr "Moderointilista päivitetty" -#: src/view/screens/Moderation.tsx:95 +#: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" msgstr "Moderointilistat" @@ -2244,13 +2298,13 @@ msgstr "Ylläpitäjä on asettanut yleisen varoituksen sisällölle." msgid "More feeds" msgstr "Lisää syötteitä" -#: src/view/com/profile/ProfileHeader.tsx:522 -#: src/view/screens/ProfileFeed.tsx:362 -#: src/view/screens/ProfileList.tsx:616 +#: src/view/com/profile/ProfileHeader.tsx:523 +#: src/view/screens/ProfileFeed.tsx:363 +#: src/view/screens/ProfileList.tsx:617 msgid "More options" msgstr "Lisää asetuksia" -#: src/view/com/util/forms/PostDropdownBtn.tsx:270 +#: src/view/com/util/forms/PostDropdownBtn.tsx:315 msgid "More post options" msgstr "Lisää viestiasetuksia" @@ -2258,35 +2312,70 @@ msgstr "Lisää viestiasetuksia" msgid "Most-liked replies first" msgstr "Eniten tykätyt vastaukset ensin" -#: src/view/com/profile/ProfileHeader.tsx:326 +#: src/view/com/auth/create/Step2.tsx:122 +msgid "Must be at least 3 characters" +msgstr "Täytyy olla vähintään 3 merkkiä" + +#: src/components/TagMenu/index.tsx:253 +msgid "Mute" +msgstr "Hiljennä" + +#: src/components/TagMenu/index.web.tsx:91 +msgid "Mute {truncatedTag}" +msgstr "Hiljennä {truncatedTag}" + +#: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" msgstr "Hiljennä käyttäjä" -#: src/view/screens/ProfileList.tsx:543 +#: src/view/screens/ProfileList.tsx:544 msgid "Mute accounts" msgstr "Hiljennä käyttäjät" +#: src/components/TagMenu/index.tsx:211 +msgid "Mute all {tag} posts" +msgstr "Hiljennä kaikki {tag}-viestit" -#: src/view/screens/ProfileList.tsx:490 +#: src/components/dialogs/MutedWords.tsx:131 +msgid "Mute in tags only" +msgstr "Hiljennä vain tunnisteissa" + +#: src/components/dialogs/MutedWords.tsx:116 +msgid "Mute in text & tags" +msgstr "Hiljennä tekstissä ja tunnisteissa" + +#: src/view/screens/ProfileList.tsx:491 msgid "Mute list" msgstr "Hiljennä lista" -#: src/view/screens/ProfileList.tsx:274 +#: src/view/screens/ProfileList.tsx:275 msgid "Mute these accounts?" msgstr "Hiljennä nämä käyttäjät?" -#: src/view/screens/ProfileList.tsx:278 +#: src/view/screens/ProfileList.tsx:279 msgid "Mute this List" msgstr "Hiljennä tämä lista" -#: src/view/com/util/forms/PostDropdownBtn.tsx:171 -msgid "Mute thread" -msgstr "Hiljennäkeskustelu" +#: src/components/dialogs/MutedWords.tsx:109 +msgid "Mute this word in post text and tags" +msgstr "Hiljennä tämä sana viesteissä ja tunnisteissa" -#: src/view/com/lists/ListCard.tsx:101 +#: src/components/dialogs/MutedWords.tsx:124 +msgid "Mute this word in tags only" +msgstr "Hiljennä tämä sana vain tunnisteissa" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 +msgid "Mute thread" +msgstr "Hiljennä keskustelu" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +msgid "Mute words & tags" +msgstr "Hiljennä sanat ja tunnisteet" + +#: src/view/com/lists/ListCard.tsx:102 msgid "Muted" msgstr "Hiljennetty" -#: src/view/screens/Moderation.tsx:109 +#: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" msgstr "Hiljennetyt käyttäjät" @@ -2299,7 +2388,11 @@ msgstr "Hiljennetyt käyttäjätilit" msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." msgstr "Hiljennettyjen käyttäjien viestit poistetaan syötteestäsi ja ilmoituksistasi. Hiljennykset ovat täysin yksityisiä." -#: src/view/screens/ProfileList.tsx:276 +#: src/view/screens/Moderation.tsx:100 +msgid "Muted words & tags" +msgstr "Hiljennetyt sanat ja tunnisteet" + +#: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "Hiljennys on yksityinen. Hiljennetyt käyttäjät voivat edelleen vuorovaikuttaa kanssasi, mutta et näe heidän viestejään tai saa ilmoituksia heiltä." @@ -2362,6 +2455,10 @@ msgstr "Älä koskaan menetä pääsyä seuraajiisi ja tietoihisi." msgid "Never lose access to your followers or data." msgstr "Älä koskaan menetä pääsyä seuraajiisi tai tietoihisi." +#: src/components/dialogs/MutedWords.tsx:244 +msgid "Nevermind" +msgstr "Ei väliä" + #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" @@ -2383,7 +2480,7 @@ msgstr "Uusi salasana" msgid "New Password" msgstr "Uusi salasana" -#: src/view/com/feeds/FeedPage.tsx:192 +#: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" msgstr "Uusi viesti" @@ -2391,9 +2488,9 @@ msgstr "Uusi viesti" #: src/view/screens/Feeds.tsx:555 #: src/view/screens/Notifications.tsx:168 #: src/view/screens/Profile.tsx:382 -#: src/view/screens/ProfileFeed.tsx:432 -#: src/view/screens/ProfileList.tsx:195 -#: src/view/screens/ProfileList.tsx:223 +#: src/view/screens/ProfileFeed.tsx:433 +#: src/view/screens/ProfileList.tsx:196 +#: src/view/screens/ProfileList.tsx:224 #: src/view/shell/desktop/LeftNav.tsx:248 msgid "New post" msgstr "Uusi viesti" @@ -2415,7 +2512,7 @@ msgstr "Uusimmat vastaukset ensin" msgid "News" msgstr "Uutiset" -#: src/view/com/auth/create/CreateAccount.tsx:168 +#: src/view/com/auth/create/CreateAccount.tsx:172 #: src/view/com/auth/login/ForgotPasswordForm.tsx:182 #: src/view/com/auth/login/ForgotPasswordForm.tsx:192 #: src/view/com/auth/login/LoginForm.tsx:291 @@ -2436,10 +2533,10 @@ msgstr "Seuraava" msgid "Next image" msgstr "Seuraava kuva" -#: src/view/screens/PreferencesHomeFeed.tsx:129 -#: src/view/screens/PreferencesHomeFeed.tsx:200 -#: src/view/screens/PreferencesHomeFeed.tsx:235 -#: src/view/screens/PreferencesHomeFeed.tsx:272 +#: src/view/screens/PreferencesFollowingFeed.tsx:129 +#: src/view/screens/PreferencesFollowingFeed.tsx:200 +#: src/view/screens/PreferencesFollowingFeed.tsx:235 +#: src/view/screens/PreferencesFollowingFeed.tsx:272 #: src/view/screens/PreferencesThreads.tsx:106 #: src/view/screens/PreferencesThreads.tsx:129 msgid "No" @@ -2450,7 +2547,7 @@ msgstr "Ei" msgid "No description" msgstr "Ei kuvausta" -#: src/view/com/profile/ProfileHeader.tsx:169 +#: src/view/com/profile/ProfileHeader.tsx:170 msgid "No longer following {0}" msgstr "Et enää seuraa käyttäjää {0}" @@ -2468,8 +2565,8 @@ msgid "No results found for \"{query}\"" msgstr "Ei tuloksia haulle \"{query}\"" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 -#: src/view/screens/Search/Search.tsx:280 -#: src/view/screens/Search/Search.tsx:308 +#: src/view/screens/Search/Search.tsx:281 +#: src/view/screens/Search/Search.tsx:309 msgid "No results found for {query}" msgstr "Ei tuloksia haulle {query}" @@ -2495,11 +2592,11 @@ msgstr "Ei löytynyt" msgid "Not right now" msgstr "Ei juuri nyt" -#: src/view/screens/Moderation.tsx:233 +#: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "Huomio: Bluesky on avoin ja julkinen verkosto. Tämä asetus rajoittaa vain sisältösi näkyvyyttä Bluesky-sovelluksessa ja -sivustolla, eikä muut sovellukset ehkä kunnioita tässä asetuksissaan. Sisältösi voi silti näkyä uloskirjautuneille käyttäjille muissa sovelluksissa ja verkkosivustoilla." -#: src/Navigation.tsx:447 +#: src/Navigation.tsx:450 #: src/view/screens/Notifications.tsx:124 #: src/view/screens/Notifications.tsx:148 #: src/view/shell/bottom-bar/BottomBar.tsx:205 @@ -2533,7 +2630,7 @@ msgstr "Vanhimmat vastaukset ensin" msgid "Onboarding reset" msgstr "Käyttöönoton nollaus" -#: src/view/com/composer/Composer.tsx:375 +#: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." msgstr "Yksi tai useampi kuva on ilman vaihtoehtoista Alt-tekstiä." @@ -2550,8 +2647,12 @@ msgstr "Hups!" msgid "Open" msgstr "Avaa" -#: src/view/com/composer/Composer.tsx:470 -#: src/view/com/composer/Composer.tsx:471 +#: src/view/screens/Moderation.tsx:75 +msgid "Open content filtering settings" +msgstr "Avaa sisällönsuodatusasetukset" + +#: src/view/com/composer/Composer.tsx:477 +#: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" msgstr "Avaa emoji-valitsin" @@ -2559,7 +2660,11 @@ msgstr "Avaa emoji-valitsin" msgid "Open links with in-app browser" msgstr "Avaa linkit sovelluksen sisäisellä selaimella" -#: src/view/com/pager/FeedsTabBarMobile.tsx:87 +#: src/view/screens/Moderation.tsx:92 +msgid "Open muted words settings" +msgstr "Avaa hiljennettyjen sanojen asetukset" + +#: src/view/com/home/HomeHeaderLayoutMobile.tsx:49 msgid "Open navigation" msgstr "Avaa navigointi" @@ -2595,7 +2700,7 @@ msgstr "Avaa mukautettavat kielen asetukset" msgid "Opens device photo gallery" msgstr "Avaa laitteen valokuvat" -#: src/view/com/profile/ProfileHeader.tsx:419 +#: src/view/com/profile/ProfileHeader.tsx:420 msgid "Opens editor for profile display name, avatar, background image, and description" msgstr "Avaa editorin profiilin näyttönimeä, avataria, taustakuvaa ja kuvausta varten" @@ -2603,11 +2708,11 @@ msgstr "Avaa editorin profiilin näyttönimeä, avataria, taustakuvaa ja kuvaust msgid "Opens external embeds settings" msgstr "Avaa ulkoiset upotusasetukset" -#: src/view/com/profile/ProfileHeader.tsx:574 +#: src/view/com/profile/ProfileHeader.tsx:575 msgid "Opens followers list" msgstr "Avaa seuraajalistan" -#: src/view/com/profile/ProfileHeader.tsx:593 +#: src/view/com/profile/ProfileHeader.tsx:594 msgid "Opens following list" msgstr "Avaa seurattavien listan" @@ -2635,6 +2740,7 @@ msgstr "Avaa moderointiasetukset" msgid "Opens password reset form" msgstr "Avaa salasanan palautuslomakkeen" +#: src/view/com/home/HomeHeaderLayout.web.tsx:60 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" msgstr "Avaa näkymän tallennettujen syötteiden muokkaamiseen" @@ -2735,8 +2841,8 @@ msgstr "Lemmikit" msgid "Pictures meant for adults." msgstr "Aikuisille tarkoitetut kuvat." -#: src/view/screens/ProfileFeed.tsx:353 -#: src/view/screens/ProfileList.tsx:580 +#: src/view/screens/ProfileFeed.tsx:354 +#: src/view/screens/ProfileList.tsx:581 msgid "Pin to home" msgstr "Kiinnitä etusivulle" @@ -2815,7 +2921,7 @@ msgstr "Kerro meille, miksi luulet, että tämä sisältövaroitus on sovellettu msgid "Please Verify Your Email" msgstr "Vahvista sähköpostiosoitteesi" -#: src/view/com/composer/Composer.tsx:215 +#: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" msgstr "Odota, että linkkikortti latautuu kokonaan" @@ -2827,8 +2933,8 @@ msgstr "Politiikka" msgid "Porn" msgstr "Porno" -#: src/view/com/composer/Composer.tsx:350 -#: src/view/com/composer/Composer.tsx:358 +#: src/view/com/composer/Composer.tsx:357 +#: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" msgstr "Lähetä" @@ -2838,7 +2944,7 @@ msgctxt "description" msgid "Post" msgstr "Viesti" -#: src/view/com/post-thread/PostThreadItem.tsx:172 +#: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" msgstr "Lähettäjä {0}" @@ -2848,11 +2954,11 @@ msgstr "Lähettäjä {0}" msgid "Post by @{0}" msgstr "Lähettäjä @{0}" -#: src/view/com/util/forms/PostDropdownBtn.tsx:84 +#: src/view/com/util/forms/PostDropdownBtn.tsx:90 msgid "Post deleted" msgstr "Viesti poistettu" -#: src/view/com/post-thread/PostThread.tsx:461 +#: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" msgstr "Viesti piilotettu" @@ -2864,14 +2970,22 @@ msgstr "Lähetyskieli" msgid "Post Languages" msgstr "Lähetyskielet" -#: src/view/com/post-thread/PostThread.tsx:513 +#: src/view/com/post-thread/PostThread.tsx:514 msgid "Post not found" msgstr "Viestiä ei löydy" +#: src/components/TagMenu/index.tsx:257 +msgid "posts" +msgstr "viestit" + #: src/view/screens/Profile.tsx:180 msgid "Posts" msgstr "Viestit" +#: src/components/dialogs/MutedWords.tsx:77 +msgid "Posts can be muted based on their text, their tags, or both." +msgstr "Viestejä voidaan hiljentää niiden tekstin, tunnisteiden tai molempien perusteella." + #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" msgstr "Piilotetut viestit" @@ -2936,11 +3050,11 @@ msgstr "Julkinen, jaettava käyttäjäluettelo hiljennettyjen tai estettyjen kä msgid "Public, shareable lists which can drive feeds." msgstr "Julkinen, jaettava lista, joka voi ohjata syötteitä." -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish post" msgstr "Julkaise viesti" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" msgstr "Julkaise vastaus" @@ -2974,6 +3088,7 @@ msgstr "Suositellut syötteet" msgid "Recommended Users" msgstr "Suositellut käyttäjät" +#: src/components/dialogs/MutedWords.tsx:249 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -2982,7 +3097,7 @@ msgstr "Suositellut käyttäjät" msgid "Remove" msgstr "Poista" -#: src/view/com/feeds/FeedSourceCard.tsx:106 +#: src/view/com/feeds/FeedSourceCard.tsx:108 msgid "Remove {0} from my feeds?" msgstr "Poistetaanko {0} syötteistäni?" @@ -2995,11 +3110,11 @@ msgstr "Poista tili" msgid "Remove feed" msgstr "Poista syöte" -#: src/view/com/feeds/FeedSourceCard.tsx:105 -#: src/view/com/feeds/FeedSourceCard.tsx:167 -#: src/view/com/feeds/FeedSourceCard.tsx:172 -#: src/view/com/feeds/FeedSourceCard.tsx:243 -#: src/view/screens/ProfileFeed.tsx:272 +#: src/view/com/feeds/FeedSourceCard.tsx:107 +#: src/view/com/feeds/FeedSourceCard.tsx:169 +#: src/view/com/feeds/FeedSourceCard.tsx:174 +#: src/view/com/feeds/FeedSourceCard.tsx:245 +#: src/view/screens/ProfileFeed.tsx:273 msgid "Remove from my feeds" msgstr "Poista syötteistäni" @@ -3011,11 +3126,15 @@ msgstr "Poista kuva" msgid "Remove image preview" msgstr "Poista kuvan esikatselu" +#: src/components/dialogs/MutedWords.tsx:294 +msgid "Remove mute word from your list" +msgstr "Poista hiljennetty sana listaltasi" + #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" msgstr "Poista uudelleenjako" -#: src/view/com/feeds/FeedSourceCard.tsx:173 +#: src/view/com/feeds/FeedSourceCard.tsx:175 msgid "Remove this feed from my feeds?" msgstr "Poistetaanko tämä syöte omista syötteistäni?" @@ -3028,8 +3147,8 @@ msgstr "Poistetaanko tämä syöte tallennetuista syötteistäsi?" msgid "Removed from list" msgstr "Poistettu listalta" -#: src/view/com/feeds/FeedSourceCard.tsx:111 -#: src/view/com/feeds/FeedSourceCard.tsx:178 +#: src/view/com/feeds/FeedSourceCard.tsx:113 +#: src/view/com/feeds/FeedSourceCard.tsx:180 msgid "Removed from my feeds" msgstr "Poistettu syötteistäni" @@ -3045,17 +3164,17 @@ msgstr "Vastaukset" msgid "Replies to this thread are disabled" msgstr "Tähän keskusteluun vastaaminen on estetty" -#: src/view/com/composer/Composer.tsx:348 +#: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" msgstr "Vastaa" -#: src/view/screens/PreferencesHomeFeed.tsx:144 +#: src/view/screens/PreferencesFollowingFeed.tsx:144 msgid "Reply Filters" msgstr "Vastaussuodattimet" -#: src/view/com/post/Post.tsx:166 -#: src/view/com/posts/FeedItem.tsx:284 +#: src/view/com/post/Post.tsx:167 +#: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" msgstr "Vastaa käyttäjälle <0/>" @@ -3064,20 +3183,20 @@ msgstr "Vastaa käyttäjälle <0/>" msgid "Report {collectionName}" msgstr "Raportoi {collectionName}" -#: src/view/com/profile/ProfileHeader.tsx:360 +#: src/view/com/profile/ProfileHeader.tsx:361 msgid "Report Account" msgstr "Ilmoita tili" -#: src/view/screens/ProfileFeed.tsx:292 +#: src/view/screens/ProfileFeed.tsx:293 msgid "Report feed" msgstr "Ilmoita syöte" -#: src/view/screens/ProfileList.tsx:458 +#: src/view/screens/ProfileList.tsx:459 msgid "Report List" msgstr "Ilmoita luettelo" #: src/view/com/modals/report/SendReportButton.tsx:37 -#: src/view/com/util/forms/PostDropdownBtn.tsx:210 +#: src/view/com/util/forms/PostDropdownBtn.tsx:255 msgid "Report post" msgstr "Ilmoita viesti" @@ -3102,11 +3221,11 @@ msgstr "Uudelleenjaa tai lainaa viestiä" msgid "Reposted By" msgstr "Uudelleenjakanut" -#: src/view/com/posts/FeedItem.tsx:204 +#: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" msgstr "Uudelleenjakanut {0}" -#: src/view/com/posts/FeedItem.tsx:221 +#: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" msgstr "Uudelleenjakanut <0/>" @@ -3114,7 +3233,7 @@ msgstr "Uudelleenjakanut <0/>" msgid "reposted your post" msgstr "uudelleenjakoi viestisi" -#: src/view/com/post-thread/PostThreadItem.tsx:185 +#: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" msgstr "Tämän viestin uudelleenjulkaisut" @@ -3188,8 +3307,8 @@ msgstr "Yrittää uudelleen viimeisintä toimintoa, joka epäonnistui" #: src/screens/Onboarding/StepInterests/index.tsx:221 #: src/screens/Onboarding/StepInterests/index.tsx:224 -#: src/view/com/auth/create/CreateAccount.tsx:177 -#: src/view/com/auth/create/CreateAccount.tsx:182 +#: src/view/com/auth/create/CreateAccount.tsx:181 +#: src/view/com/auth/create/CreateAccount.tsx:186 #: src/view/com/auth/login/LoginForm.tsx:268 #: src/view/com/auth/login/LoginForm.tsx:271 #: src/view/com/util/error/ErrorMessage.tsx:55 @@ -3220,7 +3339,7 @@ msgstr "Tallenna" #: src/view/com/modals/ChangeHandle.tsx:173 #: src/view/com/modals/CreateOrEditList.tsx:337 #: src/view/com/modals/EditProfile.tsx:224 -#: src/view/screens/ProfileFeed.tsx:345 +#: src/view/screens/ProfileFeed.tsx:346 msgid "Save" msgstr "Tallenna" @@ -3260,14 +3379,14 @@ msgstr "Tiede" msgid "Scroll to top" msgstr "Vieritä alkuun" -#: src/Navigation.tsx:437 +#: src/Navigation.tsx:440 #: src/view/com/auth/LoggedOut.tsx:122 #: src/view/com/modals/ListAddRemoveUsers.tsx:75 #: src/view/com/util/forms/SearchInput.tsx:67 #: src/view/com/util/forms/SearchInput.tsx:79 -#: src/view/screens/Search/Search.tsx:418 -#: src/view/screens/Search/Search.tsx:645 -#: src/view/screens/Search/Search.tsx:663 +#: src/view/screens/Search/Search.tsx:419 +#: src/view/screens/Search/Search.tsx:668 +#: src/view/screens/Search/Search.tsx:686 #: src/view/shell/bottom-bar/BottomBar.tsx:159 #: src/view/shell/desktop/LeftNav.tsx:324 #: src/view/shell/desktop/Search.tsx:214 @@ -3277,11 +3396,19 @@ msgstr "Vieritä alkuun" msgid "Search" msgstr "Haku" -#: src/view/screens/Search/Search.tsx:712 +#: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" msgstr "Haku hakusanalla \"{query}\"" +#: src/components/TagMenu/index.tsx:145 +msgid "Search for all posts by @{authorHandle} with tag {tag}" +msgstr "Etsi kaikki viestit käyttäjältä @{authorHandle} tunnisteella {tag}" + +#: src/components/TagMenu/index.tsx:90 +msgid "Search for all posts with tag {tag}" +msgstr "Etsi kaikki viestit tunnisteella {tag}" + #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 @@ -3292,6 +3419,22 @@ msgstr "Hae käyttäjiä" msgid "Security Step Required" msgstr "Turvatarkistus vaaditaan" +#: src/components/TagMenu/index.web.tsx:50 +msgid "See {truncatedTag} posts" +msgstr "Näytä {truncatedTag}-viestit" + +#: src/components/TagMenu/index.web.tsx:67 +msgid "See {truncatedTag} posts by user" +msgstr "Näytä käyttäjän {truncatedTag} viestit" + +#: src/components/TagMenu/index.tsx:128 +msgid "See <0>{tag} posts" +msgstr "Näytä <0>{tag}-viestit" + +#: src/components/TagMenu/index.tsx:189 +msgid "See <0>{tag} posts by this user" +msgstr "Näytä tämän käyttäjän <0>{tag}-viestit" + #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" msgstr "Katso tämä opas" @@ -3333,7 +3476,7 @@ msgstr "Valitse palvelu, joka hostaa tietojasi." #~ msgid "Select the types of content that you want to see (or not see), and we'll handle the rest." #~ msgstr "" -#: src/screens/Onboarding/StepTopicalFeeds.tsx:90 +#: src/screens/Onboarding/StepTopicalFeeds.tsx:96 msgid "Select topical feeds to follow from the list below" msgstr "Valitse ajankohtaisia syötteitä alla olevasta listasta" @@ -3438,15 +3581,15 @@ msgstr "Aseta uusi salasana" msgid "Set password" msgstr "Aseta salasana" -#: src/view/screens/PreferencesHomeFeed.tsx:225 +#: src/view/screens/PreferencesFollowingFeed.tsx:225 msgid "Set this setting to \"No\" to hide all quote posts from your feed. Reposts will still be visible." msgstr "Aseta tämä asetus \"Ei\"-tilaan piilottaaksesi kaikki lainaukset syötteestäsi. Uudelleenjulkaisut näkyvät silti." -#: src/view/screens/PreferencesHomeFeed.tsx:122 +#: src/view/screens/PreferencesFollowingFeed.tsx:122 msgid "Set this setting to \"No\" to hide all replies from your feed." msgstr "Aseta tämä asetus \"Ei\"-tilaan piilottaaksesi kaikki vastaukset syötteestäsi." -#: src/view/screens/PreferencesHomeFeed.tsx:191 +#: src/view/screens/PreferencesFollowingFeed.tsx:191 msgid "Set this setting to \"No\" to hide all reposts from your feed." msgstr "Aseta tämä asetus \"Ei\"-tilaan piilottaaksesi kaikki uudelleenjulkaisut syötteestäsi." @@ -3455,7 +3598,11 @@ msgid "Set this setting to \"Yes\" to show replies in a threaded view. This is a msgstr "Aseta tämä asetus \"Kyllä\" tilaan näyttääksesi vastaukset ketjumaisessa näkymässä. Tämä on kokeellinen ominaisuus." #: src/view/screens/PreferencesHomeFeed.tsx:261 -msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your following feed. This is an experimental feature." +#~ msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your following feed. This is an experimental feature." +#~ msgstr "Aseta tämä asetus \"Kyllä\"-tilaan nähdäksesi esimerkkejä tallennetuista syötteistäsi seuraamissasi syötteessäsi. Tämä on kokeellinen ominaisuus." + +#: src/view/screens/PreferencesFollowingFeed.tsx:261 +msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your Following feed. This is an experimental feature." msgstr "Aseta tämä asetus \"Kyllä\"-tilaan nähdäksesi esimerkkejä tallennetuista syötteistäsi seuraamissasi syötteessäsi. Tämä on kokeellinen ominaisuus." #: src/screens/Onboarding/Layout.tsx:50 @@ -3496,13 +3643,13 @@ msgctxt "action" msgid "Share" msgstr "Jaa" -#: src/view/com/profile/ProfileHeader.tsx:294 -#: src/view/com/util/forms/PostDropdownBtn.tsx:153 -#: src/view/screens/ProfileList.tsx:417 +#: src/view/com/profile/ProfileHeader.tsx:295 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 +#: src/view/screens/ProfileList.tsx:418 msgid "Share" msgstr "Jaa" -#: src/view/screens/ProfileFeed.tsx:304 +#: src/view/screens/ProfileFeed.tsx:305 msgid "Share feed" msgstr "Jaa syöte" @@ -3514,7 +3661,7 @@ msgstr "Jaa syöte" msgid "Show" msgstr "Näytä" -#: src/view/screens/PreferencesHomeFeed.tsx:68 +#: src/view/screens/PreferencesFollowingFeed.tsx:68 msgid "Show all replies" msgstr "Näytä kaikki vastaukset" @@ -3526,21 +3673,21 @@ msgstr "Näytä silti" msgid "Show embeds from {0}" msgstr "Näytä upotukset taholta {0}" -#: src/view/com/profile/ProfileHeader.tsx:458 +#: src/view/com/profile/ProfileHeader.tsx:459 msgid "Show follows similar to {0}" msgstr "Näytä seurannat samankaltaisilta käyttäjiltä kuin {0}" -#: src/view/com/post-thread/PostThreadItem.tsx:535 -#: src/view/com/post/Post.tsx:197 -#: src/view/com/posts/FeedItem.tsx:360 +#: src/view/com/post-thread/PostThreadItem.tsx:538 +#: src/view/com/post/Post.tsx:198 +#: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" msgstr "Näytä lisää" -#: src/view/screens/PreferencesHomeFeed.tsx:258 +#: src/view/screens/PreferencesFollowingFeed.tsx:258 msgid "Show Posts from My Feeds" msgstr "Näytä viestit omista syötteistäni" -#: src/view/screens/PreferencesHomeFeed.tsx:222 +#: src/view/screens/PreferencesFollowingFeed.tsx:222 msgid "Show Quote Posts" msgstr "Näytä lainatut viestit" @@ -3556,7 +3703,7 @@ msgstr "Näytä lainaukset seurattavissa" msgid "Show re-posts in Following feed" msgstr "Näytä uudelleenjulkaistut viestit seurattavissa" -#: src/view/screens/PreferencesHomeFeed.tsx:119 +#: src/view/screens/PreferencesFollowingFeed.tsx:119 msgid "Show Replies" msgstr "Näytä vastaukset" @@ -3572,11 +3719,11 @@ msgstr "Näytä vastaukset seurattavissa" msgid "Show replies in Following feed" msgstr "Näytä vastaukset seurattavissa" -#: src/view/screens/PreferencesHomeFeed.tsx:70 +#: src/view/screens/PreferencesFollowingFeed.tsx:70 msgid "Show replies with at least {value} {0}" msgstr "Näytä vastaukset, joissa on vähintään {value} {0}" -#: src/view/screens/PreferencesHomeFeed.tsx:188 +#: src/view/screens/PreferencesFollowingFeed.tsx:188 msgid "Show Reposts" msgstr "Näytä uudelleenjulkaisut" @@ -3593,12 +3740,12 @@ msgstr "Näytä sisältö" msgid "Show users" msgstr "Näytä käyttäjät" -#: src/view/com/profile/ProfileHeader.tsx:461 +#: src/view/com/profile/ProfileHeader.tsx:462 msgid "Shows a list of users similar to this user." msgstr "Näyttää luettelon käyttäjistä, jotka ovat samankaltaisia kuin tämä käyttäjä." #: src/view/com/post-thread/PostThreadFollowBtn.tsx:124 -#: src/view/com/profile/ProfileHeader.tsx:505 +#: src/view/com/profile/ProfileHeader.tsx:506 msgid "Shows posts from {0} in your feed" msgstr "Näyttää viestit käyttäjältä {0} syötteessäsi" @@ -3700,7 +3847,7 @@ msgstr "Ohjelmistokehitys" msgid "Something went wrong. Check your email and try again." msgstr "Jotain meni pieleen. Tarkista sähköpostisi ja yritä uudelleen." -#: src/App.native.tsx:61 +#: src/App.native.tsx:63 msgid "Sorry! Your session expired. Please log in again." msgstr "Pahoittelut! Istuntosi on vanhentunut. Kirjaudu sisään uudelleen." @@ -3745,7 +3892,7 @@ msgstr "Storybook" msgid "Submit" msgstr "Lähetä" -#: src/view/screens/ProfileList.tsx:607 +#: src/view/screens/ProfileList.tsx:608 msgid "Subscribe" msgstr "Tilaa" @@ -3754,11 +3901,11 @@ msgstr "Tilaa" msgid "Subscribe to the {0} feed" msgstr "Tilaa {0}-syöte" -#: src/view/screens/ProfileList.tsx:603 +#: src/view/screens/ProfileList.tsx:604 msgid "Subscribe to this list" msgstr "Tilaa tämä lista" -#: src/view/screens/Search/Search.tsx:373 +#: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" msgstr "Ehdotetut seurattavat" @@ -3802,6 +3949,14 @@ msgstr "Järjestelmä" msgid "System log" msgstr "Järjestelmäloki" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "tag" +msgstr "tunniste" + +#: src/components/TagMenu/index.tsx:74 +msgid "Tag menu: {tag}" +msgstr "Tunnistevalikko: {tag}" + #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" msgstr "Pitkä" @@ -3825,16 +3980,20 @@ msgstr "Ehdot" msgid "Terms of Service" msgstr "Käyttöehdot" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "text" +msgstr "teksti" + #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" msgstr "Tekstikenttä" -#: src/view/com/auth/create/CreateAccount.tsx:90 +#: src/view/com/auth/create/CreateAccount.tsx:94 msgid "That handle is already taken." msgstr "Tuo käyttätunnus on jo käytössä." -#: src/view/com/profile/ProfileHeader.tsx:262 +#: src/view/com/profile/ProfileHeader.tsx:263 msgid "The account will be able to interact with you after unblocking." msgstr "Tili voi olla vuorovaikutuksessa kanssasi, kun estäminen on poistettu." @@ -3850,7 +4009,7 @@ msgstr "Tekijänoikeuskäytäntö on siirretty kohtaan <0/>" msgid "The following steps will help customize your Bluesky experience." msgstr "Seuraavat vaiheet auttavat mukauttamaan Bluesky-kokemustasi." -#: src/view/com/post-thread/PostThread.tsx:516 +#: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." msgstr "Viesti saattaa olla poistettu." @@ -3870,7 +4029,7 @@ msgstr "Käyttöehdot on siirretty kohtaan" msgid "There are many feeds to try:" msgstr "On monia syötteitä kokeiltavaksi:" -#: src/view/screens/ProfileFeed.tsx:549 +#: src/view/screens/ProfileFeed.tsx:550 msgid "There was an an issue contacting the server, please check your internet connection and try again." msgstr "Emme saaneet yhteyttä palvelimeen, tarkista internetyhteytesi ja yritä uudelleen." @@ -3878,12 +4037,12 @@ msgstr "Emme saaneet yhteyttä palvelimeen, tarkista internetyhteytesi ja yritä msgid "There was an an issue removing this feed. Please check your internet connection and try again." msgstr "Syötteen poistossa on ongelmia. Tarkista internetyhteytesi ja yritä uudelleen." -#: src/view/screens/ProfileFeed.tsx:209 +#: src/view/screens/ProfileFeed.tsx:210 msgid "There was an an issue updating your feeds, please check your internet connection and try again." msgstr "Syötteiden päivittämisessä on ongelmia, tarkista internetyhteytesi ja yritä uudelleen." -#: src/view/screens/ProfileFeed.tsx:236 -#: src/view/screens/ProfileList.tsx:266 +#: src/view/screens/ProfileFeed.tsx:237 +#: src/view/screens/ProfileList.tsx:267 #: src/view/screens/SavedFeeds.tsx:209 #: src/view/screens/SavedFeeds.tsx:231 #: src/view/screens/SavedFeeds.tsx:252 @@ -3892,9 +4051,9 @@ msgstr "Yhteydenotto palvelimeen epäonnistui" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:57 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:66 -#: src/view/com/feeds/FeedSourceCard.tsx:113 -#: src/view/com/feeds/FeedSourceCard.tsx:127 -#: src/view/com/feeds/FeedSourceCard.tsx:181 +#: src/view/com/feeds/FeedSourceCard.tsx:115 +#: src/view/com/feeds/FeedSourceCard.tsx:129 +#: src/view/com/feeds/FeedSourceCard.tsx:183 msgid "There was an issue contacting your server" msgstr "Yhteydenotto palvelimeen epäonnistui" @@ -3926,19 +4085,19 @@ msgstr "Sovellussalasanojen hakemisessa tapahtui virhe" #: src/view/com/post-thread/PostThreadFollowBtn.tsx:93 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:105 -#: src/view/com/profile/ProfileHeader.tsx:156 -#: src/view/com/profile/ProfileHeader.tsx:177 -#: src/view/com/profile/ProfileHeader.tsx:216 -#: src/view/com/profile/ProfileHeader.tsx:229 -#: src/view/com/profile/ProfileHeader.tsx:249 -#: src/view/com/profile/ProfileHeader.tsx:271 +#: src/view/com/profile/ProfileHeader.tsx:157 +#: src/view/com/profile/ProfileHeader.tsx:178 +#: src/view/com/profile/ProfileHeader.tsx:217 +#: src/view/com/profile/ProfileHeader.tsx:230 +#: src/view/com/profile/ProfileHeader.tsx:250 +#: src/view/com/profile/ProfileHeader.tsx:272 msgid "There was an issue! {0}" msgstr "Ilmeni ongelma! {0}" -#: src/view/screens/ProfileList.tsx:287 -#: src/view/screens/ProfileList.tsx:306 -#: src/view/screens/ProfileList.tsx:328 -#: src/view/screens/ProfileList.tsx:347 +#: src/view/screens/ProfileList.tsx:288 +#: src/view/screens/ProfileList.tsx:307 +#: src/view/screens/ProfileList.tsx:329 +#: src/view/screens/ProfileList.tsx:348 msgid "There was an issue. Please check your internet connection and try again." msgstr "Ilmeni joku ongelma. Tarkista internet-yhteys ja yritä uudelleen." @@ -3987,8 +4146,8 @@ msgid "This feed is currently receiving high traffic and is temporarily unavaila msgstr "Tämä syöte saa tällä hetkellä paljon liikennettä ja on tilapäisesti pois käytöstä. Yritä uudelleen myöhemmin." #: src/view/screens/Profile.tsx:420 -#: src/view/screens/ProfileFeed.tsx:475 -#: src/view/screens/ProfileList.tsx:660 +#: src/view/screens/ProfileFeed.tsx:476 +#: src/view/screens/ProfileList.tsx:661 msgid "This feed is empty!" msgstr "Tämä syöte on tyhjä!" @@ -4016,7 +4175,7 @@ msgstr "Tämä lista on tyhjä!" msgid "This name is already in use" msgstr "Tämä nimi on jo käytössä" -#: src/view/com/post-thread/PostThreadItem.tsx:122 +#: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." msgstr "Tämä viesti on poistettu." @@ -4040,7 +4199,11 @@ msgstr "Tämä käyttäjä on <0/>-listassa, jonka olet hiljentänyt." msgid "This warning is only available for posts with media attached." msgstr "Tämä varoitus on saatavilla vain viesteille, joihin on liitetty mediatiedosto." -#: src/view/com/util/forms/PostDropdownBtn.tsx:192 +#: src/components/dialogs/MutedWords.tsx:236 +msgid "This will delete {0} from your muted words. You can always add it back later." +msgstr "Tämä poistaa {0}:n hiljennetyistä sanoistasi. Voit lisätä sen takaisin myöhemmin." + +#: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "This will hide this post from your feeds." msgstr "Tämä piilottaa tämän viestin syötteistäsi." @@ -4053,10 +4216,14 @@ msgstr "Keskusteluketjun asetukset" msgid "Threaded Mode" msgstr "Ketjumainen näkymä" -#: src/Navigation.tsx:252 +#: src/Navigation.tsx:255 msgid "Threads Preferences" msgstr "Keskusteluketjujen asetukset" +#: src/components/dialogs/MutedWords.tsx:95 +msgid "Toggle between muted word options." +msgstr "Vaihda hiljennysvaihtoehtojen välillä." + #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" msgstr "Vaihda pudotusvalikko" @@ -4065,9 +4232,9 @@ msgstr "Vaihda pudotusvalikko" msgid "Transformations" msgstr "Muutokset" -#: src/view/com/post-thread/PostThreadItem.tsx:682 -#: src/view/com/post-thread/PostThreadItem.tsx:684 -#: src/view/com/util/forms/PostDropdownBtn.tsx:125 +#: src/view/com/post-thread/PostThreadItem.tsx:685 +#: src/view/com/post-thread/PostThreadItem.tsx:687 +#: src/view/com/util/forms/PostDropdownBtn.tsx:156 msgid "Translate" msgstr "Käännä" @@ -4076,11 +4243,11 @@ msgctxt "action" msgid "Try again" msgstr "Yritä uudelleen" -#: src/view/screens/ProfileList.tsx:505 +#: src/view/screens/ProfileList.tsx:506 msgid "Un-block list" msgstr "Poista listan esto" -#: src/view/screens/ProfileList.tsx:490 +#: src/view/screens/ProfileList.tsx:491 msgid "Un-mute list" msgstr "Poista listan hiljennys" @@ -4092,8 +4259,8 @@ msgstr "Poista listan hiljennys" msgid "Unable to contact your service. Please check your Internet connection." msgstr "Yhteys palveluusi ei onnistu. Tarkista internet-yhteytesi." -#: src/view/com/profile/ProfileHeader.tsx:432 -#: src/view/screens/ProfileList.tsx:589 +#: src/view/com/profile/ProfileHeader.tsx:433 +#: src/view/screens/ProfileList.tsx:590 msgid "Unblock" msgstr "Poista esto" @@ -4102,8 +4269,8 @@ msgctxt "action" msgid "Unblock" msgstr "Poista esto" -#: src/view/com/profile/ProfileHeader.tsx:260 -#: src/view/com/profile/ProfileHeader.tsx:344 +#: src/view/com/profile/ProfileHeader.tsx:261 +#: src/view/com/profile/ProfileHeader.tsx:345 msgid "Unblock Account" msgstr "Poista tilin esto" @@ -4119,7 +4286,7 @@ msgctxt "action" msgid "Unfollow" msgstr "Lopeta seuraaminen" -#: src/view/com/profile/ProfileHeader.tsx:484 +#: src/view/com/profile/ProfileHeader.tsx:485 msgid "Unfollow {0}" msgstr "Lopeta seuraaminen {0}" @@ -4132,15 +4299,24 @@ msgstr "Valitettavasti et täytä tilin luomisen vaatimuksia." msgid "Unlike" msgstr "En tykkää" -#: src/view/screens/ProfileList.tsx:596 +#: src/components/TagMenu/index.tsx:253 +#: src/view/screens/ProfileList.tsx:597 msgid "Unmute" msgstr "Poista hiljennys" -#: src/view/com/profile/ProfileHeader.tsx:325 +#: src/components/TagMenu/index.web.tsx:90 +msgid "Unmute {truncatedTag}" +msgstr "Poista hiljennys {truncatedTag}" + +#: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" msgstr "Poista tilin hiljennys" -#: src/view/com/util/forms/PostDropdownBtn.tsx:171 +#: src/components/TagMenu/index.tsx:210 +msgid "Unmute all {tag} posts" +msgstr "Poista hiljennys kaikista {tag}-viesteistä" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Unmute thread" msgstr "Poista keskusteluketjun hiljennys" @@ -4149,11 +4325,11 @@ msgstr "Poista keskusteluketjun hiljennys" msgid "Unpin" msgstr "Poista kiinnitys" -#: src/view/screens/ProfileList.tsx:473 +#: src/view/screens/ProfileList.tsx:474 msgid "Unpin moderation list" msgstr "Poista moderointilistan kiinnitys" -#: src/view/screens/ProfileFeed.tsx:345 +#: src/view/screens/ProfileFeed.tsx:346 msgid "Unsave" msgstr "Poista tallennus" @@ -4215,11 +4391,11 @@ msgstr "Käyttäjä estetty listan vuoksi" msgid "User Blocks You" msgstr "Käyttäjä on estänyt sinut" -#: src/view/com/auth/create/Step2.tsx:44 +#: src/view/com/auth/create/Step2.tsx:79 msgid "User handle" msgstr "Käyttäjätunnus" -#: src/view/com/lists/ListCard.tsx:84 +#: src/view/com/lists/ListCard.tsx:85 #: src/view/com/modals/UserAddRemoveLists.tsx:198 msgid "User list by {0}" msgstr "Käyttäjälistan on tehnyt {0}" @@ -4228,7 +4404,7 @@ msgstr "Käyttäjälistan on tehnyt {0}" msgid "User list by <0/>" msgstr "Käyttäjälistan on tehnyt <0/>" -#: src/view/com/lists/ListCard.tsx:82 +#: src/view/com/lists/ListCard.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:196 #: src/view/screens/ProfileList.tsx:760 msgid "User list by you" @@ -4292,7 +4468,7 @@ msgstr "Vahvista sähköpostisi" msgid "Video Games" msgstr "Videopelit" -#: src/view/com/profile/ProfileHeader.tsx:661 +#: src/view/com/profile/ProfileHeader.tsx:662 msgid "View {0}'s avatar" msgstr "Katso {0}:n avatar" @@ -4341,6 +4517,10 @@ msgstr "Emme enää löytäneet viestejä seurattavilta. Tässä on uusin tekij #~ msgid "We recommend \"For You\" by Skygaze:" #~ msgstr "" +#: src/components/dialogs/MutedWords.tsx:161 +msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." +msgstr "Suosittelemme välttämään yleisiä sanoja, jotka esiintyvät monissa viesteissä. Se voi johtaa siihen, ettei viestejä näytetä." + #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" msgstr "Suosittelemme \"Tutustu\"-syötettämme:" @@ -4361,15 +4541,19 @@ msgstr "Käsittelemme vetoomuksesi pikaisesti." msgid "We'll use this to help customize your experience." msgstr "Käytämme tätä mukauttaaksemme kokemustasi." -#: src/view/com/auth/create/CreateAccount.tsx:130 +#: src/view/com/auth/create/CreateAccount.tsx:134 msgid "We're so excited to have you join us!" msgstr "Olemme innoissamme, että liityt joukkoomme!" -#: src/view/screens/ProfileList.tsx:85 +#: src/view/screens/ProfileList.tsx:86 msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." msgstr "Pahoittelemme, emme saaneet avattua tätä listaa. Jos ongelma jatkuu, ota yhteyttä listan tekijään: @{handleOrDid}." -#: src/view/screens/Search/Search.tsx:253 +#: src/components/dialogs/MutedWords.tsx:182 +msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." +msgstr "Pahoittelemme, emme pystyneet lataamaan hiljennettyjä sanojasi tällä hetkellä. Yritä uudelleen." + +#: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "Pahoittelemme, hakuasi ei voitu suorittaa loppuun. Yritä uudelleen muutaman minuutin kuluttua." @@ -4390,7 +4574,7 @@ msgid "What is the issue with this {collectionName}?" msgstr "Mikä on ongelma tämän {collectionName} kanssa?" #: src/view/com/auth/SplashScreen.tsx:59 -#: src/view/com/composer/Composer.tsx:279 +#: src/view/com/composer/Composer.tsx:286 msgid "What's up?" msgstr "Mitä kuuluu?" @@ -4411,11 +4595,11 @@ msgstr "Kuka voi vastata" msgid "Wide" msgstr "Leveä" -#: src/view/com/composer/Composer.tsx:415 +#: src/view/com/composer/Composer.tsx:422 msgid "Write post" msgstr "Kirjoita viesti" -#: src/view/com/composer/Composer.tsx:278 +#: src/view/com/composer/Composer.tsx:285 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "Kirjoita vastauksesi" @@ -4429,10 +4613,10 @@ msgstr "Kirjoittajat" #~ msgstr "XXXXXX" #: src/view/com/composer/select-language/SuggestedLanguage.tsx:77 -#: src/view/screens/PreferencesHomeFeed.tsx:129 -#: src/view/screens/PreferencesHomeFeed.tsx:201 -#: src/view/screens/PreferencesHomeFeed.tsx:236 -#: src/view/screens/PreferencesHomeFeed.tsx:271 +#: src/view/screens/PreferencesFollowingFeed.tsx:129 +#: src/view/screens/PreferencesFollowingFeed.tsx:201 +#: src/view/screens/PreferencesFollowingFeed.tsx:236 +#: src/view/screens/PreferencesFollowingFeed.tsx:271 #: src/view/screens/PreferencesThreads.tsx:106 #: src/view/screens/PreferencesThreads.tsx:129 msgid "Yes" @@ -4480,7 +4664,7 @@ msgstr "Sinulla ei ole tallennettuja syötteitä!" msgid "You don't have any saved feeds." msgstr "Sinulla ei ole tallennettuja syötteitä." -#: src/view/com/post-thread/PostThread.tsx:464 +#: src/view/com/post-thread/PostThread.tsx:465 msgid "You have blocked the author or you have been blocked by the author." msgstr "Olet estänyt tekijän tai sinut on estetty tekijän toimesta." @@ -4520,6 +4704,10 @@ msgstr "Et ole vielä luonut yhtään sovelluksen salasanaa. Voit luoda sellaise msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." msgstr "Et ole vielä hiljentänyt yhtään käyttäjää. Hiljentääksesi käyttäjän, siirry heidän profiiliinsa ja valitse \"Hiljennä käyttäjä\"-vaihtoehto heidän tilinsä valikosta." +#: src/components/dialogs/MutedWords.tsx:202 +msgid "You haven't muted any words or tags yet" +msgstr "Et ole vielä hiljentänyt yhtään sanaa tai tunnistetta" + #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." msgstr "Sinun on oltava vähintään 18-vuotias katsoaksesi aikuissisältöä." @@ -4528,11 +4716,11 @@ msgstr "Sinun on oltava vähintään 18-vuotias katsoaksesi aikuissisältöä." msgid "You must be 18 years or older to enable adult content" msgstr "Sinun on oltava vähintään 18-vuotias katsoaksesi aikuissisältöä" -#: src/view/com/util/forms/PostDropdownBtn.tsx:98 +#: src/view/com/util/forms/PostDropdownBtn.tsx:129 msgid "You will no longer receive notifications for this thread" msgstr "Et enää saa ilmoituksia tästä keskustelusta" -#: src/view/com/util/forms/PostDropdownBtn.tsx:101 +#: src/view/com/util/forms/PostDropdownBtn.tsx:132 msgid "You will now receive notifications for this thread" msgstr "Saat nyt ilmoituksia tästä keskustelusta" @@ -4604,7 +4792,7 @@ msgstr "Sähköpostiosoitettasi ei ole vielä vahvistettu. Tämä on tärkeä tu msgid "Your following feed is empty! Follow more users to see what's happening." msgstr "Seuraamiesi syöte on tyhjä! Seuraa lisää käyttäjiä nähdäksesi, mitä tapahtuu." -#: src/view/com/auth/create/Step2.tsx:48 +#: src/view/com/auth/create/Step2.tsx:83 msgid "Your full handle will be" msgstr "Käyttäjätunnuksesi tulee olemaan" @@ -4618,11 +4806,15 @@ msgstr "Käyttäjätunnuksesi tulee olemaan <0>@{0}" #~ msgid "Your invite codes are hidden when logged in using an App Password" #~ msgstr "" +#: src/components/dialogs/MutedWords.tsx:173 +msgid "Your muted words" +msgstr "Hiljentämäsi sanat" + #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" msgstr "Salasanasi on vaihdettu onnistuneesti!" -#: src/view/com/composer/Composer.tsx:267 +#: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" msgstr "Viestisi on julkaistu" @@ -4637,10 +4829,10 @@ msgstr "Julkaisusi, tykkäyksesi ja estosi ovat julkisia. Hiljennykset ovat yksi msgid "Your profile" msgstr "Profiilisi" -#: src/view/com/composer/Composer.tsx:266 +#: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" msgstr "Vastauksesi on julkaistu" -#: src/view/com/auth/create/Step2.tsx:28 +#: src/view/com/auth/create/Step2.tsx:65 msgid "Your user handle" msgstr "Käyttäjätunnuksesi" From cbc65247ae57502356165a5d51270bd8d19fd9a5 Mon Sep 17 00:00:00 2001 From: Jan-Olof Eriksson Date: Mon, 4 Mar 2024 19:09:47 +0200 Subject: [PATCH 055/109] Add files via upload --- src/locale/locales/en/messages.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locale/locales/en/messages.po b/src/locale/locales/en/messages.po index ec1b71cf29..8cdf8ebfa4 100644 --- a/src/locale/locales/en/messages.po +++ b/src/locale/locales/en/messages.po @@ -4836,4 +4836,4 @@ msgstr "" #: src/view/com/auth/create/Step2.tsx:65 msgid "Your user handle" -msgstr "" +msgstr "" \ No newline at end of file From 4a858bacd6033a443858d9c599b12adc6ea316c9 Mon Sep 17 00:00:00 2001 From: Minseo Lee Date: Wed, 6 Mar 2024 19:38:13 +0900 Subject: [PATCH 056/109] Update src/view/screens/Settings/index.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> --- src/view/screens/Settings/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/screens/Settings/index.tsx b/src/view/screens/Settings/index.tsx index 7a725a6687..f0d19e37c5 100644 --- a/src/view/screens/Settings/index.tsx +++ b/src/view/screens/Settings/index.tsx @@ -531,7 +531,7 @@ export function SettingsScreen({}: Props) { ]} onPress={openFollowingFeedPreferences} accessibilityRole="button" - accessibilityLabel={_(msg`Home feed preferences`)} + accessibilityLabel={_(msg`Following feed preferences`)} accessibilityHint={_(msg`Opens the home feed preferences`)}> Date: Wed, 6 Mar 2024 19:38:23 +0900 Subject: [PATCH 057/109] Update src/view/screens/Settings/index.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> --- src/view/screens/Settings/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/screens/Settings/index.tsx b/src/view/screens/Settings/index.tsx index f0d19e37c5..2e2de1d80c 100644 --- a/src/view/screens/Settings/index.tsx +++ b/src/view/screens/Settings/index.tsx @@ -532,7 +532,7 @@ export function SettingsScreen({}: Props) { onPress={openFollowingFeedPreferences} accessibilityRole="button" accessibilityLabel={_(msg`Following feed preferences`)} - accessibilityHint={_(msg`Opens the home feed preferences`)}> + accessibilityHint={_(msg`Opens the Following feed preferences`)}> Date: Wed, 13 Mar 2024 10:41:34 +0900 Subject: [PATCH 058/109] Update index.tsx --- src/components/Menu/index.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/Menu/index.tsx b/src/components/Menu/index.tsx index 9be9dd86bf..051e95b956 100644 --- a/src/components/Menu/index.tsx +++ b/src/components/Menu/index.tsx @@ -17,7 +17,7 @@ import { ItemIconProps, } from '#/components/Menu/types' import {Button, ButtonText} from '#/components/Button' -import {msg} from '@lingui/macro' +import {Trans, msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {isNative} from 'platform/detection' @@ -209,7 +209,9 @@ function Cancel() { variant="ghost" color="secondary" onPress={() => control.close()}> - Cancel + + Cancel + ) } From 1760043f79f6e50de3bb2df97c3d6fe9c700b035 Mon Sep 17 00:00:00 2001 From: Minseo Lee Date: Wed, 13 Mar 2024 10:41:38 +0900 Subject: [PATCH 059/109] Update index.tsx --- src/components/TagMenu/index.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/TagMenu/index.tsx b/src/components/TagMenu/index.tsx index 849a3f42d1..ae4b50bf4a 100644 --- a/src/components/TagMenu/index.tsx +++ b/src/components/TagMenu/index.tsx @@ -264,7 +264,9 @@ export function TagMenu({ variant="ghost" color="secondary" onPress={() => control.close()}> - Cancel + + Cancel + )} From fa8b21cea7247623f5eec5bbf4609e4af2586d34 Mon Sep 17 00:00:00 2001 From: Hailey Date: Fri, 15 Mar 2024 12:28:21 -0700 Subject: [PATCH 060/109] Add package diff PR labeler (#3212) * add PR labeler * test cache * rm change --- .github/workflows/pull-request-commit.yml | 185 ++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 .github/workflows/pull-request-commit.yml diff --git a/.github/workflows/pull-request-commit.yml b/.github/workflows/pull-request-commit.yml new file mode 100644 index 0000000000..76dc432756 --- /dev/null +++ b/.github/workflows/pull-request-commit.yml @@ -0,0 +1,185 @@ +# Credit https://github.com/expo/expo +# https://github.com/expo/expo/blob/main/.github/workflows/pr-labeler.yml +--- +name: PR labeler + +on: + push: + branches: [main] + pull_request: + types: [opened, synchronize] + +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test-suite-fingerprint: + runs-on: ubuntu-22.04 + if: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.event_name == 'push' }} + # REQUIRED: limit concurrency when pushing main(default) branch to prevent conflict for this action to update its fingerprint database + concurrency: fingerprint-${{ github.event_name != 'pull_request' && 'main' || github.run_id }} + permissions: + # REQUIRED: Allow comments of PRs + pull-requests: write + # REQUIRED: Allow updating fingerprint in acton caches + actions: write + steps: + - name: ⬇️ Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 100 + + - name: ⬇️ Fetch commits from base branch + run: git fetch origin main:main --depth 100 + if: github.event_name == 'pull_request' + + - name: 🔧 Setup Node + uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: yarn + + - name: ⚙️ Install Dependencies + run: yarn install + + - name: Get the base commit + id: base-commit + run: | + # Since we limit this pr-labeler workflow only triggered from limited paths, we should use custom base commit + echo base-commit=$(git log -n 1 main --pretty=format:'%H' -- .github/workflows/pr-labeler.yml packages yarn.lock) >> "$GITHUB_OUTPUT" + + - name: 📷 Check fingerprint + id: fingerprint + uses: expo/expo-github-action/fingerprint@main + with: + previous-git-commit: ${{ steps.base-commit.outputs.base-commit }} + + - name: 👀 Debug fingerprint + run: | + echo "previousGitCommit=${{ steps.fingerprint.outputs.previous-git-commit }} currentGitCommit=${{ steps.fingerprint.outputs.current-git-commit }}" + echo "isPreviousFingerprintEmpty=${{ steps.fingerprint.outputs.previous-fingerprint == '' }}" + + - name: 🏷️ Labeling PR + uses: actions/github-script@v6 + if: ${{ github.event_name == 'pull_request' && steps.fingerprint.outputs.fingerprint-diff == '[]' }} + with: + script: | + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: ['bot: fingerprint changed'] + }) + } catch (e) { + if (e.status != 404) { + throw e; + } + } + github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['bot: fingerprint compatible'] + }) + + - name: 🏷️ Labeling PR + uses: actions/github-script@v6 + if: ${{ github.event_name == 'pull_request' && steps.fingerprint.outputs.fingerprint-diff != '[]' }} + with: + script: | + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: ['bot: fingerprint compatible'] + }) + } catch (e) { + if (e.status != 404) { + throw e; + } + } + github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['bot: fingerprint changed'] + }) + + - name: 🔍 Find old comment if it exists + uses: peter-evans/find-comment@v2 + if: ${{ github.event_name == 'pull_request' }} + id: old_comment + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'expo-bot' + body-includes: + + - name: 💬 Add comment with fingerprint + if: ${{ github.event_name == 'pull_request' && steps.fingerprint.outputs.fingerprint-diff != '[]' && steps.old_comment.outputs.comment-id == '' }} + uses: actions/github-script@v6 + with: + script: | + const diff = JSON.stringify(${{ steps.fingerprint.outputs.fingerprint-diff}}, null, 2); + const body = ` + The Pull Request introduced fingerprint changes against the base commit: ${{ steps.fingerprint.outputs.previous-git-commit }} +
Fingerprint diff + + \`\`\`json + ${diff} + \`\`\` + +
+ + --- + *Generated by [PR labeler](https://github.com/expo/expo/actions/workflows/pr-labeler.yml) 🤖* + `; + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: body, + }); + + - name: 💬 Update comment with fingerprint + if: ${{ github.event_name == 'pull_request' && steps.fingerprint.outputs.fingerprint-diff != '[]' && steps.old_comment.outputs.comment-id != '' }} + uses: actions/github-script@v6 + with: + script: | + const diff = JSON.stringify(${{ steps.fingerprint.outputs.fingerprint-diff}}, null, 2); + const body = ` + The Pull Request introduced fingerprint changes against the base commit: ${{ steps.fingerprint.outputs.previous-git-commit }} +
Fingerprint diff + + \`\`\`json + ${diff} + \`\`\` + +
+ + --- + *Generated by [PR labeler](https://github.com/expo/expo/actions/workflows/pr-labeler.yml) 🤖* + `; + + github.rest.issues.updateComment({ + issue_number: context.issue.number, + comment_id: '${{ steps.old_comment.outputs.comment-id }}', + owner: context.repo.owner, + repo: context.repo.repo, + body: body, + }); + + - name: 💬 Delete comment with fingerprint + if: ${{ github.event_name == 'pull_request' && steps.fingerprint.outputs.fingerprint-diff == '[]' && steps.old_comment.outputs.comment-id != '' }} + uses: actions/github-script@v6 + with: + script: | + github.rest.issues.deleteComment({ + issue_number: context.issue.number, + comment_id: '${{ steps.old_comment.outputs.comment-id }}', + owner: context.repo.owner, + repo: context.repo.repo, + }); \ No newline at end of file From 98bca69ae996dabf3c7bf05f98497b56b62cb494 Mon Sep 17 00:00:00 2001 From: Hailey Date: Fri, 15 Mar 2024 13:42:51 -0700 Subject: [PATCH 061/109] Adjust PR Labeler (#3224) --- .github/workflows/pull-request-commit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request-commit.yml b/.github/workflows/pull-request-commit.yml index 76dc432756..72381a32d0 100644 --- a/.github/workflows/pull-request-commit.yml +++ b/.github/workflows/pull-request-commit.yml @@ -47,7 +47,7 @@ jobs: id: base-commit run: | # Since we limit this pr-labeler workflow only triggered from limited paths, we should use custom base commit - echo base-commit=$(git log -n 1 main --pretty=format:'%H' -- .github/workflows/pr-labeler.yml packages yarn.lock) >> "$GITHUB_OUTPUT" + echo base-commit=$(git log -n 1 main --pretty=format:'%H') >> "$GITHUB_OUTPUT" - name: 📷 Check fingerprint id: fingerprint From 7a0bf7266a5a871fafb08194d794318fb02ac999 Mon Sep 17 00:00:00 2001 From: Minseo Lee Date: Sat, 16 Mar 2024 16:48:58 +0900 Subject: [PATCH 062/109] Update Lists.tsx --- src/components/Lists.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/components/Lists.tsx b/src/components/Lists.tsx index 8a6dfdc7c0..f506f52ce2 100644 --- a/src/components/Lists.tsx +++ b/src/components/Lists.tsx @@ -6,7 +6,7 @@ import {Loader} from '#/components/Loader' import {Trans, msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {cleanError} from 'lib/strings/errors' -import {Button} from '#/components/Button' +import {Button, ButtonText} from '#/components/Button' import {Text} from '#/components/Typography' import {StackActions} from '@react-navigation/native' import {router} from '#/routes' @@ -223,7 +223,7 @@ export function ListMaybePlaceholder({ )}
From b4480738e3346b8b80fcdc3481b1de3266577ca0 Mon Sep 17 00:00:00 2001 From: Minseo Lee Date: Sat, 16 Mar 2024 16:50:15 +0900 Subject: [PATCH 063/109] Update ReasonOptions.tsx --- src/view/com/modals/report/ReasonOptions.tsx | 45 +++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/view/com/modals/report/ReasonOptions.tsx b/src/view/com/modals/report/ReasonOptions.tsx index 23b49b6648..de90455601 100644 --- a/src/view/com/modals/report/ReasonOptions.tsx +++ b/src/view/com/modals/report/ReasonOptions.tsx @@ -1,63 +1,66 @@ import {View} from 'react-native' import React, {useMemo} from 'react' import {AtUri, ComAtprotoModerationDefs} from '@atproto/api' +import {Trans} from '@lingui/macro' import {Text} from '../../util/text/Text' import {UsePaletteValue, usePalette} from 'lib/hooks/usePalette' import {RadioGroup, RadioGroupItem} from 'view/com/util/forms/RadioGroup' import {CollectionId} from './types' -type ReasonMap = Record +type ReasonMap = Record const CommonReasons = { [ComAtprotoModerationDefs.REASONRUDE]: { - title: 'Anti-Social Behavior', - description: 'Harassment, trolling, or intolerance', + title: Anti-Social Behavior, + description: Harassment, trolling, or intolerance, }, [ComAtprotoModerationDefs.REASONVIOLATION]: { - title: 'Illegal and Urgent', - description: 'Glaring violations of law or terms of service', + title: Illegal and Urgent, + description: Glaring violations of law or terms of service, }, [ComAtprotoModerationDefs.REASONOTHER]: { - title: 'Other', - description: 'An issue not included in these options', + title: Other, + description: An issue not included in these options, }, } const CollectionToReasonsMap: Record = { [CollectionId.Post]: { [ComAtprotoModerationDefs.REASONSPAM]: { - title: 'Spam', - description: 'Excessive mentions or replies', + title: Spam, + description: Excessive mentions or replies, }, [ComAtprotoModerationDefs.REASONSEXUAL]: { - title: 'Unwanted Sexual Content', - description: 'Nudity or pornography not labeled as such', + title: Unwanted Sexual Content, + description: Nudity or pornography not labeled as such, }, __copyright__: { - title: 'Copyright Violation', - description: 'Contains copyrighted material', + title: Copyright Violation, + description: Contains copyrighted material, }, ...CommonReasons, }, [CollectionId.List]: { ...CommonReasons, [ComAtprotoModerationDefs.REASONVIOLATION]: { - title: 'Name or Description Violates Community Standards', - description: 'Terms used violate community standards', + title: Name or Description Violates Community Standards, + description: Terms used violate community standards, }, }, } const AccountReportReasons = { [ComAtprotoModerationDefs.REASONMISLEADING]: { - title: 'Misleading Account', - description: 'Impersonation or false claims about identity or affiliation', + title: Misleading Account, + description: ( + Impersonation or false claims about identity or affiliation + ), }, [ComAtprotoModerationDefs.REASONSPAM]: { - title: 'Frequently Posts Unwanted Content', - description: 'Spam; excessive mentions or replies', + title: Frequently Posts Unwanted Content, + description: Spam; excessive mentions or replies, }, [ComAtprotoModerationDefs.REASONVIOLATION]: { - title: 'Name or Description Violates Community Standards', - description: 'Terms used violate community standards', + title: Name or Description Violates Community Standards, + description: Terms used violate community standards, }, } From 12d8f0071abc02eda8b09c181ff69d188b5b6fe5 Mon Sep 17 00:00:00 2001 From: Minseo Lee Date: Sat, 16 Mar 2024 16:56:56 +0900 Subject: [PATCH 064/109] Update ReasonOptions.tsx --- src/view/com/modals/report/ReasonOptions.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/view/com/modals/report/ReasonOptions.tsx b/src/view/com/modals/report/ReasonOptions.tsx index de90455601..1c67bd26cc 100644 --- a/src/view/com/modals/report/ReasonOptions.tsx +++ b/src/view/com/modals/report/ReasonOptions.tsx @@ -70,8 +70,8 @@ const Option = ({ description, }: { pal: UsePaletteValue - description: string - title: string + description: JSX.Element + title: JSX.Element }) => { return ( From a3786ee5cddceaa6efa78bf4ec2c9768f3abc674 Mon Sep 17 00:00:00 2001 From: Minseo Lee Date: Sat, 16 Mar 2024 17:02:05 +0900 Subject: [PATCH 065/109] Update Modal.tsx --- src/view/com/modals/report/Modal.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/view/com/modals/report/Modal.tsx b/src/view/com/modals/report/Modal.tsx index 236f32737f..dbe3648462 100644 --- a/src/view/com/modals/report/Modal.tsx +++ b/src/view/com/modals/report/Modal.tsx @@ -23,10 +23,10 @@ const DMCA_LINK = 'https://bsky.social/about/support/copyright' export const snapPoints = [575] const CollectionNames = { - [CollectionId.FeedGenerator]: 'Feed', - [CollectionId.Profile]: 'Profile', - [CollectionId.List]: 'List', - [CollectionId.Post]: 'Post', + [CollectionId.FeedGenerator]: Feed, + [CollectionId.Profile]: Profile, + [CollectionId.List]: List, + [CollectionId.Post]: Post, } type ReportComponentProps = @@ -129,9 +129,9 @@ export function Component(content: ReportComponentProps) { // If no atUri is passed, that means the reporting collection is account const getCollectionNameForReport = (atUri: AtUri | null) => { - if (!atUri) return 'Account' + if (!atUri) return Account // Generic fallback for any collection being reported - return CollectionNames[atUri.collection as CollectionId] || 'Content' + return CollectionNames[atUri.collection as CollectionId] || Content } const SelectIssue = ({ From 86d036cca8ea1546908b2e53b985162bc8023d3d Mon Sep 17 00:00:00 2001 From: Minseo Lee Date: Sat, 16 Mar 2024 17:04:45 +0900 Subject: [PATCH 066/109] Update Modal.tsx --- src/view/com/modals/report/Modal.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/view/com/modals/report/Modal.tsx b/src/view/com/modals/report/Modal.tsx index dbe3648462..90697b0782 100644 --- a/src/view/com/modals/report/Modal.tsx +++ b/src/view/com/modals/report/Modal.tsx @@ -131,7 +131,9 @@ export function Component(content: ReportComponentProps) { const getCollectionNameForReport = (atUri: AtUri | null) => { if (!atUri) return Account // Generic fallback for any collection being reported - return CollectionNames[atUri.collection as CollectionId] || Content + return ( + CollectionNames[atUri.collection as CollectionId] || Content + ) } const SelectIssue = ({ From 73dae9f7b5c169aa303e9ef9487040e850998edf Mon Sep 17 00:00:00 2001 From: Minseo Lee Date: Sat, 16 Mar 2024 17:17:54 +0900 Subject: [PATCH 067/109] Update Modal.tsx --- src/view/com/modals/report/Modal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/com/modals/report/Modal.tsx b/src/view/com/modals/report/Modal.tsx index 90697b0782..02ecefc0f3 100644 --- a/src/view/com/modals/report/Modal.tsx +++ b/src/view/com/modals/report/Modal.tsx @@ -26,7 +26,7 @@ const CollectionNames = { [CollectionId.FeedGenerator]: Feed, [CollectionId.Profile]: Profile, [CollectionId.List]: List, - [CollectionId.Post]: Post, + [CollectionId.Post]: Post, } type ReportComponentProps = From 0e3b2633b9876ac3aea39897cdb8831da8c3c1bd Mon Sep 17 00:00:00 2001 From: Alexander K Date: Sun, 17 Mar 2024 21:34:52 +0100 Subject: [PATCH 068/109] Add 'Liberation Sans' font for FireFox on Linux; lightbox buttons adjustments --- bskyweb/templates/base.html | 4 +- .../components/ImageDefaultHeader.tsx | 49 +++++++++++------ src/view/com/lightbox/Lightbox.web.tsx | 54 +++++++++++++++---- .../com/util/forms/NativeDropdown.web.tsx | 2 +- src/view/com/util/text/Text.tsx | 15 +++++- web/index.html | 4 +- 6 files changed, 94 insertions(+), 34 deletions(-) diff --git a/bskyweb/templates/base.html b/bskyweb/templates/base.html index c7c5ec0f0b..678729ffb3 100644 --- a/bskyweb/templates/base.html +++ b/bskyweb/templates/base.html @@ -44,7 +44,7 @@ scrollbar-gutter: stable both-edges; } html, body { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Liberation Sans", Helvetica, Arial, sans-serif; } /* Buttons and inputs have a font set by UA, so we'll have to reset that */ @@ -141,7 +141,7 @@ /* ProseMirror */ .ProseMirror { - font: 18px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + font: 18px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Liberation Sans", Helvetica, Arial, sans-serif; min-height: 140px; } .ProseMirror-dark { diff --git a/src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx b/src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx index 3401adaff4..b23dfedc8c 100644 --- a/src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx +++ b/src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx @@ -7,8 +7,15 @@ */ import React from 'react' import {createHitslop} from 'lib/constants' -import {SafeAreaView, Text, TouchableOpacity, StyleSheet} from 'react-native' +import { + SafeAreaView, + TouchableOpacity, + StyleSheet, + ViewStyle, +} from 'react-native' import {t} from '@lingui/macro' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import {usePalette} from '#/lib/hooks/usePalette' type Props = { onRequestClose: () => void @@ -16,20 +23,24 @@ type Props = { const HIT_SLOP = createHitslop(16) -const ImageDefaultHeader = ({onRequestClose}: Props) => ( - - - - - -) +const ImageDefaultHeader = ({onRequestClose}: Props) => { + const pal = usePalette('default') + + return ( + + + + + + ) +} const styles = StyleSheet.create({ root: { @@ -37,8 +48,8 @@ const styles = StyleSheet.create({ pointerEvents: 'box-none', }, closeButton: { - marginRight: 8, - marginTop: 8, + marginRight: 10, + marginTop: 10, width: 44, height: 44, alignItems: 'center', @@ -53,6 +64,10 @@ const styles = StyleSheet.create({ color: '#FFF', includeFontPadding: false, }, + blurredBackground: { + backdropFilter: 'blur(10px)', + WebkitBackdropFilter: 'blur(10px)', + } as ViewStyle, }) export default ImageDefaultHeader diff --git a/src/view/com/lightbox/Lightbox.web.tsx b/src/view/com/lightbox/Lightbox.web.tsx index fb97c30a45..942c9a686e 100644 --- a/src/view/com/lightbox/Lightbox.web.tsx +++ b/src/view/com/lightbox/Lightbox.web.tsx @@ -7,6 +7,7 @@ import { StyleSheet, View, Pressable, + ViewStyle, } from 'react-native' import { FontAwesomeIcon, @@ -24,6 +25,7 @@ import { ProfileImageLightbox, } from '#/state/lightbox' import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock' +import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' interface Img { uri: string @@ -111,6 +113,14 @@ function LightboxInner({ return () => window.removeEventListener('keydown', onKeyDown) }, [onKeyDown]) + const {isTabletOrDesktop} = useWebMediaQueries() + const btnStyle = React.useMemo(() => { + return isTabletOrDesktop ? styles.btnTablet : styles.btnMobile + }, [isTabletOrDesktop]) + const iconSize = React.useMemo(() => { + return isTabletOrDesktop ? 32 : 24 + }, [isTabletOrDesktop]) + return ( )} {canGoRight && ( )} @@ -213,20 +233,30 @@ const styles = StyleSheet.create({ }, btn: { position: 'absolute', - backgroundColor: '#000', - width: 50, - height: 50, + backgroundColor: '#00000077', justifyContent: 'center', alignItems: 'center', + }, + btnTablet: { + width: 50, + height: 50, borderRadius: 25, + left: 30, + right: 30, + }, + btnMobile: { + width: 44, + height: 44, + borderRadius: 22, + left: 20, + right: 20, }, leftBtn: { - left: 30, + right: 'auto', top: '50%', }, rightBtn: { - position: 'absolute', - right: 30, + left: 'auto', top: '50%', }, footer: { @@ -234,4 +264,8 @@ const styles = StyleSheet.create({ paddingVertical: 24, backgroundColor: colors.black, }, + blurredBackground: { + backdropFilter: 'blur(10px)', + WebkitBackdropFilter: 'blur(10px)', + } as ViewStyle, }) diff --git a/src/view/com/util/forms/NativeDropdown.web.tsx b/src/view/com/util/forms/NativeDropdown.web.tsx index 6abeb16cc2..94591d3931 100644 --- a/src/view/com/util/forms/NativeDropdown.web.tsx +++ b/src/view/com/util/forms/NativeDropdown.web.tsx @@ -237,7 +237,7 @@ const styles = StyleSheet.create({ paddingRight: 12, borderRadius: 8, fontFamily: - '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif', + '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Liberation Sans", Helvetica, Arial, sans-serif', outline: 0, border: 0, }, diff --git a/src/view/com/util/text/Text.tsx b/src/view/com/util/text/Text.tsx index ccb51bfca6..37d6655815 100644 --- a/src/view/com/util/text/Text.tsx +++ b/src/view/com/util/text/Text.tsx @@ -2,7 +2,7 @@ import React from 'react' import {Text as RNText, TextProps} from 'react-native' import {s, lh} from 'lib/styles' import {useTheme, TypographyVariant} from 'lib/ThemeContext' -import {isIOS} from 'platform/detection' +import {isIOS, isWeb} from 'platform/detection' import {UITextView} from 'react-native-ui-text-view' export type CustomTextProps = TextProps & { @@ -13,6 +13,11 @@ export type CustomTextProps = TextProps & { selectable?: boolean } +const fontFamilyStyle = { + fontFamily: + '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Liberation Sans", Helvetica, Arial, sans-serif', +} + export function Text({ type = 'md', children, @@ -39,7 +44,13 @@ export function Text({ return ( Date: Sun, 17 Mar 2024 22:20:50 +0100 Subject: [PATCH 069/109] remove scrollbar gutter for Chrome when body scroll is locked --- src/lib/hooks/useWebBodyScrollLock.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/hooks/useWebBodyScrollLock.ts b/src/lib/hooks/useWebBodyScrollLock.ts index 585f193f1f..0dcf911fe4 100644 --- a/src/lib/hooks/useWebBodyScrollLock.ts +++ b/src/lib/hooks/useWebBodyScrollLock.ts @@ -6,6 +6,7 @@ let refCount = 0 function incrementRefCount() { if (refCount === 0) { document.body.style.overflow = 'hidden' + document.documentElement.style.scrollbarGutter = 'auto' } refCount++ } @@ -14,6 +15,7 @@ function decrementRefCount() { refCount-- if (refCount === 0) { document.body.style.overflow = '' + document.documentElement.style.scrollbarGutter = '' } } From fbfb78b8604598954e7959f68afc32686a468085 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Mon, 18 Mar 2024 14:37:30 +0000 Subject: [PATCH 070/109] change usage of t to msg --- .../select-language/SelectLangBtn.tsx | 8 ++-- .../components/ImageDefaultHeader.tsx | 37 +++++++++++-------- .../com/util/BottomSheetCustomBackdrop.tsx | 7 +++- src/view/com/util/ErrorBoundary.tsx | 23 +++++++++--- src/view/shell/index.web.tsx | 11 ++++-- 5 files changed, 54 insertions(+), 32 deletions(-) diff --git a/src/view/com/composer/select-language/SelectLangBtn.tsx b/src/view/com/composer/select-language/SelectLangBtn.tsx index 78b1e9ba27..cfc53d67be 100644 --- a/src/view/com/composer/select-language/SelectLangBtn.tsx +++ b/src/view/com/composer/select-language/SelectLangBtn.tsx @@ -20,7 +20,7 @@ import { toPostLanguages, hasPostLanguage, } from '#/state/preferences/languages' -import {t, msg} from '@lingui/macro' +import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' export function SelectLangBtn() { @@ -84,15 +84,15 @@ export function SelectLangBtn() { } return [ - {heading: true, label: t`Post language`}, + {heading: true, label: _(msg`Post language`)}, ...arr.slice(0, 6), {sep: true}, { - label: t`Other...`, + label: _(`Other...`), onPress: onPressMore, }, ] - }, [onPressMore, langPrefs, setLangPrefs, postLanguagesPref]) + }, [onPressMore, langPrefs, setLangPrefs, postLanguagesPref, _]) return ( void @@ -16,20 +18,23 @@ type Props = { const HIT_SLOP = createHitslop(16) -const ImageDefaultHeader = ({onRequestClose}: Props) => ( - - - - - -) +const ImageDefaultHeader = ({onRequestClose}: Props) => { + const {_} = useLingui() + return ( + + + + + + ) +} const styles = StyleSheet.create({ root: { diff --git a/src/view/com/util/BottomSheetCustomBackdrop.tsx b/src/view/com/util/BottomSheetCustomBackdrop.tsx index ed5a2f1654..ab6570252c 100644 --- a/src/view/com/util/BottomSheetCustomBackdrop.tsx +++ b/src/view/com/util/BottomSheetCustomBackdrop.tsx @@ -6,12 +6,15 @@ import Animated, { interpolate, useAnimatedStyle, } from 'react-native-reanimated' -import {t} from '@lingui/macro' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' export function createCustomBackdrop( onClose?: (() => void) | undefined, ): React.FC { const CustomBackdrop = ({animatedIndex, style}: BottomSheetBackdropProps) => { + const {_} = useLingui() + // animated variables const opacity = useAnimatedStyle(() => ({ opacity: interpolate( @@ -30,7 +33,7 @@ export function createCustomBackdrop( return ( { if (onClose !== undefined) { diff --git a/src/view/com/util/ErrorBoundary.tsx b/src/view/com/util/ErrorBoundary.tsx index 5ec1d00144..22fdd606e4 100644 --- a/src/view/com/util/ErrorBoundary.tsx +++ b/src/view/com/util/ErrorBoundary.tsx @@ -1,8 +1,9 @@ import React, {Component, ErrorInfo, ReactNode} from 'react' import {ErrorScreen} from './error/ErrorScreen' import {CenteredView} from './Views' -import {t} from '@lingui/macro' +import {msg} from '@lingui/macro' import {logger} from '#/logger' +import {useLingui} from '@lingui/react' interface Props { children?: ReactNode @@ -31,11 +32,7 @@ export class ErrorBoundary extends Component { if (this.state.hasError) { return ( - + ) } @@ -43,3 +40,17 @@ export class ErrorBoundary extends Component { return this.props.children } } + +function TranslatedErrorScreen({details}: {details?: string}) { + const {_} = useLingui() + + return ( + + ) +} diff --git a/src/view/shell/index.web.tsx b/src/view/shell/index.web.tsx index 71dccb8c48..24024e6e61 100644 --- a/src/view/shell/index.web.tsx +++ b/src/view/shell/index.web.tsx @@ -1,5 +1,9 @@ import React, {useEffect} from 'react' import {View, StyleSheet, TouchableOpacity} from 'react-native' +import {useNavigation} from '@react-navigation/native' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + import {ErrorBoundary} from '../com/util/ErrorBoundary' import {Lightbox} from '../com/lightbox/Lightbox' import {ModalsContainer} from '../com/modals/Modal' @@ -9,9 +13,7 @@ import {s, colors} from 'lib/styles' import {RoutesContainer, FlatNavigator} from '../../Navigation' import {DrawerContent} from './Drawer' import {useWebMediaQueries} from '../../lib/hooks/useWebMediaQueries' -import {useNavigation} from '@react-navigation/native' import {NavigationProp} from 'lib/routes/types' -import {t} from '@lingui/macro' import {useIsDrawerOpen, useSetDrawerOpen} from '#/state/shell' import {useCloseAllActiveElements} from '#/state/util' import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock' @@ -24,6 +26,7 @@ function ShellInner() { const {isDesktop} = useWebMediaQueries() const navigator = useNavigation() const closeAllActiveElements = useCloseAllActiveElements() + const {_} = useLingui() useWebBodyScrollLock(isDrawerOpen) @@ -48,8 +51,8 @@ function ShellInner() { setDrawerOpen(false)} style={styles.drawerMask} - accessibilityLabel={t`Close navigation footer`} - accessibilityHint={t`Closes bottom navigation bar`}> + accessibilityLabel={_(msg`Close navigation footer`)} + accessibilityHint={_(msg`Closes bottom navigation bar`)}> From 79175e2a0940d742311ba459bc2c233a45b7cc49 Mon Sep 17 00:00:00 2001 From: Hailey Date: Mon, 18 Mar 2024 08:40:43 -0700 Subject: [PATCH 071/109] Fix PR labeler bot comment delete (#3249) --- .github/workflows/pull-request-commit.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull-request-commit.yml b/.github/workflows/pull-request-commit.yml index 72381a32d0..b233bc4cde 100644 --- a/.github/workflows/pull-request-commit.yml +++ b/.github/workflows/pull-request-commit.yml @@ -114,7 +114,7 @@ jobs: id: old_comment with: issue-number: ${{ github.event.pull_request.number }} - comment-author: 'expo-bot' + comment-author: 'github-actions' body-includes: - name: 💬 Add comment with fingerprint @@ -182,4 +182,4 @@ jobs: comment_id: '${{ steps.old_comment.outputs.comment-id }}', owner: context.repo.owner, repo: context.repo.repo, - }); \ No newline at end of file + }); From 574c8b913d42fe94832b19645ff67e77f6b02bec Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Mon, 18 Mar 2024 16:01:48 +0000 Subject: [PATCH 072/109] Add missing macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gildásio Filho --- src/view/com/composer/select-language/SelectLangBtn.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/com/composer/select-language/SelectLangBtn.tsx b/src/view/com/composer/select-language/SelectLangBtn.tsx index cfc53d67be..7856222259 100644 --- a/src/view/com/composer/select-language/SelectLangBtn.tsx +++ b/src/view/com/composer/select-language/SelectLangBtn.tsx @@ -88,7 +88,7 @@ export function SelectLangBtn() { ...arr.slice(0, 6), {sep: true}, { - label: _(`Other...`), + label: _(msg`Other...`), onPress: onPressMore, }, ] From 88ab83bd52a76fb08a51970831f5ff1e86edd326 Mon Sep 17 00:00:00 2001 From: Hailey Date: Mon, 18 Mar 2024 09:09:08 -0700 Subject: [PATCH 073/109] Properly fill container for YT Shorts videos (#3238) account for jest account for jest yt iframe fill container --- bskyweb/static/iframe/youtube.html | 12 +++++------- src/lib/strings/embed-player.ts | 13 +++++++++++-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/bskyweb/static/iframe/youtube.html b/bskyweb/static/iframe/youtube.html index f2ada2ec55..4b74d6fcd9 100644 --- a/bskyweb/static/iframe/youtube.html +++ b/bskyweb/static/iframe/youtube.html @@ -5,16 +5,14 @@ } .container { position: relative; - width: 100%; - height: 0; - padding-bottom: 56.25%; + overflow: hidden; + width: 100vw; + height: 100vh; } .video { position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; + width: 100vw; + height: 100vh; }
diff --git a/src/lib/strings/embed-player.ts b/src/lib/strings/embed-player.ts index 1cf3b12937..ee73284785 100644 --- a/src/lib/strings/embed-player.ts +++ b/src/lib/strings/embed-player.ts @@ -2,6 +2,15 @@ import {Dimensions} from 'react-native' import {isWeb} from 'platform/detection' const {height: SCREEN_HEIGHT} = Dimensions.get('window') +const IFRAME_HOST = isWeb + ? // @ts-ignore only for web + window.location.host === 'localhost:8100' + ? 'http://localhost:8100' + : 'https://bsky.app' + : __DEV__ && !process.env.JEST_WORKER_ID + ? 'http://localhost:8100' + : 'https://bsky.app' + export const embedPlayerSources = [ 'youtube', 'youtubeShorts', @@ -74,7 +83,7 @@ export function parseEmbedPlayerFromUrl( return { type: 'youtube_video', source: 'youtube', - playerUri: `https://bsky.app/iframe/youtube.html?videoId=${videoId}&start=${seek}`, + playerUri: `${IFRAME_HOST}/iframe/youtube.html?videoId=${videoId}&start=${seek}`, } } } @@ -93,7 +102,7 @@ export function parseEmbedPlayerFromUrl( type: page === 'shorts' ? 'youtube_short' : 'youtube_video', source: page === 'shorts' ? 'youtubeShorts' : 'youtube', hideDetails: page === 'shorts' ? true : undefined, - playerUri: `https://bsky.app/iframe/youtube.html?videoId=${videoId}&start=${seek}`, + playerUri: `${IFRAME_HOST}/iframe/youtube.html?videoId=${videoId}&start=${seek}`, } } } From d5ebbeb3fc2802e80f55162996b6baabbf764f9c Mon Sep 17 00:00:00 2001 From: Hailey Date: Mon, 18 Mar 2024 09:59:39 -0700 Subject: [PATCH 074/109] Use [bot] in action username (#3250) --- .github/workflows/pull-request-commit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request-commit.yml b/.github/workflows/pull-request-commit.yml index b233bc4cde..85ebae4dba 100644 --- a/.github/workflows/pull-request-commit.yml +++ b/.github/workflows/pull-request-commit.yml @@ -114,7 +114,7 @@ jobs: id: old_comment with: issue-number: ${{ github.event.pull_request.number }} - comment-author: 'github-actions' + comment-author: 'github-actions[bot]' body-includes: - name: 💬 Add comment with fingerprint From 20d463ff2f5a112473f75a21595b3d89b8dfc0b0 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Mon, 18 Mar 2024 12:46:28 -0700 Subject: [PATCH 075/109] 3p moderation services [WIP] (#2550) * Add modservice screen and profile-header-card * Drop the guidelines for now * Remove ununsed constants * Add label & label group descriptions * Not found state * Reorg, add icon * Subheader * Header * Complete header * Clean up * Add all groups * Fix scroll view * Dialogs side quest * Remove log * Add (WIP) debug mod page * Dialog solution * Add note * Clean up and reorganize localized moderation strings * Memoize * Add example * Add first ReportDialog screen * Report dialog step 2 * Submit * Integrate updates * Move moderation screen * Migrate buttons * Migrate everything * Rough sketch * Fix types * Update atoms values * Abstract ModerationServiceCard * Hook up data to settings page * Handle subscription * Rough enablement * Rough enablement * Some validation, fixes * More work on the mod debug screen * Hook up data * Update invalidation * Hook up data to ReportDialog * Fix native error * Refactor/rewrite the entire moderation-application system * Fix toggles * Add copyright and other option to report * Handle reports on profile vs content * Little cleanup * Get post hiding back in gear * Better loading flow on Mod screen * Clean up Mod screen * Clean up ProfileMod screen * Handle muting correctly * Update enablement on ProfileMod screen * Improve Moderation screen and dialog * Styling, handle disabled labelers * Rework list of labels on own content * Use moderateNotification() * ReportDialog updates * Fix button overflow * Simplify the ProfileModerationService ui * Mod screen design * Move moderation card from the profile header to a tab * Small tweaks to the moderation screen * Enable toggle on mod page * Add notifs to debugmod and dont filter notifs from followed users * Add moderator-service profile view * Wire up more of the modservice data to profiles * A bunch of speculative non-working UI * Cleanup: delete old code * Update ModerationDetailsDialog * Update ReportDialog * Update LabelsOnMe dialog * Handle ReportDialog load better * Rename LabelsOnMeDialog, fix close * Experiment to put labeling under a tab of a normal profile * Moderator variation of profile * Remove dead code and start moving toward latest modsdk * Remove a bunch of now-dead label strings * Update ModDebug to be a bit more intuitive and support custom labels * Minor ui tweaks * Improve consistency of display name blurring * Fix profile-card warning rendering * More debugmod UI tuning * Update to use new labeler semantics * Delete some dead code and do some refactoring * Update profile to pull from labeler definition * Implement new label config controls (wip) * Tweak ui * Implement preference controls on labelers * Rework label pref ui * Get moderation screen working * Add asyncstorage query persistence * Implement label handling * Small cleanup * Implement Likes dialog * Fix: remove text outside of text element * Cleanup * Fix likes dialog on mobile * Implement the label appeal flow * Get report flow working again with temporarily fixed report options * Update onboarding * Enforce limit of ten labeler subscriptions * Fix type errors * Fix lint errors * Improve types of RQ * Some work on Likes dialog, needs discussion * Bit of ReportDialog cleanup * Replace non-single-path SVG * Update nudity descriptions * Update to use new sdk updates * Add adult-content-enabled behavior to label config * Use the default setting of custom labels * Handle global moderation label prefs with the global settings * Fix missing postAuthor * Fix empty moderation page * Add mutewords control back to Mod screen * Tweak adult setting styles * Remove deprecated global labels * Handle underage users on mod screen * Adjust font sizes * Swap in RichText * Like button improvements * Tweaks to Labeler profile * Design tweaks for mod pref dialog * Add tertiary button color * Switch moderation UIs to tertiary color * Update mutewords and hiddenposts to use the new sdk * Add test-environment mod authority * Switch 'gore' to 'graphic-media' * Move nudity out of the adult content control * Remove focus styles from buttons - let the browser behavior handle it * Fixes to the adult content age-gating in moderaiton * Ditch tertiary button color, lighten secondary button * Fix some colors * Remove focused overrides from toggles * Liked by screen * Rework the moderationlabelpref * Fix optimistic like * Cleanup * Change how onboarding handles adult content enabled/disabled * Add special handling of the mod authorities * Tweaks * Update the default labeler avatar to a shield * Add route to go server * Avoid dups due to bad config * Fix attrs * Fix: dont try to detect link/label mismatches on post meta * Correctly show the label behavior when adult content is disabled * Readd the local hiddenPosts handling * WIP * Fix bad merge * Conten hider design tweaks * Fix text string breakage * Adjust source text in ContentHider * Fix link bug * Design tweaks to ContentHider and ModDetailsDialog * Adjust spacing of inform badges * Adjust spacing of embeds in posts * Style tweaks to post/profile alerts * Labels on me and dialog * Remove bad focus styles from post dropdown * Better spacing solution * Tune moderation UIs * Moderation UI tweaks for mobile * Move labelers query on Mod screen * Update to use new SDK appLabelers semantics * Implement report submission * Replace the report modal entirely with the report dialog * Add @ to mod details dialog handle * Bump SDK package * Remove silly type * Add to AWS build CI * Fix ToggleButton overflow * Clean up ModServiceCard, rename to LabelingServiceCard * Hackfix to translate gore labels to graphic-media * Tune content hider sizing on web desktop * Handle self labels * Fix spacing below text-only posts * Fix: send appeals to the right labeler * Give mod page links interactive states * Fix references * Remove focus handling * Remove remnant * Remove the like count from the subscribed labeler listing * Bump @atproto/api@0.11.1 * Remove extra @ * Fix: persist labels to local storage to reduce coverage gaps * update dipendencies * revert dipendencies * Add some explainers on how blocking affects labelers * Tweak copy * Fix underline color in header * Fix profile menu * Handle card overflow * Remove metrics from header * Mute 'account' not 'user' * Show metrics if self * Show the labels tab on logged out view * Fix bad merge * Use purple theming on labelers * Tighten space on LabelerCard * Set staleTime to 6hrs for labeler details * Memoize the memoizers * Drop staleTime to 60s * Move label defs into a context to reduce recomputes * Submit view tweaks * Move labeler fetch below auth * Mitigation: hardcode the bluesky moderation labeler name * Bump sdk * Add missing translated string Co-authored-by: Takayuki KUSANO <65759+tkusano@users.noreply.github.com> * Add missing translated string Co-authored-by: Takayuki KUSANO <65759+tkusano@users.noreply.github.com> * Hailey's fix for incorrect profile tabs Co-authored-by: Hailey * Feedback * Fix borders, add bottom space * Hailey's fix pt 2 Co-authored-by: Hailey * Fix post tabs * Integrate feedback pt 1 Co-authored-by: Takayuki KUSANO <65759+tkusano@users.noreply.github.com> * Integrate feedback pt 2 Co-authored-by: Takayuki KUSANO <65759+tkusano@users.noreply.github.com> * Integrate feedback pt 3 Co-authored-by: Takayuki KUSANO <65759+tkusano@users.noreply.github.com> * Integrate feedback pt 4 Co-authored-by: Takayuki KUSANO <65759+tkusano@users.noreply.github.com> * Integrate feedback pt 5 Co-authored-by: Takayuki KUSANO <65759+tkusano@users.noreply.github.com> * Integrate feedback pt 6 Co-authored-by: Takayuki KUSANO <65759+tkusano@users.noreply.github.com> * Integrate feedback pt 7 Co-authored-by: Takayuki KUSANO <65759+tkusano@users.noreply.github.com> * Integrate feedback pt 8 Co-authored-by: Takayuki KUSANO <65759+tkusano@users.noreply.github.com> * Format * Integrate new bday modal * Use public agent for getServices * Update casing --------- Co-authored-by: Eric Bailey Co-authored-by: Takayuki KUSANO <65759+tkusano@users.noreply.github.com> Co-authored-by: Hailey --- .../workflows/build-and-push-bskyweb-aws.yaml | 4 +- ...TriangleBottom_stroke2_corner1_rounded.svg | 1 + .../icons/bars3_stroke2_corner0_rounded.svg | 1 + .../chevronBottom_stroke2_corner0_rounded.svg | 1 + .../chevronTop_stroke2_corner0_rounded.svg | 1 + .../circleBanSign_stroke2_corner0_rounded.svg | 1 + .../icons/group3_stroke2_corner0_rounded.svg | 1 + .../heart2_filled_stroke2_corner0_rounded.svg | 1 + .../icons/heart2_stroke2_corner0_rounded.svg | 1 + .../icons/person_stroke2_corner0_rounded.svg | 1 + ...ingHand4Finger_stroke2_corner0_rounded.svg | 1 + .../settingsGear2_stroke2_corner0_rounded.svg | 1 + .../icons/shield_stroke2_corner0_rounded.svg | 1 + ...eArrowTopRight_stroke2_corner0_rounded.svg | 1 + ...eBehindSquare4_stroke2_corner0_rounded.svg | 1 + ...gleExclamation_stroke2_corner2_rounded.svg | 1 + bskyweb/cmd/bskyweb/server.go | 2 + package.json | 4 +- src/App.native.tsx | 47 +- src/App.web.tsx | 47 +- src/Navigation.tsx | 14 +- src/alf/atoms.ts | 10 + src/alf/tokens.ts | 3 + src/components/Button.tsx | 28 +- src/components/Dialog/index.web.tsx | 2 +- src/components/GradientFill.tsx | 27 + src/components/LabelingServiceCard/index.tsx | 182 ++++ src/components/LikedByList.tsx | 109 +++ src/components/LikesDialog.tsx | 131 +++ src/components/Link.tsx | 2 +- src/components/Lists.tsx | 2 +- src/components/Menu/index.web.tsx | 2 +- .../ReportDialog/SelectReportOptionView.tsx | 183 ++++ src/components/ReportDialog/SubmitView.tsx | 262 +++++ src/components/ReportDialog/const.ts | 1 + src/components/ReportDialog/index.tsx | 73 ++ src/components/ReportDialog/types.ts | 15 + src/components/TagMenu/index.tsx | 2 +- src/components/TagMenu/index.web.tsx | 2 +- src/components/Typography.tsx | 9 +- src/components/dialogs/Context.tsx | 2 +- src/components/dialogs/MutedWords.tsx | 4 +- src/components/forms/Toggle.tsx | 40 +- src/components/forms/ToggleButton.tsx | 8 +- src/components/hooks/useDelayedLoading.ts | 15 + src/components/icons/ArrowTriangle.tsx | 5 + src/components/icons/Bars.tsx | 5 + src/components/icons/Chevron.tsx | 8 + src/components/icons/CircleBanSign.tsx | 5 + src/components/icons/Gear.tsx | 5 + .../icons/{Group3.tsx => Group.tsx} | 0 src/components/icons/RaisingHand.tsx | 5 + src/components/icons/Shield.tsx | 5 + src/components/icons/SquareArrowTopRight.tsx | 5 + src/components/icons/SquareBehindSquare4.tsx | 5 + src/components/moderation/ContentHider.tsx | 182 ++++ .../moderation/GlobalModerationLabelPref.tsx | 93 ++ src/components/moderation/LabelsOnMe.tsx | 83 ++ .../moderation/LabelsOnMeDialog.tsx | 262 +++++ .../moderation/ModerationDetailsDialog.tsx | 148 +++ .../moderation/ModerationLabelPref.tsx | 154 +++ src/components/moderation/PostAlerts.tsx | 66 ++ .../moderation/PostHider.tsx | 93 +- .../moderation/ProfileHeaderAlerts.tsx | 66 ++ src/components/moderation/ScreenHider.tsx | 171 ++++ .../__tests__/moderatePost_wrapped.test.ts | 692 ------------- src/lib/constants.ts | 4 + src/lib/moderatePost_wrapped.ts | 392 +------- src/lib/moderation.ts | 204 ++-- src/lib/moderation/useGlobalLabelStrings.ts | 52 + .../moderation/useLabelBehaviorDescription.ts | 70 ++ src/lib/moderation/useLabelInfo.ts | 100 ++ .../useModerationCauseDescription.ts | 146 +++ src/lib/moderation/useReportOptions.ts | 94 ++ src/lib/react-query.ts | 20 + src/lib/routes/types.ts | 2 + src/lib/strings/display-names.ts | 3 +- src/lib/themes.ts | 2 +- src/routes.ts | 2 + src/screens/Moderation/index.tsx | 560 +++++++++++ .../AdultContentEnabledPref.tsx | 9 +- .../StepModeration/ModerationOption.tsx | 91 +- .../Onboarding/StepModeration/index.tsx | 48 +- .../SuggestedAccountCard.tsx | 2 +- .../StepSuggestedAccounts/index.tsx | 2 +- src/screens/Onboarding/StepTopicalFeeds.tsx | 8 +- src/screens/Profile/ErrorState.tsx | 72 ++ src/screens/Profile/Header/DisplayName.tsx | 31 + src/screens/Profile/Header/Handle.tsx | 46 + src/screens/Profile/Header/Metrics.tsx | 61 ++ .../Profile/Header/ProfileHeaderLabeler.tsx | 329 +++++++ .../Profile/Header/ProfileHeaderStandard.tsx | 286 ++++++ src/screens/Profile/Header/Shell.tsx | 164 ++++ src/screens/Profile/Header/index.tsx | 78 ++ src/screens/Profile/ProfileLabelerLikedBy.tsx | 46 + src/screens/Profile/Sections/Feed.tsx | 88 ++ src/screens/Profile/Sections/Labels.tsx | 233 +++++ src/screens/Profile/Sections/types.ts | 3 + src/state/modals/index.tsx | 38 +- src/state/preferences/index.tsx | 1 + src/state/preferences/label-defs.tsx | 25 + src/state/queries/actor-autocomplete.ts | 19 +- src/state/queries/labeler.ts | 89 ++ src/state/queries/notifications/util.ts | 30 +- src/state/queries/post-feed.ts | 26 +- src/state/queries/post-liked-by.ts | 4 +- src/state/queries/preferences/const.ts | 18 +- src/state/queries/preferences/index.ts | 100 +- src/state/queries/preferences/moderation.ts | 214 +--- src/state/queries/preferences/types.ts | 33 - src/state/queries/preferences/util.ts | 16 - src/state/queries/profile-extra-info.ts | 34 - src/state/queries/suggested-follows.ts | 3 +- src/state/session/agent-config.ts | 12 + src/state/session/index.tsx | 41 +- src/state/shell/composer.tsx | 4 +- src/view/com/auth/create/state.ts | 4 +- .../onboarding/RecommendedFollowsItem.tsx | 10 +- src/view/com/composer/Composer.tsx | 2 +- src/view/com/composer/ComposerReplyTo.tsx | 6 +- src/view/com/modals/AppealLabel.tsx | 139 --- .../com/modals/ContentFilteringSettings.tsx | 407 -------- src/view/com/modals/Modal.tsx | 16 - src/view/com/modals/Modal.web.tsx | 12 - src/view/com/modals/ModerationDetails.tsx | 142 --- .../com/modals/report/InputIssueDetails.tsx | 100 -- src/view/com/modals/report/Modal.tsx | 223 ----- src/view/com/modals/report/ReasonOptions.tsx | 123 --- .../com/modals/report/SendReportButton.tsx | 62 -- src/view/com/modals/report/types.ts | 8 - src/view/com/notifications/FeedItem.tsx | 10 +- src/view/com/post-thread/PostLikedBy.tsx | 4 +- src/view/com/post-thread/PostThread.tsx | 11 +- src/view/com/post-thread/PostThreadItem.tsx | 90 +- src/view/com/post/Post.tsx | 32 +- src/view/com/posts/FeedItem.tsx | 49 +- src/view/com/profile/ProfileCard.tsx | 91 +- src/view/com/profile/ProfileHeader.tsx | 598 ------------ .../profile/ProfileHeaderSuggestedFollows.tsx | 4 +- src/view/com/profile/ProfileMenu.tsx | 83 +- src/view/com/util/Link.tsx | 8 +- src/view/com/util/PostMeta.tsx | 10 +- src/view/com/util/UserAvatar.tsx | 29 +- src/view/com/util/UserBanner.tsx | 12 +- src/view/com/util/forms/PostDropdownBtn.tsx | 46 +- src/view/com/util/moderation/ContentHider.tsx | 145 --- src/view/com/util/moderation/LabelInfo.tsx | 61 -- src/view/com/util/moderation/PostAlerts.tsx | 67 -- .../util/moderation/ProfileHeaderAlerts.tsx | 89 -- src/view/com/util/moderation/ScreenHider.tsx | 180 ---- src/view/com/util/post-ctrls/PostCtrls.tsx | 3 - src/view/com/util/post-embeds/QuoteEmbed.tsx | 129 ++- src/view/com/util/post-embeds/index.tsx | 106 +- src/view/screens/DebugMod.tsx | 923 ++++++++++++++++++ src/view/screens/Moderation.tsx | 304 ------ src/view/screens/Profile.tsx | 253 +++-- src/view/screens/ProfileFeed.tsx | 21 +- src/view/screens/ProfileList.tsx | 18 +- src/view/screens/Settings/index.tsx | 14 + src/view/screens/Storybook/Buttons.tsx | 41 + src/view/screens/Storybook/index.tsx | 1 + src/view/shell/desktop/Search.tsx | 8 +- src/view/shell/index.tsx | 2 +- src/view/shell/index.web.tsx | 3 +- yarn.lock | 84 +- 165 files changed, 7034 insertions(+), 5009 deletions(-) create mode 100644 assets/icons/arrowTriangleBottom_stroke2_corner1_rounded.svg create mode 100644 assets/icons/bars3_stroke2_corner0_rounded.svg create mode 100644 assets/icons/chevronBottom_stroke2_corner0_rounded.svg create mode 100644 assets/icons/chevronTop_stroke2_corner0_rounded.svg create mode 100644 assets/icons/circleBanSign_stroke2_corner0_rounded.svg create mode 100644 assets/icons/group3_stroke2_corner0_rounded.svg create mode 100644 assets/icons/heart2_filled_stroke2_corner0_rounded.svg create mode 100644 assets/icons/heart2_stroke2_corner0_rounded.svg create mode 100644 assets/icons/person_stroke2_corner0_rounded.svg create mode 100644 assets/icons/raisingHand4Finger_stroke2_corner0_rounded.svg create mode 100644 assets/icons/settingsGear2_stroke2_corner0_rounded.svg create mode 100644 assets/icons/shield_stroke2_corner0_rounded.svg create mode 100644 assets/icons/squareArrowTopRight_stroke2_corner0_rounded.svg create mode 100644 assets/icons/squareBehindSquare4_stroke2_corner0_rounded.svg create mode 100644 assets/icons/triangleExclamation_stroke2_corner2_rounded.svg create mode 100644 src/components/GradientFill.tsx create mode 100644 src/components/LabelingServiceCard/index.tsx create mode 100644 src/components/LikedByList.tsx create mode 100644 src/components/LikesDialog.tsx create mode 100644 src/components/ReportDialog/SelectReportOptionView.tsx create mode 100644 src/components/ReportDialog/SubmitView.tsx create mode 100644 src/components/ReportDialog/const.ts create mode 100644 src/components/ReportDialog/index.tsx create mode 100644 src/components/ReportDialog/types.ts create mode 100644 src/components/hooks/useDelayedLoading.ts create mode 100644 src/components/icons/ArrowTriangle.tsx create mode 100644 src/components/icons/Bars.tsx create mode 100644 src/components/icons/CircleBanSign.tsx create mode 100644 src/components/icons/Gear.tsx rename src/components/icons/{Group3.tsx => Group.tsx} (100%) create mode 100644 src/components/icons/RaisingHand.tsx create mode 100644 src/components/icons/Shield.tsx create mode 100644 src/components/icons/SquareArrowTopRight.tsx create mode 100644 src/components/icons/SquareBehindSquare4.tsx create mode 100644 src/components/moderation/ContentHider.tsx create mode 100644 src/components/moderation/GlobalModerationLabelPref.tsx create mode 100644 src/components/moderation/LabelsOnMe.tsx create mode 100644 src/components/moderation/LabelsOnMeDialog.tsx create mode 100644 src/components/moderation/ModerationDetailsDialog.tsx create mode 100644 src/components/moderation/ModerationLabelPref.tsx create mode 100644 src/components/moderation/PostAlerts.tsx rename src/{view/com/util => components}/moderation/PostHider.tsx (54%) create mode 100644 src/components/moderation/ProfileHeaderAlerts.tsx create mode 100644 src/components/moderation/ScreenHider.tsx delete mode 100644 src/lib/__tests__/moderatePost_wrapped.test.ts create mode 100644 src/lib/moderation/useGlobalLabelStrings.ts create mode 100644 src/lib/moderation/useLabelBehaviorDescription.ts create mode 100644 src/lib/moderation/useLabelInfo.ts create mode 100644 src/lib/moderation/useModerationCauseDescription.ts create mode 100644 src/lib/moderation/useReportOptions.ts create mode 100644 src/screens/Moderation/index.tsx create mode 100644 src/screens/Profile/ErrorState.tsx create mode 100644 src/screens/Profile/Header/DisplayName.tsx create mode 100644 src/screens/Profile/Header/Handle.tsx create mode 100644 src/screens/Profile/Header/Metrics.tsx create mode 100644 src/screens/Profile/Header/ProfileHeaderLabeler.tsx create mode 100644 src/screens/Profile/Header/ProfileHeaderStandard.tsx create mode 100644 src/screens/Profile/Header/Shell.tsx create mode 100644 src/screens/Profile/Header/index.tsx create mode 100644 src/screens/Profile/ProfileLabelerLikedBy.tsx create mode 100644 src/screens/Profile/Sections/Feed.tsx create mode 100644 src/screens/Profile/Sections/Labels.tsx create mode 100644 src/screens/Profile/Sections/types.ts create mode 100644 src/state/preferences/label-defs.tsx create mode 100644 src/state/queries/labeler.ts delete mode 100644 src/state/queries/preferences/util.ts delete mode 100644 src/state/queries/profile-extra-info.ts create mode 100644 src/state/session/agent-config.ts delete mode 100644 src/view/com/modals/AppealLabel.tsx delete mode 100644 src/view/com/modals/ContentFilteringSettings.tsx delete mode 100644 src/view/com/modals/ModerationDetails.tsx delete mode 100644 src/view/com/modals/report/InputIssueDetails.tsx delete mode 100644 src/view/com/modals/report/Modal.tsx delete mode 100644 src/view/com/modals/report/ReasonOptions.tsx delete mode 100644 src/view/com/modals/report/SendReportButton.tsx delete mode 100644 src/view/com/modals/report/types.ts delete mode 100644 src/view/com/profile/ProfileHeader.tsx delete mode 100644 src/view/com/util/moderation/ContentHider.tsx delete mode 100644 src/view/com/util/moderation/LabelInfo.tsx delete mode 100644 src/view/com/util/moderation/PostAlerts.tsx delete mode 100644 src/view/com/util/moderation/ProfileHeaderAlerts.tsx delete mode 100644 src/view/com/util/moderation/ScreenHider.tsx create mode 100644 src/view/screens/DebugMod.tsx delete mode 100644 src/view/screens/Moderation.tsx diff --git a/.github/workflows/build-and-push-bskyweb-aws.yaml b/.github/workflows/build-and-push-bskyweb-aws.yaml index fef24f952b..3f60705792 100644 --- a/.github/workflows/build-and-push-bskyweb-aws.yaml +++ b/.github/workflows/build-and-push-bskyweb-aws.yaml @@ -3,8 +3,8 @@ on: push: branches: - main - - traffic-reduction - - respect-optout-for-embeds + - 3p-moderators + env: REGISTRY: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_REGISTRY }} USERNAME: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_USERNAME }} diff --git a/assets/icons/arrowTriangleBottom_stroke2_corner1_rounded.svg b/assets/icons/arrowTriangleBottom_stroke2_corner1_rounded.svg new file mode 100644 index 0000000000..f40546f7cd --- /dev/null +++ b/assets/icons/arrowTriangleBottom_stroke2_corner1_rounded.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/bars3_stroke2_corner0_rounded.svg b/assets/icons/bars3_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..cbcb531a6e --- /dev/null +++ b/assets/icons/bars3_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/chevronBottom_stroke2_corner0_rounded.svg b/assets/icons/chevronBottom_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..705c1c5139 --- /dev/null +++ b/assets/icons/chevronBottom_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/chevronTop_stroke2_corner0_rounded.svg b/assets/icons/chevronTop_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..da94ba911f --- /dev/null +++ b/assets/icons/chevronTop_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/circleBanSign_stroke2_corner0_rounded.svg b/assets/icons/circleBanSign_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..73251477fa --- /dev/null +++ b/assets/icons/circleBanSign_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/group3_stroke2_corner0_rounded.svg b/assets/icons/group3_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..2a8f43a8a4 --- /dev/null +++ b/assets/icons/group3_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/heart2_filled_stroke2_corner0_rounded.svg b/assets/icons/heart2_filled_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..1dfefb4c99 --- /dev/null +++ b/assets/icons/heart2_filled_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/heart2_stroke2_corner0_rounded.svg b/assets/icons/heart2_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..5b3da8e00e --- /dev/null +++ b/assets/icons/heart2_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/person_stroke2_corner0_rounded.svg b/assets/icons/person_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..a23ad76071 --- /dev/null +++ b/assets/icons/person_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/raisingHand4Finger_stroke2_corner0_rounded.svg b/assets/icons/raisingHand4Finger_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..aed3d9e7ec --- /dev/null +++ b/assets/icons/raisingHand4Finger_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/settingsGear2_stroke2_corner0_rounded.svg b/assets/icons/settingsGear2_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..de8a579194 --- /dev/null +++ b/assets/icons/settingsGear2_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/shield_stroke2_corner0_rounded.svg b/assets/icons/shield_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..c4ef98e5ad --- /dev/null +++ b/assets/icons/shield_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/squareArrowTopRight_stroke2_corner0_rounded.svg b/assets/icons/squareArrowTopRight_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..1407a1d6fe --- /dev/null +++ b/assets/icons/squareArrowTopRight_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/squareBehindSquare4_stroke2_corner0_rounded.svg b/assets/icons/squareBehindSquare4_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..3fa7e5d390 --- /dev/null +++ b/assets/icons/squareBehindSquare4_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/triangleExclamation_stroke2_corner2_rounded.svg b/assets/icons/triangleExclamation_stroke2_corner2_rounded.svg new file mode 100644 index 0000000000..aa56404457 --- /dev/null +++ b/assets/icons/triangleExclamation_stroke2_corner2_rounded.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bskyweb/cmd/bskyweb/server.go b/bskyweb/cmd/bskyweb/server.go index e159d780a2..54a3925c6d 100644 --- a/bskyweb/cmd/bskyweb/server.go +++ b/bskyweb/cmd/bskyweb/server.go @@ -188,6 +188,7 @@ func serve(cctx *cli.Context) error { e.GET("/settings/threads", server.WebGeneric) e.GET("/settings/external-embeds", server.WebGeneric) e.GET("/sys/debug", server.WebGeneric) + e.GET("/sys/debug-mod", server.WebGeneric) e.GET("/sys/log", server.WebGeneric) e.GET("/support", server.WebGeneric) e.GET("/support/privacy", server.WebGeneric) @@ -203,6 +204,7 @@ func serve(cctx *cli.Context) error { e.GET("/profile/:handleOrDID/lists/:rkey", server.WebGeneric) e.GET("/profile/:handleOrDID/feed/:rkey", server.WebGeneric) e.GET("/profile/:handleOrDID/feed/:rkey/liked-by", server.WebGeneric) + e.GET("/profile/:handleOrDID/labeler/liked-by", server.WebGeneric) // profile RSS feed (DID not handle) e.GET("/profile/:ident/rss", server.WebProfileRSS) diff --git a/package.json b/package.json index 8962018208..30df66950a 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "update-extensions": "scripts/updateExtensions.sh" }, "dependencies": { - "@atproto/api": "^0.10.5", + "@atproto/api": "^0.11.2", "@bam.tech/react-native-image-resizer": "^3.0.4", "@braintree/sanitize-url": "^6.0.2", "@emoji-mart/react": "^1.1.1", @@ -76,7 +76,9 @@ "@segment/sovran-react-native": "^0.4.5", "@sentry/react-native": "5.5.0", "@tamagui/focus-scope": "^1.84.1", + "@tanstack/query-async-storage-persister": "^5.25.0", "@tanstack/react-query": "^5.8.1", + "@tanstack/react-query-persist-client": "^5.25.0", "@tiptap/core": "^2.0.0-beta.220", "@tiptap/extension-document": "^2.0.0-beta.220", "@tiptap/extension-hard-break": "^2.0.3", diff --git a/src/App.native.tsx b/src/App.native.tsx index eff8ab0997..e825ffa00a 100644 --- a/src/App.native.tsx +++ b/src/App.native.tsx @@ -5,7 +5,7 @@ import React, {useState, useEffect} from 'react' import {RootSiblingParent} from 'react-native-root-siblings' import * as SplashScreen from 'expo-splash-screen' import {GestureHandlerRootView} from 'react-native-gesture-handler' -import {QueryClientProvider} from '@tanstack/react-query' +import {PersistQueryClientProvider} from '@tanstack/react-query-persist-client' import { SafeAreaProvider, initialWindowMetrics, @@ -22,7 +22,11 @@ import {s} from 'lib/styles' import {Shell} from 'view/shell' import * as notifications from 'lib/notifications/notifications' import * as Toast from 'view/com/util/Toast' -import {queryClient} from 'lib/react-query' +import { + queryClient, + asyncStoragePersister, + dehydrateOptions, +} from 'lib/react-query' import {TestCtrls} from 'view/com/testing/TestCtrls' import {Provider as ShellStateProvider} from 'state/shell' import {Provider as ModalStateProvider} from 'state/modals' @@ -33,6 +37,7 @@ import {Provider as InvitesStateProvider} from 'state/invites' import {Provider as PrefsStateProvider} from 'state/preferences' import {Provider as LoggedOutViewProvider} from 'state/shell/logged-out' import {Provider as SelectedFeedProvider} from 'state/shell/selected-feed' +import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs' import I18nProvider from './locale/i18nProvider' import { Provider as SessionProvider, @@ -79,21 +84,23 @@ function InnerApp() { // Resets the entire tree below when it changes: key={currentAccount?.did}> - - - - - {/* All components should be within this provider */} - - - - - - - - - - + + + + + + {/* All components should be within this provider */} + + + + + + + + + + + @@ -118,7 +125,9 @@ function App() { * that is set up in the InnerApp component above. */ return ( - + @@ -140,7 +149,7 @@ function App() { - + ) } diff --git a/src/App.web.tsx b/src/App.web.tsx index eb2e425930..f47f763da1 100644 --- a/src/App.web.tsx +++ b/src/App.web.tsx @@ -1,7 +1,7 @@ import 'lib/sentry' // must be near top import React, {useState, useEffect} from 'react' -import {QueryClientProvider} from '@tanstack/react-query' +import {PersistQueryClientProvider} from '@tanstack/react-query-persist-client' import {SafeAreaProvider} from 'react-native-safe-area-context' import {RootSiblingParent} from 'react-native-root-siblings' @@ -13,7 +13,11 @@ import {init as initPersistedState} from '#/state/persisted' import {Shell} from 'view/shell/index' import {ToastContainer} from 'view/com/util/Toast.web' import {ThemeProvider} from 'lib/ThemeContext' -import {queryClient} from 'lib/react-query' +import { + queryClient, + asyncStoragePersister, + dehydrateOptions, +} from 'lib/react-query' import {Provider as ShellStateProvider} from 'state/shell' import {Provider as ModalStateProvider} from 'state/modals' import {Provider as DialogStateProvider} from 'state/dialogs' @@ -23,6 +27,7 @@ import {Provider as InvitesStateProvider} from 'state/invites' import {Provider as PrefsStateProvider} from 'state/preferences' import {Provider as LoggedOutViewProvider} from 'state/shell/logged-out' import {Provider as SelectedFeedProvider} from 'state/shell/selected-feed' +import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs' import I18nProvider from './locale/i18nProvider' import { Provider as SessionProvider, @@ -56,21 +61,23 @@ function InnerApp() { // Resets the entire tree below when it changes: key={currentAccount?.did}> - - - - - {/* All components should be within this provider */} - - - - - - - - - - + + + + + + {/* All components should be within this provider */} + + + + + + + + + + + @@ -93,7 +100,9 @@ function App() { * that is set up in the InnerApp component above. */ return ( - + @@ -115,7 +124,7 @@ function App() { - + ) } diff --git a/src/Navigation.tsx b/src/Navigation.tsx index 77706ce34d..3d6a15c4eb 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -46,7 +46,7 @@ import {SearchScreen} from './view/screens/Search' import {FeedsScreen} from './view/screens/Feeds' import {NotificationsScreen} from './view/screens/Notifications' import {ListsScreen} from './view/screens/Lists' -import {ModerationScreen} from './view/screens/Moderation' +import {ModerationScreen} from '#/screens/Moderation' import {ModerationModlistsScreen} from './view/screens/ModerationModlists' import {NotFoundScreen} from './view/screens/NotFound' import {SettingsScreen} from './view/screens/Settings' @@ -61,6 +61,7 @@ import {PostThreadScreen} from './view/screens/PostThread' import {PostLikedByScreen} from './view/screens/PostLikedBy' import {PostRepostedByScreen} from './view/screens/PostRepostedBy' import {Storybook} from './view/screens/Storybook' +import {DebugModScreen} from './view/screens/DebugMod' import {LogScreen} from './view/screens/Log' import {SupportScreen} from './view/screens/Support' import {PrivacyPolicyScreen} from './view/screens/PrivacyPolicy' @@ -78,6 +79,7 @@ import {createNativeStackNavigatorWithAuth} from './view/shell/createNativeStack import {msg} from '@lingui/macro' import {i18n, MessageDescriptor} from '@lingui/core' import HashtagScreen from '#/screens/Hashtag' +import {ProfileLabelerLikedByScreen} from '#/screens/Profile/ProfileLabelerLikedBy' import {logEvent, attachRouteToLogEvents} from './lib/statsig/statsig' const navigationRef = createNavigationContainerRef() @@ -198,11 +200,21 @@ function commonScreens(Stack: typeof HomeTab, unreadCountLabel?: string) { getComponent={() => ProfileFeedLikedByScreen} options={{title: title(msg`Liked by`)}} /> + ProfileLabelerLikedByScreen} + options={{title: title(msg`Liked by`)}} + /> Storybook} options={{title: title(msg`Storybook`), requireAuth: true}} /> + DebugModScreen} + options={{title: title(msg`Moderation states`), requireAuth: true}} + /> LogScreen} diff --git a/src/alf/atoms.ts b/src/alf/atoms.ts index 5088e3aaca..0b473ba903 100644 --- a/src/alf/atoms.ts +++ b/src/alf/atoms.ts @@ -50,6 +50,9 @@ export const atoms = { h_full: { height: '100%', }, + h_full_vh: web({ + height: '100vh', + }), /* * Border radius @@ -243,6 +246,9 @@ export const atoms = { font_normal: { fontWeight: tokens.fontWeight.normal, }, + font_semibold: { + fontWeight: '500', + }, font_bold: { fontWeight: tokens.fontWeight.semibold, }, @@ -528,6 +534,10 @@ export const atoms = { /* * Margin */ + mx_auto: { + marginLeft: 'auto', + marginRight: 'auto', + }, m_2xs: { margin: tokens.space._2xs, }, diff --git a/src/alf/tokens.ts b/src/alf/tokens.ts index b1468f461d..4045c831c5 100644 --- a/src/alf/tokens.ts +++ b/src/alf/tokens.ts @@ -12,6 +12,9 @@ export const dimScale = generateScale(12, 100) export const color = { trueBlack: '#000000', + temp_purple: 'rgb(105 0 255)', + temp_purple_dark: 'rgb(83 0 202)', + gray_0: `hsl(${BLUE_HUE}, 20%, ${scale[14]}%)`, gray_25: `hsl(${BLUE_HUE}, 20%, ${scale[13]}%)`, gray_50: `hsl(${BLUE_HUE}, 20%, ${scale[12]}%)`, diff --git a/src/components/Button.tsx b/src/components/Button.tsx index d3bf73cc3e..0e22944a33 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -15,6 +15,7 @@ import LinearGradient from 'react-native-linear-gradient' import {useTheme, atoms as a, tokens, android, flatten} from '#/alf' import {Props as SVGIconProps} from '#/components/icons/common' +import {normalizeTextStyles} from '#/components/Typography' export type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'gradient' export type ButtonColor = @@ -139,7 +140,7 @@ export function Button({ })) }, [setState]) - const {baseStyles, hoverStyles, focusStyles} = React.useMemo(() => { + const {baseStyles, hoverStyles} = React.useMemo(() => { const baseStyles: ViewStyle[] = [] const hoverStyles: ViewStyle[] = [] const light = t.name === 'light' @@ -191,14 +192,14 @@ export function Button({ if (variant === 'solid') { if (!disabled) { baseStyles.push({ - backgroundColor: t.palette.contrast_50, + backgroundColor: t.palette.contrast_25, }) hoverStyles.push({ - backgroundColor: t.palette.contrast_100, + backgroundColor: t.palette.contrast_50, }) } else { baseStyles.push({ - backgroundColor: t.palette.contrast_200, + backgroundColor: t.palette.contrast_100, }) } } else if (variant === 'outline') { @@ -308,12 +309,6 @@ export function Button({ return { baseStyles, hoverStyles, - focusStyles: [ - ...hoverStyles, - { - outline: 0, - } as ViewStyle, - ], } }, [t, variant, color, size, shape, disabled]) @@ -376,10 +371,8 @@ export function Button({ a.flex_row, a.align_center, a.justify_center, - a.justify_center, flattenedBaseStyles, ...(state.hovered || state.pressed ? hoverStyles : []), - ...(state.focused ? focusStyles : []), flatten(style), ]} onPressIn={onPressIn} @@ -398,7 +391,7 @@ export function Button({ ]}> + {children} ) diff --git a/src/components/Dialog/index.web.tsx b/src/components/Dialog/index.web.tsx index 3a7f73342d..038f6295ae 100644 --- a/src/components/Dialog/index.web.tsx +++ b/src/components/Dialog/index.web.tsx @@ -99,7 +99,7 @@ export function Outer({ style={[ web(a.fixed), a.inset_0, - {opacity: 0.5, backgroundColor: t.palette.black}, + {opacity: 0.8, backgroundColor: t.palette.black}, ]} /> )} diff --git a/src/components/GradientFill.tsx b/src/components/GradientFill.tsx new file mode 100644 index 0000000000..dc14aa72b7 --- /dev/null +++ b/src/components/GradientFill.tsx @@ -0,0 +1,27 @@ +import React from 'react' +import LinearGradient from 'react-native-linear-gradient' + +import {atoms as a, tokens} from '#/alf' + +export function GradientFill({ + gradient, +}: { + gradient: + | typeof tokens.gradients.sky + | typeof tokens.gradients.midnight + | typeof tokens.gradients.sunrise + | typeof tokens.gradients.sunset + | typeof tokens.gradients.bonfire + | typeof tokens.gradients.summer + | typeof tokens.gradients.nordic +}) { + return ( + c[1])} + locations={gradient.values.map(c => c[0])} + start={{x: 0, y: 0}} + end={{x: 1, y: 1}} + style={[a.absolute, a.inset_0]} + /> + ) +} diff --git a/src/components/LabelingServiceCard/index.tsx b/src/components/LabelingServiceCard/index.tsx new file mode 100644 index 0000000000..6d06135110 --- /dev/null +++ b/src/components/LabelingServiceCard/index.tsx @@ -0,0 +1,182 @@ +import React from 'react' +import {View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {AppBskyLabelerDefs} from '@atproto/api' + +import {getLabelingServiceTitle} from '#/lib/moderation' +import {Link as InternalLink, LinkProps} from '#/components/Link' +import {Text} from '#/components/Typography' +import {useLabelerInfoQuery} from '#/state/queries/labeler' +import {atoms as a, useTheme, ViewStyleProp} from '#/alf' +import {RichText} from '#/components/RichText' +import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '../icons/Chevron' +import {UserAvatar} from '#/view/com/util/UserAvatar' +import {sanitizeHandle} from '#/lib/strings/handles' +import {pluralize} from '#/lib/strings/helpers' + +type LabelingServiceProps = { + labeler: AppBskyLabelerDefs.LabelerViewDetailed +} + +export function Outer({ + children, + style, +}: React.PropsWithChildren) { + return ( + + {children} + + ) +} + +export function Avatar({avatar}: {avatar?: string}) { + return +} + +export function Title({value}: {value: string}) { + return {value} +} + +export function Description({value, handle}: {value?: string; handle: string}) { + return value ? ( + + + + ) : ( + + By {sanitizeHandle(handle, '@')} + + ) +} + +export function LikeCount({count}: {count: number}) { + const t = useTheme() + return ( + + + Liked by {count} {pluralize(count, 'user')} + + + ) +} + +export function Content({children}: React.PropsWithChildren<{}>) { + const t = useTheme() + + return ( + + {children} + + + + ) +} + +/** + * The canonical view for a labeling service. Use this or compose your own. + */ +export function Default({ + labeler, + style, +}: LabelingServiceProps & ViewStyleProp) { + return ( + + + + + <Description + value={labeler.creator.description} + handle={labeler.creator.handle} + /> + {labeler.likeCount ? <LikeCount count={labeler.likeCount} /> : null} + </Content> + </Outer> + ) +} + +export function Link({ + children, + labeler, +}: LabelingServiceProps & Pick<LinkProps, 'children'>) { + const {_} = useLingui() + + return ( + <InternalLink + to={{ + screen: 'Profile', + params: { + name: labeler.creator.handle, + }, + }} + label={_( + msg`View the labeling service provided by @${labeler.creator.handle}`, + )}> + {children} + </InternalLink> + ) +} + +// TODO not finished yet +export function DefaultSkeleton() { + return ( + <View> + <Text>Loading</Text> + </View> + ) +} + +export function Loader({ + did, + loading: LoadingComponent = DefaultSkeleton, + error: ErrorComponent, + component: Component, +}: { + did: string + loading?: React.ComponentType<{}> + error?: React.ComponentType<{error: string}> + component: React.ComponentType<{ + labeler: AppBskyLabelerDefs.LabelerViewDetailed + }> +}) { + const {isLoading, data, error} = useLabelerInfoQuery({did}) + + return isLoading ? ( + LoadingComponent ? ( + <LoadingComponent /> + ) : null + ) : error || !data ? ( + ErrorComponent ? ( + <ErrorComponent error={error?.message || 'Unknown error'} /> + ) : null + ) : ( + <Component labeler={data} /> + ) +} diff --git a/src/components/LikedByList.tsx b/src/components/LikedByList.tsx new file mode 100644 index 0000000000..bd12136394 --- /dev/null +++ b/src/components/LikedByList.tsx @@ -0,0 +1,109 @@ +import React from 'react' +import {View} from 'react-native' +import {AppBskyFeedGetLikes as GetLikes} from '@atproto/api' +import {Trans} from '@lingui/macro' + +import {logger} from '#/logger' +import {List} from '#/view/com/util/List' +import {ProfileCardWithFollowBtn} from '#/view/com/profile/ProfileCard' +import {useResolveUriQuery} from '#/state/queries/resolve-uri' +import {useLikedByQuery} from '#/state/queries/post-liked-by' +import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender' +import {ListFooter} from '#/components/Lists' + +import {atoms as a, useTheme} from '#/alf' +import {Loader} from '#/components/Loader' +import {Text} from '#/components/Typography' + +export function LikedByList({uri}: {uri: string}) { + const t = useTheme() + const [isPTRing, setIsPTRing] = React.useState(false) + const { + data: resolvedUri, + error: resolveError, + isFetching: isFetchingResolvedUri, + } = useResolveUriQuery(uri) + const { + data, + isFetching, + isFetched, + isRefetching, + hasNextPage, + fetchNextPage, + isError, + error: likedByError, + refetch, + } = useLikedByQuery(resolvedUri?.uri) + const likes = React.useMemo(() => { + if (data?.pages) { + return data.pages.flatMap(page => page.likes) + } + return [] + }, [data]) + const initialNumToRender = useInitialNumToRender() + const error = resolveError || likedByError + + const onRefresh = React.useCallback(async () => { + setIsPTRing(true) + try { + await refetch() + } catch (err) { + logger.error('Failed to refresh likes', {message: err}) + } + setIsPTRing(false) + }, [refetch, setIsPTRing]) + + const onEndReached = React.useCallback(async () => { + if (isFetching || !hasNextPage || isError) return + try { + await fetchNextPage() + } catch (err) { + logger.error('Failed to load more likes', {message: err}) + } + }, [isFetching, hasNextPage, isError, fetchNextPage]) + + const renderItem = React.useCallback(({item}: {item: GetLikes.Like}) => { + return ( + <ProfileCardWithFollowBtn key={item.actor.did} profile={item.actor} /> + ) + }, []) + + if (isFetchingResolvedUri || !isFetched) { + return ( + <View style={[a.w_full, a.align_center, a.p_lg]}> + <Loader size="xl" /> + </View> + ) + } + + return likes.length ? ( + <List + data={likes} + keyExtractor={item => item.actor.did} + refreshing={isPTRing} + onRefresh={onRefresh} + onEndReached={onEndReached} + onEndReachedThreshold={3} + renderItem={renderItem} + initialNumToRender={initialNumToRender} + ListFooterComponent={() => ( + <ListFooter + isFetching={isFetching && !isRefetching} + isError={isError} + error={error ? error.toString() : undefined} + onRetry={fetchNextPage} + /> + )} + /> + ) : ( + <View style={[a.p_lg]}> + <View style={[a.p_lg, a.rounded_sm, t.atoms.bg_contrast_25]}> + <Text style={[a.text_md, a.leading_snug]}> + <Trans> + Nobody has liked this yet. Maybe you should be the first! + </Trans> + </Text> + </View> + </View> + ) +} diff --git a/src/components/LikesDialog.tsx b/src/components/LikesDialog.tsx new file mode 100644 index 0000000000..94a3f27e26 --- /dev/null +++ b/src/components/LikesDialog.tsx @@ -0,0 +1,131 @@ +import React, {useMemo, useCallback} from 'react' +import {ActivityIndicator, FlatList, View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {AppBskyFeedGetLikes as GetLikes} from '@atproto/api' + +import {useResolveUriQuery} from '#/state/queries/resolve-uri' +import {useLikedByQuery} from '#/state/queries/post-liked-by' +import {cleanError} from '#/lib/strings/errors' +import {logger} from '#/logger' + +import {atoms as a, useTheme} from '#/alf' +import {Text} from '#/components/Typography' +import * as Dialog from '#/components/Dialog' +import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' +import {ProfileCardWithFollowBtn} from '#/view/com/profile/ProfileCard' +import {Loader} from '#/components/Loader' + +interface LikesDialogProps { + control: Dialog.DialogOuterProps['control'] + uri: string +} + +export function LikesDialog(props: LikesDialogProps) { + return ( + <Dialog.Outer control={props.control}> + <Dialog.Handle /> + + <LikesDialogInner {...props} /> + </Dialog.Outer> + ) +} + +export function LikesDialogInner({control, uri}: LikesDialogProps) { + const {_} = useLingui() + const t = useTheme() + + const { + data: resolvedUri, + error: resolveError, + isFetched: hasFetchedResolvedUri, + } = useResolveUriQuery(uri) + const { + data, + isFetching: isFetchingLikedBy, + isFetched: hasFetchedLikedBy, + isFetchingNextPage, + hasNextPage, + fetchNextPage, + isError, + error: likedByError, + } = useLikedByQuery(resolvedUri?.uri) + + const isLoading = !hasFetchedResolvedUri || !hasFetchedLikedBy + const likes = useMemo(() => { + if (data?.pages) { + return data.pages.flatMap(page => page.likes) + } + return [] + }, [data]) + + const onEndReached = useCallback(async () => { + if (isFetchingLikedBy || !hasNextPage || isError) return + try { + await fetchNextPage() + } catch (err) { + logger.error('Failed to load more likes', {message: err}) + } + }, [isFetchingLikedBy, hasNextPage, isError, fetchNextPage]) + + const renderItem = useCallback( + ({item}: {item: GetLikes.Like}) => { + return ( + <ProfileCardWithFollowBtn + key={item.actor.did} + profile={item.actor} + onPress={() => control.close()} + /> + ) + }, + [control], + ) + + return ( + <Dialog.Inner label={_(msg`Users that have liked this content or profile`)}> + <Text style={[a.text_2xl, a.font_bold, a.leading_tight, a.pb_lg]}> + <Trans>Liked by</Trans> + </Text> + + {isLoading ? ( + <View style={{minHeight: 300}}> + <Loader size="xl" /> + </View> + ) : resolveError || likedByError || !data ? ( + <ErrorMessage message={cleanError(resolveError || likedByError)} /> + ) : likes.length === 0 ? ( + <View style={[t.atoms.bg_contrast_50, a.px_md, a.py_xl, a.rounded_md]}> + <Text style={[a.text_center]}> + <Trans> + Nobody has liked this yet. Maybe you should be the first! + </Trans> + </Text> + </View> + ) : ( + <FlatList + data={likes} + keyExtractor={item => item.actor.did} + onEndReached={onEndReached} + renderItem={renderItem} + initialNumToRender={15} + ListFooterComponent={ + <ListFooterComponent isFetching={isFetchingNextPage} /> + } + /> + )} + + <Dialog.Close /> + </Dialog.Inner> + ) +} + +function ListFooterComponent({isFetching}: {isFetching: boolean}) { + if (isFetching) { + return ( + <View style={a.pt_lg}> + <ActivityIndicator /> + </View> + ) + } + return null +} diff --git a/src/components/Link.tsx b/src/components/Link.tsx index 00e6a56f42..7d0e833329 100644 --- a/src/components/Link.tsx +++ b/src/components/Link.tsx @@ -251,7 +251,7 @@ export function InlineLink({ onIn: onPressIn, onOut: onPressOut, } = useInteractionState() - const flattenedStyle = flatten(style) + const flattenedStyle = flatten(style) || {} return ( <Text diff --git a/src/components/Lists.tsx b/src/components/Lists.tsx index bb0d247971..8a889c15e3 100644 --- a/src/components/Lists.tsx +++ b/src/components/Lists.tsx @@ -33,7 +33,7 @@ export function ListFooter({ a.border_t, a.pb_lg, t.atoms.border_contrast_low, - {height: 100}, + {height: 180}, ]}> {isFetching ? ( <Loader size="xl" /> diff --git a/src/components/Menu/index.web.tsx b/src/components/Menu/index.web.tsx index f4b03f680e..60b2342034 100644 --- a/src/components/Menu/index.web.tsx +++ b/src/components/Menu/index.web.tsx @@ -223,7 +223,7 @@ export function Item({children, label, onPress, ...rest}: ItemProps) { style={flatten([ a.flex_row, a.align_center, - a.gap_sm, + a.gap_lg, a.py_sm, a.rounded_xs, {minHeight: 32, paddingHorizontal: 10}, diff --git a/src/components/ReportDialog/SelectReportOptionView.tsx b/src/components/ReportDialog/SelectReportOptionView.tsx new file mode 100644 index 0000000000..8ae0b52ecb --- /dev/null +++ b/src/components/ReportDialog/SelectReportOptionView.tsx @@ -0,0 +1,183 @@ +import React from 'react' +import {View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {AppBskyLabelerDefs} from '@atproto/api' + +import {useReportOptions, ReportOption} from '#/lib/moderation/useReportOptions' +import {DMCA_LINK} from '#/components/ReportDialog/const' +import {Link} from '#/components/Link' +export {useDialogControl as useReportDialogControl} from '#/components/Dialog' + +import {atoms as a, useTheme} from '#/alf' +import {Text} from '#/components/Typography' +import { + Button, + ButtonIcon, + ButtonText, + useButtonContext, +} from '#/components/Button' +import {Divider} from '#/components/Divider' +import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' +import {SquareArrowTopRight_Stroke2_Corner0_Rounded as SquareArrowTopRight} from '#/components/icons/SquareArrowTopRight' + +import {ReportDialogProps} from './types' + +export function SelectReportOptionView({ + ...props +}: ReportDialogProps & { + labelers: AppBskyLabelerDefs.LabelerViewDetailed[] + onSelectReportOption: (reportOption: ReportOption) => void +}) { + const t = useTheme() + const {_} = useLingui() + const allReportOptions = useReportOptions() + const reportOptions = allReportOptions[props.params.type] + + const i18n = React.useMemo(() => { + let title = _(msg`Report this content`) + let description = _(msg`Why should this content be reviewed?`) + + if (props.params.type === 'account') { + title = _(msg`Report this user`) + description = _(msg`Why should this user be reviewed?`) + } else if (props.params.type === 'post') { + title = _(msg`Report this post`) + description = _(msg`Why should this post be reviewed?`) + } else if (props.params.type === 'list') { + title = _(msg`Report this list`) + description = _(msg`Why should this list be reviewed?`) + } else if (props.params.type === 'feedgen') { + title = _(msg`Report this feed`) + description = _(msg`Why should this feed be reviewed?`) + } + + return { + title, + description, + } + }, [_, props.params.type]) + + return ( + <View style={[a.gap_lg]}> + <View style={[a.justify_center, a.gap_sm]}> + <Text style={[a.text_2xl, a.font_bold]}>{i18n.title}</Text> + <Text style={[a.text_md, t.atoms.text_contrast_medium]}> + {i18n.description} + </Text> + </View> + + <Divider /> + + <View style={[a.gap_sm, {marginHorizontal: a.p_md.padding * -1}]}> + {reportOptions.map(reportOption => { + return ( + <Button + key={reportOption.reason} + label={_(msg`Create report for ${reportOption.title}`)} + onPress={() => props.onSelectReportOption(reportOption)}> + <ReportOptionButton + title={reportOption.title} + description={reportOption.description} + /> + </Button> + ) + })} + + {(props.params.type === 'post' || props.params.type === 'account') && ( + <View style={[a.pt_md, a.px_md]}> + <View + style={[ + a.flex_row, + a.align_center, + a.justify_between, + a.gap_lg, + a.p_md, + a.pl_lg, + a.rounded_md, + t.atoms.bg_contrast_900, + ]}> + <Text + style={[ + a.flex_1, + t.atoms.text_inverted, + a.italic, + a.leading_snug, + ]}> + <Trans>Need to report a copyright violation?</Trans> + </Text> + <Link + to={DMCA_LINK} + label={_(msg`View details for reporting a copyright violation`)} + size="small" + variant="solid" + color="secondary"> + <ButtonText> + <Trans>View details</Trans> + </ButtonText> + <ButtonIcon position="right" icon={SquareArrowTopRight} /> + </Link> + </View> + </View> + )} + </View> + </View> + ) +} + +function ReportOptionButton({ + title, + description, +}: { + title: string + description: string +}) { + const t = useTheme() + const {hovered, pressed} = useButtonContext() + const interacted = hovered || pressed + + const styles = React.useMemo(() => { + return { + interacted: { + backgroundColor: t.palette.contrast_50, + }, + } + }, [t]) + + return ( + <View + style={[ + a.w_full, + a.flex_row, + a.align_center, + a.justify_between, + a.p_md, + a.rounded_md, + {paddingRight: 70}, + interacted && styles.interacted, + ]}> + <View style={[a.flex_1, a.gap_xs]}> + <Text style={[a.text_md, a.font_bold, t.atoms.text_contrast_medium]}> + {title} + </Text> + <Text style={[a.leading_tight, {maxWidth: 400}]}>{description}</Text> + </View> + + <View + style={[ + a.absolute, + a.inset_0, + a.justify_center, + a.pr_md, + {left: 'auto'}, + ]}> + <ChevronRight + size="md" + fill={ + hovered ? t.palette.primary_500 : t.atoms.text_contrast_low.color + } + /> + </View> + </View> + ) +} diff --git a/src/components/ReportDialog/SubmitView.tsx b/src/components/ReportDialog/SubmitView.tsx new file mode 100644 index 0000000000..99af64a2a6 --- /dev/null +++ b/src/components/ReportDialog/SubmitView.tsx @@ -0,0 +1,262 @@ +import React from 'react' +import {View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {AppBskyLabelerDefs} from '@atproto/api' + +import {getLabelingServiceTitle} from '#/lib/moderation' +import {ReportOption} from '#/lib/moderation/useReportOptions' + +import {atoms as a, useTheme, native} from '#/alf' +import {Text} from '#/components/Typography' +import * as Dialog from '#/components/Dialog' +import {Button, ButtonIcon, ButtonText} from '#/components/Button' +import {ChevronLeft_Stroke2_Corner0_Rounded as ChevronLeft} from '#/components/icons/Chevron' +import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check' +import * as Toggle from '#/components/forms/Toggle' +import {CharProgress} from '#/view/com/composer/char-progress/CharProgress' +import {Loader} from '#/components/Loader' +import * as Toast from '#/view/com/util/Toast' + +import {ReportDialogProps} from './types' +import {getAgent} from '#/state/session' + +export function SubmitView({ + params, + labelers, + selectedReportOption, + goBack, + onSubmitComplete, +}: ReportDialogProps & { + labelers: AppBskyLabelerDefs.LabelerViewDetailed[] + selectedReportOption: ReportOption + goBack: () => void + onSubmitComplete: () => void +}) { + const t = useTheme() + const {_} = useLingui() + const [details, setDetails] = React.useState<string>('') + const [submitting, setSubmitting] = React.useState<boolean>(false) + const [selectedServices, setSelectedServices] = React.useState<string[]>( + labelers?.map(labeler => labeler.creator.did) || [], + ) + const [error, setError] = React.useState('') + + const submit = React.useCallback(async () => { + setSubmitting(true) + setError('') + + const $type = + params.type === 'account' + ? 'com.atproto.admin.defs#repoRef' + : 'com.atproto.repo.strongRef' + const report = { + reasonType: selectedReportOption.reason, + subject: { + $type, + ...params, + }, + reason: details, + } + const results = await Promise.all( + selectedServices.map(did => + getAgent() + .withProxy('atproto_labeler', did) + .createModerationReport(report) + .then( + _ => true, + _ => false, + ), + ), + ) + + setSubmitting(false) + + if (results.includes(true)) { + Toast.show(_(msg`Thank you. Your report has been sent.`)) + onSubmitComplete() + } else { + setError( + _( + msg`There was an issue sending your report. Please check your internet connection.`, + ), + ) + } + }, [ + _, + params, + details, + selectedReportOption, + selectedServices, + onSubmitComplete, + setError, + ]) + + return ( + <View style={[a.gap_2xl]}> + <Button + size="small" + variant="solid" + color="secondary" + shape="round" + label={_(msg`Go back to previous step`)} + onPress={goBack}> + <ButtonIcon icon={ChevronLeft} /> + </Button> + + <View + style={[ + a.w_full, + a.flex_row, + a.align_center, + a.justify_between, + a.gap_lg, + a.p_md, + a.rounded_md, + a.border, + t.atoms.border_contrast_low, + ]}> + <View style={[a.flex_1, a.gap_xs]}> + <Text style={[a.text_md, a.font_bold]}> + {selectedReportOption.title} + </Text> + <Text style={[a.leading_tight, {maxWidth: 400}]}> + {selectedReportOption.description} + </Text> + </View> + + <Check size="md" style={[a.pr_sm, t.atoms.text_contrast_low]} /> + </View> + + <View style={[a.gap_md]}> + <Text style={[t.atoms.text_contrast_medium]}> + <Trans>Select the moderation service(s) to report to</Trans> + </Text> + + <Toggle.Group + label="Select mod services" + values={selectedServices} + onChange={setSelectedServices}> + <View style={[a.flex_row, a.gap_md, a.flex_wrap]}> + {labelers.map(labeler => { + const title = getLabelingServiceTitle({ + displayName: labeler.creator.displayName, + handle: labeler.creator.handle, + }) + return ( + <Toggle.Item + key={labeler.creator.did} + name={labeler.creator.did} + label={title}> + <LabelerToggle title={title} /> + </Toggle.Item> + ) + })} + </View> + </Toggle.Group> + </View> + <View style={[a.gap_md]}> + <Text style={[t.atoms.text_contrast_medium]}> + <Trans>Optionally provide additional information below:</Trans> + </Text> + + <View style={[a.relative, a.w_full]}> + <Dialog.Input + multiline + value={details} + onChangeText={setDetails} + label="Text field" + style={{paddingRight: 60}} + numberOfLines={6} + /> + + <View + style={[ + a.absolute, + a.flex_row, + a.align_center, + a.pr_md, + a.pb_sm, + { + bottom: 0, + right: 0, + }, + ]}> + <CharProgress count={details?.length || 0} /> + </View> + </View> + </View> + + <View style={[a.flex_row, a.align_center, a.justify_end, a.gap_lg]}> + {!selectedServices.length || + (error && ( + <Text + style={[ + a.flex_1, + a.italic, + a.leading_snug, + t.atoms.text_contrast_medium, + ]}> + {error ? ( + error + ) : ( + <Trans>You must select at least one labeler for a report</Trans> + )} + </Text> + ))} + + <Button + size="large" + variant="solid" + color="negative" + label={_(msg`Send report`)} + onPress={submit} + disabled={!selectedServices.length}> + <ButtonText> + <Trans>Send report</Trans> + </ButtonText> + {submitting && <ButtonIcon icon={Loader} />} + </Button> + </View> + </View> + ) +} + +function LabelerToggle({title}: {title: string}) { + const t = useTheme() + const ctx = Toggle.useItemContext() + + return ( + <View + style={[ + a.flex_row, + a.align_center, + a.gap_md, + a.p_md, + a.pr_lg, + a.rounded_sm, + a.overflow_hidden, + t.atoms.bg_contrast_25, + ctx.selected && [t.atoms.bg_contrast_50], + ]}> + <Toggle.Checkbox /> + <View + style={[ + a.flex_row, + a.align_center, + a.justify_between, + a.gap_lg, + a.z_10, + ]}> + <Text + style={[ + native({marginTop: 2}), + t.atoms.text_contrast_medium, + ctx.selected && t.atoms.text, + ]}> + {title} + </Text> + </View> + </View> + ) +} diff --git a/src/components/ReportDialog/const.ts b/src/components/ReportDialog/const.ts new file mode 100644 index 0000000000..30c9aff88d --- /dev/null +++ b/src/components/ReportDialog/const.ts @@ -0,0 +1 @@ +export const DMCA_LINK = 'https://bsky.social/about/support/copyright' diff --git a/src/components/ReportDialog/index.tsx b/src/components/ReportDialog/index.tsx new file mode 100644 index 0000000000..b35727c7dd --- /dev/null +++ b/src/components/ReportDialog/index.tsx @@ -0,0 +1,73 @@ +import React from 'react' +import {View, Pressable} from 'react-native' +import {Trans} from '@lingui/macro' + +import {useMyLabelersQuery} from '#/state/queries/preferences' +import {ReportOption} from '#/lib/moderation/useReportOptions' +export {useDialogControl as useReportDialogControl} from '#/components/Dialog' + +import {atoms as a} from '#/alf' +import {Loader} from '#/components/Loader' +import * as Dialog from '#/components/Dialog' +import {Text} from '#/components/Typography' + +import {ReportDialogProps} from './types' +import {SelectReportOptionView} from './SelectReportOptionView' +import {SubmitView} from './SubmitView' +import {useDelayedLoading} from '#/components/hooks/useDelayedLoading' + +export function ReportDialog(props: ReportDialogProps) { + return ( + <Dialog.Outer control={props.control}> + <Dialog.Handle /> + + <ReportDialogInner {...props} /> + </Dialog.Outer> + ) +} + +function ReportDialogInner(props: ReportDialogProps) { + const { + isLoading: isLabelerLoading, + data: labelers, + error, + } = useMyLabelersQuery() + const isLoading = useDelayedLoading(500, isLabelerLoading) + const [selectedReportOption, setSelectedReportOption] = React.useState< + ReportOption | undefined + >() + + return ( + <Dialog.ScrollableInner label="Report Dialog"> + {isLoading ? ( + <View style={[a.align_center, {height: 100}]}> + <Loader size="xl" /> + {/* Here to capture focus for a hot sec to prevent flash */} + <Pressable accessible={false} /> + </View> + ) : error || !labelers ? ( + <View> + <Text style={[a.text_md]}> + <Trans>Something went wrong, please try again.</Trans> + </Text> + </View> + ) : selectedReportOption ? ( + <SubmitView + {...props} + labelers={labelers} + selectedReportOption={selectedReportOption} + goBack={() => setSelectedReportOption(undefined)} + onSubmitComplete={() => props.control.close()} + /> + ) : ( + <SelectReportOptionView + {...props} + labelers={labelers} + onSelectReportOption={setSelectedReportOption} + /> + )} + + <Dialog.Close /> + </Dialog.ScrollableInner> + ) +} diff --git a/src/components/ReportDialog/types.ts b/src/components/ReportDialog/types.ts new file mode 100644 index 0000000000..0c8a1e0778 --- /dev/null +++ b/src/components/ReportDialog/types.ts @@ -0,0 +1,15 @@ +import * as Dialog from '#/components/Dialog' + +export type ReportDialogProps = { + control: Dialog.DialogOuterProps['control'] + params: + | { + type: 'post' | 'list' | 'feedgen' | 'other' + uri: string + cid: string + } + | { + type: 'account' + did: string + } +} diff --git a/src/components/TagMenu/index.tsx b/src/components/TagMenu/index.tsx index 849a3f42d1..13e4e7d6b2 100644 --- a/src/components/TagMenu/index.tsx +++ b/src/components/TagMenu/index.tsx @@ -59,7 +59,7 @@ export function TagMenu({ const displayTag = '#' + tag const isMuted = Boolean( - (preferences?.mutedWords?.find( + (preferences?.moderationPrefs.mutedWords?.find( m => m.value === tag && m.targets.includes('tag'), ) ?? optimisticUpsert?.find( diff --git a/src/components/TagMenu/index.web.tsx b/src/components/TagMenu/index.web.tsx index 8245bd0191..b2f5c90756 100644 --- a/src/components/TagMenu/index.web.tsx +++ b/src/components/TagMenu/index.web.tsx @@ -50,7 +50,7 @@ export function TagMenu({ const {mutateAsync: removeMutedWord, variables: optimisticRemove} = useRemoveMutedWordMutation() const isMuted = Boolean( - (preferences?.mutedWords?.find( + (preferences?.moderationPrefs.mutedWords?.find( m => m.value === tag && m.targets.includes('tag'), ) ?? optimisticUpsert?.find( diff --git a/src/components/Typography.tsx b/src/components/Typography.tsx index 5268e7f468..f8b3ad1bd8 100644 --- a/src/components/Typography.tsx +++ b/src/components/Typography.tsx @@ -1,5 +1,10 @@ import React from 'react' -import {Text as RNText, TextStyle, TextProps as RNTextProps} from 'react-native' +import { + Text as RNText, + StyleProp, + TextStyle, + TextProps as RNTextProps, +} from 'react-native' import {UITextView} from 'react-native-ui-text-view' import {useTheme, atoms, web, flatten} from '#/alf' @@ -34,7 +39,7 @@ export function leading< * If the `lineHeight` value is > 2, we assume it's an absolute value and * returns it as-is. */ -function normalizeTextStyles(styles: TextStyle[]) { +export function normalizeTextStyles(styles: StyleProp<TextStyle>) { const s = flatten(styles) // should always be defined on these components const fontSize = s.fontSize || atoms.text_md.fontSize diff --git a/src/components/dialogs/Context.tsx b/src/components/dialogs/Context.tsx index d86c90a92e..87bd5c2ed7 100644 --- a/src/components/dialogs/Context.tsx +++ b/src/components/dialogs/Context.tsx @@ -18,7 +18,7 @@ export function useGlobalDialogsControlContext() { export function Provider({children}: React.PropsWithChildren<{}>) { const mutedWordsDialogControl = Dialog.useDialogControl() - const ctx = React.useMemo( + const ctx = React.useMemo<ControlsContext>( () => ({mutedWordsDialogControl}), [mutedWordsDialogControl], ) diff --git a/src/components/dialogs/MutedWords.tsx b/src/components/dialogs/MutedWords.tsx index dcdaccea3e..46f319adfe 100644 --- a/src/components/dialogs/MutedWords.tsx +++ b/src/components/dialogs/MutedWords.tsx @@ -233,8 +233,8 @@ function MutedWordsInner({}: {control: Dialog.DialogOuterProps['control']}) { </Trans> </Text> </View> - ) : preferences.mutedWords.length ? ( - [...preferences.mutedWords] + ) : preferences.moderationPrefs.mutedWords.length ? ( + [...preferences.moderationPrefs.mutedWords] .reverse() .map((word, i) => ( <MutedWordRow diff --git a/src/components/forms/Toggle.tsx b/src/components/forms/Toggle.tsx index a83f92a2a6..7a4b5ac959 100644 --- a/src/components/forms/Toggle.tsx +++ b/src/components/forms/Toggle.tsx @@ -2,7 +2,14 @@ import React from 'react' import {Pressable, View, ViewStyle} from 'react-native' import {HITSLOP_10} from 'lib/constants' -import {useTheme, atoms as a, web, native, flatten, ViewStyleProp} from '#/alf' +import { + useTheme, + atoms as a, + native, + flatten, + ViewStyleProp, + TextStyleProp, +} from '#/alf' import {Text} from '#/components/Typography' import {useInteractionState} from '#/components/hooks/useInteractionState' import {CheckThick_Stroke2_Corner0_Rounded as Checkmark} from '#/components/icons/Check' @@ -220,20 +227,17 @@ export function Item({ onPressOut={onPressOut} onFocus={onFocus} onBlur={onBlur} - style={[ - a.flex_row, - a.align_center, - a.gap_sm, - focused ? web({outline: 'none'}) : {}, - flatten(style), - ]}> + style={[a.flex_row, a.align_center, a.gap_sm, flatten(style)]}> {typeof children === 'function' ? children(state) : children} </Pressable> </ItemContext.Provider> ) } -export function Label({children}: React.PropsWithChildren<{}>) { +export function Label({ + children, + style, +}: React.PropsWithChildren<TextStyleProp>) { const t = useTheme() const {disabled} = useItemContext() return ( @@ -242,11 +246,14 @@ export function Label({children}: React.PropsWithChildren<{}>) { a.font_bold, { userSelect: 'none', - color: disabled ? t.palette.contrast_400 : t.palette.contrast_600, + color: disabled + ? t.atoms.text_contrast_low.color + : t.atoms.text_contrast_high.color, }, native({ paddingTop: 3, }), + flatten(style), ]}> {children} </Text> @@ -257,7 +264,6 @@ export function Label({children}: React.PropsWithChildren<{}>) { export function createSharedToggleStyles({ theme: t, hovered, - focused, selected, disabled, isInvalid, @@ -280,7 +286,7 @@ export function createSharedToggleStyles({ borderColor: t.palette.primary_500, }) - if (hovered || focused) { + if (hovered) { baseHover.push({ backgroundColor: t.name === 'light' ? t.palette.primary_100 : t.palette.primary_800, @@ -289,7 +295,7 @@ export function createSharedToggleStyles({ }) } } else { - if (hovered || focused) { + if (hovered) { baseHover.push({ backgroundColor: t.name === 'light' ? t.palette.contrast_50 : t.palette.contrast_100, @@ -306,7 +312,7 @@ export function createSharedToggleStyles({ t.name === 'light' ? t.palette.negative_300 : t.palette.negative_800, }) - if (hovered || focused) { + if (hovered) { baseHover.push({ backgroundColor: t.name === 'light' ? t.palette.negative_25 : t.palette.negative_900, @@ -353,7 +359,7 @@ export function Checkbox() { width: 20, }, baseStyles, - hovered || focused ? baseHoverStyles : {}, + hovered ? baseHoverStyles : {}, ]}> {selected ? <Checkmark size="xs" fill={t.palette.primary_500} /> : null} </View> @@ -385,7 +391,7 @@ export function Switch() { width: 30, }, baseStyles, - hovered || focused ? baseHoverStyles : {}, + hovered ? baseHoverStyles : {}, ]}> <View style={[ @@ -437,7 +443,7 @@ export function Radio() { width: 20, }, baseStyles, - hovered || focused ? baseHoverStyles : {}, + hovered ? baseHoverStyles : {}, ]}> {selected ? ( <View diff --git a/src/components/forms/ToggleButton.tsx b/src/components/forms/ToggleButton.tsx index 7e1bd70b99..9cdaaaa9d1 100644 --- a/src/components/forms/ToggleButton.tsx +++ b/src/components/forms/ToggleButton.tsx @@ -8,7 +8,9 @@ import * as Toggle from '#/components/forms/Toggle' export type ItemProps = Omit<Toggle.ItemProps, 'style' | 'role' | 'children'> & AccessibilityProps & - React.PropsWithChildren<{testID?: string}> + React.PropsWithChildren<{ + testID?: string + }> export type GroupProps = Omit<Toggle.GroupProps, 'style' | 'type'> & { multiple?: boolean @@ -101,12 +103,12 @@ function ButtonInner({children}: React.PropsWithChildren<{}>) { native({ paddingBottom: 10, }), - a.px_sm, + a.px_md, t.atoms.bg, t.atoms.border_contrast_low, baseStyles, activeStyles, - (state.hovered || state.focused || state.pressed) && hoverStyles, + (state.hovered || state.pressed) && hoverStyles, ]}> {typeof children === 'string' ? ( <Text diff --git a/src/components/hooks/useDelayedLoading.ts b/src/components/hooks/useDelayedLoading.ts new file mode 100644 index 0000000000..6c7e2ede06 --- /dev/null +++ b/src/components/hooks/useDelayedLoading.ts @@ -0,0 +1,15 @@ +import React from 'react' + +export function useDelayedLoading(delay: number, initialState: boolean = true) { + const [isLoading, setIsLoading] = React.useState(initialState) + + React.useEffect(() => { + let timeout: NodeJS.Timeout + // on initial load, show a loading spinner for a hot sec to prevent flash + if (isLoading) timeout = setTimeout(() => setIsLoading(false), delay) + + return () => timeout && clearTimeout(timeout) + }, [isLoading, delay]) + + return isLoading +} diff --git a/src/components/icons/ArrowTriangle.tsx b/src/components/icons/ArrowTriangle.tsx new file mode 100644 index 0000000000..b27b719aef --- /dev/null +++ b/src/components/icons/ArrowTriangle.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const ArrowTriangleBottom_Stroke2_Corner1_Rounded = createSinglePathSVG({ + path: 'M4.213 6.886c-.673-1.35.334-2.889 1.806-2.889H17.98c1.472 0 2.479 1.539 1.806 2.89l-5.982 11.997c-.74 1.484-2.87 1.484-3.61 0L4.213 6.886Z', +}) diff --git a/src/components/icons/Bars.tsx b/src/components/icons/Bars.tsx new file mode 100644 index 0000000000..7b1415a4bc --- /dev/null +++ b/src/components/icons/Bars.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Bars3_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M3 5a1 1 0 0 0 0 2h18a1 1 0 1 0 0-2H3Zm-1 7a1 1 0 0 1 1-1h18a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Zm0 6a1 1 0 0 1 1-1h18a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Z', +}) diff --git a/src/components/icons/Chevron.tsx b/src/components/icons/Chevron.tsx index b1a9deea0b..a04e6e0092 100644 --- a/src/components/icons/Chevron.tsx +++ b/src/components/icons/Chevron.tsx @@ -7,3 +7,11 @@ export const ChevronLeft_Stroke2_Corner0_Rounded = createSinglePathSVG({ export const ChevronRight_Stroke2_Corner0_Rounded = createSinglePathSVG({ path: 'M8.293 3.293a1 1 0 0 1 1.414 0l8 8a1 1 0 0 1 0 1.414l-8 8a1 1 0 0 1-1.414-1.414L15.586 12 8.293 4.707a1 1 0 0 1 0-1.414Z', }) + +export const ChevronTop_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M12 6a1 1 0 0 1 .707.293l8 8a1 1 0 0 1-1.414 1.414L12 8.414l-7.293 7.293a1 1 0 0 1-1.414-1.414l8-8A1 1 0 0 1 12 6Z', +}) + +export const ChevronBottom_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M3.293 8.293a1 1 0 0 1 1.414 0L12 15.586l7.293-7.293a1 1 0 1 1 1.414 1.414l-8 8a1 1 0 0 1-1.414 0l-8-8a1 1 0 0 1 0-1.414Z', +}) diff --git a/src/components/icons/CircleBanSign.tsx b/src/components/icons/CircleBanSign.tsx new file mode 100644 index 0000000000..543985d43a --- /dev/null +++ b/src/components/icons/CircleBanSign.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const CircleBanSign_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M12 4a8 8 0 0 0-6.32 12.906L16.906 5.68A7.962 7.962 0 0 0 12 4Zm6.32 3.094L7.094 18.32A8 8 0 0 0 18.32 7.094ZM2 12C2 6.477 6.477 2 12 2a9.972 9.972 0 0 1 7.071 2.929A9.972 9.972 0 0 1 22 12c0 5.523-4.477 10-10 10a9.972 9.972 0 0 1-7.071-2.929A9.972 9.972 0 0 1 2 12Z', +}) diff --git a/src/components/icons/Gear.tsx b/src/components/icons/Gear.tsx new file mode 100644 index 0000000000..980b7413bd --- /dev/null +++ b/src/components/icons/Gear.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const SettingsGear2_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M11.1 2a1 1 0 0 0-.832.445L8.851 4.57 6.6 4.05a1 1 0 0 0-.932.268l-1.35 1.35a1 1 0 0 0-.267.932l.52 2.251-2.126 1.417A1 1 0 0 0 2 11.1v1.8a1 1 0 0 0 .445.832l2.125 1.417-.52 2.251a1 1 0 0 0 .268.932l1.35 1.35a1 1 0 0 0 .932.267l2.251-.52 1.417 2.126A1 1 0 0 0 11.1 22h1.8a1 1 0 0 0 .832-.445l1.417-2.125 2.251.52a1 1 0 0 0 .932-.268l1.35-1.35a1 1 0 0 0 .267-.932l-.52-2.251 2.126-1.417A1 1 0 0 0 22 12.9v-1.8a1 1 0 0 0-.445-.832L19.43 8.851l.52-2.251a1 1 0 0 0-.268-.932l-1.35-1.35a1 1 0 0 0-.932-.267l-2.251.52-1.417-2.126A1 1 0 0 0 12.9 2h-1.8Zm-.968 4.255L11.635 4h.73l1.503 2.255a1 1 0 0 0 1.057.42l2.385-.551.566.566-.55 2.385a1 1 0 0 0 .42 1.057L20 11.635v.73l-2.255 1.503a1 1 0 0 0-.42 1.057l.551 2.385-.566.566-2.385-.55a1 1 0 0 0-1.057.42L12.365 20h-.73l-1.503-2.255a1 1 0 0 0-1.057-.42l-2.385.551-.566-.566.55-2.385a1 1 0 0 0-.42-1.057L4 12.365v-.73l2.255-1.503a1 1 0 0 0 .42-1.057L6.123 6.69l.566-.566 2.385.55a1 1 0 0 0 1.057-.42ZM8 12a4 4 0 1 1 8 0 4 4 0 0 1-8 0Zm4-2a2 2 0 1 0 0 4 2 2 0 0 0 0-4Z', +}) diff --git a/src/components/icons/Group3.tsx b/src/components/icons/Group.tsx similarity index 100% rename from src/components/icons/Group3.tsx rename to src/components/icons/Group.tsx diff --git a/src/components/icons/RaisingHand.tsx b/src/components/icons/RaisingHand.tsx new file mode 100644 index 0000000000..cd023cb7ef --- /dev/null +++ b/src/components/icons/RaisingHand.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const RaisingHande4Finger_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M10.25 4a.75.75 0 0 0-.75.75V11a1 1 0 1 1-2 0V6.75a.75.75 0 0 0-1.5 0V14a6 6 0 0 0 12 0V9a2 2 0 0 0-2 2v1.5a1 1 0 0 1-.684.949l-.628.21A2.469 2.469 0 0 0 13 16a1 1 0 1 1-2 0 4.469 4.469 0 0 1 3-4.22V11c0-.703.181-1.364.5-1.938V5.75a.75.75 0 0 0-1.5 0V9a1 1 0 1 1-2 0V4.75a.75.75 0 0 0-.75-.75Zm2.316-.733A2.75 2.75 0 0 1 16.5 5.75v1.54c.463-.187.97-.29 1.5-.29h1a1 1 0 0 1 1 1v6a8 8 0 1 1-16 0V6.75a2.75 2.75 0 0 1 3.571-2.625 2.751 2.751 0 0 1 4.995-.858Z', +}) diff --git a/src/components/icons/Shield.tsx b/src/components/icons/Shield.tsx new file mode 100644 index 0000000000..5038d5c244 --- /dev/null +++ b/src/components/icons/Shield.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Shield_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M11.675 2.054a1 1 0 0 1 .65 0l8 2.75A1 1 0 0 1 21 5.75v6.162c0 2.807-1.149 4.83-2.813 6.405-1.572 1.488-3.632 2.6-5.555 3.636l-.157.085a1 1 0 0 1-.95 0l-.157-.085c-1.923-1.037-3.983-2.148-5.556-3.636C4.15 16.742 3 14.719 3 11.912V5.75a1 1 0 0 1 .675-.946l8-2.75ZM5 6.464v5.448c0 2.166.851 3.687 2.188 4.952 1.276 1.209 2.964 2.158 4.812 3.157 1.848-1 3.536-1.948 4.813-3.157C18.148 15.6 19 14.078 19 11.912V6.464l-7-2.407-7 2.407Z', +}) diff --git a/src/components/icons/SquareArrowTopRight.tsx b/src/components/icons/SquareArrowTopRight.tsx new file mode 100644 index 0000000000..7701e26e56 --- /dev/null +++ b/src/components/icons/SquareArrowTopRight.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const SquareArrowTopRight_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M14 5a1 1 0 1 1 0-2h6a1 1 0 0 1 1 1v6a1 1 0 1 1-2 0V6.414l-7.293 7.293a1 1 0 0 1-1.414-1.414L17.586 5H14ZM3 6a1 1 0 0 1 1-1h5a1 1 0 0 1 0 2H5v12h12v-4a1 1 0 1 1 2 0v5a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V6Z', +}) diff --git a/src/components/icons/SquareBehindSquare4.tsx b/src/components/icons/SquareBehindSquare4.tsx new file mode 100644 index 0000000000..425599cbce --- /dev/null +++ b/src/components/icons/SquareBehindSquare4.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const SquareBehindSquare4_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M8 8V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1h-5v5a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1h5Zm1 8a1 1 0 0 1-1-1v-5H4v10h10v-4H9Z', +}) diff --git a/src/components/moderation/ContentHider.tsx b/src/components/moderation/ContentHider.tsx new file mode 100644 index 0000000000..1e8f36d310 --- /dev/null +++ b/src/components/moderation/ContentHider.tsx @@ -0,0 +1,182 @@ +import React from 'react' +import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native' +import {ModerationUI} from '@atproto/api' +import {useLingui} from '@lingui/react' +import {msg, Trans} from '@lingui/macro' + +import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription' +import {isJustAMute} from '#/lib/moderation' +import {sanitizeDisplayName} from '#/lib/strings/display-names' + +import {atoms as a, useTheme, useBreakpoints, web} from '#/alf' +import {Button} from '#/components/Button' +import {Text} from '#/components/Typography' +import { + ModerationDetailsDialog, + useModerationDetailsDialogControl, +} from '#/components/moderation/ModerationDetailsDialog' + +export function ContentHider({ + testID, + modui, + ignoreMute, + style, + childContainerStyle, + children, +}: React.PropsWithChildren<{ + testID?: string + modui: ModerationUI | undefined + ignoreMute?: boolean + style?: StyleProp<ViewStyle> + childContainerStyle?: StyleProp<ViewStyle> +}>) { + const t = useTheme() + const {_} = useLingui() + const {gtMobile} = useBreakpoints() + const [override, setOverride] = React.useState(false) + const control = useModerationDetailsDialogControl() + + const blur = modui?.blurs[0] + const desc = useModerationCauseDescription(blur) + + if (!blur || (ignoreMute && isJustAMute(modui))) { + return ( + <View testID={testID} style={[styles.outer, style]}> + {children} + </View> + ) + } + + return ( + <View testID={testID} style={[a.overflow_hidden, style]}> + <ModerationDetailsDialog control={control} modcause={blur} /> + + <Button + onPress={() => { + if (!modui.noOverride) { + setOverride(v => !v) + } else { + control.open() + } + }} + label={desc.name} + accessibilityHint={ + modui.noOverride + ? _(msg`Learn more about the moderation applied to this content.`) + : override + ? _(msg`Hide the content`) + : _(msg`Show the content`) + }> + {state => ( + <View + style={[ + a.flex_row, + a.w_full, + a.justify_start, + a.align_center, + a.py_md, + a.px_lg, + a.gap_xs, + a.rounded_sm, + t.atoms.bg_contrast_25, + gtMobile && [a.gap_sm, a.py_lg, a.mt_xs, a.px_xl], + (state.hovered || state.pressed) && t.atoms.bg_contrast_50, + ]}> + <desc.icon + size="md" + fill={t.atoms.text_contrast_medium.color} + style={{marginLeft: -2}} + /> + <Text + style={[ + a.flex_1, + a.text_left, + a.font_bold, + a.leading_snug, + gtMobile && [a.font_semibold], + t.atoms.text_contrast_medium, + web({ + marginBottom: 1, + }), + ]}> + {desc.name} + </Text> + {!modui.noOverride && ( + <Text + style={[ + a.font_bold, + a.leading_snug, + gtMobile && [a.font_semibold], + t.atoms.text_contrast_high, + web({ + marginBottom: 1, + }), + ]}> + {override ? <Trans>Hide</Trans> : <Trans>Show</Trans>} + </Text> + )} + </View> + )} + </Button> + + {desc.source && blur.type === 'label' && !override && ( + <Button + onPress={() => { + control.open() + }} + label={_( + msg`Learn more about the moderation applied to this content.`, + )} + style={[a.pt_sm]}> + {state => ( + <Text + style={[ + a.flex_1, + a.text_sm, + a.font_normal, + a.leading_snug, + t.atoms.text_contrast_medium, + a.text_left, + ]}> + {desc.sourceType === 'user' ? ( + <Trans>Labeled by the author.</Trans> + ) : ( + <Trans>Labeled by {sanitizeDisplayName(desc.source!)}.</Trans> + )}{' '} + <Text + style={[ + {color: t.palette.primary_500}, + a.text_sm, + state.hovered && [web({textDecoration: 'underline'})], + ]}> + <Trans>Learn more.</Trans> + </Text> + </Text> + )} + </Button> + )} + + {override && <View style={childContainerStyle}>{children}</View>} + </View> + ) +} + +const styles = StyleSheet.create({ + outer: { + overflow: 'hidden', + }, + cover: { + flexDirection: 'row', + alignItems: 'center', + gap: 6, + borderRadius: 8, + marginTop: 4, + paddingVertical: 14, + paddingLeft: 14, + paddingRight: 18, + }, + showBtn: { + marginLeft: 'auto', + alignSelf: 'center', + }, +}) diff --git a/src/components/moderation/GlobalModerationLabelPref.tsx b/src/components/moderation/GlobalModerationLabelPref.tsx new file mode 100644 index 0000000000..7633cb9f21 --- /dev/null +++ b/src/components/moderation/GlobalModerationLabelPref.tsx @@ -0,0 +1,93 @@ +import React from 'react' +import {View} from 'react-native' +import {InterpretedLabelValueDefinition, LabelPreference} from '@atproto/api' +import {useLingui} from '@lingui/react' +import {msg} from '@lingui/macro' + +import {useGlobalLabelStrings} from '#/lib/moderation/useGlobalLabelStrings' +import { + usePreferencesQuery, + usePreferencesSetContentLabelMutation, +} from '#/state/queries/preferences' + +import {useTheme, atoms as a} from '#/alf' +import {Text} from '#/components/Typography' +import * as ToggleButton from '#/components/forms/ToggleButton' + +export function GlobalModerationLabelPref({ + labelValueDefinition, + disabled, +}: { + labelValueDefinition: InterpretedLabelValueDefinition + disabled?: boolean +}) { + const {_} = useLingui() + const t = useTheme() + + const {identifier} = labelValueDefinition + const {data: preferences} = usePreferencesQuery() + const {mutate, variables} = usePreferencesSetContentLabelMutation() + const savedPref = preferences?.moderationPrefs.labels[identifier] + const pref = variables?.visibility ?? savedPref ?? 'warn' + + const allLabelStrings = useGlobalLabelStrings() + const labelStrings = + labelValueDefinition.identifier in allLabelStrings + ? allLabelStrings[labelValueDefinition.identifier] + : { + name: labelValueDefinition.identifier, + description: `Labeled "${labelValueDefinition.identifier}"`, + } + + const labelOptions = { + hide: _(msg`Hide`), + warn: _(msg`Warn`), + ignore: _(msg`Show`), + } + + return ( + <View + style={[ + a.flex_row, + a.justify_between, + a.gap_sm, + a.py_md, + a.pl_lg, + a.pr_md, + a.align_center, + ]}> + <View style={[a.gap_xs, a.flex_1]}> + <Text style={[a.font_bold]}>{labelStrings.name}</Text> + <Text style={[t.atoms.text_contrast_medium, a.leading_snug]}> + {labelStrings.description} + </Text> + </View> + <View style={[a.justify_center, {minHeight: 35}]}> + {!disabled && ( + <ToggleButton.Group + label={_( + msg`Configure content filtering setting for category: ${labelStrings.name.toLowerCase()}`, + )} + values={[pref]} + onChange={newPref => + mutate({ + label: identifier, + visibility: newPref[0] as LabelPreference, + labelerDid: undefined, + }) + }> + <ToggleButton.Button name="ignore" label={labelOptions.ignore}> + {labelOptions.ignore} + </ToggleButton.Button> + <ToggleButton.Button name="warn" label={labelOptions.warn}> + {labelOptions.warn} + </ToggleButton.Button> + <ToggleButton.Button name="hide" label={labelOptions.hide}> + {labelOptions.hide} + </ToggleButton.Button> + </ToggleButton.Group> + )} + </View> + </View> + ) +} diff --git a/src/components/moderation/LabelsOnMe.tsx b/src/components/moderation/LabelsOnMe.tsx new file mode 100644 index 0000000000..099769fa76 --- /dev/null +++ b/src/components/moderation/LabelsOnMe.tsx @@ -0,0 +1,83 @@ +import React from 'react' +import {StyleProp, View, ViewStyle} from 'react-native' +import {AppBskyFeedDefs, ComAtprotoLabelDefs} from '@atproto/api' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {useSession} from '#/state/session' + +import {atoms as a} from '#/alf' +import {Button, ButtonText, ButtonIcon, ButtonSize} from '#/components/Button' +import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' +import { + LabelsOnMeDialog, + useLabelsOnMeDialogControl, +} from '#/components/moderation/LabelsOnMeDialog' + +export function LabelsOnMe({ + details, + labels, + size, + style, +}: { + details: {did: string} | {uri: string; cid: string} + labels: ComAtprotoLabelDefs.Label[] | undefined + size?: ButtonSize + style?: StyleProp<ViewStyle> +}) { + const {_} = useLingui() + const {currentAccount} = useSession() + const isAccount = 'did' in details + const control = useLabelsOnMeDialogControl() + + if (!labels || !currentAccount) { + return null + } + labels = labels.filter( + l => !l.val.startsWith('!') && l.src !== currentAccount.did, + ) + if (!labels.length) { + return null + } + + const labelTarget = isAccount ? _(msg`account`) : _(msg`content`) + return ( + <View style={[a.flex_row, style]}> + <LabelsOnMeDialog control={control} subject={details} labels={labels} /> + + <Button + variant="solid" + color="secondary" + size={size || 'small'} + label={_(msg`View information about these labels`)} + onPress={() => { + control.open() + }}> + <ButtonIcon position="left" icon={CircleInfo} /> + <ButtonText style={[a.leading_snug]}> + {labels.length}{' '} + {labels.length === 1 ? ( + <Trans>label has been placed on this {labelTarget}</Trans> + ) : ( + <Trans>labels have been placed on this {labelTarget}</Trans> + )} + </ButtonText> + </Button> + </View> + ) +} + +export function LabelsOnMyPost({ + post, + style, +}: { + post: AppBskyFeedDefs.PostView + style?: StyleProp<ViewStyle> +}) { + const {currentAccount} = useSession() + if (post.author.did !== currentAccount?.did) { + return null + } + return ( + <LabelsOnMe details={post} labels={post.labels} size="tiny" style={style} /> + ) +} diff --git a/src/components/moderation/LabelsOnMeDialog.tsx b/src/components/moderation/LabelsOnMeDialog.tsx new file mode 100644 index 0000000000..6eddbc7ceb --- /dev/null +++ b/src/components/moderation/LabelsOnMeDialog.tsx @@ -0,0 +1,262 @@ +import React from 'react' +import {View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {ComAtprotoLabelDefs, ComAtprotoModerationDefs} from '@atproto/api' + +import {useLabelInfo} from '#/lib/moderation/useLabelInfo' +import {makeProfileLink} from '#/lib/routes/links' +import {sanitizeHandle} from '#/lib/strings/handles' +import {getAgent} from '#/state/session' + +import {atoms as a, useBreakpoints, useTheme} from '#/alf' +import {Text} from '#/components/Typography' +import * as Dialog from '#/components/Dialog' +import {Button, ButtonText} from '#/components/Button' +import {InlineLink} from '#/components/Link' +import * as Toast from '#/view/com/util/Toast' +import {Divider} from '../Divider' + +export {useDialogControl as useLabelsOnMeDialogControl} from '#/components/Dialog' + +type Subject = + | { + uri: string + cid: string + } + | { + did: string + } + +export interface LabelsOnMeDialogProps { + control: Dialog.DialogOuterProps['control'] + subject: Subject + labels: ComAtprotoLabelDefs.Label[] +} + +export function LabelsOnMeDialogInner(props: LabelsOnMeDialogProps) { + const {_} = useLingui() + const [appealingLabel, setAppealingLabel] = React.useState< + ComAtprotoLabelDefs.Label | undefined + >(undefined) + const {subject, labels} = props + const isAccount = 'did' in subject + + return ( + <Dialog.ScrollableInner + label={ + isAccount + ? _(msg`The following labels were applied to your account.`) + : _(msg`The following labels were applied to your content.`) + }> + {appealingLabel ? ( + <AppealForm + label={appealingLabel} + subject={subject} + control={props.control} + onPressBack={() => setAppealingLabel(undefined)} + /> + ) : ( + <> + <Text style={[a.text_2xl, a.font_bold, a.pb_xs, a.leading_tight]}> + {isAccount ? ( + <Trans>Labels on your account</Trans> + ) : ( + <Trans>Labels on your content</Trans> + )} + </Text> + <Text style={[a.text_md, a.leading_snug]}> + <Trans> + You may appeal these labels if you feel they were placed in error. + </Trans> + </Text> + + <View style={[a.py_lg, a.gap_md]}> + {labels.map(label => ( + <Label + key={`${label.val}-${label.src}`} + label={label} + control={props.control} + onPressAppeal={label => setAppealingLabel(label)} + /> + ))} + </View> + </> + )} + + <Dialog.Close /> + </Dialog.ScrollableInner> + ) +} + +export function LabelsOnMeDialog(props: LabelsOnMeDialogProps) { + return ( + <Dialog.Outer control={props.control}> + <Dialog.Handle /> + + <LabelsOnMeDialogInner {...props} /> + </Dialog.Outer> + ) +} + +function Label({ + label, + control, + onPressAppeal, +}: { + label: ComAtprotoLabelDefs.Label + control: Dialog.DialogOuterProps['control'] + onPressAppeal: (label: ComAtprotoLabelDefs.Label) => void +}) { + const t = useTheme() + const {_} = useLingui() + const {labeler, strings} = useLabelInfo(label) + return ( + <View + style={[ + a.border, + t.atoms.border_contrast_low, + a.rounded_sm, + a.overflow_hidden, + ]}> + <View style={[a.p_md, a.gap_sm, a.flex_row]}> + <View style={[a.flex_1, a.gap_xs]}> + <Text style={[a.font_bold, a.text_md]}>{strings.name}</Text> + <Text style={[t.atoms.text_contrast_medium, a.leading_snug]}> + {strings.description} + </Text> + </View> + <View> + <Button + variant="solid" + color="secondary" + size="small" + label={_(msg`Appeal`)} + onPress={() => onPressAppeal(label)}> + <ButtonText> + <Trans>Appeal</Trans> + </ButtonText> + </Button> + </View> + </View> + + <Divider /> + + <View style={[a.px_md, a.py_sm, t.atoms.bg_contrast_25]}> + <Text style={[t.atoms.text_contrast_medium]}> + <Trans>Source:</Trans>{' '} + <InlineLink + to={makeProfileLink( + labeler ? labeler.creator : {did: label.src, handle: ''}, + )} + onPress={() => control.close()}> + {labeler ? sanitizeHandle(labeler.creator.handle, '@') : label.src} + </InlineLink> + </Text> + </View> + </View> + ) +} + +function AppealForm({ + label, + subject, + control, + onPressBack, +}: { + label: ComAtprotoLabelDefs.Label + subject: Subject + control: Dialog.DialogOuterProps['control'] + onPressBack: () => void +}) { + const {_} = useLingui() + const {labeler, strings} = useLabelInfo(label) + const {gtMobile} = useBreakpoints() + const [details, setDetails] = React.useState('') + const isAccountReport = 'did' in subject + + const onSubmit = async () => { + try { + const $type = !isAccountReport + ? 'com.atproto.repo.strongRef' + : 'com.atproto.admin.defs#repoRef' + await getAgent() + .withProxy('atproto_labeler', label.src) + .createModerationReport({ + reasonType: ComAtprotoModerationDefs.REASONAPPEAL, + subject: { + $type, + ...subject, + }, + reason: details, + }) + Toast.show(_(msg`Appeal submitted.`)) + } finally { + control.close() + } + } + + return ( + <> + <Text style={[a.text_2xl, a.font_bold, a.pb_xs, a.leading_tight]}> + <Trans>Appeal "{strings.name}" label</Trans> + </Text> + <Text style={[a.text_md, a.leading_snug]}> + <Trans> + This appeal will be sent to{' '} + <InlineLink + to={makeProfileLink( + labeler ? labeler.creator : {did: label.src, handle: ''}, + )} + onPress={() => control.close()} + style={[a.text_md, a.leading_snug]}> + {labeler ? sanitizeHandle(labeler.creator.handle, '@') : label.src} + </InlineLink> + . + </Trans> + </Text> + <View style={[a.my_md]}> + <Dialog.Input + label={_(msg`Text input field`)} + placeholder={_( + msg`Please explain why you think this label was incorrectly applied by ${ + labeler ? sanitizeHandle(labeler.creator.handle, '@') : label.src + }`, + )} + value={details} + onChangeText={setDetails} + autoFocus={true} + numberOfLines={3} + multiline + maxLength={300} + /> + </View> + + <View + style={ + gtMobile + ? [a.flex_row, a.justify_between] + : [{flexDirection: 'column-reverse'}, a.gap_sm] + }> + <Button + testID="backBtn" + variant="solid" + color="secondary" + size="medium" + onPress={onPressBack} + label={_(msg`Back`)}> + {_(msg`Back`)} + </Button> + <Button + testID="submitBtn" + variant="solid" + color="primary" + size="medium" + onPress={onSubmit} + label={_(msg`Submit`)}> + {_(msg`Submit`)} + </Button> + </View> + </> + ) +} diff --git a/src/components/moderation/ModerationDetailsDialog.tsx b/src/components/moderation/ModerationDetailsDialog.tsx new file mode 100644 index 0000000000..da490cb43e --- /dev/null +++ b/src/components/moderation/ModerationDetailsDialog.tsx @@ -0,0 +1,148 @@ +import React from 'react' +import {View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {ModerationCause} from '@atproto/api' + +import {listUriToHref} from '#/lib/strings/url-helpers' +import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription' +import {makeProfileLink} from '#/lib/routes/links' + +import {isNative} from '#/platform/detection' +import {useTheme, atoms as a} from '#/alf' +import {Text} from '#/components/Typography' +import * as Dialog from '#/components/Dialog' +import {InlineLink} from '#/components/Link' +import {Divider} from '#/components/Divider' + +export {useDialogControl as useModerationDetailsDialogControl} from '#/components/Dialog' + +export interface ModerationDetailsDialogProps { + control: Dialog.DialogOuterProps['control'] + modcause: ModerationCause +} + +export function ModerationDetailsDialog(props: ModerationDetailsDialogProps) { + return ( + <Dialog.Outer control={props.control}> + <Dialog.Handle /> + <ModerationDetailsDialogInner {...props} /> + </Dialog.Outer> + ) +} + +function ModerationDetailsDialogInner({ + modcause, + control, +}: ModerationDetailsDialogProps & { + control: Dialog.DialogOuterProps['control'] +}) { + const t = useTheme() + const {_} = useLingui() + const desc = useModerationCauseDescription(modcause) + + let name + let description + if (!modcause) { + name = _(msg`Content Warning`) + description = _( + msg`Moderator has chosen to set a general warning on the content.`, + ) + } else if (modcause.type === 'blocking') { + if (modcause.source.type === 'list') { + const list = modcause.source.list + name = _(msg`User Blocked by List`) + description = ( + <Trans> + This user is included in the{' '} + <InlineLink to={listUriToHref(list.uri)} style={[a.text_sm]}> + {list.name} + </InlineLink>{' '} + list which you have blocked. + </Trans> + ) + } else { + name = _(msg`User Blocked`) + description = _( + msg`You have blocked this user. You cannot view their content.`, + ) + } + } else if (modcause.type === 'blocked-by') { + name = _(msg`User Blocks You`) + description = _( + msg`This user has blocked you. You cannot view their content.`, + ) + } else if (modcause.type === 'block-other') { + name = _(msg`Content Not Available`) + description = _( + msg`This content is not available because one of the users involved has blocked the other.`, + ) + } else if (modcause.type === 'muted') { + if (modcause.source.type === 'list') { + const list = modcause.source.list + name = _(msg`Account Muted by List`) + description = ( + <Trans> + This user is included in the{' '} + <InlineLink to={listUriToHref(list.uri)} style={[a.text_sm]}> + {list.name} + </InlineLink>{' '} + list which you have muted. + </Trans> + ) + } else { + name = _(msg`Account Muted`) + description = _(msg`You have muted this account.`) + } + } else if (modcause.type === 'mute-word') { + name = _(msg`Post Hidden by Muted Word`) + description = _(msg`You've chosen to hide a word or tag within this post.`) + } else if (modcause.type === 'hidden') { + name = _(msg`Post Hidden by You`) + description = _(msg`You have hidden this post.`) + } else if (modcause.type === 'label') { + name = desc.name + description = desc.description + } else { + // should never happen + name = '' + description = '' + } + + return ( + <Dialog.ScrollableInner label={_(msg`Moderation details`)}> + <Text style={[t.atoms.text, a.text_2xl, a.font_bold, a.mb_sm]}> + {name} + </Text> + <Text style={[t.atoms.text, a.text_md, a.mb_lg, a.leading_snug]}> + {description} + </Text> + + {modcause.type === 'label' && ( + <> + <Divider /> + <Text style={[t.atoms.text, a.text_md, a.leading_snug, a.mt_lg]}> + <Trans> + This label was applied by{' '} + {modcause.source.type === 'user' ? ( + <Trans>the author</Trans> + ) : ( + <InlineLink + to={makeProfileLink({did: modcause.label.src, handle: ''})} + onPress={() => control.close()} + style={a.text_md}> + {desc.source} + </InlineLink> + )} + . + </Trans> + </Text> + </> + )} + + {isNative && <View style={{height: 40}} />} + + <Dialog.Close /> + </Dialog.ScrollableInner> + ) +} diff --git a/src/components/moderation/ModerationLabelPref.tsx b/src/components/moderation/ModerationLabelPref.tsx new file mode 100644 index 0000000000..f145504881 --- /dev/null +++ b/src/components/moderation/ModerationLabelPref.tsx @@ -0,0 +1,154 @@ +import React from 'react' +import {View} from 'react-native' +import {InterpretedLabelValueDefinition, LabelPreference} from '@atproto/api' +import {useLingui} from '@lingui/react' +import {msg, Trans} from '@lingui/macro' + +import {useGlobalLabelStrings} from '#/lib/moderation/useGlobalLabelStrings' +import {useLabelBehaviorDescription} from '#/lib/moderation/useLabelBehaviorDescription' +import { + usePreferencesQuery, + usePreferencesSetContentLabelMutation, +} from '#/state/queries/preferences' +import {getLabelStrings} from '#/lib/moderation/useLabelInfo' + +import {useTheme, atoms as a} from '#/alf' +import {Text} from '#/components/Typography' +import {InlineLink} from '#/components/Link' +import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '../icons/CircleInfo' +import * as ToggleButton from '#/components/forms/ToggleButton' + +export function ModerationLabelPref({ + labelValueDefinition, + labelerDid, + disabled, +}: { + labelValueDefinition: InterpretedLabelValueDefinition + labelerDid: string | undefined + disabled?: boolean +}) { + const {_, i18n} = useLingui() + const t = useTheme() + + const isGlobalLabel = !labelValueDefinition.definedBy + const {identifier} = labelValueDefinition + const {data: preferences} = usePreferencesQuery() + const {mutate, variables} = usePreferencesSetContentLabelMutation() + const savedPref = + labelerDid && !isGlobalLabel + ? preferences?.moderationPrefs.labelers.find(l => l.did === labelerDid) + ?.labels[identifier] + : preferences?.moderationPrefs.labels[identifier] + const pref = + variables?.visibility ?? + savedPref ?? + labelValueDefinition.defaultSetting ?? + 'warn' + + // does the 'warn' setting make sense for this label? + const canWarn = !( + labelValueDefinition.blurs === 'none' && + labelValueDefinition.severity === 'none' + ) + // is this label adult only? + const adultOnly = labelValueDefinition.flags.includes('adult') + // is this label disabled because it's adult only? + const adultDisabled = + adultOnly && !preferences?.moderationPrefs.adultContentEnabled + // are there any reasons we cant configure this label here? + const cantConfigure = isGlobalLabel || adultDisabled + + // adjust the pref based on whether warn is available + let prefAdjusted = pref + if (adultDisabled) { + prefAdjusted = 'hide' + } else if (!canWarn && pref === 'warn') { + prefAdjusted = 'ignore' + } + + // grab localized descriptions of the label and its settings + const currentPrefLabel = useLabelBehaviorDescription( + labelValueDefinition, + prefAdjusted, + ) + const hideLabel = useLabelBehaviorDescription(labelValueDefinition, 'hide') + const warnLabel = useLabelBehaviorDescription(labelValueDefinition, 'warn') + const ignoreLabel = useLabelBehaviorDescription( + labelValueDefinition, + 'ignore', + ) + const globalLabelStrings = useGlobalLabelStrings() + const labelStrings = getLabelStrings( + i18n.locale, + globalLabelStrings, + labelValueDefinition, + ) + + return ( + <View style={[a.flex_row, a.gap_sm, a.px_lg, a.py_lg, a.justify_between]}> + <View style={[a.gap_xs, a.flex_1]}> + <Text style={[a.font_bold]}>{labelStrings.name}</Text> + <Text style={[t.atoms.text_contrast_medium, a.leading_snug]}> + {labelStrings.description} + </Text> + + {cantConfigure && ( + <View style={[a.flex_row, a.gap_xs, a.align_center, a.mt_xs]}> + <CircleInfo size="sm" fill={t.atoms.text_contrast_high.color} /> + + <Text + style={[t.atoms.text_contrast_medium, a.font_semibold, a.italic]}> + {adultDisabled ? ( + <Trans>Adult content is disabled.</Trans> + ) : isGlobalLabel ? ( + <Trans> + Configured in{' '} + <InlineLink to="/moderation" style={a.text_sm}> + moderation settings + </InlineLink> + . + </Trans> + ) : null} + </Text> + </View> + )} + </View> + {disabled ? ( + <></> + ) : cantConfigure ? ( + <View style={[{minHeight: 35}, a.px_sm, a.py_md]}> + <Text style={[a.font_bold, t.atoms.text_contrast_medium]}> + {currentPrefLabel} + </Text> + </View> + ) : ( + <View style={[{minHeight: 35}]}> + <ToggleButton.Group + label={_( + msg`Configure content filtering setting for category: ${labelStrings.name.toLowerCase()}`, + )} + values={[prefAdjusted]} + onChange={newPref => + mutate({ + label: identifier, + visibility: newPref[0] as LabelPreference, + labelerDid, + }) + }> + <ToggleButton.Button name="ignore" label={ignoreLabel}> + {ignoreLabel} + </ToggleButton.Button> + {canWarn && ( + <ToggleButton.Button name="warn" label={warnLabel}> + {warnLabel} + </ToggleButton.Button> + )} + <ToggleButton.Button name="hide" label={hideLabel}> + {hideLabel} + </ToggleButton.Button> + </ToggleButton.Group> + </View> + )} + </View> + ) +} diff --git a/src/components/moderation/PostAlerts.tsx b/src/components/moderation/PostAlerts.tsx new file mode 100644 index 0000000000..0bfe696788 --- /dev/null +++ b/src/components/moderation/PostAlerts.tsx @@ -0,0 +1,66 @@ +import React from 'react' +import {StyleProp, View, ViewStyle} from 'react-native' +import {ModerationUI, ModerationCause} from '@atproto/api' + +import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription' +import {getModerationCauseKey} from '#/lib/moderation' + +import {atoms as a} from '#/alf' +import {Button, ButtonText, ButtonIcon} from '#/components/Button' +import { + ModerationDetailsDialog, + useModerationDetailsDialogControl, +} from '#/components/moderation/ModerationDetailsDialog' + +export function PostAlerts({ + modui, + style, +}: { + modui: ModerationUI + includeMute?: boolean + style?: StyleProp<ViewStyle> +}) { + if (!modui.alert && !modui.inform) { + return null + } + + return ( + <View style={[a.flex_col, a.gap_xs, style]}> + <View style={[a.flex_row, a.flex_wrap, a.gap_xs]}> + {modui.alerts.map(cause => ( + <PostLabel key={getModerationCauseKey(cause)} cause={cause} /> + ))} + {modui.informs.map(cause => ( + <PostLabel key={getModerationCauseKey(cause)} cause={cause} /> + ))} + </View> + </View> + ) +} + +function PostLabel({cause}: {cause: ModerationCause}) { + const control = useModerationDetailsDialogControl() + const desc = useModerationCauseDescription(cause) + + return ( + <> + <Button + label={desc.name} + variant="solid" + color="secondary" + size="small" + shape="default" + onPress={() => { + control.open() + }} + style={[a.px_sm, a.py_xs, a.gap_xs]}> + <ButtonIcon icon={desc.icon} position="left" /> + <ButtonText style={[a.text_left, a.leading_snug]}> + {desc.name} + </ButtonText> + </Button> + + <ModerationDetailsDialog control={control} modcause={cause} /> + </> + ) +} diff --git a/src/view/com/util/moderation/PostHider.tsx b/src/components/moderation/PostHider.tsx similarity index 54% rename from src/view/com/util/moderation/PostHider.tsx rename to src/components/moderation/PostHider.tsx index ede62e988c..464ee20778 100644 --- a/src/view/com/util/moderation/PostHider.tsx +++ b/src/components/moderation/PostHider.tsx @@ -1,45 +1,50 @@ import React, {ComponentProps} from 'react' import {StyleSheet, Pressable, View, ViewStyle, StyleProp} from 'react-native' import {ModerationUI} from '@atproto/api' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {usePalette} from 'lib/hooks/usePalette' -import {Link} from '../Link' -import {Text} from '../text/Text' -import {addStyle} from 'lib/styles' -import {describeModerationCause} from 'lib/moderation' -import {ShieldExclamation} from 'lib/icons' import {useLingui} from '@lingui/react' import {Trans, msg} from '@lingui/macro' -import {useModalControls} from '#/state/modals' + +import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription' +import {addStyle} from 'lib/styles' + +import {useTheme, atoms as a} from '#/alf' +import { + ModerationDetailsDialog, + useModerationDetailsDialogControl, +} from '#/components/moderation/ModerationDetailsDialog' +import {Text} from '#/components/Typography' +// import {Link} from '#/components/Link' TODO this imposes some styles that screw things up +import {Link} from '#/view/com/util/Link' interface Props extends ComponentProps<typeof Link> { iconSize: number iconStyles: StyleProp<ViewStyle> - moderation: ModerationUI + modui: ModerationUI } export function PostHider({ testID, href, - moderation, + modui, style, children, iconSize, iconStyles, ...props }: Props) { - const pal = usePalette('default') + const t = useTheme() const {_} = useLingui() const [override, setOverride] = React.useState(false) - const {openModal} = useModalControls() + const control = useModerationDetailsDialogControl() + const blur = modui.blurs[0] + const desc = useModerationCauseDescription(blur) - if (!moderation.blur) { + if (!blur) { return ( <Link testID={testID} style={style} href={href} - noFeedback accessible={false} {...props}> {children} @@ -47,12 +52,10 @@ export function PostHider({ ) } - const isMute = ['muted', 'muted-word'].includes(moderation.cause?.type || '') - const desc = describeModerationCause(moderation.cause, 'content') return !override ? ( <Pressable onPress={() => { - if (!moderation.noOverride) { + if (!modui.noOverride) { setOverride(v => !v) } }} @@ -62,49 +65,45 @@ export function PostHider({ } accessibilityLabel="" style={[ - styles.description, + a.flex_row, + a.align_center, + a.gap_sm, + a.py_md, + { + paddingLeft: 6, + paddingRight: 18, + }, override ? {paddingBottom: 0} : undefined, - pal.view, + t.atoms.bg, ]}> + <ModerationDetailsDialog control={control} modcause={blur} /> <Pressable onPress={() => { - openModal({ - name: 'moderation-details', - context: 'content', - moderation, - }) + control.open() }} accessibilityRole="button" accessibilityLabel={_(msg`Learn more about this warning`)} accessibilityHint=""> <View style={[ - pal.viewLight, + t.atoms.bg_contrast_25, + a.align_center, + a.justify_center, { width: iconSize, height: iconSize, borderRadius: iconSize, - alignItems: 'center', - justifyContent: 'center', }, iconStyles, ]}> - {isMute ? ( - <FontAwesomeIcon - icon={['far', 'eye-slash']} - size={14} - color={pal.colors.textLight} - /> - ) : ( - <ShieldExclamation size={14} style={pal.textLight} /> - )} + <desc.icon size="sm" fill={t.atoms.text_contrast_medium.color} /> </View> </Pressable> - <Text type="sm" style={[{flex: 1}, pal.textLight]} numberOfLines={1}> + <Text style={[t.atoms.text_contrast_medium, a.flex_1]} numberOfLines={1}> {desc.name} </Text> - {!moderation.noOverride && ( - <Text type="sm" style={[styles.showBtn, pal.link]}> + {!modui.noOverride && ( + <Text style={[{color: t.palette.primary_500}]}> {override ? <Trans>Hide</Trans> : <Trans>Show</Trans>} </Text> )} @@ -114,26 +113,14 @@ export function PostHider({ testID={testID} style={addStyle(style, styles.child)} href={href} - noFeedback> + accessible={false} + {...props}> {children} </Link> ) } const styles = StyleSheet.create({ - description: { - flexDirection: 'row', - alignItems: 'center', - gap: 4, - paddingVertical: 10, - paddingLeft: 6, - paddingRight: 18, - marginTop: 1, - }, - showBtn: { - marginLeft: 'auto', - alignSelf: 'center', - }, child: { borderWidth: 0, borderTopWidth: 0, diff --git a/src/components/moderation/ProfileHeaderAlerts.tsx b/src/components/moderation/ProfileHeaderAlerts.tsx new file mode 100644 index 0000000000..dfc2aa5571 --- /dev/null +++ b/src/components/moderation/ProfileHeaderAlerts.tsx @@ -0,0 +1,66 @@ +import React from 'react' +import {StyleProp, View, ViewStyle} from 'react-native' +import {ModerationCause, ModerationDecision} from '@atproto/api' + +import {getModerationCauseKey} from 'lib/moderation' +import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription' + +import {atoms as a} from '#/alf' +import {Button, ButtonText, ButtonIcon} from '#/components/Button' +import { + ModerationDetailsDialog, + useModerationDetailsDialogControl, +} from '#/components/moderation/ModerationDetailsDialog' + +export function ProfileHeaderAlerts({ + moderation, + style, +}: { + moderation: ModerationDecision + style?: StyleProp<ViewStyle> +}) { + const modui = moderation.ui('profileView') + if (!modui.alert && !modui.inform) { + return null + } + + return ( + <View style={[a.flex_col, a.gap_xs, style]}> + <View style={[a.flex_row, a.flex_wrap, a.gap_xs]}> + {modui.alerts.map(cause => ( + <ProfileLabel key={getModerationCauseKey(cause)} cause={cause} /> + ))} + {modui.informs.map(cause => ( + <ProfileLabel key={getModerationCauseKey(cause)} cause={cause} /> + ))} + </View> + </View> + ) +} + +function ProfileLabel({cause}: {cause: ModerationCause}) { + const control = useModerationDetailsDialogControl() + const desc = useModerationCauseDescription(cause) + + return ( + <> + <Button + label={desc.name} + variant="solid" + color="secondary" + size="small" + shape="default" + onPress={() => { + control.open() + }} + style={[a.px_sm, a.py_xs, a.gap_xs]}> + <ButtonIcon icon={desc.icon} position="left" /> + <ButtonText style={[a.text_left, a.leading_snug]}> + {desc.name} + </ButtonText> + </Button> + + <ModerationDetailsDialog control={control} modcause={cause} /> + </> + ) +} diff --git a/src/components/moderation/ScreenHider.tsx b/src/components/moderation/ScreenHider.tsx new file mode 100644 index 0000000000..71ca85a926 --- /dev/null +++ b/src/components/moderation/ScreenHider.tsx @@ -0,0 +1,171 @@ +import React from 'react' +import { + TouchableWithoutFeedback, + StyleProp, + View, + ViewStyle, +} from 'react-native' +import {useNavigation} from '@react-navigation/native' +import {ModerationUI} from '@atproto/api' +import {Trans, msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' +import {NavigationProp} from 'lib/routes/types' +import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription' + +import {useTheme, atoms as a} from '#/alf' +import {CenteredView} from '#/view/com/util/Views' +import {Text} from '#/components/Typography' +import {Button, ButtonText} from '#/components/Button' +import { + ModerationDetailsDialog, + useModerationDetailsDialogControl, +} from '#/components/moderation/ModerationDetailsDialog' + +export function ScreenHider({ + testID, + screenDescription, + modui, + style, + containerStyle, + children, +}: React.PropsWithChildren<{ + testID?: string + screenDescription: string + modui: ModerationUI + style?: StyleProp<ViewStyle> + containerStyle?: StyleProp<ViewStyle> +}>) { + const t = useTheme() + const {_} = useLingui() + const [override, setOverride] = React.useState(false) + const navigation = useNavigation<NavigationProp>() + const {isMobile} = useWebMediaQueries() + const control = useModerationDetailsDialogControl() + const blur = modui.blurs[0] + const desc = useModerationCauseDescription(blur) + + if (!blur || override) { + return ( + <View testID={testID} style={style}> + {children} + </View> + ) + } + + const isNoPwi = !!modui.blurs.find( + cause => + cause.type === 'label' && cause.labelDef.id === '!no-unauthenticated', + ) + return ( + <CenteredView + style={[ + a.flex_1, + { + paddingTop: 100, + paddingBottom: 150, + }, + t.atoms.bg, + containerStyle, + ]} + sideBorders> + <View style={[a.align_center, a.mb_md]}> + <View + style={[ + t.atoms.bg_contrast_975, + a.align_center, + a.justify_center, + { + borderRadius: 25, + width: 50, + height: 50, + }, + ]}> + <desc.icon width={24} fill={t.atoms.bg.backgroundColor} /> + </View> + </View> + <Text + style={[ + a.text_4xl, + a.font_semibold, + a.text_center, + a.mb_md, + t.atoms.text, + ]}> + {isNoPwi ? ( + <Trans>Sign-in Required</Trans> + ) : ( + <Trans>Content Warning</Trans> + )} + </Text> + <Text + style={[ + a.text_lg, + a.mb_md, + a.px_lg, + a.text_center, + t.atoms.text_contrast_medium, + ]}> + {isNoPwi ? ( + <Trans> + This account has requested that users sign in to view their profile. + </Trans> + ) : ( + <> + <Trans>This {screenDescription} has been flagged:</Trans> + <Text style={[a.text_lg, a.font_semibold, t.atoms.text, a.ml_xs]}> + {desc.name}.{' '} + </Text> + <TouchableWithoutFeedback + onPress={() => { + control.open() + }} + accessibilityRole="button" + accessibilityLabel={_(msg`Learn more about this warning`)} + accessibilityHint=""> + <Text style={[a.text_lg, {color: t.palette.primary_500}]}> + <Trans>Learn More</Trans> + </Text> + </TouchableWithoutFeedback> + + <ModerationDetailsDialog control={control} modcause={blur} /> + </> + )}{' '} + </Text> + {isMobile && <View style={a.flex_1} />} + <View style={[a.flex_row, a.justify_center, a.my_md, a.gap_md]}> + <Button + variant="solid" + color="primary" + size="large" + style={[a.rounded_full]} + label={_(msg`Go back`)} + onPress={() => { + if (navigation.canGoBack()) { + navigation.goBack() + } else { + navigation.navigate('Home') + } + }}> + <ButtonText> + <Trans>Go back</Trans> + </ButtonText> + </Button> + {!modui.noOverride && ( + <Button + variant="solid" + color="secondary" + size="large" + style={[a.rounded_full]} + label={_(msg`Show anyway`)} + onPress={() => setOverride(v => !v)}> + <ButtonText> + <Trans>Show anyway</Trans> + </ButtonText> + </Button> + )} + </View> + </CenteredView> + ) +} diff --git a/src/lib/__tests__/moderatePost_wrapped.test.ts b/src/lib/__tests__/moderatePost_wrapped.test.ts deleted file mode 100644 index 45566281af..0000000000 --- a/src/lib/__tests__/moderatePost_wrapped.test.ts +++ /dev/null @@ -1,692 +0,0 @@ -import {describe, it, expect} from '@jest/globals' -import {RichText} from '@atproto/api' - -import {hasMutedWord} from '../moderatePost_wrapped' - -describe(`hasMutedWord`, () => { - describe(`tags`, () => { - it(`match: outline tag`, () => { - const rt = new RichText({ - text: `This is a post #inlineTag`, - }) - rt.detectFacetsWithoutResolution() - - const match = hasMutedWord({ - mutedWords: [{value: 'outlineTag', targets: ['tag']}], - text: rt.text, - facets: rt.facets, - outlineTags: ['outlineTag'], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`match: inline tag`, () => { - const rt = new RichText({ - text: `This is a post #inlineTag`, - }) - rt.detectFacetsWithoutResolution() - - const match = hasMutedWord({ - mutedWords: [{value: 'inlineTag', targets: ['tag']}], - text: rt.text, - facets: rt.facets, - outlineTags: ['outlineTag'], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`match: content target matches inline tag`, () => { - const rt = new RichText({ - text: `This is a post #inlineTag`, - }) - rt.detectFacetsWithoutResolution() - - const match = hasMutedWord({ - mutedWords: [{value: 'inlineTag', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: ['outlineTag'], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`no match: only tag targets`, () => { - const rt = new RichText({ - text: `This is a post`, - }) - rt.detectFacetsWithoutResolution() - - const match = hasMutedWord({ - mutedWords: [{value: 'inlineTag', targets: ['tag']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(false) - }) - }) - - describe(`early exits`, () => { - it(`match: single character 希`, () => { - /** - * @see https://bsky.app/profile/mukuuji.bsky.social/post/3klji4fvsdk2c - */ - const rt = new RichText({ - text: `改善希望です`, - }) - rt.detectFacetsWithoutResolution() - - const match = hasMutedWord({ - mutedWords: [{value: '希', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`no match: long muted word, short post`, () => { - const rt = new RichText({ - text: `hey`, - }) - rt.detectFacetsWithoutResolution() - - const match = hasMutedWord({ - mutedWords: [{value: 'politics', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(false) - }) - - it(`match: exact text`, () => { - const rt = new RichText({ - text: `javascript`, - }) - rt.detectFacetsWithoutResolution() - - const match = hasMutedWord({ - mutedWords: [{value: 'javascript', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - }) - - describe(`general content`, () => { - it(`match: word within post`, () => { - const rt = new RichText({ - text: `This is a post about javascript`, - }) - rt.detectFacetsWithoutResolution() - - const match = hasMutedWord({ - mutedWords: [{value: 'javascript', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`no match: partial word`, () => { - const rt = new RichText({ - text: `Use your brain, Eric`, - }) - rt.detectFacetsWithoutResolution() - - const match = hasMutedWord({ - mutedWords: [{value: 'ai', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(false) - }) - - it(`match: multiline`, () => { - const rt = new RichText({ - text: `Use your\n\tbrain, Eric`, - }) - rt.detectFacetsWithoutResolution() - - const match = hasMutedWord({ - mutedWords: [{value: 'brain', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`match: :)`, () => { - const rt = new RichText({ - text: `So happy :)`, - }) - rt.detectFacetsWithoutResolution() - - const match = hasMutedWord({ - mutedWords: [{value: `:)`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - }) - - describe(`punctuation semi-fuzzy`, () => { - describe(`yay!`, () => { - const rt = new RichText({ - text: `We're federating, yay!`, - }) - rt.detectFacetsWithoutResolution() - - it(`match: yay!`, () => { - const match = hasMutedWord({ - mutedWords: [{value: 'yay!', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`match: yay`, () => { - const match = hasMutedWord({ - mutedWords: [{value: 'yay', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - }) - - describe(`y!ppee!!`, () => { - const rt = new RichText({ - text: `We're federating, y!ppee!!`, - }) - rt.detectFacetsWithoutResolution() - - it(`match: y!ppee`, () => { - const match = hasMutedWord({ - mutedWords: [{value: 'y!ppee', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - // single exclamation point, source has double - it(`no match: y!ppee!`, () => { - const match = hasMutedWord({ - mutedWords: [{value: 'y!ppee!', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - }) - - describe(`Why so S@assy?`, () => { - const rt = new RichText({ - text: `Why so S@assy?`, - }) - rt.detectFacetsWithoutResolution() - - it(`match: S@assy`, () => { - const match = hasMutedWord({ - mutedWords: [{value: 'S@assy', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`match: s@assy`, () => { - const match = hasMutedWord({ - mutedWords: [{value: 's@assy', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - }) - - describe(`New York Times`, () => { - const rt = new RichText({ - text: `New York Times`, - }) - rt.detectFacetsWithoutResolution() - - // case insensitive - it(`match: new york times`, () => { - const match = hasMutedWord({ - mutedWords: [{value: 'new york times', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - }) - - describe(`!command`, () => { - const rt = new RichText({ - text: `Idk maybe a bot !command`, - }) - rt.detectFacetsWithoutResolution() - - it(`match: !command`, () => { - const match = hasMutedWord({ - mutedWords: [{value: `!command`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`match: command`, () => { - const match = hasMutedWord({ - mutedWords: [{value: `command`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`no match: !command`, () => { - const rt = new RichText({ - text: `Idk maybe a bot command`, - }) - rt.detectFacetsWithoutResolution() - - const match = hasMutedWord({ - mutedWords: [{value: `!command`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(false) - }) - }) - - describe(`e/acc`, () => { - const rt = new RichText({ - text: `I'm e/acc pilled`, - }) - rt.detectFacetsWithoutResolution() - - it(`match: e/acc`, () => { - const match = hasMutedWord({ - mutedWords: [{value: `e/acc`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`match: acc`, () => { - const match = hasMutedWord({ - mutedWords: [{value: `acc`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - }) - - describe(`super-bad`, () => { - const rt = new RichText({ - text: `I'm super-bad`, - }) - rt.detectFacetsWithoutResolution() - - it(`match: super-bad`, () => { - const match = hasMutedWord({ - mutedWords: [{value: `super-bad`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`match: super`, () => { - const match = hasMutedWord({ - mutedWords: [{value: `super`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`match: super bad`, () => { - const match = hasMutedWord({ - mutedWords: [{value: `super bad`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`match: superbad`, () => { - const match = hasMutedWord({ - mutedWords: [{value: `superbad`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(false) - }) - }) - - describe(`idk_what_this_would_be`, () => { - const rt = new RichText({ - text: `Weird post with idk_what_this_would_be`, - }) - rt.detectFacetsWithoutResolution() - - it(`match: idk what this would be`, () => { - const match = hasMutedWord({ - mutedWords: [{value: `idk what this would be`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`no match: idk what this would be for`, () => { - // extra word - const match = hasMutedWord({ - mutedWords: [ - {value: `idk what this would be for`, targets: ['content']}, - ], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(false) - }) - - it(`match: idk`, () => { - // extra word - const match = hasMutedWord({ - mutedWords: [{value: `idk`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`match: idkwhatthiswouldbe`, () => { - const match = hasMutedWord({ - mutedWords: [{value: `idkwhatthiswouldbe`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(false) - }) - }) - - describe(`parentheses`, () => { - const rt = new RichText({ - text: `Post with context(iykyk)`, - }) - rt.detectFacetsWithoutResolution() - - it(`match: context(iykyk)`, () => { - const match = hasMutedWord({ - mutedWords: [{value: `context(iykyk)`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`match: context`, () => { - const match = hasMutedWord({ - mutedWords: [{value: `context`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`match: iykyk`, () => { - const match = hasMutedWord({ - mutedWords: [{value: `iykyk`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`match: (iykyk)`, () => { - const match = hasMutedWord({ - mutedWords: [{value: `(iykyk)`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - }) - - describe(`🦋`, () => { - const rt = new RichText({ - text: `Post with 🦋`, - }) - rt.detectFacetsWithoutResolution() - - it(`match: 🦋`, () => { - const match = hasMutedWord({ - mutedWords: [{value: `🦋`, targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - }) - }) - - describe(`phrases`, () => { - describe(`I like turtles, or how I learned to stop worrying and love the internet.`, () => { - const rt = new RichText({ - text: `I like turtles, or how I learned to stop worrying and love the internet.`, - }) - rt.detectFacetsWithoutResolution() - - it(`match: stop worrying`, () => { - const match = hasMutedWord({ - mutedWords: [{value: 'stop worrying', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`match: turtles, or how`, () => { - const match = hasMutedWord({ - mutedWords: [{value: 'turtles, or how', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - }) - }) - - describe(`languages without spaces`, () => { - // I love turtles, or how I learned to stop worrying and love the internet - describe(`私はカメが好きです、またはどのようにして心配するのをやめてインターネットを愛するようになったのか`, () => { - const rt = new RichText({ - text: `私はカメが好きです、またはどのようにして心配するのをやめてインターネットを愛するようになったのか`, - }) - rt.detectFacetsWithoutResolution() - - // internet - it(`match: インターネット`, () => { - const match = hasMutedWord({ - mutedWords: [{value: 'インターネット', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - languages: ['ja'], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - }) - }) - - describe(`doesn't mute own post`, () => { - it(`does mute if it isn't own post`, () => { - const rt = new RichText({ - text: `Mute words!`, - }) - - const match = hasMutedWord({ - mutedWords: [{value: 'words', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: false, - }) - - expect(match).toBe(true) - }) - - it(`doesn't mute own post when muted word is in text`, () => { - const rt = new RichText({ - text: `Mute words!`, - }) - - const match = hasMutedWord({ - mutedWords: [{value: 'words', targets: ['content']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: true, - }) - - expect(match).toBe(false) - }) - - it(`doesn't mute own post when muted word is in tags`, () => { - const rt = new RichText({ - text: `Mute #words!`, - }) - - const match = hasMutedWord({ - mutedWords: [{value: 'words', targets: ['tags']}], - text: rt.text, - facets: rt.facets, - outlineTags: [], - isOwnPost: true, - }) - - expect(match).toBe(false) - }) - }) -}) diff --git a/src/lib/constants.ts b/src/lib/constants.ts index e868443950..f5a72669a9 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -35,6 +35,10 @@ export const MAX_GRAPHEME_LENGTH = 300 // but increasing limit per user feedback export const MAX_ALT_TEXT = 1000 +export function IS_TEST_USER(handle?: string) { + return handle && handle?.endsWith('.test') +} + export function IS_PROD_SERVICE(url?: string) { return url && url !== STAGING_SERVICE && url !== LOCAL_DEV_SERVICE } diff --git a/src/lib/moderatePost_wrapped.ts b/src/lib/moderatePost_wrapped.ts index 9f6fa9c076..0ce01368af 100644 --- a/src/lib/moderatePost_wrapped.ts +++ b/src/lib/moderatePost_wrapped.ts @@ -1,380 +1,30 @@ -import { - AppBskyEmbedRecord, - AppBskyEmbedRecordWithMedia, - moderatePost, - AppBskyActorDefs, - AppBskyFeedPost, - AppBskyRichtextFacet, - AppBskyEmbedImages, - AppBskyEmbedExternal, -} from '@atproto/api' +import {moderatePost, BSKY_LABELER_DID} from '@atproto/api' type ModeratePost = typeof moderatePost -type Options = Parameters<ModeratePost>[1] & { - hiddenPosts?: string[] - mutedWords?: AppBskyActorDefs.MutedWord[] -} - -const REGEX = { - LEADING_TRAILING_PUNCTUATION: /(?:^\p{P}+|\p{P}+$)/gu, - ESCAPE: /[[\]{}()*+?.\\^$|\s]/g, - SEPARATORS: /[\/\-\–\—\(\)\[\]\_]+/g, - WORD_BOUNDARY: /[\s\n\t\r\f\v]+?/g, -} - -/** - * List of 2-letter lang codes for languages that either don't use spaces, or - * don't use spaces in a way conducive to word-based filtering. - * - * For these, we use a simple `String.includes` to check for a match. - */ -const LANGUAGE_EXCEPTIONS = [ - 'ja', // Japanese - 'zh', // Chinese - 'ko', // Korean - 'th', // Thai - 'vi', // Vietnamese -] - -export function hasMutedWord({ - mutedWords, - text, - facets, - outlineTags, - languages, - isOwnPost, -}: { - mutedWords: AppBskyActorDefs.MutedWord[] - text: string - facets?: AppBskyRichtextFacet.Main[] - outlineTags?: string[] - languages?: string[] - isOwnPost: boolean -}) { - if (isOwnPost) return false - - const exception = LANGUAGE_EXCEPTIONS.includes(languages?.[0] || '') - const tags = ([] as string[]) - .concat(outlineTags || []) - .concat( - facets - ?.filter(facet => { - return facet.features.find(feature => - AppBskyRichtextFacet.isTag(feature), - ) - }) - .map(t => t.features[0].tag as string) || [], - ) - .map(t => t.toLowerCase()) - - for (const mute of mutedWords) { - const mutedWord = mute.value.toLowerCase() - const postText = text.toLowerCase() - - // `content` applies to tags as well - if (tags.includes(mutedWord)) return true - // rest of the checks are for `content` only - if (!mute.targets.includes('content')) continue - // single character or other exception, has to use includes - if ((mutedWord.length === 1 || exception) && postText.includes(mutedWord)) - return true - // too long - if (mutedWord.length > postText.length) continue - // exact match - if (mutedWord === postText) return true - // any muted phrase with space or punctuation - if (/(?:\s|\p{P})+?/u.test(mutedWord) && postText.includes(mutedWord)) - return true - - // check individual character groups - const words = postText.split(REGEX.WORD_BOUNDARY) - for (const word of words) { - if (word === mutedWord) return true - - // compare word without leading/trailing punctuation, but allow internal - // punctuation (such as `s@ssy`) - const wordTrimmedPunctuation = word.replace( - REGEX.LEADING_TRAILING_PUNCTUATION, - '', - ) - - if (mutedWord === wordTrimmedPunctuation) return true - if (mutedWord.length > wordTrimmedPunctuation.length) continue - - // handle hyphenated, slash separated words, etc - if (REGEX.SEPARATORS.test(wordTrimmedPunctuation)) { - // check against full normalized phrase - const wordNormalizedSeparators = wordTrimmedPunctuation.replace( - REGEX.SEPARATORS, - ' ', - ) - const mutedWordNormalizedSeparators = mutedWord.replace( - REGEX.SEPARATORS, - ' ', - ) - // hyphenated (or other sep) to spaced words - if (wordNormalizedSeparators === mutedWordNormalizedSeparators) - return true - - /* Disabled for now e.g. `super-cool` to `supercool` - const wordNormalizedCompressed = wordNormalizedSeparators.replace( - REGEX.WORD_BOUNDARY, - '', - ) - const mutedWordNormalizedCompressed = - mutedWordNormalizedSeparators.replace(/\s+?/g, '') - // hyphenated (or other sep) to non-hyphenated contiguous word - if (mutedWordNormalizedCompressed === wordNormalizedCompressed) - return true - */ - - // then individual parts of separated phrases/words - const wordParts = wordTrimmedPunctuation.split(REGEX.SEPARATORS) - for (const wp of wordParts) { - // still retain internal punctuation - if (wp === mutedWord) return true - } - } - } - } - - return false -} +type Options = Parameters<ModeratePost>[1] export function moderatePost_wrapped( subject: Parameters<ModeratePost>[0], opts: Options, ) { - const {hiddenPosts = [], mutedWords = [], ...options} = opts - const moderations = moderatePost(subject, options) - const isOwnPost = subject.author.did === opts.userDid + // HACK + // temporarily translate 'gore' into 'graphic-media' during the transition period + // can remove this in a few months + // -prf + translateOldLabels(subject) - if (hiddenPosts.includes(subject.uri)) { - moderations.content.filter = true - moderations.content.blur = true - if (!moderations.content.cause) { - moderations.content.cause = { - // @ts-ignore Temporary extension to the moderation system -prf - type: 'post-hidden', - source: {type: 'user'}, - priority: 1, - } - } - } - - if (AppBskyFeedPost.isRecord(subject.record)) { - let muted = hasMutedWord({ - mutedWords, - text: subject.record.text, - facets: subject.record.facets || [], - outlineTags: subject.record.tags || [], - languages: subject.record.langs, - isOwnPost, - }) - - if ( - subject.record.embed && - AppBskyEmbedImages.isMain(subject.record.embed) - ) { - for (const image of subject.record.embed.images) { - muted = - muted || - hasMutedWord({ - mutedWords, - text: image.alt, - facets: [], - outlineTags: [], - languages: subject.record.langs, - isOwnPost, - }) - } - } - - if (muted) { - moderations.content.filter = true - moderations.content.blur = true - if (!moderations.content.cause) { - moderations.content.cause = { - // @ts-ignore Temporary extension to the moderation system -prf - type: 'muted-word', - source: {type: 'user'}, - priority: 1, - } - } - } - } - - if (subject.embed) { - let embedHidden = false - let embedMuted = false - let externalMuted = false - - if (AppBskyEmbedRecord.isViewRecord(subject.embed.record)) { - embedHidden = hiddenPosts.includes(subject.embed.record.uri) - } - if ( - AppBskyEmbedRecordWithMedia.isView(subject.embed) && - AppBskyEmbedRecord.isViewRecord(subject.embed.record.record) - ) { - embedHidden = hiddenPosts.includes(subject.embed.record.record.uri) - } - - if (AppBskyEmbedRecord.isViewRecord(subject.embed.record)) { - if (AppBskyFeedPost.isRecord(subject.embed.record.value)) { - const embeddedPost = subject.embed.record.value - - embedMuted = - embedMuted || - hasMutedWord({ - mutedWords, - text: embeddedPost.text, - facets: embeddedPost.facets, - outlineTags: embeddedPost.tags, - languages: embeddedPost.langs, - isOwnPost, - }) - - if (AppBskyEmbedImages.isMain(embeddedPost.embed)) { - for (const image of embeddedPost.embed.images) { - embedMuted = - embedMuted || - hasMutedWord({ - mutedWords, - text: image.alt, - facets: [], - outlineTags: [], - languages: embeddedPost.langs, - isOwnPost, - }) - } - } - - if (AppBskyEmbedExternal.isMain(embeddedPost.embed)) { - const {external} = embeddedPost.embed - - embedMuted = - embedMuted || - hasMutedWord({ - mutedWords, - text: external.title + ' ' + external.description, - facets: [], - outlineTags: [], - languages: [], - isOwnPost, - }) - } - - if (AppBskyEmbedRecordWithMedia.isMain(embeddedPost.embed)) { - if (AppBskyEmbedExternal.isMain(embeddedPost.embed.media)) { - const {external} = embeddedPost.embed.media - - embedMuted = - embedMuted || - hasMutedWord({ - mutedWords, - text: external.title + ' ' + external.description, - facets: [], - outlineTags: [], - languages: [], - isOwnPost, - }) - } - - if (AppBskyEmbedImages.isMain(embeddedPost.embed.media)) { - for (const image of embeddedPost.embed.media.images) { - embedMuted = - embedMuted || - hasMutedWord({ - mutedWords, - text: image.alt, - facets: [], - outlineTags: [], - languages: AppBskyFeedPost.isRecord(embeddedPost.record) - ? embeddedPost.langs - : [], - isOwnPost, - }) - } - } - } - } - } - - if (AppBskyEmbedExternal.isView(subject.embed)) { - const {external} = subject.embed - - externalMuted = - externalMuted || - hasMutedWord({ - mutedWords, - text: external.title + ' ' + external.description, - facets: [], - outlineTags: [], - languages: [], - isOwnPost, - }) - } - - if ( - AppBskyEmbedRecordWithMedia.isView(subject.embed) && - AppBskyEmbedRecord.isViewRecord(subject.embed.record.record) - ) { - if (AppBskyFeedPost.isRecord(subject.embed.record.record.value)) { - const post = subject.embed.record.record.value - embedMuted = - embedMuted || - hasMutedWord({ - mutedWords, - text: post.text, - facets: post.facets, - outlineTags: post.tags, - languages: post.langs, - isOwnPost, - }) - } - - if (AppBskyEmbedImages.isView(subject.embed.media)) { - for (const image of subject.embed.media.images) { - embedMuted = - embedMuted || - hasMutedWord({ - mutedWords, - text: image.alt, - facets: [], - outlineTags: [], - languages: AppBskyFeedPost.isRecord(subject.record) - ? subject.record.langs - : [], - isOwnPost, - }) - } - } - } - - if (embedHidden) { - moderations.embed.filter = true - moderations.embed.blur = true - if (!moderations.embed.cause) { - moderations.embed.cause = { - // @ts-ignore Temporary extension to the moderation system -prf - type: 'post-hidden', - source: {type: 'user'}, - priority: 1, - } - } - } else if (externalMuted || embedMuted) { - moderations.content.filter = true - moderations.content.blur = true - if (!moderations.content.cause) { - moderations.content.cause = { - // @ts-ignore Temporary extension to the moderation system -prf - type: 'muted-word', - source: {type: 'user'}, - priority: 1, - } - } - } - } - - return moderations + return moderatePost(subject, opts) +} + +function translateOldLabels(subject: Parameters<ModeratePost>[0]) { + if (subject.labels) { + for (const label of subject.labels) { + if ( + label.val === 'gore' && + (!label.src || label.src === BSKY_LABELER_DID) + ) { + label.val = 'graphic-media' + } + } + } } diff --git a/src/lib/moderation.ts b/src/lib/moderation.ts index b6ebb47a02..4105c2c2dd 100644 --- a/src/lib/moderation.ts +++ b/src/lib/moderation.ts @@ -1,144 +1,20 @@ -import {ModerationCause, ProfileModeration, PostModeration} from '@atproto/api' +import { + ModerationCause, + ModerationUI, + InterpretedLabelValueDefinition, + LABELS, + AppBskyLabelerDefs, + BskyAgent, + ModerationOpts, +} from '@atproto/api' -export interface ModerationCauseDescription { - name: string - description: string -} - -export function describeModerationCause( - cause: ModerationCause | undefined, - context: 'account' | 'content', -): ModerationCauseDescription { - if (!cause) { - return { - name: 'Content Warning', - description: - 'Moderator has chosen to set a general warning on the content.', - } - } - if (cause.type === 'blocking') { - if (cause.source.type === 'list') { - return { - name: `User Blocked by "${cause.source.list.name}"`, - description: - 'You have blocked this user. You cannot view their content.', - } - } else { - return { - name: 'User Blocked', - description: - 'You have blocked this user. You cannot view their content.', - } - } - } - if (cause.type === 'blocked-by') { - return { - name: 'User Blocking You', - description: 'This user has blocked you. You cannot view their content.', - } - } - if (cause.type === 'block-other') { - return { - name: 'Content Not Available', - description: - 'This content is not available because one of the users involved has blocked the other.', - } - } - if (cause.type === 'muted') { - if (cause.source.type === 'list') { - return { - name: - context === 'account' - ? `Muted by "${cause.source.list.name}"` - : `Post by muted user ("${cause.source.list.name}")`, - description: 'You have muted this user', - } - } else { - return { - name: context === 'account' ? 'Muted User' : 'Post by muted user', - description: 'You have muted this user', - } - } - } - // @ts-ignore Temporary extension to the moderation system -prf - if (cause.type === 'post-hidden') { - return { - name: 'Post Hidden by You', - description: 'You have hidden this post', - } - } - // @ts-ignore Temporary extension to the moderation system -prf - if (cause.type === 'muted-word') { - return { - name: 'Post hidden by muted word', - description: `You've chosen to hide a word or tag within this post.`, - } - } - return cause.labelDef.strings[context].en -} - -export function getProfileModerationCauses( - moderation: ProfileModeration, -): ModerationCause[] { - /* - Gather everything on profile and account that blurs or alerts - */ - return [ - moderation.decisions.profile.cause, - ...moderation.decisions.profile.additionalCauses, - moderation.decisions.account.cause, - ...moderation.decisions.account.additionalCauses, - ].filter(cause => { - if (!cause) { - return false - } - if (cause?.type === 'label') { - if ( - cause.labelDef.onwarn === 'blur' || - cause.labelDef.onwarn === 'alert' - ) { - return true - } else { - return false - } - } - return true - }) as ModerationCause[] -} - -export function isPostMediaBlurred( - decisions: PostModeration['decisions'], -): boolean { - return decisions.post.blurMedia -} - -export function isQuoteBlurred( - decisions: PostModeration['decisions'], -): boolean { - return ( - decisions.quote?.blur || - decisions.quote?.blurMedia || - decisions.quote?.filter || - decisions.quotedAccount?.blur || - decisions.quotedAccount?.filter || - false - ) -} - -export function isCauseALabelOnUri( - cause: ModerationCause | undefined, - uri: string, -): boolean { - if (cause?.type !== 'label') { - return false - } - return cause.label.uri === uri -} +import {sanitizeDisplayName} from '#/lib/strings/display-names' +import {sanitizeHandle} from '#/lib/strings/handles' export function getModerationCauseKey(cause: ModerationCause): string { const source = cause.source.type === 'labeler' - ? cause.source.labeler.did + ? cause.source.did : cause.source.type === 'list' ? cause.source.list.uri : 'user' @@ -147,3 +23,59 @@ export function getModerationCauseKey(cause: ModerationCause): string { } return `${cause.type}:${source}` } + +export function isJustAMute(modui: ModerationUI): boolean { + return modui.filters.length === 1 && modui.filters[0].type === 'muted' +} + +export function getLabelingServiceTitle({ + displayName, + handle, +}: { + displayName?: string + handle: string +}) { + return displayName + ? sanitizeDisplayName(displayName) + : sanitizeHandle(handle, '@') +} + +export function lookupLabelValueDefinition( + labelValue: string, + customDefs: InterpretedLabelValueDefinition[] | undefined, +): InterpretedLabelValueDefinition | undefined { + let def + if (!labelValue.startsWith('!') && customDefs) { + def = customDefs.find(d => d.identifier === labelValue) + } + if (!def) { + def = LABELS[labelValue as keyof typeof LABELS] + } + return def +} + +export function isAppLabeler( + labeler: + | string + | AppBskyLabelerDefs.LabelerView + | AppBskyLabelerDefs.LabelerViewDetailed, +): boolean { + if (typeof labeler === 'string') { + return BskyAgent.appLabelers.includes(labeler) + } + return BskyAgent.appLabelers.includes(labeler.creator.did) +} + +export function isLabelerSubscribed( + labeler: + | string + | AppBskyLabelerDefs.LabelerView + | AppBskyLabelerDefs.LabelerViewDetailed, + modOpts: ModerationOpts, +) { + labeler = typeof labeler === 'string' ? labeler : labeler.creator.did + if (isAppLabeler(labeler)) { + return true + } + return modOpts.prefs.labelers.find(l => l.did === labeler) +} diff --git a/src/lib/moderation/useGlobalLabelStrings.ts b/src/lib/moderation/useGlobalLabelStrings.ts new file mode 100644 index 0000000000..1c5a482314 --- /dev/null +++ b/src/lib/moderation/useGlobalLabelStrings.ts @@ -0,0 +1,52 @@ +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {useMemo} from 'react' + +export type GlobalLabelStrings = Record< + string, + { + name: string + description: string + } +> + +export function useGlobalLabelStrings(): GlobalLabelStrings { + const {_} = useLingui() + return useMemo( + () => ({ + '!hide': { + name: _(msg`Content Blocked`), + description: _(msg`This content has been hidden by the moderators.`), + }, + '!warn': { + name: _(msg`Content Warning`), + description: _( + msg`This content has received a general warning from moderators.`, + ), + }, + '!no-unauthenticated': { + name: _(msg`Sign-in Required`), + description: _( + msg`This user has requested that their content only be shown to signed-in users.`, + ), + }, + porn: { + name: _(msg`Pornography`), + description: _(msg`Explicit sexual images.`), + }, + sexual: { + name: _(msg`Sexually Suggestive`), + description: _(msg`Does not include nudity.`), + }, + nudity: { + name: _(msg`Non-sexual Nudity`), + description: _(msg`E.g. artistic nudes.`), + }, + 'graphic-media': { + name: _(msg`Graphic Media`), + description: _(msg`Explicit or potentially disturbing media.`), + }, + }), + [_], + ) +} diff --git a/src/lib/moderation/useLabelBehaviorDescription.ts b/src/lib/moderation/useLabelBehaviorDescription.ts new file mode 100644 index 0000000000..0250c1bc89 --- /dev/null +++ b/src/lib/moderation/useLabelBehaviorDescription.ts @@ -0,0 +1,70 @@ +import {InterpretedLabelValueDefinition, LabelPreference} from '@atproto/api' +import {useLingui} from '@lingui/react' +import {msg} from '@lingui/macro' + +export function useLabelBehaviorDescription( + labelValueDef: InterpretedLabelValueDefinition, + pref: LabelPreference, +) { + const {_} = useLingui() + if (pref === 'ignore') { + return _(msg`Off`) + } + if (labelValueDef.blurs === 'content' || labelValueDef.blurs === 'media') { + if (pref === 'hide') { + return _(msg`Hide`) + } + return _(msg`Warn`) + } else if (labelValueDef.severity === 'alert') { + if (pref === 'hide') { + return _(msg`Hide`) + } + return _(msg`Warn`) + } else if (labelValueDef.severity === 'inform') { + if (pref === 'hide') { + return _(msg`Hide`) + } + return _(msg`Show badge`) + } else { + if (pref === 'hide') { + return _(msg`Hide`) + } + return _(msg`Disabled`) + } +} + +export function useLabelLongBehaviorDescription( + labelValueDef: InterpretedLabelValueDefinition, + pref: LabelPreference, +) { + const {_} = useLingui() + if (pref === 'ignore') { + return _(msg`Disabled`) + } + if (labelValueDef.blurs === 'content') { + if (pref === 'hide') { + return _(msg`Warn content and filter from feeds`) + } + return _(msg`Warn content`) + } else if (labelValueDef.blurs === 'media') { + if (pref === 'hide') { + return _(msg`Blur images and filter from feeds`) + } + return _(msg`Blur images`) + } else if (labelValueDef.severity === 'alert') { + if (pref === 'hide') { + return _(msg`Show warning and filter from feeds`) + } + return _(msg`Show warning`) + } else if (labelValueDef.severity === 'inform') { + if (pref === 'hide') { + return _(msg`Show badge and filter from feeds`) + } + return _(msg`Show badge`) + } else { + if (pref === 'hide') { + return _(msg`Filter from feeds`) + } + return _(msg`Disabled`) + } +} diff --git a/src/lib/moderation/useLabelInfo.ts b/src/lib/moderation/useLabelInfo.ts new file mode 100644 index 0000000000..b1cffe1e71 --- /dev/null +++ b/src/lib/moderation/useLabelInfo.ts @@ -0,0 +1,100 @@ +import { + ComAtprotoLabelDefs, + AppBskyLabelerDefs, + LABELS, + interpretLabelValueDefinition, + InterpretedLabelValueDefinition, +} from '@atproto/api' +import {useLingui} from '@lingui/react' +import * as bcp47Match from 'bcp-47-match' + +import { + GlobalLabelStrings, + useGlobalLabelStrings, +} from '#/lib/moderation/useGlobalLabelStrings' +import {useLabelDefinitions} from '#/state/preferences' + +export interface LabelInfo { + label: ComAtprotoLabelDefs.Label + def: InterpretedLabelValueDefinition + strings: ComAtprotoLabelDefs.LabelValueDefinitionStrings + labeler: AppBskyLabelerDefs.LabelerViewDetailed | undefined +} + +export function useLabelInfo(label: ComAtprotoLabelDefs.Label): LabelInfo { + const {i18n} = useLingui() + const {labelDefs, labelers} = useLabelDefinitions() + const globalLabelStrings = useGlobalLabelStrings() + const def = getDefinition(labelDefs, label) + return { + label, + def, + strings: getLabelStrings(i18n.locale, globalLabelStrings, def), + labeler: labelers.find(labeler => label.src === labeler.creator.did), + } +} + +export function getDefinition( + labelDefs: Record<string, InterpretedLabelValueDefinition[]>, + label: ComAtprotoLabelDefs.Label, +): InterpretedLabelValueDefinition { + // check local definitions + const customDef = + !label.val.startsWith('!') && + labelDefs[label.src]?.find( + def => def.identifier === label.val && def.definedBy === label.src, + ) + if (customDef) { + return customDef + } + + // check global definitions + const globalDef = LABELS[label.val as keyof typeof LABELS] + if (globalDef) { + return globalDef + } + + // fallback to a noop definition + return interpretLabelValueDefinition( + { + identifier: label.val, + severity: 'none', + blurs: 'none', + defaultSetting: 'ignore', + locales: [], + }, + label.src, + ) +} + +export function getLabelStrings( + locale: string, + globalLabelStrings: GlobalLabelStrings, + def: InterpretedLabelValueDefinition, +): ComAtprotoLabelDefs.LabelValueDefinitionStrings { + if (!def.definedBy) { + // global definition, look up strings + if (def.identifier in globalLabelStrings) { + return globalLabelStrings[ + def.identifier + ] as ComAtprotoLabelDefs.LabelValueDefinitionStrings + } + } else { + // try to find locale match in the definition's strings + const localeMatch = def.locales.find( + strings => bcp47Match.basicFilter(locale, strings.lang).length > 0, + ) + if (localeMatch) { + return localeMatch + } + // fall back to the zero item if no match + if (def.locales[0]) { + return def.locales[0] + } + } + return { + lang: locale, + name: def.identifier, + description: `Labeled "${def.identifier}"`, + } +} diff --git a/src/lib/moderation/useModerationCauseDescription.ts b/src/lib/moderation/useModerationCauseDescription.ts new file mode 100644 index 0000000000..46771e9584 --- /dev/null +++ b/src/lib/moderation/useModerationCauseDescription.ts @@ -0,0 +1,146 @@ +import React from 'react' +import { + BSKY_LABELER_DID, + ModerationCause, + ModerationCauseSource, +} from '@atproto/api' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {getDefinition, getLabelStrings} from './useLabelInfo' +import {useLabelDefinitions} from '#/state/preferences' +import {useGlobalLabelStrings} from './useGlobalLabelStrings' + +import {Props as SVGIconProps} from '#/components/icons/common' +import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning' +import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' +import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash' +import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign' + +export interface ModerationCauseDescription { + icon: React.ComponentType<SVGIconProps> + name: string + description: string + source?: string + sourceType?: ModerationCauseSource['type'] +} + +export function useModerationCauseDescription( + cause: ModerationCause | undefined, +): ModerationCauseDescription { + const {_, i18n} = useLingui() + const {labelDefs, labelers} = useLabelDefinitions() + const globalLabelStrings = useGlobalLabelStrings() + + return React.useMemo(() => { + if (!cause) { + return { + icon: Warning, + name: _(msg`Content Warning`), + description: _( + msg`Moderator has chosen to set a general warning on the content.`, + ), + } + } + if (cause.type === 'blocking') { + if (cause.source.type === 'list') { + return { + icon: CircleBanSign, + name: _(msg`User Blocked by "${cause.source.list.name}"`), + description: _( + msg`You have blocked this user. You cannot view their content.`, + ), + } + } else { + return { + icon: CircleBanSign, + name: _(msg`User Blocked`), + description: _( + msg`You have blocked this user. You cannot view their content.`, + ), + } + } + } + if (cause.type === 'blocked-by') { + return { + icon: CircleBanSign, + name: _(msg`User Blocking You`), + description: _( + msg`This user has blocked you. You cannot view their content.`, + ), + } + } + if (cause.type === 'block-other') { + return { + icon: CircleBanSign, + name: _(msg`Content Not Available`), + description: _( + msg`This content is not available because one of the users involved has blocked the other.`, + ), + } + } + if (cause.type === 'muted') { + if (cause.source.type === 'list') { + return { + icon: EyeSlash, + name: _(msg`Muted by "${cause.source.list.name}"`), + description: _(msg`You have muted this user`), + } + } else { + return { + icon: EyeSlash, + name: _(msg`Account Muted`), + description: _(msg`You have muted this account.`), + } + } + } + if (cause.type === 'mute-word') { + return { + icon: EyeSlash, + name: _(msg`Post Hidden by Muted Word`), + description: _( + msg`You've chosen to hide a word or tag within this post.`, + ), + } + } + if (cause.type === 'hidden') { + return { + icon: EyeSlash, + name: _(msg`Post Hidden by You`), + description: _(msg`You have hidden this post`), + } + } + if (cause.type === 'label') { + const def = cause.labelDef || getDefinition(labelDefs, cause.label) + const strings = getLabelStrings(i18n.locale, globalLabelStrings, def) + const labeler = labelers.find(l => l.creator.did === cause.label.src) + let source = + labeler?.creator.displayName || + (labeler?.creator.handle ? '@' + labeler?.creator.handle : undefined) + if (!source) { + if (cause.label.src === BSKY_LABELER_DID) { + source = 'Bluesky Moderation' + } else { + source = cause.label.src + } + } + return { + icon: + def.identifier === '!no-unauthenticated' + ? EyeSlash + : def.severity === 'alert' + ? Warning + : CircleInfo, + name: strings.name, + description: strings.description, + source, + sourceType: cause.source.type, + } + } + // should never happen + return { + icon: CircleInfo, + name: '', + description: ``, + } + }, [labelDefs, labelers, globalLabelStrings, cause, _, i18n.locale]) +} diff --git a/src/lib/moderation/useReportOptions.ts b/src/lib/moderation/useReportOptions.ts new file mode 100644 index 0000000000..e001705943 --- /dev/null +++ b/src/lib/moderation/useReportOptions.ts @@ -0,0 +1,94 @@ +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {useMemo} from 'react' +import {ComAtprotoModerationDefs} from '@atproto/api' + +export interface ReportOption { + reason: string + title: string + description: string +} + +interface ReportOptions { + account: ReportOption[] + post: ReportOption[] + list: ReportOption[] + feedgen: ReportOption[] + other: ReportOption[] +} + +export function useReportOptions(): ReportOptions { + const {_} = useLingui() + return useMemo(() => { + const other = { + reason: ComAtprotoModerationDefs.REASONOTHER, + title: _(msg`Other`), + description: _(msg`An issue not included in these options`), + } + const common = [ + { + reason: ComAtprotoModerationDefs.REASONRUDE, + title: _(msg`Anti-Social Behavior`), + description: _(msg`Harassment, trolling, or intolerance`), + }, + { + reason: ComAtprotoModerationDefs.REASONVIOLATION, + title: _(msg`Illegal and Urgent`), + description: _(msg`Glaring violations of law or terms of service`), + }, + other, + ] + return { + account: [ + { + reason: ComAtprotoModerationDefs.REASONMISLEADING, + title: _(msg`Misleading Account`), + description: _( + msg`Impersonation or false claims about identity or affiliation`, + ), + }, + { + reason: ComAtprotoModerationDefs.REASONSPAM, + title: _(msg`Frequently Posts Unwanted Content`), + description: _(msg`Spam; excessive mentions or replies`), + }, + { + reason: ComAtprotoModerationDefs.REASONVIOLATION, + title: _(msg`Name or Description Violates Community Standards`), + description: _(msg`Terms used violate community standards`), + }, + other, + ], + post: [ + { + reason: ComAtprotoModerationDefs.REASONSPAM, + title: _(msg`Spam`), + description: _(msg`Excessive mentions or replies`), + }, + { + reason: ComAtprotoModerationDefs.REASONSEXUAL, + title: _(msg`Unwanted Sexual Content`), + description: _(msg`Nudity or pornography not labeled as such`), + }, + ...common, + ], + list: [ + { + reason: ComAtprotoModerationDefs.REASONVIOLATION, + title: _(msg`Name or Description Violates Community Standards`), + description: _(msg`Terms used violate community standards`), + }, + ...common, + ], + feedgen: [ + { + reason: ComAtprotoModerationDefs.REASONVIOLATION, + title: _(msg`Name or Description Violates Community Standards`), + description: _(msg`Terms used violate community standards`), + }, + ...common, + ], + other: common, + } + }, [_]) +} diff --git a/src/lib/react-query.ts b/src/lib/react-query.ts index 7fe3fe7a47..d6cd3c54b2 100644 --- a/src/lib/react-query.ts +++ b/src/lib/react-query.ts @@ -1,7 +1,14 @@ import {AppState, AppStateStatus} from 'react-native' import {QueryClient, focusManager} from '@tanstack/react-query' +import {createAsyncStoragePersister} from '@tanstack/query-async-storage-persister' +import AsyncStorage from '@react-native-async-storage/async-storage' +import {PersistQueryClientProviderProps} from '@tanstack/react-query-persist-client' + import {isNative} from '#/platform/detection' +// any query keys in this array will be persisted to AsyncStorage +const STORED_CACHE_QUERY_KEYS = ['labelers-detailed-info'] + focusManager.setEventListener(onFocus => { if (isNative) { const subscription = AppState.addEventListener( @@ -48,3 +55,16 @@ export const queryClient = new QueryClient({ }, }, }) + +export const asyncStoragePersister = createAsyncStoragePersister({ + storage: AsyncStorage, + key: 'queryCache', +}) + +export const dehydrateOptions: PersistQueryClientProviderProps['persistOptions']['dehydrateOptions'] = + { + shouldDehydrateMutation: (_: any) => false, + shouldDehydrateQuery: query => { + return STORED_CACHE_QUERY_KEYS.includes(String(query.queryKey[0])) + }, + } diff --git a/src/lib/routes/types.ts b/src/lib/routes/types.ts index 6756a62a67..95af2f237d 100644 --- a/src/lib/routes/types.ts +++ b/src/lib/routes/types.ts @@ -21,7 +21,9 @@ export type CommonNavigatorParams = { PostRepostedBy: {name: string; rkey: string} ProfileFeed: {name: string; rkey: string} ProfileFeedLikedBy: {name: string; rkey: string} + ProfileLabelerLikedBy: {name: string} Debug: undefined + DebugMod: undefined Log: undefined Support: undefined PrivacyPolicy: undefined diff --git a/src/lib/strings/display-names.ts b/src/lib/strings/display-names.ts index 75383dd4fd..e0f23fa2cc 100644 --- a/src/lib/strings/display-names.ts +++ b/src/lib/strings/display-names.ts @@ -1,5 +1,4 @@ import {ModerationUI} from '@atproto/api' -import {describeModerationCause} from '../moderation' // \u2705 = ✅ // \u2713 = ✓ @@ -14,7 +13,7 @@ export function sanitizeDisplayName( moderation?: ModerationUI, ): string { if (moderation?.blur) { - return `⚠${describeModerationCause(moderation.cause, 'account').name}` + return '' } if (typeof str === 'string') { return str.replace(CHECK_MARKS_RE, '').replace(CONTROL_CHARS_RE, '').trim() diff --git a/src/lib/themes.ts b/src/lib/themes.ts index bd75aabea6..6fada40a7f 100644 --- a/src/lib/themes.ts +++ b/src/lib/themes.ts @@ -9,7 +9,7 @@ export const defaultTheme: Theme = { palette: { default: { background: lightPalette.white, - backgroundLight: lightPalette.contrast_50, + backgroundLight: lightPalette.contrast_25, text: lightPalette.black, textLight: lightPalette.contrast_700, textInverted: lightPalette.white, diff --git a/src/routes.ts b/src/routes.ts index 5c263fd6f5..f6f3729475 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -21,7 +21,9 @@ export const router = new Router({ PostRepostedBy: '/profile/:name/post/:rkey/reposted-by', ProfileFeed: '/profile/:name/feed/:rkey', ProfileFeedLikedBy: '/profile/:name/feed/:rkey/liked-by', + ProfileLabelerLikedBy: '/profile/:name/labeler/liked-by', Debug: '/sys/debug', + DebugMod: '/sys/debug-mod', Log: '/sys/log', AppPasswords: '/settings/app-passwords', PreferencesFollowingFeed: '/settings/following-feed', diff --git a/src/screens/Moderation/index.tsx b/src/screens/Moderation/index.tsx new file mode 100644 index 0000000000..26fa9ec77c --- /dev/null +++ b/src/screens/Moderation/index.tsx @@ -0,0 +1,560 @@ +import React from 'react' +import {View} from 'react-native' +import {useFocusEffect} from '@react-navigation/native' +import {ComAtprotoLabelDefs} from '@atproto/api' +import {Trans, msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {LABELS} from '@atproto/api' +import {useSafeAreaFrame} from 'react-native-safe-area-context' + +import {NativeStackScreenProps, CommonNavigatorParams} from '#/lib/routes/types' +import {CenteredView} from '#/view/com/util/Views' +import {ViewHeader} from '#/view/com/util/ViewHeader' +import {useAnalytics} from 'lib/analytics/analytics' +import {useSetMinimalShellMode} from '#/state/shell' +import {useSession} from '#/state/session' +import { + useProfileQuery, + useProfileUpdateMutation, +} from '#/state/queries/profile' +import {ScrollView} from '#/view/com/util/Views' + +import { + UsePreferencesQueryResponse, + useMyLabelersQuery, + usePreferencesQuery, + usePreferencesSetAdultContentMutation, +} from '#/state/queries/preferences' + +import {getLabelingServiceTitle} from '#/lib/moderation' +import {logger} from '#/logger' +import {useTheme, atoms as a, useBreakpoints, ViewStyleProp} from '#/alf' +import {Divider} from '#/components/Divider' +import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign' +import {Group3_Stroke2_Corner0_Rounded as Group} from '#/components/icons/Group' +import {Person_Stroke2_Corner0_Rounded as Person} from '#/components/icons/Person' +import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' +import {Filter_Stroke2_Corner0_Rounded as Filter} from '#/components/icons/Filter' +import {Text} from '#/components/Typography' +import * as Toggle from '#/components/forms/Toggle' +import {InlineLink, Link} from '#/components/Link' +import {Button, ButtonText} from '#/components/Button' +import {Loader} from '#/components/Loader' +import * as LabelingService from '#/components/LabelingServiceCard' +import {GlobalModerationLabelPref} from '#/components/moderation/GlobalModerationLabelPref' +import {useGlobalDialogsControlContext} from '#/components/dialogs/Context' +import {Props as SVGIconProps} from '#/components/icons/common' +import {BirthDateSettingsDialog} from '#/components/dialogs/BirthDateSettings' +import * as Dialog from '#/components/Dialog' + +function ErrorState({error}: {error: string}) { + const t = useTheme() + return ( + <View style={[a.p_xl]}> + <Text + style={[ + a.text_md, + a.leading_normal, + a.pb_md, + t.atoms.text_contrast_medium, + ]}> + <Trans> + Hmmmm, it seems we're having trouble loading this data. See below for + more details. If this issue persists, please contact us. + </Trans> + </Text> + <View + style={[ + a.relative, + a.py_md, + a.px_lg, + a.rounded_md, + a.mb_2xl, + t.atoms.bg_contrast_25, + ]}> + <Text style={[a.text_md, a.leading_normal]}>{error}</Text> + </View> + </View> + ) +} + +export function ModerationScreen( + _props: NativeStackScreenProps<CommonNavigatorParams, 'Moderation'>, +) { + const t = useTheme() + const {_} = useLingui() + const { + isLoading: isPreferencesLoading, + error: preferencesError, + data: preferences, + } = usePreferencesQuery() + const {gtMobile} = useBreakpoints() + const {height} = useSafeAreaFrame() + + const isLoading = isPreferencesLoading + const error = preferencesError + + return ( + <CenteredView + testID="moderationScreen" + style={[ + t.atoms.border_contrast_low, + t.atoms.bg, + {minHeight: height}, + ...(gtMobile ? [a.border_l, a.border_r] : []), + ]}> + <ViewHeader title={_(msg`Moderation`)} showOnDesktop /> + + {isLoading ? ( + <View style={[a.w_full, a.align_center, a.pt_2xl]}> + <Loader size="xl" fill={t.atoms.text.color} /> + </View> + ) : error || !preferences ? ( + <ErrorState + error={ + preferencesError?.toString() || + _(msg`Something went wrong, please try again.`) + } + /> + ) : ( + <ModerationScreenInner preferences={preferences} /> + )} + </CenteredView> + ) +} + +function SubItem({ + title, + icon: Icon, + style, +}: ViewStyleProp & { + title: string + icon: React.ComponentType<SVGIconProps> +}) { + const t = useTheme() + return ( + <View + style={[ + a.w_full, + a.flex_row, + a.align_center, + a.justify_between, + a.p_lg, + a.gap_sm, + style, + ]}> + <View style={[a.flex_row, a.align_center, a.gap_md]}> + <Icon size="md" style={[t.atoms.text_contrast_medium]} /> + <Text style={[a.text_sm, a.font_bold]}>{title}</Text> + </View> + <ChevronRight + size="sm" + style={[t.atoms.text_contrast_low, a.self_end, {paddingBottom: 2}]} + /> + </View> + ) +} + +export function ModerationScreenInner({ + preferences, +}: { + preferences: UsePreferencesQueryResponse +}) { + const {_} = useLingui() + const t = useTheme() + const setMinimalShellMode = useSetMinimalShellMode() + const {screen} = useAnalytics() + const {gtMobile} = useBreakpoints() + const {mutedWordsDialogControl} = useGlobalDialogsControlContext() + const birthdateDialogControl = Dialog.useDialogControl() + const { + isLoading: isLabelersLoading, + data: labelers, + error: labelersError, + } = useMyLabelersQuery() + + useFocusEffect( + React.useCallback(() => { + screen('Moderation') + setMinimalShellMode(false) + }, [screen, setMinimalShellMode]), + ) + + const {mutateAsync: setAdultContentPref, variables: optimisticAdultContent} = + usePreferencesSetAdultContentMutation() + const adultContentEnabled = !!( + (optimisticAdultContent && optimisticAdultContent.enabled) || + (!optimisticAdultContent && preferences.moderationPrefs.adultContentEnabled) + ) + const ageNotSet = !preferences.userAge + const isUnderage = (preferences.userAge || 0) < 18 + + const onToggleAdultContentEnabled = React.useCallback( + async (selected: boolean) => { + try { + await setAdultContentPref({ + enabled: selected, + }) + } catch (e: any) { + logger.error(`Failed to set adult content pref`, { + message: e.message, + }) + } + }, + [setAdultContentPref], + ) + + return ( + <View> + <ScrollView + contentContainerStyle={[ + a.border_0, + a.pt_2xl, + a.px_lg, + gtMobile && a.px_2xl, + ]}> + <Text + style={[a.text_md, a.font_bold, a.pb_md, t.atoms.text_contrast_high]}> + <Trans>Moderation tools</Trans> + </Text> + + <View + style={[ + a.w_full, + a.rounded_md, + a.overflow_hidden, + t.atoms.bg_contrast_25, + ]}> + <Button + testID="mutedWordsBtn" + label={_(msg`Open muted words and tags settings`)} + onPress={() => mutedWordsDialogControl.open()}> + {state => ( + <SubItem + title={_(msg`Muted words & tags`)} + icon={Filter} + style={[ + (state.hovered || state.pressed) && [t.atoms.bg_contrast_50], + ]} + /> + )} + </Button> + <Divider /> + <Link testID="moderationlistsBtn" to="/moderation/modlists"> + {state => ( + <SubItem + title={_(msg`Moderation lists`)} + icon={Group} + style={[ + (state.hovered || state.pressed) && [t.atoms.bg_contrast_50], + ]} + /> + )} + </Link> + <Divider /> + <Link testID="mutedAccountsBtn" to="/moderation/muted-accounts"> + {state => ( + <SubItem + title={_(msg`Muted accounts`)} + icon={Person} + style={[ + (state.hovered || state.pressed) && [t.atoms.bg_contrast_50], + ]} + /> + )} + </Link> + <Divider /> + <Link testID="blockedAccountsBtn" to="/moderation/blocked-accounts"> + {state => ( + <SubItem + title={_(msg`Blocked accounts`)} + icon={CircleBanSign} + style={[ + (state.hovered || state.pressed) && [t.atoms.bg_contrast_50], + ]} + /> + )} + </Link> + </View> + + <Text + style={[ + a.pt_2xl, + a.pb_md, + a.text_md, + a.font_bold, + t.atoms.text_contrast_high, + ]}> + <Trans>Content filters</Trans> + </Text> + + <View style={[a.gap_md]}> + {ageNotSet && ( + <> + <Button + label={_(msg`Confirm your birthdate`)} + size="small" + variant="solid" + color="secondary" + onPress={() => { + birthdateDialogControl.open() + }} + style={[a.justify_between, a.rounded_md, a.px_lg, a.py_lg]}> + <ButtonText> + <Trans>Confirm your age:</Trans> + </ButtonText> + <ButtonText> + <Trans>Set birthdate</Trans> + </ButtonText> + </Button> + + <BirthDateSettingsDialog + control={birthdateDialogControl} + preferences={preferences} + /> + </> + )} + <View + style={[ + a.w_full, + a.rounded_md, + a.overflow_hidden, + t.atoms.bg_contrast_25, + ]}> + {!ageNotSet && !isUnderage && ( + <> + <View + style={[ + a.py_lg, + a.px_lg, + a.flex_row, + a.align_center, + a.justify_between, + ]}> + <Text style={[a.font_semibold, t.atoms.text_contrast_high]}> + <Trans>Enable adult content</Trans> + </Text> + <Toggle.Item + label={_(msg`Toggle to enable or disable adult content`)} + name="adultContent" + value={adultContentEnabled} + onChange={onToggleAdultContentEnabled}> + <View style={[a.flex_row, a.align_center, a.gap_sm]}> + <Text style={[t.atoms.text_contrast_medium]}> + {adultContentEnabled ? ( + <Trans>Enabled</Trans> + ) : ( + <Trans>Disabled</Trans> + )} + </Text> + <Toggle.Switch /> + </View> + </Toggle.Item> + </View> + <Divider /> + </> + )} + {!isUnderage && adultContentEnabled && ( + <> + <GlobalModerationLabelPref labelValueDefinition={LABELS.porn} /> + <Divider /> + <GlobalModerationLabelPref + labelValueDefinition={LABELS.sexual} + /> + <Divider /> + <GlobalModerationLabelPref + labelValueDefinition={LABELS['graphic-media']} + /> + <Divider /> + </> + )} + <GlobalModerationLabelPref labelValueDefinition={LABELS.nudity} /> + </View> + </View> + + <Text + style={[ + a.text_md, + a.font_bold, + a.pt_2xl, + a.pb_md, + t.atoms.text_contrast_high, + ]}> + <Trans>Advanced</Trans> + </Text> + + {isLabelersLoading ? ( + <Loader /> + ) : labelersError || !labelers ? ( + <View style={[a.p_lg, a.rounded_sm, t.atoms.bg_contrast_25]}> + <Text> + <Trans> + We were unable to load your configured labelers at this time. + </Trans> + </Text> + </View> + ) : ( + <View style={[a.rounded_sm, t.atoms.bg_contrast_25]}> + {labelers.map((labeler, i) => { + return ( + <React.Fragment key={labeler.creator.did}> + {i !== 0 && <Divider />} + <LabelingService.Link labeler={labeler}> + {state => ( + <LabelingService.Outer + style={[ + i === 0 && { + borderTopLeftRadius: a.rounded_sm.borderRadius, + borderTopRightRadius: a.rounded_sm.borderRadius, + }, + i === labelers.length - 1 && { + borderBottomLeftRadius: a.rounded_sm.borderRadius, + borderBottomRightRadius: a.rounded_sm.borderRadius, + }, + (state.hovered || state.pressed) && [ + t.atoms.bg_contrast_50, + ], + ]}> + <LabelingService.Avatar /> + <LabelingService.Content> + <LabelingService.Title + value={getLabelingServiceTitle({ + displayName: labeler.creator.displayName, + handle: labeler.creator.handle, + })} + /> + <LabelingService.Description + value={labeler.creator.description} + handle={labeler.creator.handle} + /> + </LabelingService.Content> + </LabelingService.Outer> + )} + </LabelingService.Link> + </React.Fragment> + ) + })} + </View> + )} + + <Text + style={[ + a.text_md, + a.font_bold, + a.pt_2xl, + a.pb_md, + t.atoms.text_contrast_high, + ]}> + <Trans>Logged-out visibility</Trans> + </Text> + + <PwiOptOut /> + + <View style={{height: 200}} /> + </ScrollView> + </View> + ) +} + +function PwiOptOut() { + const t = useTheme() + const {_} = useLingui() + const {currentAccount} = useSession() + const {data: profile} = useProfileQuery({did: currentAccount?.did}) + const updateProfile = useProfileUpdateMutation() + + const isOptedOut = + profile?.labels?.some(l => l.val === '!no-unauthenticated') || false + const canToggle = profile && !updateProfile.isPending + + const onToggleOptOut = React.useCallback(() => { + if (!profile) { + return + } + let wasAdded = false + updateProfile.mutate({ + profile, + updates: existing => { + // create labels attr if needed + existing.labels = ComAtprotoLabelDefs.isSelfLabels(existing.labels) + ? existing.labels + : { + $type: 'com.atproto.label.defs#selfLabels', + values: [], + } + + // toggle the label + const hasLabel = existing.labels.values.some( + l => l.val === '!no-unauthenticated', + ) + if (hasLabel) { + wasAdded = false + existing.labels.values = existing.labels.values.filter( + l => l.val !== '!no-unauthenticated', + ) + } else { + wasAdded = true + existing.labels.values.push({val: '!no-unauthenticated'}) + } + + // delete if no longer needed + if (existing.labels.values.length === 0) { + delete existing.labels + } + return existing + }, + checkCommitted: res => { + const exists = !!res.data.labels?.some( + l => l.val === '!no-unauthenticated', + ) + return exists === wasAdded + }, + }) + }, [updateProfile, profile]) + + return ( + <View style={[a.pt_sm]}> + <View style={[a.flex_row, a.align_center, a.justify_between, a.gap_lg]}> + <Toggle.Item + disabled={!canToggle} + value={isOptedOut} + onChange={onToggleOptOut} + name="logged_out_visibility" + label={_( + msg`Discourage apps from showing my account to logged-out users`, + )}> + <Toggle.Switch /> + <Toggle.Label style={[a.text_md]}> + <Trans> + Discourage apps from showing my account to logged-out users + </Trans> + </Toggle.Label> + </Toggle.Item> + + {updateProfile.isPending && <Loader />} + </View> + + <View style={[a.pt_md, a.gap_md, {paddingLeft: 38}]}> + <Text style={[a.leading_snug, t.atoms.text_contrast_high]}> + <Trans> + Bluesky will not show your profile and posts to logged-out users. + Other apps may not honor this request. This does not make your + account private. + </Trans> + </Text> + <Text style={[a.font_bold, a.leading_snug, t.atoms.text_contrast_high]}> + <Trans> + Note: Bluesky is an open and public network. This setting only + limits the visibility of your content on the Bluesky app and + website, and other apps may not respect this setting. Your content + may still be shown to logged-out users by other apps and websites. + </Trans> + </Text> + + <InlineLink to="https://blueskyweb.zendesk.com/hc/en-us/articles/15835264007693-Data-Privacy"> + <Trans>Learn more about what is public on Bluesky.</Trans> + </InlineLink> + </View> + </View> + ) +} diff --git a/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx b/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx index 360025c02f..0bff534362 100644 --- a/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx +++ b/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx @@ -56,7 +56,9 @@ export function AdultContentEnabledPref({ try { mutate({ - enabled: !(variables?.enabled ?? preferences?.adultContentEnabled), + enabled: !( + variables?.enabled ?? preferences?.moderationPrefs.adultContentEnabled + ), }) } catch (e) { Toast.show( @@ -75,7 +77,10 @@ export function AdultContentEnabledPref({ <Toggle.Item name={_(msg`Enable adult content in your feeds`)} label={_(msg`Enable adult content in your feeds`)} - value={variables?.enabled ?? preferences?.adultContentEnabled} + value={ + variables?.enabled ?? + preferences?.moderationPrefs.adultContentEnabled + } onChange={onToggleAdultContent}> <View style={[ diff --git a/src/screens/Onboarding/StepModeration/ModerationOption.tsx b/src/screens/Onboarding/StepModeration/ModerationOption.tsx index c61b520bab..ac02a874cb 100644 --- a/src/screens/Onboarding/StepModeration/ModerationOption.tsx +++ b/src/screens/Onboarding/StepModeration/ModerationOption.tsx @@ -1,40 +1,51 @@ import React from 'react' import {View} from 'react-native' -import {LabelPreference} from '@atproto/api' +import {LabelPreference, InterpretedLabelValueDefinition} from '@atproto/api' import {useLingui} from '@lingui/react' -import {msg} from '@lingui/macro' -import Animated, {Easing, Layout, FadeIn} from 'react-native-reanimated' +import {msg, Trans} from '@lingui/macro' import { - CONFIGURABLE_LABEL_GROUPS, - ConfigurableLabelGroup, usePreferencesQuery, usePreferencesSetContentLabelMutation, } from '#/state/queries/preferences' import {atoms as a, useTheme} from '#/alf' import {Text} from '#/components/Typography' import * as ToggleButton from '#/components/forms/ToggleButton' +import {useGlobalLabelStrings} from '#/lib/moderation/useGlobalLabelStrings' export function ModerationOption({ - labelGroup, - isMounted, + labelValueDefinition, + disabled, }: { - labelGroup: ConfigurableLabelGroup - isMounted: React.MutableRefObject<boolean> + labelValueDefinition: InterpretedLabelValueDefinition + disabled?: boolean }) { const {_} = useLingui() const t = useTheme() - const groupInfo = CONFIGURABLE_LABEL_GROUPS[labelGroup] const {data: preferences} = usePreferencesQuery() const {mutate, variables} = usePreferencesSetContentLabelMutation() + const label = labelValueDefinition.identifier const visibility = - variables?.visibility ?? preferences?.contentLabels?.[labelGroup] + variables?.visibility ?? preferences?.moderationPrefs.labels?.[label] + + const allLabelStrings = useGlobalLabelStrings() + const labelStrings = + labelValueDefinition.identifier in allLabelStrings + ? allLabelStrings[labelValueDefinition.identifier] + : { + name: labelValueDefinition.identifier, + description: `Labeled "${labelValueDefinition.identifier}"`, + } const onChange = React.useCallback( (vis: string[]) => { - mutate({labelGroup, visibility: vis[0] as LabelPreference}) + mutate({ + label, + visibility: vis[0] as LabelPreference, + labelerDid: undefined, + }) }, - [mutate, labelGroup], + [mutate, label], ) const labels = { @@ -44,7 +55,7 @@ export function ModerationOption({ } return ( - <Animated.View + <View style={[ a.flex_row, a.justify_between, @@ -52,33 +63,37 @@ export function ModerationOption({ a.py_xs, a.px_xs, a.align_center, - ]} - layout={Layout.easing(Easing.ease).duration(200)} - entering={isMounted.current ? FadeIn : undefined}> - <View style={[a.gap_xs, {width: '50%'}]}> - <Text style={[a.font_bold]}>{groupInfo.title}</Text> + ]}> + <View style={[a.gap_xs, a.flex_1]}> + <Text style={[a.font_bold]}>{labelStrings.name}</Text> <Text style={[t.atoms.text_contrast_medium, a.leading_snug]}> - {groupInfo.subtitle} + {labelStrings.description} </Text> </View> - <View style={[a.justify_center, {minHeight: 35}]}> - <ToggleButton.Group - label={_( - msg`Configure content filtering setting for category: ${groupInfo.title.toLowerCase()}`, - )} - values={[visibility ?? 'hide']} - onChange={onChange}> - <ToggleButton.Button name="hide" label={labels.hide}> - {labels.hide} - </ToggleButton.Button> - <ToggleButton.Button name="warn" label={labels.warn}> - {labels.warn} - </ToggleButton.Button> - <ToggleButton.Button name="ignore" label={labels.show}> - {labels.show} - </ToggleButton.Button> - </ToggleButton.Group> + <View style={[a.justify_center, {minHeight: 40}]}> + {disabled ? ( + <Text style={[a.font_bold]}> + <Trans>Hide</Trans> + </Text> + ) : ( + <ToggleButton.Group + label={_( + msg`Configure content filtering setting for category: ${labelStrings.name.toLowerCase()}`, + )} + values={[visibility ?? 'hide']} + onChange={onChange}> + <ToggleButton.Button name="ignore" label={labels.show}> + {labels.show} + </ToggleButton.Button> + <ToggleButton.Button name="warn" label={labels.warn}> + {labels.warn} + </ToggleButton.Button> + <ToggleButton.Button name="hide" label={labels.hide}> + {labels.hide} + </ToggleButton.Button> + </ToggleButton.Group> + )} </View> - </Animated.View> + </View> ) } diff --git a/src/screens/Onboarding/StepModeration/index.tsx b/src/screens/Onboarding/StepModeration/index.tsx index 543a5b1598..9b52f9f439 100644 --- a/src/screens/Onboarding/StepModeration/index.tsx +++ b/src/screens/Onboarding/StepModeration/index.tsx @@ -2,15 +2,10 @@ import React from 'react' import {View} from 'react-native' import {useLingui} from '@lingui/react' import {msg, Trans} from '@lingui/macro' -import Animated, {Easing, Layout} from 'react-native-reanimated' +import {LABELS} from '@atproto/api' import {atoms as a} from '#/alf' -import { - configurableAdultLabelGroups, - configurableOtherLabelGroups, - usePreferencesSetAdultContentMutation, -} from 'state/queries/preferences' -import {Divider} from '#/components/Divider' +import {usePreferencesSetAdultContentMutation} from 'state/queries/preferences' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash' @@ -28,14 +23,6 @@ import {AdultContentEnabledPref} from '#/screens/Onboarding/StepModeration/Adult import {Context} from '#/screens/Onboarding/state' import {IconCircle} from '#/components/IconCircle' -function AnimatedDivider() { - return ( - <Animated.View layout={Layout.easing(Easing.ease).duration(200)}> - <Divider /> - </Animated.View> - ) -} - export function StepModeration() { const {_} = useLingui() const {track} = useAnalytics() @@ -52,7 +39,7 @@ export function StepModeration() { const adultContentEnabled = !!( (variables && variables.enabled) || - (!variables && preferences?.adultContentEnabled) + (!variables && preferences?.moderationPrefs.adultContentEnabled) ) const onContinue = React.useCallback(() => { @@ -86,22 +73,19 @@ export function StepModeration() { <AdultContentEnabledPref mutate={mutate} variables={variables} /> <View style={[a.gap_sm, a.w_full]}> - {adultContentEnabled && - configurableAdultLabelGroups.map((g, index) => ( - <React.Fragment key={index}> - {index === 0 && <AnimatedDivider />} - <ModerationOption labelGroup={g} isMounted={isMounted} /> - <AnimatedDivider /> - </React.Fragment> - ))} - - {configurableOtherLabelGroups.map((g, index) => ( - <React.Fragment key={index}> - {!adultContentEnabled && index === 0 && <AnimatedDivider />} - <ModerationOption labelGroup={g} isMounted={isMounted} /> - <AnimatedDivider /> - </React.Fragment> - ))} + <ModerationOption + labelValueDefinition={LABELS.porn} + disabled={!adultContentEnabled} + /> + <ModerationOption + labelValueDefinition={LABELS.sexual} + disabled={!adultContentEnabled} + /> + <ModerationOption + labelValueDefinition={LABELS['graphic-media']} + disabled={!adultContentEnabled} + /> + <ModerationOption labelValueDefinition={LABELS.nudity} /> </View> </> )} diff --git a/src/screens/Onboarding/StepSuggestedAccounts/SuggestedAccountCard.tsx b/src/screens/Onboarding/StepSuggestedAccounts/SuggestedAccountCard.tsx index 0670058920..7e4ea1f8b8 100644 --- a/src/screens/Onboarding/StepSuggestedAccounts/SuggestedAccountCard.tsx +++ b/src/screens/Onboarding/StepSuggestedAccounts/SuggestedAccountCard.tsx @@ -88,7 +88,7 @@ export function SuggestedAccountCard({ <UserAvatar size={48} avatar={profile.avatar} - moderation={moderation.avatar} + moderation={moderation.ui('avatar')} /> </View> <View style={[a.flex_1]}> diff --git a/src/screens/Onboarding/StepSuggestedAccounts/index.tsx b/src/screens/Onboarding/StepSuggestedAccounts/index.tsx index 14faddc10f..bdf94d8246 100644 --- a/src/screens/Onboarding/StepSuggestedAccounts/index.tsx +++ b/src/screens/Onboarding/StepSuggestedAccounts/index.tsx @@ -76,7 +76,7 @@ export function StepSuggestedAccounts() { return aggregateInterestItems( state.interestsStepResults.selectedInterests, state.interestsStepResults.apiResponse.suggestedAccountDids, - state.interestsStepResults.apiResponse.suggestedAccountDids.default, + state.interestsStepResults.apiResponse.suggestedAccountDids.default || [], ) }, [state.interestsStepResults]) const moderationOpts = useModerationOpts() diff --git a/src/screens/Onboarding/StepTopicalFeeds.tsx b/src/screens/Onboarding/StepTopicalFeeds.tsx index 636565e340..089363c233 100644 --- a/src/screens/Onboarding/StepTopicalFeeds.tsx +++ b/src/screens/Onboarding/StepTopicalFeeds.tsx @@ -21,7 +21,7 @@ import { import {FeedCard} from '#/screens/Onboarding/StepAlgoFeeds/FeedCard' import {aggregateInterestItems} from '#/screens/Onboarding/util' import {IconCircle} from '#/components/IconCircle' -import {IS_PROD_SERVICE} from 'lib/constants' +import {IS_TEST_USER} from 'lib/constants' import {useSession} from 'state/session' export function StepTopicalFeeds() { @@ -32,14 +32,14 @@ export function StepTopicalFeeds() { const [selectedFeedUris, setSelectedFeedUris] = React.useState<string[]>([]) const [saving, setSaving] = React.useState(false) const suggestedFeedUris = React.useMemo(() => { - if (!IS_PROD_SERVICE(currentAccount?.service)) return [] + if (IS_TEST_USER(currentAccount?.handle)) return [] return aggregateInterestItems( state.interestsStepResults.selectedInterests, state.interestsStepResults.apiResponse.suggestedFeedUris, - state.interestsStepResults.apiResponse.suggestedFeedUris.default, + state.interestsStepResults.apiResponse.suggestedFeedUris.default || [], ).slice(0, 10) }, [ - currentAccount?.service, + currentAccount?.handle, state.interestsStepResults.apiResponse.suggestedFeedUris, state.interestsStepResults.selectedInterests, ]) diff --git a/src/screens/Profile/ErrorState.tsx b/src/screens/Profile/ErrorState.tsx new file mode 100644 index 0000000000..2ec2cf592e --- /dev/null +++ b/src/screens/Profile/ErrorState.tsx @@ -0,0 +1,72 @@ +import React from 'react' +import {View} from 'react-native' +import {Trans, msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {useNavigation} from '@react-navigation/native' + +import {useTheme, atoms as a} from '#/alf' +import {Text} from '#/components/Typography' +import {Button, ButtonText} from '#/components/Button' +import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' +import {NavigationProp} from '#/lib/routes/types' + +export function ErrorState({error}: {error: string}) { + const t = useTheme() + const {_} = useLingui() + const navigation = useNavigation<NavigationProp>() + + const onPressBack = React.useCallback(() => { + if (navigation.canGoBack()) { + navigation.goBack() + } else { + navigation.navigate('Home') + } + }, [navigation]) + + return ( + <View style={[a.px_xl]}> + <CircleInfo width={48} style={[t.atoms.text_contrast_low]} /> + + <Text style={[a.text_xl, a.font_bold, a.pb_md, a.pt_xl]}> + <Trans>Hmmmm, we couldn't load that moderation service.</Trans> + </Text> + <Text + style={[ + a.text_md, + a.leading_normal, + a.pb_md, + t.atoms.text_contrast_medium, + ]}> + <Trans> + This moderation service is unavailable. See below for more details. If + this issue persists, contact us. + </Trans> + </Text> + <View + style={[ + a.relative, + a.py_md, + a.px_lg, + a.rounded_md, + a.mb_2xl, + t.atoms.bg_contrast_25, + ]}> + <Text style={[a.text_md, a.leading_normal]}>{error}</Text> + </View> + + <View style={{flexDirection: 'row'}}> + <Button + size="small" + color="secondary" + variant="solid" + label={_(msg`Go Back`)} + accessibilityHint="Return to previous page" + onPress={onPressBack}> + <ButtonText> + <Trans>Go Back</Trans> + </ButtonText> + </Button> + </View> + </View> + ) +} diff --git a/src/screens/Profile/Header/DisplayName.tsx b/src/screens/Profile/Header/DisplayName.tsx new file mode 100644 index 0000000000..b6d88db712 --- /dev/null +++ b/src/screens/Profile/Header/DisplayName.tsx @@ -0,0 +1,31 @@ +import React from 'react' +import {View} from 'react-native' +import {AppBskyActorDefs, ModerationDecision} from '@atproto/api' +import {sanitizeHandle} from 'lib/strings/handles' +import {sanitizeDisplayName} from 'lib/strings/display-names' +import {Shadow} from '#/state/cache/types' + +import {atoms as a, useTheme} from '#/alf' +import {Text} from '#/components/Typography' + +export function ProfileHeaderDisplayName({ + profile, + moderation, +}: { + profile: Shadow<AppBskyActorDefs.ProfileViewDetailed> + moderation: ModerationDecision +}) { + const t = useTheme() + return ( + <View pointerEvents="none"> + <Text + testID="profileHeaderDisplayName" + style={[t.atoms.text, a.text_4xl, {fontWeight: '500'}]}> + {sanitizeDisplayName( + profile.displayName || sanitizeHandle(profile.handle), + moderation.ui('displayName'), + )} + </Text> + </View> + ) +} diff --git a/src/screens/Profile/Header/Handle.tsx b/src/screens/Profile/Header/Handle.tsx new file mode 100644 index 0000000000..fd1cbe5333 --- /dev/null +++ b/src/screens/Profile/Header/Handle.tsx @@ -0,0 +1,46 @@ +import React from 'react' +import {View} from 'react-native' +import {AppBskyActorDefs} from '@atproto/api' +import {isInvalidHandle} from 'lib/strings/handles' +import {Shadow} from '#/state/cache/types' +import {Trans} from '@lingui/macro' + +import {atoms as a, useTheme, web} from '#/alf' +import {Text} from '#/components/Typography' + +export function ProfileHeaderHandle({ + profile, +}: { + profile: Shadow<AppBskyActorDefs.ProfileViewDetailed> +}) { + const t = useTheme() + const invalidHandle = isInvalidHandle(profile.handle) + const blockHide = profile.viewer?.blocking || profile.viewer?.blockedBy + return ( + <View style={[a.flex_row, a.gap_xs, a.align_center]} pointerEvents="none"> + {profile.viewer?.followedBy && !blockHide ? ( + <View style={[t.atoms.bg_contrast_25, a.rounded_xs, a.px_sm, a.py_xs]}> + <Text style={[t.atoms.text, a.text_sm]}> + <Trans>Follows you</Trans> + </Text> + </View> + ) : undefined} + <Text + style={[ + invalidHandle + ? [ + a.border, + a.text_xs, + a.px_sm, + a.py_xs, + a.rounded_xs, + {borderColor: t.palette.contrast_200}, + ] + : [a.text_md, t.atoms.text_contrast_medium], + web({wordBreak: 'break-all'}), + ]}> + {invalidHandle ? <Trans>⚠Invalid Handle</Trans> : `@${profile.handle}`} + </Text> + </View> + ) +} diff --git a/src/screens/Profile/Header/Metrics.tsx b/src/screens/Profile/Header/Metrics.tsx new file mode 100644 index 0000000000..d9a8a01a86 --- /dev/null +++ b/src/screens/Profile/Header/Metrics.tsx @@ -0,0 +1,61 @@ +import React from 'react' +import {View} from 'react-native' +import {AppBskyActorDefs} from '@atproto/api' +import {Trans, msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {Shadow} from '#/state/cache/types' +import {pluralize} from '#/lib/strings/helpers' +import {makeProfileLink} from 'lib/routes/links' +import {formatCount} from 'view/com/util/numeric/format' + +import {atoms as a, useTheme} from '#/alf' +import {Text} from '#/components/Typography' +import {InlineLink} from '#/components/Link' + +export function ProfileHeaderMetrics({ + profile, +}: { + profile: Shadow<AppBskyActorDefs.ProfileViewDetailed> +}) { + const t = useTheme() + const {_} = useLingui() + const following = formatCount(profile.followsCount || 0) + const followers = formatCount(profile.followersCount || 0) + const pluralizedFollowers = pluralize(profile.followersCount || 0, 'follower') + + return ( + <View + style={[a.flex_row, a.gap_sm, a.align_center, a.pb_md]} + pointerEvents="box-none"> + <InlineLink + testID="profileHeaderFollowersButton" + style={[a.flex_row, t.atoms.text]} + to={makeProfileLink(profile, 'followers')} + label={`${followers} ${pluralizedFollowers}`}> + <Text style={[a.font_bold, a.text_md]}>{followers} </Text> + <Text style={[t.atoms.text_contrast_medium, a.text_md]}> + {pluralizedFollowers} + </Text> + </InlineLink> + <InlineLink + testID="profileHeaderFollowsButton" + style={[a.flex_row, t.atoms.text]} + to={makeProfileLink(profile, 'follows')} + label={_(msg`${following} following`)}> + <Trans> + <Text style={[a.font_bold, a.text_md]}>{following} </Text> + <Text style={[t.atoms.text_contrast_medium, a.text_md]}> + following + </Text> + </Trans> + </InlineLink> + <Text style={[a.font_bold, t.atoms.text, a.text_md]}> + {formatCount(profile.postsCount || 0)}{' '} + <Text style={[t.atoms.text_contrast_medium, a.font_normal, a.text_md]}> + {pluralize(profile.postsCount || 0, 'post')} + </Text> + </Text> + </View> + ) +} diff --git a/src/screens/Profile/Header/ProfileHeaderLabeler.tsx b/src/screens/Profile/Header/ProfileHeaderLabeler.tsx new file mode 100644 index 0000000000..6722ed09b2 --- /dev/null +++ b/src/screens/Profile/Header/ProfileHeaderLabeler.tsx @@ -0,0 +1,329 @@ +import React, {memo, useMemo} from 'react' +import {View} from 'react-native' +import { + AppBskyActorDefs, + AppBskyLabelerDefs, + ModerationOpts, + moderateProfile, + RichText as RichTextAPI, +} from '@atproto/api' +import {Trans, msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {RichText} from '#/components/RichText' +import {useModalControls} from '#/state/modals' +import {usePreferencesQuery} from '#/state/queries/preferences' +import {useAnalytics} from 'lib/analytics/analytics' +import {useSession} from '#/state/session' +import {Shadow} from '#/state/cache/types' +import {useProfileShadow} from 'state/cache/profile-shadow' +import {useLabelerSubscriptionMutation} from '#/state/queries/labeler' +import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like' +import {logger} from '#/logger' +import {Haptics} from '#/lib/haptics' +import {pluralize} from '#/lib/strings/helpers' +import {isAppLabeler} from '#/lib/moderation' + +import {atoms as a, useTheme, tokens} from '#/alf' +import {Button, ButtonText} from '#/components/Button' +import {Text} from '#/components/Typography' +import * as Toast from '#/view/com/util/Toast' +import {ProfileHeaderShell} from './Shell' +import {ProfileMenu} from '#/view/com/profile/ProfileMenu' +import {ProfileHeaderDisplayName} from './DisplayName' +import {ProfileHeaderHandle} from './Handle' +import {ProfileHeaderMetrics} from './Metrics' +import { + Heart2_Stroke2_Corner0_Rounded as Heart, + Heart2_Filled_Stroke2_Corner0_Rounded as HeartFilled, +} from '#/components/icons/Heart2' +import {DialogOuterProps} from '#/components/Dialog' +import * as Prompt from '#/components/Prompt' +import {Link} from '#/components/Link' + +interface Props { + profile: AppBskyActorDefs.ProfileViewDetailed + labeler: AppBskyLabelerDefs.LabelerViewDetailed + descriptionRT: RichTextAPI | null + moderationOpts: ModerationOpts + hideBackButton?: boolean + isPlaceholderProfile?: boolean +} + +let ProfileHeaderLabeler = ({ + profile: profileUnshadowed, + labeler, + descriptionRT, + moderationOpts, + hideBackButton = false, + isPlaceholderProfile, +}: Props): React.ReactNode => { + const profile: Shadow<AppBskyActorDefs.ProfileViewDetailed> = + useProfileShadow(profileUnshadowed) + const t = useTheme() + const {_} = useLingui() + const {currentAccount, hasSession} = useSession() + const {openModal} = useModalControls() + const {track} = useAnalytics() + const cantSubscribePrompt = Prompt.usePromptControl() + const isSelf = currentAccount?.did === profile.did + + const moderation = useMemo( + () => moderateProfile(profile, moderationOpts), + [profile, moderationOpts], + ) + const {data: preferences} = usePreferencesQuery() + const {mutateAsync: toggleSubscription, variables} = + useLabelerSubscriptionMutation() + const isSubscribed = + variables?.subscribe ?? + preferences?.moderationPrefs.labelers.find(l => l.did === profile.did) + const canSubscribe = + isSubscribed || + (preferences ? preferences?.moderationPrefs.labelers.length < 9 : false) + const {mutateAsync: likeMod, isPending: isLikePending} = useLikeMutation() + const {mutateAsync: unlikeMod, isPending: isUnlikePending} = + useUnlikeMutation() + const [likeUri, setLikeUri] = React.useState<string>( + labeler.viewer?.like || '', + ) + const [likeCount, setLikeCount] = React.useState(labeler.likeCount || 0) + + const onToggleLiked = React.useCallback(async () => { + if (!labeler) { + return + } + try { + Haptics.default() + + if (likeUri) { + await unlikeMod({uri: likeUri}) + track('CustomFeed:Unlike') + setLikeCount(c => c - 1) + setLikeUri('') + } else { + const res = await likeMod({uri: labeler.uri, cid: labeler.cid}) + track('CustomFeed:Like') + setLikeCount(c => c + 1) + setLikeUri(res.uri) + } + } catch (e: any) { + Toast.show( + _( + msg`There was an an issue contacting the server, please check your internet connection and try again.`, + ), + ) + logger.error(`Failed to toggle labeler like`, {message: e.message}) + } + }, [labeler, likeUri, likeMod, unlikeMod, track, _]) + + const onPressEditProfile = React.useCallback(() => { + track('ProfileHeader:EditProfileButtonClicked') + openModal({ + name: 'edit-profile', + profile, + }) + }, [track, openModal, profile]) + + const onPressSubscribe = React.useCallback(async () => { + if (!canSubscribe) { + cantSubscribePrompt.open() + return + } + try { + await toggleSubscription({ + did: profile.did, + subscribe: !isSubscribed, + }) + } catch (e: any) { + // setSubscriptionError(e.message) + logger.error(`Failed to subscribe to labeler`, {message: e.message}) + } + }, [ + toggleSubscription, + isSubscribed, + profile, + canSubscribe, + cantSubscribePrompt, + ]) + + const isMe = React.useMemo( + () => currentAccount?.did === profile.did, + [currentAccount, profile], + ) + + return ( + <ProfileHeaderShell + profile={profile} + moderation={moderation} + hideBackButton={hideBackButton} + isPlaceholderProfile={isPlaceholderProfile}> + <View style={[a.px_lg, a.pt_md, a.pb_sm]} pointerEvents="box-none"> + <View + style={[a.flex_row, a.justify_end, a.gap_sm, a.pb_lg]} + pointerEvents="box-none"> + {isMe ? ( + <Button + testID="profileHeaderEditProfileButton" + size="small" + color="secondary" + variant="solid" + onPress={onPressEditProfile} + label={_(msg`Edit profile`)} + style={a.rounded_full}> + <ButtonText> + <Trans>Edit Profile</Trans> + </ButtonText> + </Button> + ) : !isAppLabeler(profile.did) ? ( + <> + <Button + testID="toggleSubscribeBtn" + label={ + isSubscribed + ? _(msg`Unsubscribe from this labeler`) + : _(msg`Subscribe to this labeler`) + } + disabled={!hasSession} + onPress={onPressSubscribe}> + {state => ( + <View + style={[ + { + paddingVertical: 12, + backgroundColor: + isSubscribed || !canSubscribe + ? state.hovered || state.pressed + ? t.palette.contrast_50 + : t.palette.contrast_25 + : state.hovered || state.pressed + ? tokens.color.temp_purple_dark + : tokens.color.temp_purple, + }, + a.px_lg, + a.rounded_sm, + a.gap_sm, + ]}> + <Text + style={[ + { + color: canSubscribe + ? isSubscribed + ? t.palette.contrast_700 + : t.palette.white + : t.palette.contrast_400, + }, + a.font_bold, + a.text_center, + ]}> + {isSubscribed ? ( + <Trans>Unsubscribe</Trans> + ) : ( + <Trans>Subscribe to Labeler</Trans> + )} + </Text> + </View> + )} + </Button> + </> + ) : null} + <ProfileMenu profile={profile} /> + </View> + <View style={[a.flex_col, a.gap_xs, a.pb_md]}> + <ProfileHeaderDisplayName profile={profile} moderation={moderation} /> + <ProfileHeaderHandle profile={profile} /> + </View> + {!isPlaceholderProfile && ( + <> + {isSelf && <ProfileHeaderMetrics profile={profile} />} + {descriptionRT && !moderation.ui('profileView').blur ? ( + <View pointerEvents="auto"> + <RichText + testID="profileHeaderDescription" + style={[a.text_md]} + numberOfLines={15} + value={descriptionRT} + /> + </View> + ) : undefined} + {!isAppLabeler(profile.did) && ( + <View style={[a.flex_row, a.gap_xs, a.align_center, a.pt_lg]}> + <Button + testID="toggleLikeBtn" + size="small" + color="secondary" + variant="solid" + shape="round" + label={_(msg`Like this feed`)} + disabled={!hasSession || isLikePending || isUnlikePending} + onPress={onToggleLiked}> + {likeUri ? ( + <HeartFilled fill={t.palette.negative_400} /> + ) : ( + <Heart fill={t.atoms.text_contrast_medium.color} /> + )} + </Button> + + {typeof likeCount === 'number' && ( + <Link + to={{ + screen: 'ProfileLabelerLikedBy', + params: { + name: labeler.creator.handle || labeler.creator.did, + }, + }} + size="tiny" + label={_( + msg`Liked by ${likeCount} ${pluralize( + likeCount, + 'user', + )}`, + )}> + {({hovered, focused, pressed}) => ( + <Text + style={[ + a.font_bold, + a.text_sm, + t.atoms.text_contrast_medium, + (hovered || focused || pressed) && + t.atoms.text_contrast_high, + ]}> + <Trans> + Liked by {likeCount} {pluralize(likeCount, 'user')} + </Trans> + </Text> + )} + </Link> + )} + </View> + )} + </> + )} + </View> + <CantSubscribePrompt control={cantSubscribePrompt} /> + </ProfileHeaderShell> + ) +} +ProfileHeaderLabeler = memo(ProfileHeaderLabeler) +export {ProfileHeaderLabeler} + +function CantSubscribePrompt({ + control, +}: { + control: DialogOuterProps['control'] +}) { + return ( + <Prompt.Outer control={control}> + <Prompt.Title>Unable to subscribe</Prompt.Title> + <Prompt.Description> + <Trans> + We're sorry! You can only subscribe to ten labelers, and you've + reached your limit of ten. + </Trans> + </Prompt.Description> + <Prompt.Actions> + <Prompt.Action onPress={control.close}>OK</Prompt.Action> + </Prompt.Actions> + </Prompt.Outer> + ) +} diff --git a/src/screens/Profile/Header/ProfileHeaderStandard.tsx b/src/screens/Profile/Header/ProfileHeaderStandard.tsx new file mode 100644 index 0000000000..8b90382441 --- /dev/null +++ b/src/screens/Profile/Header/ProfileHeaderStandard.tsx @@ -0,0 +1,286 @@ +import React, {memo, useMemo} from 'react' +import {View} from 'react-native' +import { + AppBskyActorDefs, + ModerationOpts, + moderateProfile, + RichText as RichTextAPI, +} from '@atproto/api' +import {Trans, msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' + +import {useModalControls} from '#/state/modals' +import {useAnalytics} from 'lib/analytics/analytics' +import {useSession, useRequireAuth} from '#/state/session' +import {Shadow} from '#/state/cache/types' +import {useProfileShadow} from 'state/cache/profile-shadow' +import { + useProfileFollowMutationQueue, + useProfileBlockMutationQueue, +} from '#/state/queries/profile' +import {logger} from '#/logger' +import {sanitizeDisplayName} from 'lib/strings/display-names' + +import {atoms as a, useTheme} from '#/alf' +import {Button, ButtonText, ButtonIcon} from '#/components/Button' +import * as Toast from '#/view/com/util/Toast' +import {ProfileHeaderShell} from './Shell' +import {ProfileMenu} from '#/view/com/profile/ProfileMenu' +import {ProfileHeaderDisplayName} from './DisplayName' +import {ProfileHeaderHandle} from './Handle' +import {ProfileHeaderMetrics} from './Metrics' +import {ProfileHeaderSuggestedFollows} from '#/view/com/profile/ProfileHeaderSuggestedFollows' +import {RichText} from '#/components/RichText' +import * as Prompt from '#/components/Prompt' +import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check' +import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' + +interface Props { + profile: AppBskyActorDefs.ProfileViewDetailed + descriptionRT: RichTextAPI | null + moderationOpts: ModerationOpts + hideBackButton?: boolean + isPlaceholderProfile?: boolean +} + +let ProfileHeaderStandard = ({ + profile: profileUnshadowed, + descriptionRT, + moderationOpts, + hideBackButton = false, + isPlaceholderProfile, +}: Props): React.ReactNode => { + const profile: Shadow<AppBskyActorDefs.ProfileViewDetailed> = + useProfileShadow(profileUnshadowed) + const t = useTheme() + const {currentAccount, hasSession} = useSession() + const {_} = useLingui() + const {openModal} = useModalControls() + const {track} = useAnalytics() + const moderation = useMemo( + () => moderateProfile(profile, moderationOpts), + [profile, moderationOpts], + ) + const [showSuggestedFollows, setShowSuggestedFollows] = React.useState(false) + const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( + profile, + 'ProfileHeader', + ) + const [_queueBlock, queueUnblock] = useProfileBlockMutationQueue(profile) + const unblockPromptControl = Prompt.usePromptControl() + const requireAuth = useRequireAuth() + + const onPressEditProfile = React.useCallback(() => { + track('ProfileHeader:EditProfileButtonClicked') + openModal({ + name: 'edit-profile', + profile, + }) + }, [track, openModal, profile]) + + const onPressFollow = () => { + requireAuth(async () => { + try { + track('ProfileHeader:FollowButtonClicked') + await queueFollow() + Toast.show( + _( + msg`Following ${sanitizeDisplayName( + profile.displayName || profile.handle, + moderation.ui('displayName'), + )}`, + ), + ) + } catch (e: any) { + if (e?.name !== 'AbortError') { + logger.error('Failed to follow', {message: String(e)}) + Toast.show(_(msg`There was an issue! ${e.toString()}`)) + } + } + }) + } + + const onPressUnfollow = () => { + requireAuth(async () => { + try { + track('ProfileHeader:UnfollowButtonClicked') + await queueUnfollow() + Toast.show( + _( + msg`No longer following ${sanitizeDisplayName( + profile.displayName || profile.handle, + moderation.ui('displayName'), + )}`, + ), + ) + } catch (e: any) { + if (e?.name !== 'AbortError') { + logger.error('Failed to unfollow', {message: String(e)}) + Toast.show(_(msg`There was an issue! ${e.toString()}`)) + } + } + }) + } + + const unblockAccount = React.useCallback(async () => { + track('ProfileHeader:UnblockAccountButtonClicked') + try { + await queueUnblock() + Toast.show(_(msg`Account unblocked`)) + } catch (e: any) { + if (e?.name !== 'AbortError') { + logger.error('Failed to unblock account', {message: e}) + Toast.show(_(msg`There was an issue! ${e.toString()}`)) + } + } + }, [_, queueUnblock, track]) + + const isMe = React.useMemo( + () => currentAccount?.did === profile.did, + [currentAccount, profile], + ) + + return ( + <ProfileHeaderShell + profile={profile} + moderation={moderation} + hideBackButton={hideBackButton} + isPlaceholderProfile={isPlaceholderProfile}> + <View style={[a.px_lg, a.pt_md, a.pb_sm]} pointerEvents="box-none"> + <View + style={[a.flex_row, a.justify_end, a.gap_sm, a.pb_sm]} + pointerEvents="box-none"> + {isMe ? ( + <Button + testID="profileHeaderEditProfileButton" + size="small" + color="secondary" + variant="solid" + onPress={onPressEditProfile} + label={_(msg`Edit profile`)} + style={a.rounded_full}> + <ButtonText> + <Trans>Edit Profile</Trans> + </ButtonText> + </Button> + ) : profile.viewer?.blocking ? ( + profile.viewer?.blockingByList ? null : ( + <Button + testID="unblockBtn" + size="small" + color="secondary" + variant="solid" + label={_(msg`Unblock`)} + disabled={!hasSession} + onPress={() => unblockPromptControl.open()} + style={a.rounded_full}> + <ButtonText> + <Trans context="action">Unblock</Trans> + </ButtonText> + </Button> + ) + ) : !profile.viewer?.blockedBy ? ( + <> + {hasSession && ( + <Button + testID="suggestedFollowsBtn" + size="small" + color={showSuggestedFollows ? 'primary' : 'secondary'} + variant="solid" + shape="round" + onPress={() => setShowSuggestedFollows(!showSuggestedFollows)} + label={_(msg`Show follows similar to ${profile.handle}`)}> + <FontAwesomeIcon + icon="user-plus" + style={ + showSuggestedFollows + ? {color: t.palette.white} + : t.atoms.text + } + size={14} + /> + </Button> + )} + + <Button + testID={profile.viewer?.following ? 'unfollowBtn' : 'followBtn'} + size="small" + color={profile.viewer?.following ? 'secondary' : 'primary'} + variant="solid" + label={ + profile.viewer?.following + ? _(msg`Unfollow ${profile.handle}`) + : _(msg`Follow ${profile.handle}`) + } + disabled={!hasSession} + onPress={ + profile.viewer?.following ? onPressUnfollow : onPressFollow + } + style={[a.rounded_full, a.gap_xs]}> + <ButtonIcon + position="left" + icon={profile.viewer?.following ? Check : Plus} + /> + <ButtonText> + {profile.viewer?.following ? ( + <Trans>Following</Trans> + ) : ( + <Trans>Follow</Trans> + )} + </ButtonText> + </Button> + </> + ) : null} + <ProfileMenu profile={profile} /> + </View> + <View style={[a.flex_col, a.gap_xs, a.pb_sm]}> + <ProfileHeaderDisplayName profile={profile} moderation={moderation} /> + <ProfileHeaderHandle profile={profile} /> + </View> + {!isPlaceholderProfile && ( + <> + <ProfileHeaderMetrics profile={profile} /> + {descriptionRT && !moderation.ui('profileView').blur ? ( + <View pointerEvents="auto"> + <RichText + testID="profileHeaderDescription" + style={[a.text_md]} + numberOfLines={15} + value={descriptionRT} + /> + </View> + ) : undefined} + </> + )} + </View> + {showSuggestedFollows && ( + <ProfileHeaderSuggestedFollows + actorDid={profile.did} + requestDismiss={() => { + if (showSuggestedFollows) { + setShowSuggestedFollows(false) + } else { + track('ProfileHeader:SuggestedFollowsOpened') + setShowSuggestedFollows(true) + } + }} + /> + )} + <Prompt.Basic + control={unblockPromptControl} + title={_(msg`Unblock Account?`)} + description={_( + msg`The account will be able to interact with you after unblocking.`, + )} + onConfirm={unblockAccount} + confirmButtonCta={ + profile.viewer?.blocking ? _(msg`Unblock`) : _(msg`Block`) + } + confirmButtonColor="negative" + /> + </ProfileHeaderShell> + ) +} +ProfileHeaderStandard = memo(ProfileHeaderStandard) +export {ProfileHeaderStandard} diff --git a/src/screens/Profile/Header/Shell.tsx b/src/screens/Profile/Header/Shell.tsx new file mode 100644 index 0000000000..1348b394cd --- /dev/null +++ b/src/screens/Profile/Header/Shell.tsx @@ -0,0 +1,164 @@ +import React, {memo} from 'react' +import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import {useNavigation} from '@react-navigation/native' +import {AppBskyActorDefs, ModerationDecision} from '@atproto/api' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {NavigationProp} from 'lib/routes/types' +import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' +import {BACK_HITSLOP} from 'lib/constants' +import {useSession} from '#/state/session' +import {Shadow} from '#/state/cache/types' +import {useLightboxControls, ProfileImageLightbox} from '#/state/lightbox' + +import {atoms as a, useTheme} from '#/alf' +import {LabelsOnMe} from '#/components/moderation/LabelsOnMe' +import {BlurView} from 'view/com/util/BlurView' +import {LoadingPlaceholder} from 'view/com/util/LoadingPlaceholder' +import {UserAvatar} from 'view/com/util/UserAvatar' +import {UserBanner} from 'view/com/util/UserBanner' +import {ProfileHeaderAlerts} from '#/components/moderation/ProfileHeaderAlerts' + +interface Props { + profile: Shadow<AppBskyActorDefs.ProfileViewDetailed> + moderation: ModerationDecision + hideBackButton?: boolean + isPlaceholderProfile?: boolean +} + +let ProfileHeaderShell = ({ + children, + profile, + moderation, + hideBackButton = false, + isPlaceholderProfile, +}: React.PropsWithChildren<Props>): React.ReactNode => { + const t = useTheme() + const {currentAccount} = useSession() + const {_} = useLingui() + const {openLightbox} = useLightboxControls() + const navigation = useNavigation<NavigationProp>() + const {isDesktop} = useWebMediaQueries() + + const onPressBack = React.useCallback(() => { + if (navigation.canGoBack()) { + navigation.goBack() + } else { + navigation.navigate('Home') + } + }, [navigation]) + + const onPressAvi = React.useCallback(() => { + const modui = moderation.ui('avatar') + if (profile.avatar && !(modui.blur && modui.noOverride)) { + openLightbox(new ProfileImageLightbox(profile)) + } + }, [openLightbox, profile, moderation]) + + const isMe = React.useMemo( + () => currentAccount?.did === profile.did, + [currentAccount, profile], + ) + + return ( + <View style={t.atoms.bg} pointerEvents="box-none"> + <View pointerEvents="none"> + {isPlaceholderProfile ? ( + <LoadingPlaceholder + width="100%" + height={150} + style={{borderRadius: 0}} + /> + ) : ( + <UserBanner + type={profile.associated?.labeler ? 'labeler' : 'default'} + banner={profile.banner} + moderation={moderation.ui('banner')} + /> + )} + </View> + + {children} + + <View style={[a.px_lg, a.pb_sm]} pointerEvents="box-none"> + <ProfileHeaderAlerts moderation={moderation} /> + {isMe && ( + <LabelsOnMe details={{did: profile.did}} labels={profile.labels} /> + )} + </View> + + {!isDesktop && !hideBackButton && ( + <TouchableWithoutFeedback + testID="profileHeaderBackBtn" + onPress={onPressBack} + hitSlop={BACK_HITSLOP} + accessibilityRole="button" + accessibilityLabel={_(msg`Back`)} + accessibilityHint=""> + <View style={styles.backBtnWrapper}> + <BlurView style={styles.backBtn} blurType="dark"> + <FontAwesomeIcon size={18} icon="angle-left" color="white" /> + </BlurView> + </View> + </TouchableWithoutFeedback> + )} + <TouchableWithoutFeedback + testID="profileHeaderAviButton" + onPress={onPressAvi} + accessibilityRole="image" + accessibilityLabel={_(msg`View ${profile.handle}'s avatar`)} + accessibilityHint=""> + <View + style={[ + t.atoms.bg, + {borderColor: t.atoms.bg.backgroundColor}, + styles.avi, + profile.associated?.labeler && styles.aviLabeler, + ]}> + <UserAvatar + type={profile.associated?.labeler ? 'labeler' : 'user'} + size={90} + avatar={profile.avatar} + moderation={moderation.ui('avatar')} + /> + </View> + </TouchableWithoutFeedback> + </View> + ) +} +ProfileHeaderShell = memo(ProfileHeaderShell) +export {ProfileHeaderShell} + +const styles = StyleSheet.create({ + backBtnWrapper: { + position: 'absolute', + top: 10, + left: 10, + width: 30, + height: 30, + overflow: 'hidden', + borderRadius: 15, + // @ts-ignore web only + cursor: 'pointer', + }, + backBtn: { + width: 30, + height: 30, + borderRadius: 15, + alignItems: 'center', + justifyContent: 'center', + }, + avi: { + position: 'absolute', + top: 110, + left: 10, + width: 94, + height: 94, + borderRadius: 47, + borderWidth: 2, + }, + aviLabeler: { + borderRadius: 12, + }, +}) diff --git a/src/screens/Profile/Header/index.tsx b/src/screens/Profile/Header/index.tsx new file mode 100644 index 0000000000..1280dd8b10 --- /dev/null +++ b/src/screens/Profile/Header/index.tsx @@ -0,0 +1,78 @@ +import React, {memo} from 'react' +import {StyleSheet, View} from 'react-native' +import { + AppBskyActorDefs, + AppBskyLabelerDefs, + ModerationOpts, + RichText as RichTextAPI, +} from '@atproto/api' +import {LoadingPlaceholder} from 'view/com/util/LoadingPlaceholder' +import {usePalette} from 'lib/hooks/usePalette' + +import {ProfileHeaderStandard} from './ProfileHeaderStandard' +import {ProfileHeaderLabeler} from './ProfileHeaderLabeler' + +let ProfileHeaderLoading = (_props: {}): React.ReactNode => { + const pal = usePalette('default') + return ( + <View style={pal.view}> + <LoadingPlaceholder width="100%" height={150} style={{borderRadius: 0}} /> + <View + style={[pal.view, {borderColor: pal.colors.background}, styles.avi]}> + <LoadingPlaceholder width={80} height={80} style={styles.br40} /> + </View> + <View style={styles.content}> + <View style={[styles.buttonsLine]}> + <LoadingPlaceholder width={167} height={31} style={styles.br50} /> + </View> + </View> + </View> + ) +} +ProfileHeaderLoading = memo(ProfileHeaderLoading) +export {ProfileHeaderLoading} + +interface Props { + profile: AppBskyActorDefs.ProfileViewDetailed + labeler: AppBskyLabelerDefs.LabelerViewDetailed | undefined + descriptionRT: RichTextAPI | null + moderationOpts: ModerationOpts + hideBackButton?: boolean + isPlaceholderProfile?: boolean +} + +let ProfileHeader = (props: Props): React.ReactNode => { + if (props.profile.associated?.labeler) { + if (!props.labeler) { + return <ProfileHeaderLoading /> + } + return <ProfileHeaderLabeler {...props} labeler={props.labeler} /> + } + return <ProfileHeaderStandard {...props} /> +} +ProfileHeader = memo(ProfileHeader) +export {ProfileHeader} + +const styles = StyleSheet.create({ + avi: { + position: 'absolute', + top: 110, + left: 10, + width: 84, + height: 84, + borderRadius: 42, + borderWidth: 2, + }, + content: { + paddingTop: 8, + paddingHorizontal: 14, + paddingBottom: 4, + }, + buttonsLine: { + flexDirection: 'row', + marginLeft: 'auto', + marginBottom: 12, + }, + br40: {borderRadius: 40}, + br50: {borderRadius: 50}, +}) diff --git a/src/screens/Profile/ProfileLabelerLikedBy.tsx b/src/screens/Profile/ProfileLabelerLikedBy.tsx new file mode 100644 index 0000000000..1d21675208 --- /dev/null +++ b/src/screens/Profile/ProfileLabelerLikedBy.tsx @@ -0,0 +1,46 @@ +import React from 'react' +import {View} from 'react-native' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {useFocusEffect} from '@react-navigation/native' + +import {NativeStackScreenProps, CommonNavigatorParams} from '#/lib/routes/types' +import {ViewHeader} from '#/view/com/util/ViewHeader' +import {LikedByList} from '#/components/LikedByList' +import {useSetMinimalShellMode} from '#/state/shell' +import {makeRecordUri} from '#/lib/strings/url-helpers' + +import {atoms as a, useBreakpoints} from '#/alf' + +export function ProfileLabelerLikedByScreen({ + route, +}: NativeStackScreenProps<CommonNavigatorParams, 'ProfileLabelerLikedBy'>) { + const setMinimalShellMode = useSetMinimalShellMode() + const {name: handleOrDid} = route.params + const uri = makeRecordUri(handleOrDid, 'app.bsky.labeler.service', 'self') + const {_} = useLingui() + const {gtMobile} = useBreakpoints() + + useFocusEffect( + React.useCallback(() => { + setMinimalShellMode(false) + }, [setMinimalShellMode]), + ) + + return ( + <View + style={[ + a.mx_auto, + a.w_full, + a.h_full_vh, + gtMobile && [ + { + maxWidth: 600, + }, + ], + ]}> + <ViewHeader title={_(msg`Liked By`)} /> + <LikedByList uri={uri} /> + </View> + ) +} diff --git a/src/screens/Profile/Sections/Feed.tsx b/src/screens/Profile/Sections/Feed.tsx new file mode 100644 index 0000000000..0a5e2208d6 --- /dev/null +++ b/src/screens/Profile/Sections/Feed.tsx @@ -0,0 +1,88 @@ +import React from 'react' +import {View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {ListRef} from 'view/com/util/List' +import {Feed} from 'view/com/posts/Feed' +import {EmptyState} from 'view/com/util/EmptyState' +import {FeedDescriptor} from '#/state/queries/post-feed' +import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed' +import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn' +import {useQueryClient} from '@tanstack/react-query' +import {truncateAndInvalidate} from '#/state/queries/util' +import {Text} from '#/view/com/util/text/Text' +import {usePalette} from 'lib/hooks/usePalette' +import {isNative} from '#/platform/detection' +import {SectionRef} from './types' + +interface FeedSectionProps { + feed: FeedDescriptor + headerHeight: number + isFocused: boolean + scrollElRef: ListRef + ignoreFilterFor?: string +} +export const ProfileFeedSection = React.forwardRef< + SectionRef, + FeedSectionProps +>(function FeedSectionImpl( + {feed, headerHeight, isFocused, scrollElRef, ignoreFilterFor}, + ref, +) { + const {_} = useLingui() + const queryClient = useQueryClient() + const [hasNew, setHasNew] = React.useState(false) + const [isScrolledDown, setIsScrolledDown] = React.useState(false) + + const onScrollToTop = React.useCallback(() => { + scrollElRef.current?.scrollToOffset({ + animated: isNative, + offset: -headerHeight, + }) + truncateAndInvalidate(queryClient, FEED_RQKEY(feed)) + setHasNew(false) + }, [scrollElRef, headerHeight, queryClient, feed, setHasNew]) + React.useImperativeHandle(ref, () => ({ + scrollToTop: onScrollToTop, + })) + + const renderPostsEmpty = React.useCallback(() => { + return <EmptyState icon="feed" message={_(msg`This feed is empty!`)} /> + }, [_]) + + return ( + <View> + <Feed + testID="postsFeed" + enabled={isFocused} + feed={feed} + scrollElRef={scrollElRef} + onHasNew={setHasNew} + onScrolledDownChange={setIsScrolledDown} + renderEmptyState={renderPostsEmpty} + headerOffset={headerHeight} + renderEndOfFeed={ProfileEndOfFeed} + ignoreFilterFor={ignoreFilterFor} + /> + {(isScrolledDown || hasNew) && ( + <LoadLatestBtn + onPress={onScrollToTop} + label={_(msg`Load new posts`)} + showIndicator={hasNew} + /> + )} + </View> + ) +}) + +function ProfileEndOfFeed() { + const pal = usePalette('default') + + return ( + <View style={[pal.border, {paddingTop: 32, borderTopWidth: 1}]}> + <Text style={[pal.textLight, pal.border, {textAlign: 'center'}]}> + <Trans>End of feed</Trans> + </Text> + </View> + ) +} diff --git a/src/screens/Profile/Sections/Labels.tsx b/src/screens/Profile/Sections/Labels.tsx new file mode 100644 index 0000000000..07beb95294 --- /dev/null +++ b/src/screens/Profile/Sections/Labels.tsx @@ -0,0 +1,233 @@ +import React from 'react' +import {View} from 'react-native' +import { + AppBskyLabelerDefs, + ModerationOpts, + interpretLabelValueDefinitions, + InterpretedLabelValueDefinition, +} from '@atproto/api' +import {Trans, msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {useSafeAreaFrame} from 'react-native-safe-area-context' + +import {useScrollHandlers} from '#/lib/ScrollContext' +import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED' +import {isLabelerSubscribed, lookupLabelValueDefinition} from '#/lib/moderation' +import {ListRef} from '#/view/com/util/List' +import {SectionRef} from './types' +import {isNative} from '#/platform/detection' + +import {useTheme, atoms as a} from '#/alf' +import {Text} from '#/components/Typography' +import {Loader} from '#/components/Loader' +import {Divider} from '#/components/Divider' +import {CenteredView, ScrollView} from '#/view/com/util/Views' +import {ErrorState} from '../ErrorState' +import {ModerationLabelPref} from '#/components/moderation/ModerationLabelPref' +import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' + +interface LabelsSectionProps { + isLabelerLoading: boolean + labelerInfo: AppBskyLabelerDefs.LabelerViewDetailed | undefined + labelerError: Error | null + moderationOpts: ModerationOpts + scrollElRef: ListRef + headerHeight: number +} +export const ProfileLabelsSection = React.forwardRef< + SectionRef, + LabelsSectionProps +>(function LabelsSectionImpl( + { + isLabelerLoading, + labelerInfo, + labelerError, + moderationOpts, + scrollElRef, + headerHeight, + }, + ref, +) { + const t = useTheme() + const {_} = useLingui() + const {height: minHeight} = useSafeAreaFrame() + + const onScrollToTop = React.useCallback(() => { + // @ts-ignore TODO fix this + scrollElRef.current?.scrollTo({ + animated: isNative, + x: 0, + y: -headerHeight, + }) + }, [scrollElRef, headerHeight]) + + React.useImperativeHandle(ref, () => ({ + scrollToTop: onScrollToTop, + })) + + return ( + <CenteredView> + <View + style={[ + a.border_l, + a.border_r, + a.border_t, + t.atoms.border_contrast_low, + { + minHeight, + }, + ]}> + {isLabelerLoading ? ( + <View style={[a.w_full, a.align_center]}> + <Loader size="xl" /> + </View> + ) : labelerError || !labelerInfo ? ( + <ErrorState + error={ + labelerError?.toString() || + _(msg`Something went wrong, please try again.`) + } + /> + ) : ( + <ProfileLabelsSectionInner + moderationOpts={moderationOpts} + labelerInfo={labelerInfo} + scrollElRef={scrollElRef} + headerHeight={headerHeight} + /> + )} + </View> + </CenteredView> + ) +}) + +export function ProfileLabelsSectionInner({ + moderationOpts, + labelerInfo, + scrollElRef, + headerHeight, +}: { + moderationOpts: ModerationOpts + labelerInfo: AppBskyLabelerDefs.LabelerViewDetailed + scrollElRef: ListRef + headerHeight: number +}) { + const t = useTheme() + const contextScrollHandlers = useScrollHandlers() + + const scrollHandler = useAnimatedScrollHandler({ + onBeginDrag(e, ctx) { + contextScrollHandlers.onBeginDrag?.(e, ctx) + }, + onEndDrag(e, ctx) { + contextScrollHandlers.onEndDrag?.(e, ctx) + }, + onScroll(e, ctx) { + contextScrollHandlers.onScroll?.(e, ctx) + }, + }) + + const {labelValues} = labelerInfo.policies + const isSubscribed = isLabelerSubscribed(labelerInfo, moderationOpts) + const labelDefs = React.useMemo(() => { + const customDefs = interpretLabelValueDefinitions(labelerInfo) + return labelValues + .map(val => lookupLabelValueDefinition(val, customDefs)) + .filter( + def => def && def?.configurable, + ) as InterpretedLabelValueDefinition[] + }, [labelerInfo, labelValues]) + + return ( + <ScrollView + // @ts-ignore TODO fix this + ref={scrollElRef} + scrollEventThrottle={1} + contentContainerStyle={{ + paddingTop: headerHeight, + borderWidth: 0, + }} + contentOffset={{x: 0, y: headerHeight * -1}} + onScroll={scrollHandler}> + <View + style={[ + a.pt_xl, + a.px_lg, + isNative && a.border_t, + t.atoms.border_contrast_low, + ]}> + <View> + <Text style={[t.atoms.text_contrast_high, a.leading_snug, a.text_sm]}> + <Trans> + Labels are annotations on users and content. They can be used to + hide, warn, and categorize the network. + </Trans> + </Text> + {labelerInfo.creator.viewer?.blocking ? ( + <View style={[a.flex_row, a.gap_sm, a.align_center, a.mt_md]}> + <CircleInfo size="sm" fill={t.atoms.text_contrast_medium.color} /> + <Text + style={[t.atoms.text_contrast_high, a.leading_snug, a.text_sm]}> + <Trans> + Blocking does not prevent this labeler from placing labels on + your account. + </Trans> + </Text> + </View> + ) : null} + {labelValues.length === 0 ? ( + <Text + style={[ + a.pt_xl, + t.atoms.text_contrast_high, + a.leading_snug, + a.text_sm, + ]}> + <Trans> + This labeler hasn't declared what labels it publishes, and may + not be active. + </Trans> + </Text> + ) : !isSubscribed ? ( + <Text + style={[ + a.pt_xl, + t.atoms.text_contrast_high, + a.leading_snug, + a.text_sm, + ]}> + <Trans> + Subscribe to @{labelerInfo.creator.handle} to use these labels: + </Trans> + </Text> + ) : null} + </View> + {labelDefs.length > 0 && ( + <View + style={[ + a.mt_xl, + a.w_full, + a.rounded_md, + a.overflow_hidden, + t.atoms.bg_contrast_25, + ]}> + {labelDefs.map((labelDef, i) => { + return ( + <React.Fragment key={labelDef.identifier}> + {i !== 0 && <Divider />} + <ModerationLabelPref + disabled={isSubscribed ? undefined : true} + labelValueDefinition={labelDef} + labelerDid={labelerInfo.creator.did} + /> + </React.Fragment> + ) + })} + </View> + )} + + <View style={{height: 400}} /> + </View> + </ScrollView> + ) +} diff --git a/src/screens/Profile/Sections/types.ts b/src/screens/Profile/Sections/types.ts new file mode 100644 index 0000000000..a7f77d648c --- /dev/null +++ b/src/screens/Profile/Sections/types.ts @@ -0,0 +1,3 @@ +export interface SectionRef { + scrollToTop: () => void +} diff --git a/src/state/modals/index.tsx b/src/state/modals/index.tsx index db5be0b8d7..524dcb1bac 100644 --- a/src/state/modals/index.tsx +++ b/src/state/modals/index.tsx @@ -1,5 +1,5 @@ import React from 'react' -import {AppBskyActorDefs, AppBskyGraphDefs, ModerationUI} from '@atproto/api' +import {AppBskyActorDefs, AppBskyGraphDefs} from '@atproto/api' import {Image as RNImage} from 'react-native-image-crop-picker' import {ImageModel} from '#/state/models/media/image' @@ -14,32 +14,6 @@ export interface EditProfileModal { onUpdate?: () => void } -export interface ModerationDetailsModal { - name: 'moderation-details' - context: 'account' | 'content' - moderation: ModerationUI -} - -export type ReportModal = { - name: 'report' -} & ( - | { - uri: string - cid: string - } - | {did: string} -) - -export type AppealLabelModal = { - name: 'appeal-label' -} & ( - | { - uri: string - cid: string - } - | {did: string} -) - export interface CreateOrEditListModal { name: 'create-or-edit-list' purpose?: string @@ -123,10 +97,6 @@ export interface AddAppPasswordModal { name: 'add-app-password' } -export interface ContentFilteringSettingsModal { - name: 'content-filtering-settings' -} - export interface ContentLanguagesSettingsModal { name: 'content-languages-settings' } @@ -181,15 +151,9 @@ export type Modal = | SwitchAccountModal // Curation - | ContentFilteringSettingsModal | ContentLanguagesSettingsModal | PostLanguagesSettingsModal - // Moderation - | ModerationDetailsModal - | ReportModal - | AppealLabelModal - // Lists | CreateOrEditListModal | UserAddRemoveListsModal diff --git a/src/state/preferences/index.tsx b/src/state/preferences/index.tsx index a442b763ad..cf1d901511 100644 --- a/src/state/preferences/index.tsx +++ b/src/state/preferences/index.tsx @@ -15,6 +15,7 @@ export { useSetExternalEmbedPref, } from './external-embeds-prefs' export * from './hidden-posts' +export {useLabelDefinitions} from './label-defs' export function Provider({children}: React.PropsWithChildren<{}>) { return ( diff --git a/src/state/preferences/label-defs.tsx b/src/state/preferences/label-defs.tsx new file mode 100644 index 0000000000..d60f8ccb88 --- /dev/null +++ b/src/state/preferences/label-defs.tsx @@ -0,0 +1,25 @@ +import React from 'react' +import {InterpretedLabelValueDefinition, AppBskyLabelerDefs} from '@atproto/api' +import {useLabelDefinitionsQuery} from '../queries/preferences' + +interface StateContext { + labelDefs: Record<string, InterpretedLabelValueDefinition[]> + labelers: AppBskyLabelerDefs.LabelerViewDetailed[] +} + +const stateContext = React.createContext<StateContext>({ + labelDefs: {}, + labelers: [], +}) + +export function Provider({children}: React.PropsWithChildren<{}>) { + const {labelDefs, labelers} = useLabelDefinitionsQuery() + + const state = {labelDefs, labelers} + + return <stateContext.Provider value={state}>{children}</stateContext.Provider> +} + +export function useLabelDefinitions() { + return React.useContext(stateContext) +} diff --git a/src/state/queries/actor-autocomplete.ts b/src/state/queries/actor-autocomplete.ts index 3159ad7aaf..f14b3d65f1 100644 --- a/src/state/queries/actor-autocomplete.ts +++ b/src/state/queries/actor-autocomplete.ts @@ -6,17 +6,14 @@ import {logger} from '#/logger' import {getAgent} from '#/state/session' import {useMyFollowsQuery} from '#/state/queries/my-follows' import {STALE} from '#/state/queries' -import { - DEFAULT_LOGGED_OUT_PREFERENCES, - getModerationOpts, - useModerationOpts, -} from './preferences' +import {DEFAULT_LOGGED_OUT_PREFERENCES, useModerationOpts} from './preferences' import {isInvalidHandle} from '#/lib/strings/handles' +import {isJustAMute} from '#/lib/moderation' -const DEFAULT_MOD_OPTS = getModerationOpts({ - userDid: '', - preferences: DEFAULT_LOGGED_OUT_PREFERENCES, -}) +const DEFAULT_MOD_OPTS = { + userDid: undefined, + prefs: DEFAULT_LOGGED_OUT_PREFERENCES.moderationPrefs, +} export const RQKEY = (prefix: string) => ['actor-autocomplete', prefix] @@ -114,8 +111,8 @@ function computeSuggestions( } } return items.filter(profile => { - const mod = moderateProfile(profile, moderationOpts) - return !mod.account.filter && mod.account.cause?.type !== 'muted' + const modui = moderateProfile(profile, moderationOpts).ui('profileList') + return !modui.filter || isJustAMute(modui) }) } diff --git a/src/state/queries/labeler.ts b/src/state/queries/labeler.ts new file mode 100644 index 0000000000..c405a6b575 --- /dev/null +++ b/src/state/queries/labeler.ts @@ -0,0 +1,89 @@ +import {z} from 'zod' +import {useQuery, useMutation, useQueryClient} from '@tanstack/react-query' +import {AppBskyLabelerDefs} from '@atproto/api' + +import {getAgent} from '#/state/session' +import {preferencesQueryKey} from '#/state/queries/preferences' +import {STALE, PUBLIC_BSKY_AGENT} from '#/state/queries' + +export const labelerInfoQueryKey = (did: string) => ['labeler-info', did] +export const labelersInfoQueryKey = (dids: string[]) => [ + 'labelers-info', + dids.sort(), +] +export const labelersDetailedInfoQueryKey = (dids: string[]) => [ + 'labelers-detailed-info', + dids, +] + +export function useLabelerInfoQuery({ + did, + enabled, +}: { + did?: string + enabled?: boolean +}) { + return useQuery({ + enabled: !!did && enabled !== false, + queryKey: labelerInfoQueryKey(did as string), + queryFn: async () => { + const res = await PUBLIC_BSKY_AGENT.app.bsky.labeler.getServices({ + dids: [did as string], + detailed: true, + }) + return res.data.views[0] as AppBskyLabelerDefs.LabelerViewDetailed + }, + }) +} + +export function useLabelersInfoQuery({dids}: {dids: string[]}) { + return useQuery({ + enabled: !!dids.length, + queryKey: labelersInfoQueryKey(dids), + queryFn: async () => { + const res = await PUBLIC_BSKY_AGENT.app.bsky.labeler.getServices({dids}) + return res.data.views as AppBskyLabelerDefs.LabelerView[] + }, + }) +} + +export function useLabelersDetailedInfoQuery({dids}: {dids: string[]}) { + return useQuery({ + enabled: !!dids.length, + queryKey: labelersDetailedInfoQueryKey(dids), + gcTime: 1000 * 60 * 60 * 6, // 6 hours + staleTime: STALE.MINUTES.ONE, + queryFn: async () => { + const res = await PUBLIC_BSKY_AGENT.app.bsky.labeler.getServices({ + dids, + detailed: true, + }) + return res.data.views as AppBskyLabelerDefs.LabelerViewDetailed[] + }, + }) +} + +export function useLabelerSubscriptionMutation() { + const queryClient = useQueryClient() + + return useMutation({ + async mutationFn({did, subscribe}: {did: string; subscribe: boolean}) { + // TODO + z.object({ + did: z.string(), + subscribe: z.boolean(), + }).parse({did, subscribe}) + + if (subscribe) { + await getAgent().addLabeler(did) + } else { + await getAgent().removeLabeler(did) + } + }, + onSuccess() { + queryClient.invalidateQueries({ + queryKey: preferencesQueryKey, + }) + }, + }) +} diff --git a/src/state/queries/notifications/util.ts b/src/state/queries/notifications/util.ts index 626d3e9118..97fc57dc18 100644 --- a/src/state/queries/notifications/util.ts +++ b/src/state/queries/notifications/util.ts @@ -1,14 +1,13 @@ import { AppBskyNotificationListNotifications, ModerationOpts, - moderateProfile, + moderateNotification, AppBskyFeedDefs, AppBskyFeedPost, AppBskyFeedRepost, AppBskyFeedLike, AppBskyEmbedRecord, } from '@atproto/api' -import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped' import chunk from 'lodash.chunk' import {QueryClient} from '@tanstack/react-query' import {getAgent} from '../../session' @@ -88,37 +87,20 @@ export async function fetchPage({ // internal methods // = -// TODO this should be in the sdk as moderateNotification -prf -function shouldFilterNotif( +export function shouldFilterNotif( notif: AppBskyNotificationListNotifications.Notification, moderationOpts: ModerationOpts | undefined, ): boolean { if (!moderationOpts) { return false } - const profile = moderateProfile(notif.author, moderationOpts) - if ( - profile.account.filter || - profile.profile.filter || - notif.author.viewer?.muted - ) { - return true + if (notif.author.viewer?.following) { + return false } - if ( - notif.type === 'reply' || - notif.type === 'quote' || - notif.type === 'mention' - ) { - // NOTE: the notification overlaps the post enough for this to work - const post = moderatePost(notif, moderationOpts) - if (post.content.filter) { - return true - } - } - return false + return moderateNotification(notif, moderationOpts).ui('contentList').filter } -function groupNotifications( +export function groupNotifications( notifs: AppBskyNotificationListNotifications.Notification[], ): FeedNotification[] { const groupedNotifs: FeedNotification[] = [] diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts index c295ffcb03..0e6eef52ca 100644 --- a/src/state/queries/post-feed.ts +++ b/src/state/queries/post-feed.ts @@ -3,8 +3,8 @@ import {AppState} from 'react-native' import { AppBskyFeedDefs, AppBskyFeedPost, + ModerationDecision, AtUri, - PostModeration, } from '@atproto/api' import { useInfiniteQuery, @@ -29,7 +29,6 @@ import {STALE} from '#/state/queries' import {precacheFeedPostProfiles} from './profile' import {getAgent} from '#/state/session' import {DEFAULT_LOGGED_OUT_PREFERENCES} from '#/state/queries/preferences/const' -import {getModerationOpts} from '#/state/queries/preferences/moderation' import {KnownError} from '#/view/com/posts/FeedErrorMessage' import {embedViewRecordToPostView, getEmbeddedPost} from './util' import {useModerationOpts} from './preferences' @@ -69,7 +68,7 @@ export interface FeedPostSliceItem { post: AppBskyFeedDefs.PostView record: AppBskyFeedPost.Record reason?: AppBskyFeedDefs.ReasonRepost | ReasonFeedSource - moderation: PostModeration + moderation: ModerationDecision } export interface FeedPostSlice { @@ -250,9 +249,17 @@ export function usePostFeedQuery( // apply moderation filter for (let i = 0; i < slice.items.length; i++) { + const ignoreFilter = + slice.items[i].post.author.did === ignoreFilterFor + if (ignoreFilter) { + // remove mutes to avoid confused UIs + moderations[i].causes = moderations[i].causes.filter( + cause => cause.type !== 'muted', + ) + } if ( - moderations[i]?.content.filter && - slice.items[i].post.author.did !== ignoreFilterFor + !ignoreFilter && + moderations[i]?.ui('contentList').filter ) { return undefined } @@ -435,13 +442,12 @@ function assertSomePostsPassModeration(feed: AppBskyFeedDefs.FeedViewPost[]) { let somePostsPassModeration = false for (const item of feed) { - const moderationOpts = getModerationOpts({ - userDid: '', - preferences: DEFAULT_LOGGED_OUT_PREFERENCES, + const moderation = moderatePost(item.post, { + userDid: undefined, + prefs: DEFAULT_LOGGED_OUT_PREFERENCES.moderationPrefs, }) - const moderation = moderatePost(item.post, moderationOpts) - if (!moderation.content.filter) { + if (!moderation.ui('contentList').filter) { // we have a sfw post somePostsPassModeration = true } diff --git a/src/state/queries/post-liked-by.ts b/src/state/queries/post-liked-by.ts index 2cde07f280..a0498ada44 100644 --- a/src/state/queries/post-liked-by.ts +++ b/src/state/queries/post-liked-by.ts @@ -12,9 +12,9 @@ const PAGE_SIZE = 30 type RQPageParam = string | undefined // TODO refactor invalidate on mutate? -export const RQKEY = (resolvedUri: string) => ['post-liked-by', resolvedUri] +export const RQKEY = (resolvedUri: string) => ['liked-by', resolvedUri] -export function usePostLikedByQuery(resolvedUri: string | undefined) { +export function useLikedByQuery(resolvedUri: string | undefined) { return useInfiniteQuery< AppBskyFeedGetLikes.OutputSchema, Error, diff --git a/src/state/queries/preferences/const.ts b/src/state/queries/preferences/const.ts index 53c9e482af..4cb4d1e964 100644 --- a/src/state/queries/preferences/const.ts +++ b/src/state/queries/preferences/const.ts @@ -29,26 +29,20 @@ export const DEFAULT_PROD_FEEDS = { export const DEFAULT_LOGGED_OUT_PREFERENCES: UsePreferencesQueryResponse = { birthDate: new Date('2022-11-17'), // TODO(pwi) - adultContentEnabled: false, feeds: { saved: [], pinned: [], unpinned: [], }, - // labels are undefined until set by user - contentLabels: { - nsfw: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES.nsfw, - nudity: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES.nudity, - suggestive: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES.suggestive, - gore: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES.gore, - hate: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES.hate, - spam: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES.spam, - impersonation: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES.impersonation, + moderationPrefs: { + adultContentEnabled: false, + labels: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES, + labelers: [], + mutedWords: [], + hiddenPosts: [], }, feedViewPrefs: DEFAULT_HOME_FEED_PREFS, threadViewPrefs: DEFAULT_THREAD_VIEW_PREFS, userAge: 13, // TODO(pwi) interests: {tags: []}, - mutedWords: [], - hiddenPosts: [], } diff --git a/src/state/queries/preferences/index.ts b/src/state/queries/preferences/index.ts index 37ef10ae0c..cfc5c5bbe5 100644 --- a/src/state/queries/preferences/index.ts +++ b/src/state/queries/preferences/index.ts @@ -1,29 +1,27 @@ -import {useMemo} from 'react' +import {useMemo, createContext, useContext} from 'react' import {useQuery, useMutation, useQueryClient} from '@tanstack/react-query' import { LabelPreference, BskyFeedViewPreference, + ModerationOpts, AppBskyActorDefs, } from '@atproto/api' import {track} from '#/lib/analytics/analytics' import {getAge} from '#/lib/strings/time' -import {useSession, getAgent} from '#/state/session' -import {DEFAULT_LABEL_PREFERENCES} from '#/state/queries/preferences/moderation' +import {getAgent, useSession} from '#/state/session' import { - ConfigurableLabelGroup, UsePreferencesQueryResponse, ThreadViewPreferences, } from '#/state/queries/preferences/types' -import {temp__migrateLabelPref} from '#/state/queries/preferences/util' import { DEFAULT_HOME_FEED_PREFS, DEFAULT_THREAD_VIEW_PREFS, DEFAULT_LOGGED_OUT_PREFERENCES, } from '#/state/queries/preferences/const' -import {getModerationOpts} from '#/state/queries/preferences/moderation' import {STALE} from '#/state/queries' -import {useHiddenPosts} from '#/state/preferences/hidden-posts' +import {useHiddenPosts, useLabelDefinitions} from '#/state/preferences' +import {saveLabelers} from '#/state/session/agent-config' export * from '#/state/queries/preferences/types' export * from '#/state/queries/preferences/moderation' @@ -44,6 +42,13 @@ export function usePreferencesQuery() { return DEFAULT_LOGGED_OUT_PREFERENCES } else { const res = await agent.getPreferences() + + // save to local storage to ensure there are labels on initial requests + saveLabelers( + agent.session.did, + res.moderationPrefs.labelers.map(l => l.did), + ) + const preferences: UsePreferencesQueryResponse = { ...res, feeds: { @@ -54,32 +59,6 @@ export function usePreferencesQuery() { return !res.feeds.pinned?.includes(f) }) || [], }, - // labels are undefined until set by user - contentLabels: { - nsfw: temp__migrateLabelPref( - res.contentLabels?.nsfw || DEFAULT_LABEL_PREFERENCES.nsfw, - ), - nudity: temp__migrateLabelPref( - res.contentLabels?.nudity || DEFAULT_LABEL_PREFERENCES.nudity, - ), - suggestive: temp__migrateLabelPref( - res.contentLabels?.suggestive || - DEFAULT_LABEL_PREFERENCES.suggestive, - ), - gore: temp__migrateLabelPref( - res.contentLabels?.gore || DEFAULT_LABEL_PREFERENCES.gore, - ), - hate: temp__migrateLabelPref( - res.contentLabels?.hate || DEFAULT_LABEL_PREFERENCES.hate, - ), - spam: temp__migrateLabelPref( - res.contentLabels?.spam || DEFAULT_LABEL_PREFERENCES.spam, - ), - impersonation: temp__migrateLabelPref( - res.contentLabels?.impersonation || - DEFAULT_LABEL_PREFERENCES.impersonation, - ), - }, feedViewPrefs: { ...DEFAULT_HOME_FEED_PREFS, ...(res.feedViewPrefs.home || {}), @@ -96,25 +75,30 @@ export function usePreferencesQuery() { }) } +// used in the moderation state devtool +export const moderationOptsOverrideContext = createContext< + ModerationOpts | undefined +>(undefined) + export function useModerationOpts() { + const override = useContext(moderationOptsOverrideContext) const {currentAccount} = useSession() const prefs = usePreferencesQuery() - const hiddenPosts = useHiddenPosts() - const opts = useMemo(() => { + const {labelDefs} = useLabelDefinitions() + const hiddenPosts = useHiddenPosts() // TODO move this into pds-stored prefs + const opts = useMemo<ModerationOpts | undefined>(() => { + if (override) { + return override + } if (!prefs.data) { return } - const moderationOpts = getModerationOpts({ - userDid: currentAccount?.did || '', - preferences: prefs.data, - }) - return { - ...moderationOpts, - hiddenPosts, - mutedWords: prefs.data.mutedWords || [], + userDid: currentAccount?.did, + prefs: {...prefs.data.moderationPrefs, hiddenPosts: hiddenPosts || []}, + labelDefs, } - }, [currentAccount?.did, prefs.data, hiddenPosts]) + }, [override, currentAccount, labelDefs, prefs.data, hiddenPosts]) return opts } @@ -138,10 +122,32 @@ export function usePreferencesSetContentLabelMutation() { return useMutation< void, unknown, - {labelGroup: ConfigurableLabelGroup; visibility: LabelPreference} + {label: string; visibility: LabelPreference; labelerDid: string | undefined} >({ - mutationFn: async ({labelGroup, visibility}) => { - await getAgent().setContentLabelPref(labelGroup, visibility) + mutationFn: async ({label, visibility, labelerDid}) => { + await getAgent().setContentLabelPref(label, visibility, labelerDid) + // triggers a refetch + await queryClient.invalidateQueries({ + queryKey: preferencesQueryKey, + }) + }, + }) +} + +export function useSetContentLabelMutation() { + const queryClient = useQueryClient() + + return useMutation({ + mutationFn: async ({ + label, + visibility, + labelerDid, + }: { + label: string + visibility: LabelPreference + labelerDid?: string + }) => { + await getAgent().setContentLabelPref(label, visibility, labelerDid) // triggers a refetch await queryClient.invalidateQueries({ queryKey: preferencesQueryKey, diff --git a/src/state/queries/preferences/moderation.ts b/src/state/queries/preferences/moderation.ts index cdae529374..9cd183e8b1 100644 --- a/src/state/queries/preferences/moderation.ts +++ b/src/state/queries/preferences/moderation.ts @@ -1,181 +1,53 @@ +import React from 'react' import { - LabelPreference, - ComAtprotoLabelDefs, - ModerationOpts, + DEFAULT_LABEL_SETTINGS, + BskyAgent, + interpretLabelValueDefinitions, } from '@atproto/api' -import { - LabelGroup, - ConfigurableLabelGroup, - UsePreferencesQueryResponse, -} from '#/state/queries/preferences/types' - -export type Label = ComAtprotoLabelDefs.Label - -export type LabelGroupConfig = { - id: LabelGroup - title: string - isAdultImagery?: boolean - subtitle?: string - warning: string - values: string[] -} - -export const DEFAULT_LABEL_PREFERENCES: Record< - ConfigurableLabelGroup, - LabelPreference -> = { - nsfw: 'hide', - nudity: 'warn', - suggestive: 'warn', - gore: 'warn', - hate: 'hide', - spam: 'hide', - impersonation: 'hide', -} +import {usePreferencesQuery} from './index' +import {useLabelersDetailedInfoQuery} from '../labeler' /** * More strict than our default settings for logged in users. - * - * TODO(pwi) */ -export const DEFAULT_LOGGED_OUT_LABEL_PREFERENCES: Record< - ConfigurableLabelGroup, - LabelPreference -> = { - nsfw: 'hide', - nudity: 'hide', - suggestive: 'hide', - gore: 'hide', - hate: 'hide', - spam: 'hide', - impersonation: 'hide', +export const DEFAULT_LOGGED_OUT_LABEL_PREFERENCES: typeof DEFAULT_LABEL_SETTINGS = + Object.fromEntries( + Object.entries(DEFAULT_LABEL_SETTINGS).map(([key, _pref]) => [key, 'hide']), + ) + +export function useMyLabelersQuery() { + const prefs = usePreferencesQuery() + const dids = Array.from( + new Set( + BskyAgent.appLabelers.concat( + prefs.data?.moderationPrefs.labelers.map(l => l.did) || [], + ), + ), + ) + const labelers = useLabelersDetailedInfoQuery({dids}) + const isLoading = prefs.isLoading || labelers.isLoading + const error = prefs.error || labelers.error + return React.useMemo(() => { + return { + isLoading, + error, + data: labelers.data, + } + }, [labelers, isLoading, error]) } -export const ILLEGAL_LABEL_GROUP: LabelGroupConfig = { - id: 'illegal', - title: 'Illegal Content', - warning: 'Illegal Content', - values: ['csam', 'dmca-violation', 'nudity-nonconsensual'], -} - -export const ALWAYS_FILTER_LABEL_GROUP: LabelGroupConfig = { - id: 'always-filter', - title: 'Content Warning', - warning: 'Content Warning', - values: ['!filter'], -} - -export const ALWAYS_WARN_LABEL_GROUP: LabelGroupConfig = { - id: 'always-warn', - title: 'Content Warning', - warning: 'Content Warning', - values: ['!warn', 'account-security'], -} - -export const UNKNOWN_LABEL_GROUP: LabelGroupConfig = { - id: 'unknown', - title: 'Unknown Label', - warning: 'Content Warning', - values: [], -} - -export const CONFIGURABLE_LABEL_GROUPS: Record< - ConfigurableLabelGroup, - LabelGroupConfig -> = { - nsfw: { - id: 'nsfw', - title: 'Explicit Sexual Images', - subtitle: 'i.e. pornography', - warning: 'Sexually Explicit', - values: ['porn', 'nsfl'], - isAdultImagery: true, - }, - nudity: { - id: 'nudity', - title: 'Other Nudity', - subtitle: 'Including non-sexual and artistic', - warning: 'Nudity', - values: ['nudity'], - isAdultImagery: true, - }, - suggestive: { - id: 'suggestive', - title: 'Sexually Suggestive', - subtitle: 'Does not include nudity', - warning: 'Sexually Suggestive', - values: ['sexual'], - isAdultImagery: true, - }, - gore: { - id: 'gore', - title: 'Violent / Bloody', - subtitle: 'Gore, self-harm, torture', - warning: 'Violence', - values: ['gore', 'self-harm', 'torture', 'nsfl', 'corpse'], - isAdultImagery: true, - }, - hate: { - id: 'hate', - title: 'Hate Group Iconography', - subtitle: 'Images of terror groups, articles covering events, etc.', - warning: 'Hate Groups', - values: ['icon-kkk', 'icon-nazi', 'icon-intolerant', 'behavior-intolerant'], - }, - spam: { - id: 'spam', - title: 'Spam', - subtitle: 'Excessive unwanted interactions', - warning: 'Spam', - values: ['spam'], - }, - impersonation: { - id: 'impersonation', - title: 'Impersonation', - subtitle: 'Accounts falsely claiming to be people or orgs', - warning: 'Impersonation', - values: ['impersonation'], - }, -} - -export function getModerationOpts({ - userDid, - preferences, -}: { - userDid: string - preferences: UsePreferencesQueryResponse -}): ModerationOpts { - return { - userDid: userDid, - adultContentEnabled: preferences.adultContentEnabled, - labels: { - porn: preferences.contentLabels.nsfw, - sexual: preferences.contentLabels.suggestive, - nudity: preferences.contentLabels.nudity, - nsfl: preferences.contentLabels.gore, - corpse: preferences.contentLabels.gore, - gore: preferences.contentLabels.gore, - torture: preferences.contentLabels.gore, - 'self-harm': preferences.contentLabels.gore, - 'intolerant-race': preferences.contentLabels.hate, - 'intolerant-gender': preferences.contentLabels.hate, - 'intolerant-sexual-orientation': preferences.contentLabels.hate, - 'intolerant-religion': preferences.contentLabels.hate, - intolerant: preferences.contentLabels.hate, - 'icon-intolerant': preferences.contentLabels.hate, - spam: preferences.contentLabels.spam, - impersonation: preferences.contentLabels.impersonation, - scam: 'warn', - }, - labelers: [ - { - labeler: { - did: '', - displayName: 'Bluesky Social', - }, - labels: {}, - }, - ], - } +export function useLabelDefinitionsQuery() { + const labelers = useMyLabelersQuery() + return React.useMemo(() => { + return { + labelDefs: Object.fromEntries( + (labelers.data || []).map(labeler => [ + labeler.creator.did, + interpretLabelValueDefinitions(labeler), + ]), + ), + labelers: labelers.data || [], + } + }, [labelers]) } diff --git a/src/state/queries/preferences/types.ts b/src/state/queries/preferences/types.ts index 45c9eed7de..96da16f1a8 100644 --- a/src/state/queries/preferences/types.ts +++ b/src/state/queries/preferences/types.ts @@ -1,46 +1,13 @@ import { BskyPreferences, - LabelPreference, BskyThreadViewPreference, BskyFeedViewPreference, } from '@atproto/api' -export const configurableAdultLabelGroups = [ - 'nsfw', - 'nudity', - 'suggestive', - 'gore', -] as const - -export const configurableOtherLabelGroups = [ - 'hate', - 'spam', - 'impersonation', -] as const - -export const configurableLabelGroups = [ - ...configurableAdultLabelGroups, - ...configurableOtherLabelGroups, -] as const -export type ConfigurableLabelGroup = (typeof configurableLabelGroups)[number] - -export type LabelGroup = - | ConfigurableLabelGroup - | 'illegal' - | 'always-filter' - | 'always-warn' - | 'unknown' - export type UsePreferencesQueryResponse = Omit< BskyPreferences, 'contentLabels' | 'feedViewPrefs' | 'feeds' > & { - /* - * Content labels previously included 'show', which has been deprecated in - * favor of 'ignore'. The API can return legacy data from the database, and - * we clean up the data in `usePreferencesQuery`. - */ - contentLabels: Record<ConfigurableLabelGroup, LabelPreference> feedViewPrefs: BskyFeedViewPreference & { lab_mergeFeedEnabled?: boolean } diff --git a/src/state/queries/preferences/util.ts b/src/state/queries/preferences/util.ts deleted file mode 100644 index 7b8160c283..0000000000 --- a/src/state/queries/preferences/util.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {LabelPreference} from '@atproto/api' - -/** - * Content labels previously included 'show', which has been deprecated in - * favor of 'ignore'. The API can return legacy data from the database, and - * we clean up the data in `usePreferencesQuery`. - * - * @deprecated - */ -export function temp__migrateLabelPref( - pref: LabelPreference | 'show', -): LabelPreference { - // @ts-ignore - if (pref === 'show') return 'ignore' - return pref -} diff --git a/src/state/queries/profile-extra-info.ts b/src/state/queries/profile-extra-info.ts deleted file mode 100644 index 8fc32c33eb..0000000000 --- a/src/state/queries/profile-extra-info.ts +++ /dev/null @@ -1,34 +0,0 @@ -import {useQuery} from '@tanstack/react-query' - -import {getAgent} from '#/state/session' -import {STALE} from '#/state/queries' - -// TODO refactor invalidate on mutate? -export const RQKEY = (did: string) => ['profile-extra-info', did] - -/** - * Fetches some additional information for the profile screen which - * is not available in the API's ProfileView - */ -export function useProfileExtraInfoQuery(did: string) { - return useQuery({ - staleTime: STALE.MINUTES.ONE, - queryKey: RQKEY(did), - async queryFn() { - const [listsRes, feedsRes] = await Promise.all([ - getAgent().app.bsky.graph.getLists({ - actor: did, - limit: 1, - }), - getAgent().app.bsky.feed.getActorFeeds({ - actor: did, - limit: 1, - }), - ]) - return { - hasLists: listsRes.data.lists.length > 0, - hasFeedgens: feedsRes.data.feeds.length > 0, - } - }, - }) -} diff --git a/src/state/queries/suggested-follows.ts b/src/state/queries/suggested-follows.ts index 932226b75c..45b3ebb62f 100644 --- a/src/state/queries/suggested-follows.ts +++ b/src/state/queries/suggested-follows.ts @@ -46,7 +46,8 @@ export function useSuggestedFollowsQuery() { res.data.actors = res.data.actors .filter( - actor => !moderateProfile(actor, moderationOpts!).account.filter, + actor => + !moderateProfile(actor, moderationOpts!).ui('profileList').filter, ) .filter(actor => { const viewer = actor.viewer diff --git a/src/state/session/agent-config.ts b/src/state/session/agent-config.ts new file mode 100644 index 0000000000..3ee2718a39 --- /dev/null +++ b/src/state/session/agent-config.ts @@ -0,0 +1,12 @@ +import AsyncStorage from '@react-native-async-storage/async-storage' + +const PREFIX = 'agent-labelers' + +export async function saveLabelers(did: string, value: string[]) { + await AsyncStorage.setItem(`${PREFIX}:${did}`, JSON.stringify(value)) +} + +export async function readLabelers(did: string): Promise<string[] | undefined> { + const rawData = await AsyncStorage.getItem(`${PREFIX}:${did}`) + return rawData ? JSON.parse(rawData) : undefined +} diff --git a/src/state/session/index.tsx b/src/state/session/index.tsx index 46628318c5..6b14748393 100644 --- a/src/state/session/index.tsx +++ b/src/state/session/index.tsx @@ -1,8 +1,15 @@ import React from 'react' -import {BskyAgent, AtpPersistSessionHandler} from '@atproto/api' +import { + BskyAgent, + AtpPersistSessionHandler, + BSKY_LABELER_DID, +} from '@atproto/api' import {useQueryClient} from '@tanstack/react-query' import {jwtDecode} from 'jwt-decode' +import {IS_DEV} from '#/env' +import {IS_TEST_USER} from '#/lib/constants' +import {isWeb} from '#/platform/detection' import {networkRetry} from '#/lib/async/retry' import {logger} from '#/logger' import * as persisted from '#/state/persisted' @@ -12,6 +19,7 @@ import {useLoggedOutViewControls} from '#/state/shell/logged-out' import {useCloseAllActiveElements} from '#/state/util' import {track} from '#/lib/analytics/analytics' import {hasProp} from '#/lib/type-guards' +import {readLabelers} from './agent-config' let __globalAgent: BskyAgent = PUBLIC_BSKY_AGENT @@ -255,6 +263,8 @@ export function Provider({children}: React.PropsWithChildren<{}>) { deactivated, } + await configureModeration(agent, account) + agent.setPersistSessionHandler( createPersistSessionHandler( account, @@ -298,6 +308,8 @@ export function Provider({children}: React.PropsWithChildren<{}>) { deactivated: isSessionDeactivated(agent.session.accessJwt), } + await configureModeration(agent, account) + agent.setPersistSessionHandler( createPersistSessionHandler( account, @@ -309,6 +321,8 @@ export function Provider({children}: React.PropsWithChildren<{}>) { ) __globalAgent = agent + // @ts-ignore + if (IS_DEV && isWeb) window.agent = agent queryClient.clear() upsertAccount(account) @@ -348,6 +362,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { {networkErrorCallback: clearCurrentAccount}, ), }) + // @ts-ignore + if (IS_DEV && isWeb) window.agent = agent + await configureModeration(agent, account) let canReusePrevSession = false try { @@ -643,6 +660,28 @@ export function Provider({children}: React.PropsWithChildren<{}>) { ) } +async function configureModeration(agent: BskyAgent, account: SessionAccount) { + if (IS_TEST_USER(account.handle)) { + const did = ( + await agent + .resolveHandle({handle: 'mod-authority.test'}) + .catch(_ => undefined) + )?.data.did + if (did) { + console.warn('USING TEST ENV MODERATION') + BskyAgent.configure({appLabelers: [did]}) + } + } else { + BskyAgent.configure({appLabelers: [BSKY_LABELER_DID]}) + const labelerDids = await readLabelers(account.did).catch(_ => {}) + if (labelerDids) { + agent.configureLabelersHeader( + labelerDids.filter(did => did !== BSKY_LABELER_DID), + ) + } + } +} + export function useSession() { return React.useContext(StateContext) } diff --git a/src/state/shell/composer.tsx b/src/state/shell/composer.tsx index c9dbfbeac4..a09e8fba9f 100644 --- a/src/state/shell/composer.tsx +++ b/src/state/shell/composer.tsx @@ -2,7 +2,7 @@ import React from 'react' import { AppBskyEmbedRecord, AppBskyRichtextFacet, - PostModeration, + ModerationDecision, } from '@atproto/api' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' @@ -16,7 +16,7 @@ export interface ComposerOptsPostRef { avatar?: string } embed?: AppBskyEmbedRecord.ViewRecord['embed'] - moderation?: PostModeration + moderation?: ModerationDecision } export interface ComposerOptsQuote { uri: string diff --git a/src/view/com/auth/create/state.ts b/src/view/com/auth/create/state.ts index 7a727ec0b2..840084dcb7 100644 --- a/src/view/com/auth/create/state.ts +++ b/src/view/com/auth/create/state.ts @@ -12,7 +12,7 @@ import {createFullHandle, validateHandle} from '#/lib/strings/handles' import {cleanError} from '#/lib/strings/errors' import {useOnboardingDispatch} from '#/state/shell/onboarding' import {useSessionApi} from '#/state/session' -import {DEFAULT_SERVICE, IS_PROD_SERVICE} from '#/lib/constants' +import {DEFAULT_SERVICE, IS_TEST_USER} from '#/lib/constants' import { DEFAULT_PROD_FEEDS, usePreferencesSetBirthDateMutation, @@ -147,7 +147,7 @@ export function useSubmitCreateAccount( : undefined, }) setBirthDate({birthDate: uiState.birthDate}) - if (IS_PROD_SERVICE(uiState.serviceUrl)) { + if (!IS_TEST_USER(uiState.handle)) { setSavedFeeds(DEFAULT_PROD_FEEDS) } } catch (e: any) { diff --git a/src/view/com/auth/onboarding/RecommendedFollowsItem.tsx b/src/view/com/auth/onboarding/RecommendedFollowsItem.tsx index 5f81a4d657..434b10c223 100644 --- a/src/view/com/auth/onboarding/RecommendedFollowsItem.tsx +++ b/src/view/com/auth/onboarding/RecommendedFollowsItem.tsx @@ -1,6 +1,6 @@ import React from 'react' import {View, StyleSheet, ActivityIndicator} from 'react-native' -import {ProfileModeration, AppBskyActorDefs} from '@atproto/api' +import {ModerationDecision, AppBskyActorDefs} from '@atproto/api' import {Button} from '#/view/com/util/forms/Button' import {usePalette} from 'lib/hooks/usePalette' import {sanitizeDisplayName} from 'lib/strings/display-names' @@ -18,7 +18,7 @@ import {logger} from '#/logger' type Props = { profile: AppBskyActorDefs.ProfileViewBasic - moderation: ProfileModeration + moderation: ModerationDecision onFollowStateChange: (props: { did: string following: boolean @@ -62,7 +62,7 @@ function ProfileCard({ moderation, }: { profile: Shadow<AppBskyActorDefs.ProfileViewBasic> - moderation: ProfileModeration + moderation: ModerationDecision onFollowStateChange: (props: { did: string following: boolean @@ -113,7 +113,7 @@ function ProfileCard({ <UserAvatar size={40} avatar={profile.avatar} - moderation={moderation.avatar} + moderation={moderation.ui('avatar')} /> </View> <View style={styles.layoutContent}> @@ -124,7 +124,7 @@ function ProfileCard({ lineHeight={1.2}> {sanitizeDisplayName( profile.displayName || sanitizeHandle(profile.handle), - moderation.profile, + moderation.ui('displayName'), )} </Text> <Text type="xl" style={[pal.textLight]} numberOfLines={1}> diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 97f8e51940..0a2692d06c 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -39,7 +39,7 @@ import {usePalette} from 'lib/hooks/usePalette' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {useExternalLinkFetch} from './useExternalLinkFetch' import {isWeb, isNative, isAndroid, isIOS} from 'platform/detection' -import QuoteEmbed from '../util/post-embeds/QuoteEmbed' +import {QuoteEmbed} from '../util/post-embeds/QuoteEmbed' import {GalleryModel} from 'state/models/media/gallery' import {Gallery} from './photos/Gallery' import {MAX_GRAPHEME_LENGTH} from 'lib/constants' diff --git a/src/view/com/composer/ComposerReplyTo.tsx b/src/view/com/composer/ComposerReplyTo.tsx index 39a1473a3b..4832bca02c 100644 --- a/src/view/com/composer/ComposerReplyTo.tsx +++ b/src/view/com/composer/ComposerReplyTo.tsx @@ -15,7 +15,7 @@ import {sanitizeDisplayName} from 'lib/strings/display-names' import {sanitizeHandle} from 'lib/strings/handles' import {UserAvatar} from 'view/com/util/UserAvatar' import {Text} from 'view/com/util/text/Text' -import QuoteEmbed from 'view/com/util/post-embeds/QuoteEmbed' +import {QuoteEmbed} from 'view/com/util/post-embeds/QuoteEmbed' export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { const pal = usePalette('default') @@ -86,7 +86,7 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { <UserAvatar avatar={replyTo.author.avatar} size={50} - moderation={replyTo.moderation?.avatar} + moderation={replyTo.moderation?.ui('avatar')} /> <View style={styles.replyToPost}> <Text type="xl-medium" style={[pal.text]}> @@ -103,7 +103,7 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { {replyTo.text} </Text> </View> - {images && !replyTo.moderation?.embed.blur && ( + {images && !replyTo.moderation?.ui('contentMedia').blur && ( <ComposerReplyToImages images={images} showFull={showFull} /> )} </View> diff --git a/src/view/com/modals/AppealLabel.tsx b/src/view/com/modals/AppealLabel.tsx deleted file mode 100644 index b0aaaf6255..0000000000 --- a/src/view/com/modals/AppealLabel.tsx +++ /dev/null @@ -1,139 +0,0 @@ -import React, {useState} from 'react' -import {StyleSheet, TouchableOpacity, View} from 'react-native' -import {ComAtprotoModerationDefs} from '@atproto/api' -import {ScrollView, TextInput} from './util' -import {Text} from '../util/text/Text' -import {s, colors} from 'lib/styles' -import {usePalette} from 'lib/hooks/usePalette' -import {Trans, msg} from '@lingui/macro' -import {useLingui} from '@lingui/react' -import {useModalControls} from '#/state/modals' -import {CharProgress} from '../composer/char-progress/CharProgress' -import {getAgent} from '#/state/session' -import * as Toast from '../util/Toast' -import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' - -export const snapPoints = ['40%'] - -type ReportComponentProps = - | { - uri: string - cid: string - } - | { - did: string - } - -export function Component(props: ReportComponentProps) { - const pal = usePalette('default') - const [details, setDetails] = useState<string>('') - const {_} = useLingui() - const {closeModal} = useModalControls() - const {isMobile} = useWebMediaQueries() - const isAccountReport = 'did' in props - - const submit = async () => { - try { - const $type = !isAccountReport - ? 'com.atproto.repo.strongRef' - : 'com.atproto.admin.defs#repoRef' - await getAgent().createModerationReport({ - reasonType: ComAtprotoModerationDefs.REASONAPPEAL, - subject: { - $type, - ...props, - }, - reason: details, - }) - Toast.show(_(msg`We'll look into your appeal promptly.`)) - } finally { - closeModal() - } - } - - return ( - <View - style={[ - pal.view, - s.flex1, - isMobile ? {paddingHorizontal: 12} : undefined, - ]} - testID="appealLabelModal"> - <Text - type="2xl-bold" - style={[pal.text, s.textCenter, {paddingBottom: 8}]}> - <Trans>Appeal Content Warning</Trans> - </Text> - <ScrollView> - <View style={[pal.btn, styles.detailsInputContainer]}> - <TextInput - accessibilityLabel={_(msg`Text input field`)} - accessibilityHint={_( - msg`Please tell us why you think this content warning was incorrectly applied!`, - )} - placeholder={_( - msg`Please tell us why you think this content warning was incorrectly applied!`, - )} - placeholderTextColor={pal.textLight.color} - value={details} - onChangeText={setDetails} - autoFocus={true} - numberOfLines={3} - multiline={true} - textAlignVertical="top" - maxLength={300} - style={[styles.detailsInput, pal.text]} - /> - <View style={styles.detailsInputBottomBar}> - <View style={styles.charCounter}> - <CharProgress count={details?.length || 0} /> - </View> - </View> - </View> - <TouchableOpacity - testID="confirmBtn" - onPress={submit} - style={styles.btn} - accessibilityRole="button" - accessibilityLabel={_(msg`Confirm`)} - accessibilityHint=""> - <Text style={[s.white, s.bold, s.f18]}> - <Trans>Submit</Trans> - </Text> - </TouchableOpacity> - </ScrollView> - </View> - ) -} - -const styles = StyleSheet.create({ - detailsInputContainer: { - borderRadius: 8, - marginBottom: 8, - }, - detailsInput: { - paddingHorizontal: 12, - paddingTop: 12, - paddingBottom: 12, - borderRadius: 8, - minHeight: 100, - fontSize: 16, - }, - detailsInputBottomBar: { - alignSelf: 'flex-end', - }, - charCounter: { - flexDirection: 'row', - alignItems: 'center', - paddingRight: 10, - paddingBottom: 8, - }, - btn: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'center', - borderRadius: 32, - padding: 14, - backgroundColor: colors.blue3, - }, -}) diff --git a/src/view/com/modals/ContentFilteringSettings.tsx b/src/view/com/modals/ContentFilteringSettings.tsx deleted file mode 100644 index 3c7edcf0dc..0000000000 --- a/src/view/com/modals/ContentFilteringSettings.tsx +++ /dev/null @@ -1,407 +0,0 @@ -import React from 'react' -import {LabelPreference} from '@atproto/api' -import {StyleSheet, Pressable, View, Linking} from 'react-native' -import LinearGradient from 'react-native-linear-gradient' -import {ScrollView} from './util' -import {s, colors, gradients} from 'lib/styles' -import {Text} from '../util/text/Text' -import {TextLink} from '../util/Link' -import {ToggleButton} from '../util/forms/ToggleButton' -import {Button} from '../util/forms/Button' -import {usePalette} from 'lib/hooks/usePalette' -import {isIOS} from 'platform/detection' -import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import * as Toast from '../util/Toast' -import {logger} from '#/logger' -import {Trans, msg} from '@lingui/macro' -import {useLingui} from '@lingui/react' -import {useModalControls} from '#/state/modals' -import { - usePreferencesQuery, - usePreferencesSetContentLabelMutation, - usePreferencesSetAdultContentMutation, - ConfigurableLabelGroup, - CONFIGURABLE_LABEL_GROUPS, - UsePreferencesQueryResponse, -} from '#/state/queries/preferences' -import {useDialogControl} from '#/components/Dialog' -import {BirthDateSettingsDialog} from '#/components/dialogs/BirthDateSettings' - -export const snapPoints = ['90%'] - -export function Component({}: {}) { - const {isMobile} = useWebMediaQueries() - const pal = usePalette('default') - const {_} = useLingui() - const {closeModal} = useModalControls() - const {data: preferences} = usePreferencesQuery() - - const onPressDone = React.useCallback(() => { - closeModal() - }, [closeModal]) - - return ( - <View testID="contentFilteringModal" style={[pal.view, styles.container]}> - <Text style={[pal.text, styles.title]}> - <Trans>Content Filtering</Trans> - </Text> - - <ScrollView style={styles.scrollContainer}> - <AdultContentEnabledPref /> - <ContentLabelPref - preferences={preferences} - labelGroup="nsfw" - disabled={!preferences?.adultContentEnabled} - /> - <ContentLabelPref - preferences={preferences} - labelGroup="nudity" - disabled={!preferences?.adultContentEnabled} - /> - <ContentLabelPref - preferences={preferences} - labelGroup="suggestive" - disabled={!preferences?.adultContentEnabled} - /> - <ContentLabelPref - preferences={preferences} - labelGroup="gore" - disabled={!preferences?.adultContentEnabled} - /> - <ContentLabelPref preferences={preferences} labelGroup="hate" /> - <ContentLabelPref preferences={preferences} labelGroup="spam" /> - <ContentLabelPref - preferences={preferences} - labelGroup="impersonation" - /> - <View style={{height: isMobile ? 60 : 0}} /> - </ScrollView> - - <View - style={[ - styles.btnContainer, - isMobile && styles.btnContainerMobile, - pal.borderDark, - ]}> - <Pressable - testID="sendReportBtn" - onPress={onPressDone} - accessibilityRole="button" - accessibilityLabel={_(msg`Done`)} - accessibilityHint=""> - <LinearGradient - colors={[gradients.blueLight.start, gradients.blueLight.end]} - start={{x: 0, y: 0}} - end={{x: 1, y: 1}} - style={[styles.btn]}> - <Text style={[s.white, s.bold, s.f18]}> - <Trans>Done</Trans> - </Text> - </LinearGradient> - </Pressable> - </View> - </View> - ) -} - -function AdultContentEnabledPref() { - const pal = usePalette('default') - const {_} = useLingui() - const {data: preferences} = usePreferencesQuery() - const {mutate, variables} = usePreferencesSetAdultContentMutation() - const bithdayDialogControl = useDialogControl() - - const onSetAge = React.useCallback( - () => bithdayDialogControl.open(), - [bithdayDialogControl], - ) - - const onToggleAdultContent = React.useCallback(async () => { - if (isIOS) return - - try { - mutate({ - enabled: !(variables?.enabled ?? preferences?.adultContentEnabled), - }) - } catch (e) { - Toast.show( - _(msg`There was an issue syncing your preferences with the server`), - ) - logger.error('Failed to update preferences with server', {message: e}) - } - }, [variables, preferences, mutate, _]) - - const onAdultContentLinkPress = React.useCallback(() => { - Linking.openURL('https://bsky.app/') - }, []) - - return ( - <View style={s.mb10}> - <BirthDateSettingsDialog - control={bithdayDialogControl} - preferences={preferences} - /> - {isIOS ? ( - preferences?.adultContentEnabled ? null : ( - <Text type="md" style={pal.textLight}> - <Trans> - Adult content can only be enabled via the Web at{' '} - <TextLink - style={pal.link} - href="" - text="bsky.app" - onPress={onAdultContentLinkPress} - /> - . - </Trans> - </Text> - ) - ) : typeof preferences?.birthDate === 'undefined' ? ( - <View style={[pal.viewLight, styles.agePrompt]}> - <Text type="md" style={[pal.text, {flex: 1}]}> - <Trans>Confirm your age to enable adult content.</Trans> - </Text> - <Button - type="primary" - label={_(msg({message: 'Set Age', context: 'action'}))} - onPress={onSetAge} - /> - </View> - ) : (preferences.userAge || 0) >= 18 ? ( - <ToggleButton - type="default-light" - label={_(msg`Enable Adult Content`)} - isSelected={variables?.enabled ?? preferences?.adultContentEnabled} - onPress={onToggleAdultContent} - style={styles.toggleBtn} - /> - ) : ( - <View style={[pal.viewLight, styles.agePrompt]}> - <Text type="md" style={[pal.text, {flex: 1}]}> - <Trans>You must be 18 or older to enable adult content.</Trans> - </Text> - <Button - type="primary" - label={_(msg({message: 'Set Age', context: 'action'}))} - onPress={onSetAge} - /> - </View> - )} - </View> - ) -} - -// TODO: Refactor this component to pass labels down to each tab -function ContentLabelPref({ - preferences, - labelGroup, - disabled, -}: { - preferences?: UsePreferencesQueryResponse - labelGroup: ConfigurableLabelGroup - disabled?: boolean -}) { - const pal = usePalette('default') - const visibility = preferences?.contentLabels?.[labelGroup] - const {mutate, variables} = usePreferencesSetContentLabelMutation() - - const onChange = React.useCallback( - (vis: LabelPreference) => { - mutate({labelGroup, visibility: vis}) - }, - [mutate, labelGroup], - ) - - return ( - <View style={[styles.contentLabelPref, pal.border]}> - <View style={s.flex1}> - <Text type="md-medium" style={[pal.text]}> - {CONFIGURABLE_LABEL_GROUPS[labelGroup].title} - </Text> - {typeof CONFIGURABLE_LABEL_GROUPS[labelGroup].subtitle === 'string' && ( - <Text type="sm" style={[pal.textLight]}> - {CONFIGURABLE_LABEL_GROUPS[labelGroup].subtitle} - </Text> - )} - </View> - - {disabled || !visibility ? ( - <Text type="sm-bold" style={pal.textLight}> - <Trans context="action">Hide</Trans> - </Text> - ) : ( - <SelectGroup - current={variables?.visibility || visibility} - onChange={onChange} - labelGroup={labelGroup} - /> - )} - </View> - ) -} - -interface SelectGroupProps { - current: LabelPreference - onChange: (v: LabelPreference) => void - labelGroup: ConfigurableLabelGroup -} - -function SelectGroup({current, onChange, labelGroup}: SelectGroupProps) { - const {_} = useLingui() - - return ( - <View style={styles.selectableBtns}> - <SelectableBtn - current={current} - value="hide" - label={_(msg`Hide`)} - left - onChange={onChange} - labelGroup={labelGroup} - /> - <SelectableBtn - current={current} - value="warn" - label={_(msg`Warn`)} - onChange={onChange} - labelGroup={labelGroup} - /> - <SelectableBtn - current={current} - value="ignore" - label={_(msg`Show`)} - right - onChange={onChange} - labelGroup={labelGroup} - /> - </View> - ) -} - -interface SelectableBtnProps { - current: string - value: LabelPreference - label: string - left?: boolean - right?: boolean - onChange: (v: LabelPreference) => void - labelGroup: ConfigurableLabelGroup -} - -function SelectableBtn({ - current, - value, - label, - left, - right, - onChange, - labelGroup, -}: SelectableBtnProps) { - const pal = usePalette('default') - const palPrimary = usePalette('inverted') - const {_} = useLingui() - - return ( - <Pressable - style={[ - styles.selectableBtn, - left && styles.selectableBtnLeft, - right && styles.selectableBtnRight, - pal.border, - current === value ? palPrimary.view : pal.view, - ]} - onPress={() => onChange(value)} - accessibilityRole="button" - accessibilityLabel={value} - accessibilityHint={_( - msg`Set ${value} for ${labelGroup} content moderation policy`, - )}> - <Text style={current === value ? palPrimary.text : pal.text}> - {label} - </Text> - </Pressable> - ) -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - }, - title: { - textAlign: 'center', - fontWeight: 'bold', - fontSize: 24, - marginBottom: 12, - }, - description: { - paddingHorizontal: 2, - marginBottom: 10, - }, - scrollContainer: { - flex: 1, - paddingHorizontal: 10, - }, - btnContainer: { - paddingTop: 10, - paddingHorizontal: 10, - }, - btnContainerMobile: { - paddingBottom: 40, - borderTopWidth: 1, - }, - - agePrompt: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - paddingLeft: 14, - paddingRight: 10, - paddingVertical: 8, - borderRadius: 8, - }, - - contentLabelPref: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - paddingTop: 14, - paddingLeft: 4, - marginBottom: 14, - borderTopWidth: 1, - }, - - selectableBtns: { - flexDirection: 'row', - marginLeft: 10, - }, - selectableBtn: { - flexDirection: 'row', - justifyContent: 'center', - borderWidth: 1, - borderLeftWidth: 0, - paddingHorizontal: 10, - paddingVertical: 10, - }, - selectableBtnLeft: { - borderTopLeftRadius: 8, - borderBottomLeftRadius: 8, - borderLeftWidth: 1, - }, - selectableBtnRight: { - borderTopRightRadius: 8, - borderBottomRightRadius: 8, - }, - - btn: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'center', - width: '100%', - borderRadius: 32, - padding: 14, - backgroundColor: colors.gray1, - }, - toggleBtn: { - paddingHorizontal: 0, - }, -}) diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx index e382e6fabd..238cfc502c 100644 --- a/src/view/com/modals/Modal.tsx +++ b/src/view/com/modals/Modal.tsx @@ -15,16 +15,12 @@ import * as UserAddRemoveListsModal from './UserAddRemoveLists' import * as ListAddUserModal from './ListAddRemoveUsers' import * as AltImageModal from './AltImage' import * as EditImageModal from './AltImage' -import * as ReportModal from './report/Modal' -import * as AppealLabelModal from './AppealLabel' import * as DeleteAccountModal from './DeleteAccount' import * as ChangeHandleModal from './ChangeHandle' import * as InviteCodesModal from './InviteCodes' import * as AddAppPassword from './AddAppPasswords' -import * as ContentFilteringSettingsModal from './ContentFilteringSettings' import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings' import * as PostLanguagesSettingsModal from './lang-settings/PostLanguagesSettings' -import * as ModerationDetailsModal from './ModerationDetails' import * as VerifyEmailModal from './VerifyEmail' import * as ChangeEmailModal from './ChangeEmail' import * as ChangePasswordModal from './ChangePassword' @@ -67,12 +63,6 @@ export function ModalsContainer() { if (activeModal?.name === 'edit-profile') { snapPoints = EditProfileModal.snapPoints element = <EditProfileModal.Component {...activeModal} /> - } else if (activeModal?.name === 'report') { - snapPoints = ReportModal.snapPoints - element = <ReportModal.Component {...activeModal} /> - } else if (activeModal?.name === 'appeal-label') { - snapPoints = AppealLabelModal.snapPoints - element = <AppealLabelModal.Component {...activeModal} /> } else if (activeModal?.name === 'create-or-edit-list') { snapPoints = CreateOrEditListModal.snapPoints element = <CreateOrEditListModal.Component {...activeModal} /> @@ -109,18 +99,12 @@ export function ModalsContainer() { } else if (activeModal?.name === 'add-app-password') { snapPoints = AddAppPassword.snapPoints element = <AddAppPassword.Component /> - } else if (activeModal?.name === 'content-filtering-settings') { - snapPoints = ContentFilteringSettingsModal.snapPoints - element = <ContentFilteringSettingsModal.Component /> } else if (activeModal?.name === 'content-languages-settings') { snapPoints = ContentLanguagesSettingsModal.snapPoints element = <ContentLanguagesSettingsModal.Component /> } else if (activeModal?.name === 'post-languages-settings') { snapPoints = PostLanguagesSettingsModal.snapPoints element = <PostLanguagesSettingsModal.Component /> - } else if (activeModal?.name === 'moderation-details') { - snapPoints = ModerationDetailsModal.snapPoints - element = <ModerationDetailsModal.Component {...activeModal} /> } else if (activeModal?.name === 'verify-email') { snapPoints = VerifyEmailModal.snapPoints element = <VerifyEmailModal.Component {...activeModal} /> diff --git a/src/view/com/modals/Modal.web.tsx b/src/view/com/modals/Modal.web.tsx index 66ea2311f8..7e5d548ace 100644 --- a/src/view/com/modals/Modal.web.tsx +++ b/src/view/com/modals/Modal.web.tsx @@ -8,8 +8,6 @@ import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock' import {useModals, useModalControls} from '#/state/modals' import type {Modal as ModalIface} from '#/state/modals' import * as EditProfileModal from './EditProfile' -import * as ReportModal from './report/Modal' -import * as AppealLabelModal from './AppealLabel' import * as CreateOrEditListModal from './CreateOrEditList' import * as UserAddRemoveLists from './UserAddRemoveLists' import * as ListAddUserModal from './ListAddRemoveUsers' @@ -23,10 +21,8 @@ import * as EditImageModal from './EditImage' import * as ChangeHandleModal from './ChangeHandle' import * as InviteCodesModal from './InviteCodes' import * as AddAppPassword from './AddAppPasswords' -import * as ContentFilteringSettingsModal from './ContentFilteringSettings' import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings' import * as PostLanguagesSettingsModal from './lang-settings/PostLanguagesSettings' -import * as ModerationDetailsModal from './ModerationDetails' import * as VerifyEmailModal from './VerifyEmail' import * as ChangeEmailModal from './ChangeEmail' import * as ChangePasswordModal from './ChangePassword' @@ -78,10 +74,6 @@ function Modal({modal}: {modal: ModalIface}) { let element if (modal.name === 'edit-profile') { element = <EditProfileModal.Component {...modal} /> - } else if (modal.name === 'report') { - element = <ReportModal.Component {...modal} /> - } else if (modal.name === 'appeal-label') { - element = <AppealLabelModal.Component {...modal} /> } else if (modal.name === 'create-or-edit-list') { element = <CreateOrEditListModal.Component {...modal} /> } else if (modal.name === 'user-add-remove-lists') { @@ -104,8 +96,6 @@ function Modal({modal}: {modal: ModalIface}) { element = <InviteCodesModal.Component /> } else if (modal.name === 'add-app-password') { element = <AddAppPassword.Component /> - } else if (modal.name === 'content-filtering-settings') { - element = <ContentFilteringSettingsModal.Component /> } else if (modal.name === 'content-languages-settings') { element = <ContentLanguagesSettingsModal.Component /> } else if (modal.name === 'post-languages-settings') { @@ -114,8 +104,6 @@ function Modal({modal}: {modal: ModalIface}) { element = <AltTextImageModal.Component {...modal} /> } else if (modal.name === 'edit-image') { element = <EditImageModal.Component {...modal} /> - } else if (modal.name === 'moderation-details') { - element = <ModerationDetailsModal.Component {...modal} /> } else if (modal.name === 'verify-email') { element = <VerifyEmailModal.Component {...modal} /> } else if (modal.name === 'change-email') { diff --git a/src/view/com/modals/ModerationDetails.tsx b/src/view/com/modals/ModerationDetails.tsx deleted file mode 100644 index f890d50dce..0000000000 --- a/src/view/com/modals/ModerationDetails.tsx +++ /dev/null @@ -1,142 +0,0 @@ -import React from 'react' -import {StyleSheet, View} from 'react-native' -import {ModerationUI} from '@atproto/api' -import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {s} from 'lib/styles' -import {Text} from '../util/text/Text' -import {TextLink} from '../util/Link' -import {usePalette} from 'lib/hooks/usePalette' -import {isWeb} from 'platform/detection' -import {listUriToHref} from 'lib/strings/url-helpers' -import {Button} from '../util/forms/Button' -import {useModalControls} from '#/state/modals' -import {useLingui} from '@lingui/react' -import {Trans, msg} from '@lingui/macro' - -export const snapPoints = [300] - -export function Component({ - context, - moderation, -}: { - context: 'account' | 'content' - moderation: ModerationUI -}) { - const {closeModal} = useModalControls() - const {isMobile} = useWebMediaQueries() - const pal = usePalette('default') - const {_} = useLingui() - - let name - let description - if (!moderation.cause) { - name = _(msg`Content Warning`) - description = _( - msg`Moderator has chosen to set a general warning on the content.`, - ) - } else if (moderation.cause.type === 'blocking') { - if (moderation.cause.source.type === 'list') { - const list = moderation.cause.source.list - name = _(msg`User Blocked by List`) - description = ( - <Trans> - This user is included in the{' '} - <TextLink - type="2xl" - href={listUriToHref(list.uri)} - text={list.name} - style={pal.link} - />{' '} - list which you have blocked. - </Trans> - ) - } else { - name = _(msg`User Blocked`) - description = _( - msg`You have blocked this user. You cannot view their content.`, - ) - } - } else if (moderation.cause.type === 'blocked-by') { - name = _(msg`User Blocks You`) - description = _( - msg`This user has blocked you. You cannot view their content.`, - ) - } else if (moderation.cause.type === 'block-other') { - name = _(msg`Content Not Available`) - description = _( - msg`This content is not available because one of the users involved has blocked the other.`, - ) - } else if (moderation.cause.type === 'muted') { - if (moderation.cause.source.type === 'list') { - const list = moderation.cause.source.list - name = _(msg`Account Muted by List`) - description = ( - <Trans> - This user is included in the{' '} - <TextLink - type="2xl" - href={listUriToHref(list.uri)} - text={list.name} - style={pal.link} - />{' '} - list which you have muted. - </Trans> - ) - } else { - name = _(msg`Account Muted`) - description = _(msg`You have muted this user.`) - } - } else { - name = moderation.cause.labelDef.strings[context].en.name - description = moderation.cause.labelDef.strings[context].en.description - } - - return ( - <View - testID="moderationDetailsModal" - style={[ - styles.container, - { - paddingHorizontal: isMobile ? 14 : 0, - }, - pal.view, - ]}> - <Text type="title-xl" style={[pal.text, styles.title]}> - {name} - </Text> - <Text type="2xl" style={[pal.text, styles.description]}> - {description} - </Text> - <View style={s.flex1} /> - <Button - type="primary" - style={styles.btn} - onPress={() => { - closeModal() - }}> - <Text type="button-lg" style={[pal.textLight, s.textCenter, s.white]}> - Okay - </Text> - </Button> - </View> - ) -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - }, - title: { - textAlign: 'center', - fontWeight: 'bold', - marginBottom: 12, - }, - description: { - textAlign: 'center', - }, - btn: { - paddingVertical: 14, - marginTop: isWeb ? 40 : 0, - marginBottom: isWeb ? 0 : 40, - }, -}) diff --git a/src/view/com/modals/report/InputIssueDetails.tsx b/src/view/com/modals/report/InputIssueDetails.tsx deleted file mode 100644 index 2bc86f75e7..0000000000 --- a/src/view/com/modals/report/InputIssueDetails.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import React from 'react' -import {View, TouchableOpacity, StyleSheet} from 'react-native' -import {TextInput} from '../util' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {CharProgress} from '../../composer/char-progress/CharProgress' -import {Text} from '../../util/text/Text' -import {usePalette} from 'lib/hooks/usePalette' -import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {s} from 'lib/styles' -import {SendReportButton} from './SendReportButton' -import {Trans, msg} from '@lingui/macro' -import {useLingui} from '@lingui/react' - -export function InputIssueDetails({ - details, - setDetails, - goBack, - submitReport, - isProcessing, -}: { - details: string | undefined - setDetails: (v: string) => void - goBack: () => void - submitReport: () => void - isProcessing: boolean -}) { - const pal = usePalette('default') - const {_} = useLingui() - const {isMobile} = useWebMediaQueries() - - return ( - <View - style={{ - marginTop: isMobile ? 12 : 0, - }}> - <TouchableOpacity - testID="addDetailsBtn" - style={[s.mb10, styles.backBtn]} - onPress={goBack} - accessibilityRole="button" - accessibilityLabel={_(msg`Add details`)} - accessibilityHint="Add more details to your report"> - <FontAwesomeIcon size={18} icon="angle-left" style={[pal.link]} /> - <Text style={[pal.text, s.f18, pal.link]}> - {' '} - <Trans>Back</Trans> - </Text> - </TouchableOpacity> - <View style={[pal.btn, styles.detailsInputContainer]}> - <TextInput - accessibilityLabel={_(msg`Text input field`)} - accessibilityHint="Enter a reason for reporting this post." - placeholder="Enter a reason or any other details here." - placeholderTextColor={pal.textLight.color} - value={details} - onChangeText={setDetails} - autoFocus={true} - numberOfLines={3} - multiline={true} - textAlignVertical="top" - maxLength={300} - style={[styles.detailsInput, pal.text]} - /> - <View style={styles.detailsInputBottomBar}> - <View style={styles.charCounter}> - <CharProgress count={details?.length || 0} /> - </View> - </View> - </View> - <SendReportButton onPress={submitReport} isProcessing={isProcessing} /> - </View> - ) -} - -const styles = StyleSheet.create({ - backBtn: { - flexDirection: 'row', - alignItems: 'center', - }, - detailsInputContainer: { - borderRadius: 8, - }, - detailsInput: { - paddingHorizontal: 12, - paddingTop: 12, - paddingBottom: 12, - borderRadius: 8, - minHeight: 100, - fontSize: 16, - }, - detailsInputBottomBar: { - alignSelf: 'flex-end', - }, - charCounter: { - flexDirection: 'row', - alignItems: 'center', - paddingRight: 10, - paddingBottom: 8, - }, -}) diff --git a/src/view/com/modals/report/Modal.tsx b/src/view/com/modals/report/Modal.tsx deleted file mode 100644 index abbad9b402..0000000000 --- a/src/view/com/modals/report/Modal.tsx +++ /dev/null @@ -1,223 +0,0 @@ -import React, {useState, useMemo} from 'react' -import {Linking, StyleSheet, TouchableOpacity, View} from 'react-native' -import {ScrollView} from 'react-native-gesture-handler' -import {AtUri} from '@atproto/api' -import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {s} from 'lib/styles' -import {Text} from '../../util/text/Text' -import * as Toast from '../../util/Toast' -import {ErrorMessage} from '../../util/error/ErrorMessage' -import {cleanError} from 'lib/strings/errors' -import {usePalette} from 'lib/hooks/usePalette' -import {SendReportButton} from './SendReportButton' -import {InputIssueDetails} from './InputIssueDetails' -import {ReportReasonOptions} from './ReasonOptions' -import {CollectionId} from './types' -import {Trans, msg} from '@lingui/macro' -import {useLingui} from '@lingui/react' -import {useModalControls} from '#/state/modals' -import {getAgent} from '#/state/session' - -const DMCA_LINK = 'https://bsky.social/about/support/copyright' - -export const snapPoints = [575] - -const CollectionNames = { - [CollectionId.FeedGenerator]: 'Feed', - [CollectionId.Profile]: 'Profile', - [CollectionId.List]: 'List', - [CollectionId.Post]: 'Post', -} - -type ReportComponentProps = - | { - uri: string - cid: string - } - | { - did: string - } - -export function Component(content: ReportComponentProps) { - const {closeModal} = useModalControls() - const pal = usePalette('default') - const {isMobile} = useWebMediaQueries() - const [isProcessing, setIsProcessing] = useState(false) - const [showDetailsInput, setShowDetailsInput] = useState(false) - const [error, setError] = useState<string>('') - const [issue, setIssue] = useState<string>('') - const [details, setDetails] = useState<string>('') - const isAccountReport = 'did' in content - const subjectKey = isAccountReport ? content.did : content.uri - const atUri = useMemo( - () => (!isAccountReport ? new AtUri(subjectKey) : null), - [isAccountReport, subjectKey], - ) - - const submitReport = async () => { - setError('') - if (!issue) { - return - } - setIsProcessing(true) - try { - if (issue === '__copyright__') { - Linking.openURL(DMCA_LINK) - closeModal() - return - } - const $type = !isAccountReport - ? 'com.atproto.repo.strongRef' - : 'com.atproto.admin.defs#repoRef' - await getAgent().createModerationReport({ - reasonType: issue, - subject: { - $type, - ...content, - }, - reason: details, - }) - Toast.show("Thank you for your report! We'll look into it promptly.") - - closeModal() - return - } catch (e: any) { - setError(cleanError(e)) - setIsProcessing(false) - } - } - - const goBack = () => { - setShowDetailsInput(false) - } - - return ( - <ScrollView testID="reportModal" style={[s.flex1, pal.view]}> - <View - style={[ - styles.container, - isMobile && { - paddingBottom: 40, - }, - ]}> - {showDetailsInput ? ( - <InputIssueDetails - details={details} - setDetails={setDetails} - goBack={goBack} - submitReport={submitReport} - isProcessing={isProcessing} - /> - ) : ( - <SelectIssue - setShowDetailsInput={setShowDetailsInput} - error={error} - issue={issue} - setIssue={setIssue} - submitReport={submitReport} - isProcessing={isProcessing} - atUri={atUri} - /> - )} - </View> - </ScrollView> - ) -} - -// If no atUri is passed, that means the reporting collection is account -const getCollectionNameForReport = (atUri: AtUri | null) => { - if (!atUri) return 'Account' - // Generic fallback for any collection being reported - return CollectionNames[atUri.collection as CollectionId] || 'Content' -} - -const SelectIssue = ({ - error, - setShowDetailsInput, - issue, - setIssue, - submitReport, - isProcessing, - atUri, -}: { - error: string | undefined - setShowDetailsInput: (v: boolean) => void - issue: string | undefined - setIssue: (v: string) => void - submitReport: () => void - isProcessing: boolean - atUri: AtUri | null -}) => { - const pal = usePalette('default') - const {_} = useLingui() - const collectionName = getCollectionNameForReport(atUri) - const onSelectIssue = (v: string) => setIssue(v) - const goToDetails = () => { - if (issue === '__copyright__') { - Linking.openURL(DMCA_LINK) - return - } - setShowDetailsInput(true) - } - - return ( - <> - <Text style={[pal.text, styles.title]}> - <Trans>Report {collectionName}</Trans> - </Text> - <Text style={[pal.textLight, styles.description]}> - <Trans>What is the issue with this {collectionName}?</Trans> - </Text> - <View style={{marginBottom: 10}}> - <ReportReasonOptions - atUri={atUri} - selectedIssue={issue} - onSelectIssue={onSelectIssue} - /> - </View> - {error ? <ErrorMessage message={error} /> : undefined} - {/* If no atUri is present, the report would be for account in which case, we allow sending without specifying a reason */} - {issue || !atUri ? ( - <> - <SendReportButton - onPress={submitReport} - isProcessing={isProcessing} - /> - <TouchableOpacity - testID="addDetailsBtn" - style={styles.addDetailsBtn} - onPress={goToDetails} - accessibilityRole="button" - accessibilityLabel={_(msg`Add details`)} - accessibilityHint="Add more details to your report"> - <Text style={[s.f18, pal.link]}> - <Trans>Add details to report</Trans> - </Text> - </TouchableOpacity> - </> - ) : undefined} - </> - ) -} - -const styles = StyleSheet.create({ - container: { - paddingHorizontal: 10, - }, - title: { - textAlign: 'center', - fontWeight: 'bold', - fontSize: 24, - marginBottom: 12, - }, - description: { - textAlign: 'center', - fontSize: 17, - paddingHorizontal: 22, - marginBottom: 10, - }, - addDetailsBtn: { - padding: 14, - alignSelf: 'center', - }, -}) diff --git a/src/view/com/modals/report/ReasonOptions.tsx b/src/view/com/modals/report/ReasonOptions.tsx deleted file mode 100644 index 23b49b6648..0000000000 --- a/src/view/com/modals/report/ReasonOptions.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import {View} from 'react-native' -import React, {useMemo} from 'react' -import {AtUri, ComAtprotoModerationDefs} from '@atproto/api' - -import {Text} from '../../util/text/Text' -import {UsePaletteValue, usePalette} from 'lib/hooks/usePalette' -import {RadioGroup, RadioGroupItem} from 'view/com/util/forms/RadioGroup' -import {CollectionId} from './types' - -type ReasonMap = Record<string, {title: string; description: string}> -const CommonReasons = { - [ComAtprotoModerationDefs.REASONRUDE]: { - title: 'Anti-Social Behavior', - description: 'Harassment, trolling, or intolerance', - }, - [ComAtprotoModerationDefs.REASONVIOLATION]: { - title: 'Illegal and Urgent', - description: 'Glaring violations of law or terms of service', - }, - [ComAtprotoModerationDefs.REASONOTHER]: { - title: 'Other', - description: 'An issue not included in these options', - }, -} -const CollectionToReasonsMap: Record<string, ReasonMap> = { - [CollectionId.Post]: { - [ComAtprotoModerationDefs.REASONSPAM]: { - title: 'Spam', - description: 'Excessive mentions or replies', - }, - [ComAtprotoModerationDefs.REASONSEXUAL]: { - title: 'Unwanted Sexual Content', - description: 'Nudity or pornography not labeled as such', - }, - __copyright__: { - title: 'Copyright Violation', - description: 'Contains copyrighted material', - }, - ...CommonReasons, - }, - [CollectionId.List]: { - ...CommonReasons, - [ComAtprotoModerationDefs.REASONVIOLATION]: { - title: 'Name or Description Violates Community Standards', - description: 'Terms used violate community standards', - }, - }, -} -const AccountReportReasons = { - [ComAtprotoModerationDefs.REASONMISLEADING]: { - title: 'Misleading Account', - description: 'Impersonation or false claims about identity or affiliation', - }, - [ComAtprotoModerationDefs.REASONSPAM]: { - title: 'Frequently Posts Unwanted Content', - description: 'Spam; excessive mentions or replies', - }, - [ComAtprotoModerationDefs.REASONVIOLATION]: { - title: 'Name or Description Violates Community Standards', - description: 'Terms used violate community standards', - }, -} - -const Option = ({ - pal, - title, - description, -}: { - pal: UsePaletteValue - description: string - title: string -}) => { - return ( - <View> - <Text style={pal.text} type="md-bold"> - {title} - </Text> - <Text style={pal.textLight}>{description}</Text> - </View> - ) -} - -// This is mostly just content copy without almost any logic -// so this may grow over time and it makes sense to split it up into its own file -// to keep it separate from the actual reporting modal logic -const useReportRadioOptions = (pal: UsePaletteValue, atUri: AtUri | null) => - useMemo(() => { - let items: ReasonMap = {...CommonReasons} - // If no atUri is passed, that means the reporting collection is account - if (!atUri) { - items = {...AccountReportReasons} - } - - if (atUri?.collection && CollectionToReasonsMap[atUri.collection]) { - items = {...CollectionToReasonsMap[atUri.collection]} - } - - return Object.entries(items).map(([key, {title, description}]) => ({ - key, - label: <Option pal={pal} title={title} description={description} />, - })) - }, [pal, atUri]) - -export const ReportReasonOptions = ({ - atUri, - selectedIssue, - onSelectIssue, -}: { - atUri: AtUri | null - selectedIssue?: string - onSelectIssue: (key: string) => void -}) => { - const pal = usePalette('default') - const ITEMS: RadioGroupItem[] = useReportRadioOptions(pal, atUri) - return ( - <RadioGroup - items={ITEMS} - onSelect={onSelectIssue} - testID="reportReasonRadios" - initialSelection={selectedIssue} - /> - ) -} diff --git a/src/view/com/modals/report/SendReportButton.tsx b/src/view/com/modals/report/SendReportButton.tsx deleted file mode 100644 index 40c239bffe..0000000000 --- a/src/view/com/modals/report/SendReportButton.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import React from 'react' -import LinearGradient from 'react-native-linear-gradient' -import { - ActivityIndicator, - StyleSheet, - TouchableOpacity, - View, -} from 'react-native' -import {Text} from '../../util/text/Text' -import {s, gradients, colors} from 'lib/styles' -import {Trans, msg} from '@lingui/macro' -import {useLingui} from '@lingui/react' - -export function SendReportButton({ - onPress, - isProcessing, -}: { - onPress: () => void - isProcessing: boolean -}) { - const {_} = useLingui() - // loading state - // = - if (isProcessing) { - return ( - <View style={[styles.btn, s.mt10]}> - <ActivityIndicator /> - </View> - ) - } - return ( - <TouchableOpacity - testID="sendReportBtn" - style={s.mt10} - onPress={onPress} - accessibilityRole="button" - accessibilityLabel={_(msg`Report post`)} - accessibilityHint={`Reports post with reason and details`}> - <LinearGradient - colors={[gradients.blueLight.start, gradients.blueLight.end]} - start={{x: 0, y: 0}} - end={{x: 1, y: 1}} - style={[styles.btn]}> - <Text style={[s.white, s.bold, s.f18]}> - <Trans>Send Report</Trans> - </Text> - </LinearGradient> - </TouchableOpacity> - ) -} - -const styles = StyleSheet.create({ - btn: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'center', - width: '100%', - borderRadius: 32, - padding: 14, - backgroundColor: colors.gray1, - }, -}) diff --git a/src/view/com/modals/report/types.ts b/src/view/com/modals/report/types.ts deleted file mode 100644 index ca947ecbd4..0000000000 --- a/src/view/com/modals/report/types.ts +++ /dev/null @@ -1,8 +0,0 @@ -// TODO: ATM, @atproto/api does not export ids but it does have these listed at @atproto/api/client/lexicons -// once we start exporting the ids from the @atproto/ap package, replace these hardcoded ones -export enum CollectionId { - FeedGenerator = 'app.bsky.feed.generator', - Profile = 'app.bsky.actor.profile', - List = 'app.bsky.graph.list', - Post = 'app.bsky.feed.post', -} diff --git a/src/view/com/notifications/FeedItem.tsx b/src/view/com/notifications/FeedItem.tsx index a468702659..b165547904 100644 --- a/src/view/com/notifications/FeedItem.tsx +++ b/src/view/com/notifications/FeedItem.tsx @@ -11,7 +11,7 @@ import { AppBskyFeedDefs, AppBskyFeedPost, ModerationOpts, - ProfileModeration, + ModerationDecision, moderateProfile, AppBskyEmbedRecordWithMedia, } from '@atproto/api' @@ -54,7 +54,7 @@ interface Author { handle: string displayName?: string avatar?: string - moderation: ProfileModeration + moderation: ModerationDecision } let FeedItem = ({ @@ -336,7 +336,7 @@ function CondensedAuthorsList({ did={authors[0].did} handle={authors[0].handle} avatar={authors[0].avatar} - moderation={authors[0].moderation.avatar} + moderation={authors[0].moderation.ui('avatar')} /> </View> ) @@ -354,7 +354,7 @@ function CondensedAuthorsList({ <UserAvatar size={35} avatar={author.avatar} - moderation={author.moderation.avatar} + moderation={author.moderation.ui('avatar')} /> </View> ))} @@ -412,7 +412,7 @@ function ExpandedAuthorsList({ <UserAvatar size={35} avatar={author.avatar} - moderation={author.moderation.avatar} + moderation={author.moderation.ui('avatar')} /> </View> <View style={s.flex1}> diff --git a/src/view/com/post-thread/PostLikedBy.tsx b/src/view/com/post-thread/PostLikedBy.tsx index 55463dc137..0760ed7ff3 100644 --- a/src/view/com/post-thread/PostLikedBy.tsx +++ b/src/view/com/post-thread/PostLikedBy.tsx @@ -8,7 +8,7 @@ import {ProfileCardWithFollowBtn} from '../profile/ProfileCard' import {logger} from '#/logger' import {LoadingScreen} from '../util/LoadingScreen' import {useResolveUriQuery} from '#/state/queries/resolve-uri' -import {usePostLikedByQuery} from '#/state/queries/post-liked-by' +import {useLikedByQuery} from '#/state/queries/post-liked-by' import {cleanError} from '#/lib/strings/errors' export function PostLikedBy({uri}: {uri: string}) { @@ -28,7 +28,7 @@ export function PostLikedBy({uri}: {uri: string}) { isError, error, refetch, - } = usePostLikedByQuery(resolvedUri?.uri) + } = useLikedByQuery(resolvedUri?.uri) const likes = useMemo(() => { if (data?.pages) { return data.pages.flatMap(page => page.likes) diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx index a7ee42a948..bac7018c34 100644 --- a/src/view/com/post-thread/PostThread.tsx +++ b/src/view/com/post-thread/PostThread.tsx @@ -106,11 +106,12 @@ export function PostThread({ ? moderatePost(rootPost, moderationOpts) : undefined - const cause = mod?.content.cause - - return cause - ? cause.type === 'label' && cause.labelDef.id === '!no-unauthenticated' - : false + return !!mod + ?.ui('contentList') + .blurs.find( + cause => + cause.type === 'label' && cause.labelDef.id === '!no-unauthenticated', + ) }, [rootPost, moderationOpts]) useSetTitle( diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index cd746f9a91..c073b55a07 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -5,7 +5,7 @@ import { AppBskyFeedDefs, AppBskyFeedPost, RichText as RichTextAPI, - PostModeration, + ModerationDecision, } from '@atproto/api' import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' @@ -19,14 +19,14 @@ import {niceDate} from 'lib/strings/time' import {sanitizeDisplayName} from 'lib/strings/display-names' import {sanitizeHandle} from 'lib/strings/handles' import {countLines, pluralize} from 'lib/strings/helpers' -import {isEmbedByEmbedder} from 'lib/embeds' import {getTranslatorLink, isPostInLanguage} from '../../../locale/helpers' import {PostMeta} from '../util/PostMeta' import {PostEmbeds} from '../util/post-embeds' import {PostCtrls} from '../util/post-ctrls/PostCtrls' -import {PostHider} from '../util/moderation/PostHider' -import {ContentHider} from '../util/moderation/ContentHider' -import {PostAlerts} from '../util/moderation/PostAlerts' +import {PostHider} from '../../../components/moderation/PostHider' +import {ContentHider} from '../../../components/moderation/ContentHider' +import {PostAlerts} from '../../../components/moderation/PostAlerts' +import {LabelsOnMyPost} from '../../../components/moderation/LabelsOnMe' import {ErrorMessage} from '../util/error/ErrorMessage' import {usePalette} from 'lib/hooks/usePalette' import {formatCount} from '../util/numeric/format' @@ -147,7 +147,7 @@ let PostThreadItemLoaded = ({ post: Shadow<AppBskyFeedDefs.PostView> record: AppBskyFeedPost.Record richText: RichTextAPI - moderation: PostModeration + moderation: ModerationDecision treeView: boolean depth: number prevPost: ThreadPost | undefined @@ -175,7 +175,6 @@ let PostThreadItemLoaded = ({ const itemTitle = _(msg`Post by ${post.author.handle}`) const authorHref = makeProfileLink(post.author) const authorTitle = post.author.handle - const isAuthorMuted = post.author.viewer?.muted const likesHref = React.useMemo(() => { const urip = new AtUri(post.uri) return makeProfileLink(post.author, 'post', urip.rkey, 'liked-by') @@ -256,7 +255,7 @@ let PostThreadItemLoaded = ({ did={post.author.did} handle={post.author.handle} avatar={post.author.avatar} - moderation={moderation.avatar} + moderation={moderation.ui('avatar')} /> </View> <View style={styles.layoutContent}> @@ -271,35 +270,12 @@ let PostThreadItemLoaded = ({ {sanitizeDisplayName( post.author.displayName || sanitizeHandle(post.author.handle), + moderation.ui('displayName'), )} </Text> </Link> </View> <View style={styles.meta}> - {isAuthorMuted && ( - <View - style={[ - pal.viewLight, - { - flexDirection: 'row', - alignItems: 'center', - gap: 4, - borderRadius: 6, - paddingHorizontal: 6, - paddingVertical: 2, - marginRight: 4, - }, - ]}> - <FontAwesomeIcon - icon={['far', 'eye-slash']} - size={12} - color={pal.colors.textLight} - /> - <Text type="sm-medium" style={pal.textLight}> - Muted - </Text> - </View> - )} <Link style={s.flex1} href={authorHref} title={authorTitle}> <Text type="md" style={[pal.textLight]} numberOfLines={1}> {sanitizeHandle(post.author.handle, '@')} @@ -312,15 +288,16 @@ let PostThreadItemLoaded = ({ )} </View> <View style={[s.pl10, s.pr10, s.pb10]}> + <LabelsOnMyPost post={post} /> <ContentHider - moderation={moderation.content} + modui={moderation.ui('contentView')} ignoreMute style={styles.contentHider} childContainerStyle={styles.contentHiderChild}> <PostAlerts - moderation={moderation.content} + modui={moderation.ui('contentView')} includeMute - style={styles.alert} + style={[a.pt_2xs, a.pb_sm]} /> {richText?.text ? ( <View @@ -338,18 +315,9 @@ let PostThreadItemLoaded = ({ </View> ) : undefined} {post.embed && ( - <ContentHider - moderation={moderation.embed} - moderationDecisions={moderation.decisions} - ignoreMute={isEmbedByEmbedder(post.embed, post.author.did)} - ignoreQuoteDecisions - style={s.mb10}> - <PostEmbeds - embed={post.embed} - moderation={moderation.embed} - moderationDecisions={moderation.decisions} - /> - </ContentHider> + <View style={[a.pb_sm]}> + <PostEmbeds embed={post.embed} moderation={moderation} /> + </View> )} </ContentHider> <ExpandedPostDetails @@ -432,7 +400,8 @@ let PostThreadItemLoaded = ({ <PostHider testID={`postThreadItem-by-${post.author.handle}`} href={postHref} - moderation={moderation.content} + style={[pal.view]} + modui={moderation.ui('contentList')} iconSize={isThreadedChild ? 26 : 38} iconStyles={ isThreadedChild @@ -482,7 +451,7 @@ let PostThreadItemLoaded = ({ did={post.author.did} handle={post.author.handle} avatar={post.author.avatar} - moderation={moderation.avatar} + moderation={moderation.ui('avatar')} /> {showChildReplyLine && ( @@ -508,19 +477,21 @@ let PostThreadItemLoaded = ({ }> <PostMeta author={post.author} + moderation={moderation} authorHasWarning={!!post.author.labels?.length} timestamp={post.indexedAt} postHref={postHref} showAvatar={isThreadedChild} - avatarModeration={moderation.avatar} + avatarModeration={moderation.ui('avatar')} avatarSize={28} displayNameType="md-bold" displayNameStyle={isThreadedChild && s.ml2} style={isThreadedChild && s.mb2} /> + <LabelsOnMyPost post={post} /> <PostAlerts - moderation={moderation.content} - style={styles.alert} + modui={moderation.ui('contentList')} + style={[a.pt_xs, a.pb_sm]} /> {richText?.text ? ( <View style={styles.postTextContainer}> @@ -542,18 +513,9 @@ let PostThreadItemLoaded = ({ /> ) : undefined} {post.embed && ( - <ContentHider - style={styles.contentHider} - moderation={moderation.embed} - moderationDecisions={moderation.decisions} - ignoreMute={isEmbedByEmbedder(post.embed, post.author.did)} - ignoreQuoteDecisions> - <PostEmbeds - embed={post.embed} - moderation={moderation.embed} - moderationDecisions={moderation.decisions} - /> - </ContentHider> + <View style={[a.pb_xs]}> + <PostEmbeds embed={post.embed} moderation={moderation} /> + </View> )} <PostCtrls post={post} diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx index 7e53eb271b..c7bd4ba2f0 100644 --- a/src/view/com/post/Post.tsx +++ b/src/view/com/post/Post.tsx @@ -4,7 +4,7 @@ import { AppBskyFeedDefs, AppBskyFeedPost, AtUri, - PostModeration, + ModerationDecision, RichText as RichTextAPI, } from '@atproto/api' import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped' @@ -14,8 +14,9 @@ import {UserInfoText} from '../util/UserInfoText' import {PostMeta} from '../util/PostMeta' import {PostEmbeds} from '../util/post-embeds' import {PostCtrls} from '../util/post-ctrls/PostCtrls' -import {ContentHider} from '../util/moderation/ContentHider' -import {PostAlerts} from '../util/moderation/PostAlerts' +import {ContentHider} from '../../../components/moderation/ContentHider' +import {PostAlerts} from '../../../components/moderation/PostAlerts' +import {LabelsOnMyPost} from '../../../components/moderation/LabelsOnMe' import {Text} from '../util/text/Text' import {RichText} from '#/components/RichText' import {PreviewableUserAvatar} from '../util/UserAvatar' @@ -93,7 +94,7 @@ function PostInner({ post: Shadow<AppBskyFeedDefs.PostView> record: AppBskyFeedPost.Record richText: RichTextAPI - moderation: PostModeration + moderation: ModerationDecision showReplyLine?: boolean style?: StyleProp<ViewStyle> }) { @@ -142,12 +143,13 @@ function PostInner({ did={post.author.did} handle={post.author.handle} avatar={post.author.avatar} - moderation={moderation.avatar} + moderation={moderation.ui('avatar')} /> </View> <View style={styles.layoutContent}> <PostMeta author={post.author} + moderation={moderation} authorHasWarning={!!post.author.labels?.length} timestamp={post.indexedAt} postHref={itemHref} @@ -176,11 +178,15 @@ function PostInner({ </Text> </View> )} + <LabelsOnMyPost post={post} /> <ContentHider - moderation={moderation.content} + modui={moderation.ui('contentView')} style={styles.contentHider} childContainerStyle={styles.contentHiderChild}> - <PostAlerts moderation={moderation.content} style={styles.alert} /> + <PostAlerts + modui={moderation.ui('contentView')} + style={[a.py_xs]} + /> {richText.text ? ( <View style={styles.postTextContainer}> <RichText @@ -202,17 +208,7 @@ function PostInner({ /> ) : undefined} {post.embed ? ( - <ContentHider - moderation={moderation.embed} - moderationDecisions={moderation.decisions} - ignoreQuoteDecisions - style={styles.contentHider}> - <PostEmbeds - embed={post.embed} - moderation={moderation.embed} - moderationDecisions={moderation.decisions} - /> - </ContentHider> + <PostEmbeds embed={post.embed} moderation={moderation} /> ) : null} </ContentHider> <PostCtrls diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx index f3911da60e..0706ddb9b8 100644 --- a/src/view/com/posts/FeedItem.tsx +++ b/src/view/com/posts/FeedItem.tsx @@ -4,7 +4,7 @@ import { AppBskyFeedDefs, AppBskyFeedPost, AtUri, - PostModeration, + ModerationDecision, RichText as RichTextAPI, } from '@atproto/api' import { @@ -18,8 +18,9 @@ import {UserInfoText} from '../util/UserInfoText' import {PostMeta} from '../util/PostMeta' import {PostCtrls} from '../util/post-ctrls/PostCtrls' import {PostEmbeds} from '../util/post-embeds' -import {ContentHider} from '../util/moderation/ContentHider' -import {PostAlerts} from '../util/moderation/PostAlerts' +import {ContentHider} from '#/components/moderation/ContentHider' +import {PostAlerts} from '../../../components/moderation/PostAlerts' +import {LabelsOnMyPost} from '../../../components/moderation/LabelsOnMe' import {RichText} from '#/components/RichText' import {PreviewableUserAvatar} from '../util/UserAvatar' import {s} from 'lib/styles' @@ -27,13 +28,11 @@ import {usePalette} from 'lib/hooks/usePalette' import {sanitizeDisplayName} from 'lib/strings/display-names' import {sanitizeHandle} from 'lib/strings/handles' import {makeProfileLink} from 'lib/routes/links' -import {isEmbedByEmbedder} from 'lib/embeds' import {MAX_POST_LINES} from 'lib/constants' import {countLines} from 'lib/strings/helpers' import {useComposerControls} from '#/state/shell/composer' import {Shadow, usePostShadow, POST_TOMBSTONE} from '#/state/cache/post-shadow' import {FeedNameText} from '../util/FeedInfoText' -import {useSession} from '#/state/session' import {Trans, msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {atoms as a} from '#/alf' @@ -50,7 +49,7 @@ export function FeedItem({ post: AppBskyFeedDefs.PostView record: AppBskyFeedPost.Record reason: AppBskyFeedDefs.ReasonRepost | ReasonFeedSource | undefined - moderation: PostModeration + moderation: ModerationDecision isThreadChild?: boolean isThreadLastChild?: boolean isThreadParent?: boolean @@ -100,7 +99,7 @@ let FeedItemInner = ({ record: AppBskyFeedPost.Record reason: AppBskyFeedDefs.ReasonRepost | ReasonFeedSource | undefined richText: RichTextAPI - moderation: PostModeration + moderation: ModerationDecision isThreadChild?: boolean isThreadLastChild?: boolean isThreadParent?: boolean @@ -108,14 +107,10 @@ let FeedItemInner = ({ const {openComposer} = useComposerControls() const pal = usePalette('default') const {_} = useLingui() - const {currentAccount} = useSession() const href = useMemo(() => { const urip = new AtUri(post.uri) return makeProfileLink(post.author, 'post', urip.rkey) }, [post.uri, post.author]) - const isModeratedPost = - moderation.decisions.post.cause?.type === 'label' && - moderation.decisions.post.cause.label.src !== currentAccount?.did const replyAuthorDid = useMemo(() => { if (!record?.reply) { @@ -148,7 +143,7 @@ let FeedItemInner = ({ borderColor: pal.colors.border, paddingBottom: isThreadLastChild || (!isThreadChild && !isThreadParent) - ? 6 + ? 8 : undefined, }, isThreadChild ? styles.outerSmallTop : undefined, @@ -229,6 +224,7 @@ let FeedItemInner = ({ numberOfLines={1} text={sanitizeDisplayName( reason.by.displayName || sanitizeHandle(reason.by.handle), + moderation.ui('displayName'), )} href={makeProfileLink(reason.by)} /> @@ -246,7 +242,7 @@ let FeedItemInner = ({ did={post.author.did} handle={post.author.handle} avatar={post.author.avatar} - moderation={moderation.avatar} + moderation={moderation.ui('avatar')} /> {isThreadParent && ( <View @@ -264,6 +260,7 @@ let FeedItemInner = ({ <View style={styles.layoutContent}> <PostMeta author={post.author} + moderation={moderation} authorHasWarning={!!post.author.labels?.length} timestamp={post.indexedAt} postHref={href} @@ -295,6 +292,7 @@ let FeedItemInner = ({ </Text> </View> )} + <LabelsOnMyPost post={post} /> <PostContent moderation={moderation} richText={richText} @@ -306,9 +304,6 @@ let FeedItemInner = ({ record={record} richText={richText} onPressReply={onPressReply} - showAppealLabelItem={ - post.author.did === currentAccount?.did && isModeratedPost - } logContext="FeedItem" /> </View> @@ -324,7 +319,7 @@ let PostContent = ({ postEmbed, postAuthor, }: { - moderation: PostModeration + moderation: ModerationDecision richText: RichTextAPI postEmbed: AppBskyFeedDefs.PostView['embed'] postAuthor: AppBskyFeedDefs.PostView['author'] @@ -342,10 +337,10 @@ let PostContent = ({ return ( <ContentHider testID="contentHider-post" - moderation={moderation.content} + modui={moderation.ui('contentList')} ignoreMute childContainerStyle={styles.contentHiderChild}> - <PostAlerts moderation={moderation.content} style={styles.alert} /> + <PostAlerts modui={moderation.ui('contentList')} style={[a.py_xs]} /> {richText.text ? ( <View style={styles.postTextContainer}> <RichText @@ -367,19 +362,9 @@ let PostContent = ({ /> ) : undefined} {postEmbed ? ( - <ContentHider - testID="contentHider-embed" - moderation={moderation.embed} - moderationDecisions={moderation.decisions} - ignoreMute={isEmbedByEmbedder(postEmbed, postAuthor.did)} - ignoreQuoteDecisions - style={styles.embed}> - <PostEmbeds - embed={postEmbed} - moderation={moderation.embed} - moderationDecisions={moderation.decisions} - /> - </ContentHider> + <View style={[a.pb_sm]}> + <PostEmbeds embed={postEmbed} moderation={moderation} /> + </View> ) : null} </ContentHider> ) diff --git a/src/view/com/profile/ProfileCard.tsx b/src/view/com/profile/ProfileCard.tsx index 019e6c10e7..d909bda858 100644 --- a/src/view/com/profile/ProfileCard.tsx +++ b/src/view/com/profile/ProfileCard.tsx @@ -3,7 +3,8 @@ import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native' import { AppBskyActorDefs, moderateProfile, - ProfileModeration, + ModerationCause, + ModerationDecision, } from '@atproto/api' import {Link} from '../util/Link' import {Text} from '../util/text/Text' @@ -14,16 +15,13 @@ import {FollowButton} from './FollowButton' import {sanitizeDisplayName} from 'lib/strings/display-names' import {sanitizeHandle} from 'lib/strings/handles' import {makeProfileLink} from 'lib/routes/links' -import { - describeModerationCause, - getProfileModerationCauses, - getModerationCauseKey, -} from 'lib/moderation' +import {getModerationCauseKey, isJustAMute} from 'lib/moderation' import {Shadow} from '#/state/cache/types' import {useModerationOpts} from '#/state/queries/preferences' import {useProfileShadow} from '#/state/cache/profile-shadow' import {useSession} from '#/state/session' import {Trans} from '@lingui/macro' +import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription' export function ProfileCard({ testID, @@ -33,6 +31,7 @@ export function ProfileCard({ noBorder, followers, renderButton, + onPress, style, }: { testID?: string @@ -44,6 +43,7 @@ export function ProfileCard({ renderButton?: ( profile: Shadow<AppBskyActorDefs.ProfileViewBasic>, ) => React.ReactNode + onPress?: () => void style?: StyleProp<ViewStyle> }) { const pal = usePalette('default') @@ -53,11 +53,8 @@ export function ProfileCard({ return null } const moderation = moderateProfile(profile, moderationOpts) - if ( - !noModFilter && - moderation.account.filter && - moderation.account.cause?.type !== 'muted' - ) { + const modui = moderation.ui('profileList') + if (!noModFilter && modui.filter && !isJustAMute(modui)) { return null } @@ -73,6 +70,7 @@ export function ProfileCard({ ]} href={makeProfileLink(profile)} title={profile.handle} + onBeforePress={onPress} asAnchor anchorNoUnderline> <View style={styles.layout}> @@ -80,7 +78,7 @@ export function ProfileCard({ <UserAvatar size={40} avatar={profile.avatar} - moderation={moderation.avatar} + moderation={moderation.ui('avatar')} /> </View> <View style={styles.layoutContent}> @@ -91,7 +89,7 @@ export function ProfileCard({ lineHeight={1.2}> {sanitizeDisplayName( profile.displayName || sanitizeHandle(profile.handle), - moderation.profile, + moderation.ui('displayName'), )} </Text> <Text type="md" style={[pal.textLight]} numberOfLines={1}> @@ -119,17 +117,17 @@ export function ProfileCard({ ) } -function ProfileCardPills({ +export function ProfileCardPills({ followedBy, moderation, }: { followedBy: boolean - moderation: ProfileModeration + moderation: ModerationDecision }) { const pal = usePalette('default') - const causes = getProfileModerationCauses(moderation) - if (!followedBy && !causes.length) { + const modui = moderation.ui('profileList') + if (!followedBy && !modui.inform && !modui.alert) { return null } @@ -142,19 +140,41 @@ function ProfileCardPills({ </Text> </View> )} - {causes.map(cause => { - const desc = describeModerationCause(cause, 'account') - return ( - <View - style={[s.mt5, pal.btn, styles.pill]} - key={getModerationCauseKey(cause)}> - <Text type="xs" style={pal.text}> - {cause?.type === 'label' ? '⚠' : ''} - {desc.name} - </Text> - </View> - ) - })} + {modui.alerts.map(alert => ( + <ProfileCardPillModerationCause + key={getModerationCauseKey(alert)} + cause={alert} + severity="alert" + /> + ))} + {modui.informs.map(inform => ( + <ProfileCardPillModerationCause + key={getModerationCauseKey(inform)} + cause={inform} + severity="inform" + /> + ))} + </View> + ) +} + +function ProfileCardPillModerationCause({ + cause, + severity, +}: { + cause: ModerationCause + severity: 'alert' | 'inform' +}) { + const pal = usePalette('default') + const {name} = useModerationCauseDescription(cause) + return ( + <View + style={[s.mt5, pal.btn, styles.pill]} + key={getModerationCauseKey(cause)}> + <Text type="xs" style={pal.text}> + {severity === 'alert' ? '⚠ ' : ''} + {name} + </Text> </View> ) } @@ -177,7 +197,7 @@ function FollowersList({ f, mod: moderateProfile(f, moderationOpts), })) - .filter(({mod}) => !mod.account.filter) + .filter(({mod}) => !mod.ui('profileList').filter) }, [followers, moderationOpts]) if (!followersWithMods?.length) { @@ -199,7 +219,11 @@ function FollowersList({ {followersWithMods.slice(0, 3).map(({f, mod}) => ( <View key={f.did} style={styles.followedByAviContainer}> <View style={[styles.followedByAvi, pal.view]}> - <UserAvatar avatar={f.avatar} size={32} moderation={mod.avatar} /> + <UserAvatar + avatar={f.avatar} + size={32} + moderation={mod.ui('avatar')} + /> </View> </View> ))} @@ -212,11 +236,13 @@ export function ProfileCardWithFollowBtn({ noBg, noBorder, followers, + onPress, }: { profile: AppBskyActorDefs.ProfileViewBasic noBg?: boolean noBorder?: boolean followers?: AppBskyActorDefs.ProfileView[] | undefined + onPress?: () => void }) { const {currentAccount} = useSession() const isMe = profile.did === currentAccount?.did @@ -234,6 +260,7 @@ export function ProfileCardWithFollowBtn({ <FollowButton profile={profileShadow} logContext="ProfileCard" /> ) } + onPress={onPress} /> ) } diff --git a/src/view/com/profile/ProfileHeader.tsx b/src/view/com/profile/ProfileHeader.tsx deleted file mode 100644 index 17dc5ce1bd..0000000000 --- a/src/view/com/profile/ProfileHeader.tsx +++ /dev/null @@ -1,598 +0,0 @@ -import React, {memo, useMemo} from 'react' -import { - StyleSheet, - TouchableOpacity, - TouchableWithoutFeedback, - View, -} from 'react-native' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {useNavigation} from '@react-navigation/native' -import { - AppBskyActorDefs, - ModerationOpts, - moderateProfile, - RichText as RichTextAPI, -} from '@atproto/api' -import {Trans, msg} from '@lingui/macro' -import {useLingui} from '@lingui/react' -import {NavigationProp} from 'lib/routes/types' -import {isNative} from 'platform/detection' -import {BlurView} from '../util/BlurView' -import * as Toast from '../util/Toast' -import {LoadingPlaceholder} from '../util/LoadingPlaceholder' -import {Text} from '../util/text/Text' -import {ThemedText} from '../util/text/ThemedText' -import {RichText} from '#/components/RichText' -import {UserAvatar} from '../util/UserAvatar' -import {UserBanner} from '../util/UserBanner' -import {ProfileHeaderAlerts} from '../util/moderation/ProfileHeaderAlerts' -import {formatCount} from '../util/numeric/format' -import {Link} from '../util/Link' -import {ProfileHeaderSuggestedFollows} from './ProfileHeaderSuggestedFollows' -import {useModalControls} from '#/state/modals' -import {useLightboxControls, ProfileImageLightbox} from '#/state/lightbox' -import { - useProfileBlockMutationQueue, - useProfileFollowMutationQueue, -} from '#/state/queries/profile' -import {usePalette} from 'lib/hooks/usePalette' -import {useAnalytics} from 'lib/analytics/analytics' -import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {BACK_HITSLOP} from 'lib/constants' -import {isInvalidHandle, sanitizeHandle} from 'lib/strings/handles' -import {makeProfileLink} from 'lib/routes/links' -import {pluralize} from 'lib/strings/helpers' -import {sanitizeDisplayName} from 'lib/strings/display-names' -import {s, colors} from 'lib/styles' -import {logger} from '#/logger' -import {useSession} from '#/state/session' -import {Shadow} from '#/state/cache/types' -import {useRequireAuth} from '#/state/session' -import {LabelInfo} from '../util/moderation/LabelInfo' -import {useProfileShadow} from 'state/cache/profile-shadow' -import {atoms as a} from '#/alf' -import {ProfileMenu} from 'view/com/profile/ProfileMenu' -import * as Prompt from '#/components/Prompt' - -let ProfileHeaderLoading = (_props: {}): React.ReactNode => { - const pal = usePalette('default') - return ( - <View style={pal.view}> - <LoadingPlaceholder width="100%" height={150} style={{borderRadius: 0}} /> - <View - style={[pal.view, {borderColor: pal.colors.background}, styles.avi]}> - <LoadingPlaceholder width={80} height={80} style={styles.br40} /> - </View> - <View style={styles.content}> - <View style={[styles.buttonsLine]}> - <LoadingPlaceholder width={167} height={31} style={styles.br50} /> - </View> - </View> - </View> - ) -} -ProfileHeaderLoading = memo(ProfileHeaderLoading) -export {ProfileHeaderLoading} - -interface Props { - profile: AppBskyActorDefs.ProfileViewDetailed - descriptionRT: RichTextAPI | null - moderationOpts: ModerationOpts - hideBackButton?: boolean - isPlaceholderProfile?: boolean -} - -let ProfileHeader = ({ - profile: profileUnshadowed, - descriptionRT, - moderationOpts, - hideBackButton = false, - isPlaceholderProfile, -}: Props): React.ReactNode => { - const profile: Shadow<AppBskyActorDefs.ProfileViewDetailed> = - useProfileShadow(profileUnshadowed) - const pal = usePalette('default') - const palInverted = usePalette('inverted') - const {currentAccount, hasSession} = useSession() - const requireAuth = useRequireAuth() - const {_} = useLingui() - const {openModal} = useModalControls() - const {openLightbox} = useLightboxControls() - const navigation = useNavigation<NavigationProp>() - const {track} = useAnalytics() - const invalidHandle = isInvalidHandle(profile.handle) - const {isDesktop} = useWebMediaQueries() - const [showSuggestedFollows, setShowSuggestedFollows] = React.useState(false) - const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( - profile, - 'ProfileHeader', - ) - const [__, queueUnblock] = useProfileBlockMutationQueue(profile) - const unblockPromptControl = Prompt.usePromptControl() - const moderation = useMemo( - () => moderateProfile(profile, moderationOpts), - [profile, moderationOpts], - ) - - const onPressBack = React.useCallback(() => { - if (navigation.canGoBack()) { - navigation.goBack() - } else { - navigation.navigate('Home') - } - }, [navigation]) - - const onPressAvi = React.useCallback(() => { - if ( - profile.avatar && - !(moderation.avatar.blur && moderation.avatar.noOverride) - ) { - openLightbox(new ProfileImageLightbox(profile)) - } - }, [openLightbox, profile, moderation]) - - const onPressFollow = () => { - requireAuth(async () => { - try { - track('ProfileHeader:FollowButtonClicked') - await queueFollow() - Toast.show( - _( - msg`Following ${sanitizeDisplayName( - profile.displayName || profile.handle, - )}`, - ), - ) - } catch (e: any) { - if (e?.name !== 'AbortError') { - logger.error('Failed to follow', {message: String(e)}) - Toast.show(_(msg`There was an issue! ${e.toString()}`)) - } - } - }) - } - - const onPressUnfollow = () => { - requireAuth(async () => { - try { - track('ProfileHeader:UnfollowButtonClicked') - await queueUnfollow() - Toast.show( - _( - msg`No longer following ${sanitizeDisplayName( - profile.displayName || profile.handle, - )}`, - ), - ) - } catch (e: any) { - if (e?.name !== 'AbortError') { - logger.error('Failed to unfollow', {message: String(e)}) - Toast.show(_(msg`There was an issue! ${e.toString()}`)) - } - } - }) - } - - const onPressEditProfile = React.useCallback(() => { - track('ProfileHeader:EditProfileButtonClicked') - openModal({ - name: 'edit-profile', - profile, - }) - }, [track, openModal, profile]) - - const unblockAccount = React.useCallback(async () => { - track('ProfileHeader:UnblockAccountButtonClicked') - try { - await queueUnblock() - Toast.show(_(msg`Account unblocked`)) - } catch (e: any) { - if (e?.name !== 'AbortError') { - logger.error('Failed to unblock account', {message: e}) - Toast.show(_(msg`There was an issue! ${e.toString()}`)) - } - } - }, [_, queueUnblock, track]) - - const isMe = React.useMemo( - () => currentAccount?.did === profile.did, - [currentAccount, profile], - ) - - const blockHide = - !isMe && (profile.viewer?.blocking || profile.viewer?.blockedBy) - const following = formatCount(profile.followsCount || 0) - const followers = formatCount(profile.followersCount || 0) - const pluralizedFollowers = pluralize(profile.followersCount || 0, 'follower') - - return ( - <View style={[pal.view]} pointerEvents="box-none"> - <View pointerEvents="none"> - {isPlaceholderProfile ? ( - <LoadingPlaceholder - width="100%" - height={150} - style={{borderRadius: 0}} - /> - ) : ( - <UserBanner banner={profile.banner} moderation={moderation.avatar} /> - )} - </View> - <View style={styles.content} pointerEvents="box-none"> - <View style={[styles.buttonsLine]} pointerEvents="box-none"> - {isMe ? ( - <TouchableOpacity - testID="profileHeaderEditProfileButton" - onPress={onPressEditProfile} - style={[styles.btn, styles.mainBtn, pal.btn]} - accessibilityRole="button" - accessibilityLabel={_(msg`Edit profile`)} - accessibilityHint={_( - msg`Opens editor for profile display name, avatar, background image, and description`, - )}> - <Text type="button" style={pal.text}> - <Trans>Edit Profile</Trans> - </Text> - </TouchableOpacity> - ) : profile.viewer?.blocking ? ( - profile.viewer?.blockingByList ? null : ( - <TouchableOpacity - testID="unblockBtn" - onPress={() => unblockPromptControl.open()} - style={[styles.btn, styles.mainBtn, pal.btn]} - accessibilityRole="button" - accessibilityLabel={_(msg`Unblock`)} - accessibilityHint=""> - <Text type="button" style={[pal.text, s.bold]}> - <Trans context="action">Unblock</Trans> - </Text> - </TouchableOpacity> - ) - ) : !profile.viewer?.blockedBy ? ( - <> - {hasSession && ( - <TouchableOpacity - testID="suggestedFollowsBtn" - onPress={() => setShowSuggestedFollows(!showSuggestedFollows)} - style={[ - styles.btn, - styles.mainBtn, - pal.btn, - { - paddingHorizontal: 10, - backgroundColor: showSuggestedFollows - ? pal.colors.text - : pal.colors.backgroundLight, - }, - ]} - accessibilityRole="button" - accessibilityLabel={_( - msg`Show follows similar to ${profile.handle}`, - )} - accessibilityHint={_( - msg`Shows a list of users similar to this user.`, - )}> - <FontAwesomeIcon - icon="user-plus" - style={[ - pal.text, - { - color: showSuggestedFollows - ? pal.textInverted.color - : pal.text.color, - }, - ]} - size={14} - /> - </TouchableOpacity> - )} - - {profile.viewer?.following ? ( - <TouchableOpacity - testID="unfollowBtn" - onPress={onPressUnfollow} - style={[styles.btn, styles.mainBtn, pal.btn]} - accessibilityRole="button" - accessibilityLabel={_(msg`Unfollow ${profile.handle}`)} - accessibilityHint={_( - msg`Hides posts from ${profile.handle} in your feed`, - )}> - <FontAwesomeIcon - icon="check" - style={[pal.text, s.mr5]} - size={14} - /> - <Text type="button" style={pal.text}> - <Trans>Following</Trans> - </Text> - </TouchableOpacity> - ) : ( - <TouchableOpacity - testID="followBtn" - onPress={onPressFollow} - style={[styles.btn, styles.mainBtn, palInverted.view]} - accessibilityRole="button" - accessibilityLabel={_(msg`Follow ${profile.handle}`)} - accessibilityHint={_( - msg`Shows posts from ${profile.handle} in your feed`, - )}> - <FontAwesomeIcon - icon="plus" - style={[palInverted.text, s.mr5]} - /> - <Text type="button" style={[palInverted.text, s.bold]}> - <Trans>Follow</Trans> - </Text> - </TouchableOpacity> - )} - </> - ) : null} - <ProfileMenu profile={profile} /> - </View> - <View pointerEvents="none"> - <Text - testID="profileHeaderDisplayName" - type="title-2xl" - style={[pal.text, styles.title]}> - {sanitizeDisplayName( - profile.displayName || sanitizeHandle(profile.handle), - moderation.profile, - )} - </Text> - </View> - <View style={styles.handleLine} pointerEvents="none"> - {profile.viewer?.followedBy && !blockHide ? ( - <View style={[styles.pill, pal.btn, s.mr5]}> - <Text type="xs" style={[pal.text]}> - <Trans>Follows you</Trans> - </Text> - </View> - ) : undefined} - <ThemedText - type={invalidHandle ? 'xs' : 'md'} - fg={invalidHandle ? 'error' : 'light'} - border={invalidHandle ? 'error' : undefined} - style={[ - invalidHandle ? styles.invalidHandle : undefined, - styles.handle, - ]}> - {invalidHandle ? _(msg`⚠Invalid Handle`) : `@${profile.handle}`} - </ThemedText> - </View> - {!isPlaceholderProfile && !blockHide && ( - <> - <View style={styles.metricsLine} pointerEvents="box-none"> - <Link - testID="profileHeaderFollowersButton" - style={[s.flexRow, s.mr10]} - href={makeProfileLink(profile, 'followers')} - onPressOut={() => - track(`ProfileHeader:FollowersButtonClicked`, { - handle: profile.handle, - }) - } - asAnchor - accessibilityLabel={`${followers} ${pluralizedFollowers}`} - accessibilityHint={_(msg`Opens followers list`)}> - <Text type="md" style={[s.bold, pal.text]}> - {followers}{' '} - </Text> - <Text type="md" style={[pal.textLight]}> - {pluralizedFollowers} - </Text> - </Link> - <Link - testID="profileHeaderFollowsButton" - style={[s.flexRow, s.mr10]} - href={makeProfileLink(profile, 'follows')} - onPressOut={() => - track(`ProfileHeader:FollowsButtonClicked`, { - handle: profile.handle, - }) - } - asAnchor - accessibilityLabel={_(msg`${following} following`)} - accessibilityHint={_(msg`Opens following list`)}> - <Trans> - <Text type="md" style={[s.bold, pal.text]}> - {following}{' '} - </Text> - <Text type="md" style={[pal.textLight]}> - following - </Text> - </Trans> - </Link> - <Text type="md" style={[s.bold, pal.text]}> - {formatCount(profile.postsCount || 0)}{' '} - <Text type="md" style={[pal.textLight]}> - {pluralize(profile.postsCount || 0, 'post')} - </Text> - </Text> - </View> - {descriptionRT && !moderation.profile.blur ? ( - <View pointerEvents="auto" style={[styles.description]}> - <RichText - testID="profileHeaderDescription" - style={[a.text_md]} - numberOfLines={15} - value={descriptionRT} - /> - </View> - ) : undefined} - </> - )} - <ProfileHeaderAlerts moderation={moderation} /> - {isMe && ( - <LabelInfo details={{did: profile.did}} labels={profile.labels} /> - )} - </View> - - {showSuggestedFollows && ( - <ProfileHeaderSuggestedFollows - actorDid={profile.did} - requestDismiss={() => { - if (showSuggestedFollows) { - setShowSuggestedFollows(false) - } else { - track('ProfileHeader:SuggestedFollowsOpened') - setShowSuggestedFollows(true) - } - }} - /> - )} - - {!isDesktop && !hideBackButton && ( - <TouchableWithoutFeedback - testID="profileHeaderBackBtn" - onPress={onPressBack} - hitSlop={BACK_HITSLOP} - accessibilityRole="button" - accessibilityLabel={_(msg`Back`)} - accessibilityHint=""> - <View style={styles.backBtnWrapper}> - <BlurView style={styles.backBtn} blurType="dark"> - <FontAwesomeIcon size={18} icon="angle-left" style={s.white} /> - </BlurView> - </View> - </TouchableWithoutFeedback> - )} - <TouchableWithoutFeedback - testID="profileHeaderAviButton" - onPress={onPressAvi} - accessibilityRole="image" - accessibilityLabel={_(msg`View ${profile.handle}'s avatar`)} - accessibilityHint=""> - <View - style={[pal.view, {borderColor: pal.colors.background}, styles.avi]}> - <UserAvatar - size={80} - avatar={profile.avatar} - moderation={moderation.avatar} - /> - </View> - </TouchableWithoutFeedback> - <Prompt.Basic - control={unblockPromptControl} - title={_(msg`Unblock Account?`)} - description={_( - msg`The account will be able to interact with you after unblocking.`, - )} - onConfirm={unblockAccount} - confirmButtonCta={ - profile.viewer?.blocking ? _(msg`Unblock`) : _(msg`Block`) - } - confirmButtonColor="negative" - /> - </View> - ) -} -ProfileHeader = memo(ProfileHeader) -export {ProfileHeader} - -const styles = StyleSheet.create({ - banner: { - width: '100%', - height: 120, - }, - backBtnWrapper: { - position: 'absolute', - top: 10, - left: 10, - width: 30, - height: 30, - overflow: 'hidden', - borderRadius: 15, - // @ts-ignore web only - cursor: 'pointer', - }, - backBtn: { - width: 30, - height: 30, - borderRadius: 15, - alignItems: 'center', - justifyContent: 'center', - }, - avi: { - position: 'absolute', - top: 110, - left: 10, - width: 84, - height: 84, - borderRadius: 42, - borderWidth: 2, - }, - content: { - paddingTop: 8, - paddingHorizontal: 14, - paddingBottom: 4, - }, - - buttonsLine: { - flexDirection: 'row', - marginLeft: 'auto', - marginBottom: 12, - }, - primaryBtn: { - backgroundColor: colors.blue3, - paddingHorizontal: 24, - paddingVertical: 6, - }, - mainBtn: { - paddingHorizontal: 24, - }, - secondaryBtn: { - paddingHorizontal: 14, - }, - btn: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'center', - paddingVertical: 7, - borderRadius: 50, - marginLeft: 6, - }, - title: {lineHeight: 38}, - - // Word wrapping appears fine on - // mobile but overflows on desktop - handle: isNative - ? {} - : { - // @ts-ignore web only -prf - wordBreak: 'break-all', - }, - invalidHandle: { - borderWidth: 1, - borderRadius: 4, - paddingHorizontal: 4, - }, - - handleLine: { - flexDirection: 'row', - marginBottom: 8, - }, - - metricsLine: { - flexDirection: 'row', - marginBottom: 8, - }, - - description: { - marginBottom: 8, - }, - - detailLine: { - flexDirection: 'row', - alignItems: 'center', - marginBottom: 5, - }, - - pill: { - borderRadius: 4, - paddingHorizontal: 6, - paddingVertical: 2, - }, - - br40: {borderRadius: 40}, - br50: {borderRadius: 50}, -}) diff --git a/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx b/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx index 8f2c894994..947d6e9cc6 100644 --- a/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx +++ b/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx @@ -217,7 +217,7 @@ function SuggestedFollow({ <UserAvatar size={60} avatar={profile.avatar} - moderation={moderation.avatar} + moderation={moderation.ui('avatar')} /> <View style={{width: '100%', paddingVertical: 12}}> @@ -227,7 +227,7 @@ function SuggestedFollow({ numberOfLines={1}> {sanitizeDisplayName( profile.displayName || sanitizeHandle(profile.handle), - moderation.profile, + moderation.ui('displayName'), )} </Text> <Text diff --git a/src/view/com/profile/ProfileMenu.tsx b/src/view/com/profile/ProfileMenu.tsx index 0baa4f3945..cb0b1d97c8 100644 --- a/src/view/com/profile/ProfileMenu.tsx +++ b/src/view/com/profile/ProfileMenu.tsx @@ -17,6 +17,7 @@ import {toShareUrl} from 'lib/strings/url-helpers' import {makeProfileLink} from 'lib/routes/links' import {useAnalytics} from 'lib/analytics/analytics' import {useModalControls} from 'state/modals' +import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog' import { RQKEY as profileQueryKey, useProfileBlockMutationQueue, @@ -31,6 +32,7 @@ import {Flag_Stroke2_Corner0_Rounded as Flag} from '#/components/icons/Flag' import {PersonCheck_Stroke2_Corner0_Rounded as PersonCheck} from '#/components/icons/PersonCheck' import {PersonX_Stroke2_Corner0_Rounded as PersonX} from '#/components/icons/PersonX' import {PeopleRemove2_Stroke2_Corner0_Rounded as UserMinus} from '#/components/icons/PeopleRemove2' +import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' import {logger} from '#/logger' import {Shadow} from 'state/cache/types' import * as Prompt from '#/components/Prompt' @@ -47,12 +49,17 @@ let ProfileMenu = ({ const pal = usePalette('default') const {track} = useAnalytics() const {openModal} = useModalControls() + const reportDialogControl = useReportDialogControl() const queryClient = useQueryClient() const isSelf = currentAccount?.did === profile.did + const isFollowing = profile.viewer?.following + const isBlocked = profile.viewer?.blocking || profile.viewer?.blockedBy + const isFollowingBlockedAccount = isFollowing && isBlocked + const isLabelerAndNotBlocked = !!profile.associated?.labeler && !isBlocked const [queueMute, queueUnmute] = useProfileMuteMutationQueue(profile) const [queueBlock, queueUnblock] = useProfileBlockMutationQueue(profile) - const [, queueUnfollow] = useProfileFollowMutationQueue( + const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( profile, 'ProfileMenu', ) @@ -139,6 +146,19 @@ let ProfileMenu = ({ } }, [profile.viewer?.blocking, track, _, queueUnblock, queueBlock]) + const onPressFollowAccount = React.useCallback(async () => { + track('ProfileHeader:FollowButtonClicked') + try { + await queueFollow() + Toast.show(_(msg`Account followed`)) + } catch (e: any) { + if (e?.name !== 'AbortError') { + logger.error('Failed to follow account', {message: e}) + Toast.show(_(msg`There was an issue! ${e.toString()}`)) + } + } + }, [_, queueFollow, track]) + const onPressUnfollowAccount = React.useCallback(async () => { track('ProfileHeader:UnfollowButtonClicked') try { @@ -154,11 +174,8 @@ let ProfileMenu = ({ const onPressReportAccount = React.useCallback(() => { track('ProfileHeader:ReportAccountButtonClicked') - openModal({ - name: 'report', - did: profile.did, - }) - }, [track, openModal, profile]) + reportDialogControl.open() + }, [track, reportDialogControl]) return ( <EventStopper onKeyDown={false}> @@ -175,10 +192,9 @@ let ProfileMenu = ({ flexDirection: 'row', alignItems: 'center', justifyContent: 'center', - paddingVertical: 7, + paddingVertical: 10, borderRadius: 50, - marginLeft: 6, - paddingHorizontal: 14, + paddingHorizontal: 16, }, pal.btn, ]}> @@ -210,10 +226,38 @@ let ProfileMenu = ({ <Menu.ItemIcon icon={Share} /> </Menu.Item> </Menu.Group> + {hasSession && ( <> <Menu.Divider /> <Menu.Group> + {!isSelf && ( + <> + {(isLabelerAndNotBlocked || isFollowingBlockedAccount) && ( + <Menu.Item + testID="profileHeaderDropdownFollowBtn" + label={ + isFollowing + ? _(msg`Unfollow Account`) + : _(msg`Follow Account`) + } + onPress={ + isFollowing + ? onPressUnfollowAccount + : onPressFollowAccount + }> + <Menu.ItemText> + {isFollowing ? ( + <Trans>Unfollow Account</Trans> + ) : ( + <Trans>Follow Account</Trans> + )} + </Menu.ItemText> + <Menu.ItemIcon icon={isFollowing ? UserMinus : Plus} /> + </Menu.Item> + )} + </> + )} <Menu.Item testID="profileHeaderDropdownListAddRemoveBtn" label={_(msg`Add to Lists`)} @@ -225,18 +269,6 @@ let ProfileMenu = ({ </Menu.Item> {!isSelf && ( <> - {profile.viewer?.following && - (profile.viewer.blocking || profile.viewer.blockedBy) && ( - <Menu.Item - testID="profileHeaderDropdownUnfollowBtn" - label={_(msg`Unfollow Account`)} - onPress={onPressUnfollowAccount}> - <Menu.ItemText> - <Trans>Unfollow Account</Trans> - </Menu.ItemText> - <Menu.ItemIcon icon={UserMinus} /> - </Menu.Item> - )} {!profile.viewer?.blocking && !profile.viewer?.mutedByList && ( <Menu.Item @@ -299,6 +331,11 @@ let ProfileMenu = ({ </Menu.Outer> </Menu.Root> + <ReportDialog + control={reportDialogControl} + params={{type: 'account', did: profile.did}} + /> + <Prompt.Basic control={blockPromptControl} title={ @@ -311,6 +348,10 @@ let ProfileMenu = ({ ? _( msg`The account will be able to interact with you after unblocking.`, ) + : profile.associated?.labeler + ? _( + msg`Blocking will not prevent labels from being applied on your account, but it will stop this account from replying in your threads or interacting with you.`, + ) : _( msg`Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you.`, ) diff --git a/src/view/com/util/Link.tsx b/src/view/com/util/Link.tsx index 7468111b5a..b6c512b09e 100644 --- a/src/view/com/util/Link.tsx +++ b/src/view/com/util/Link.tsx @@ -47,6 +47,7 @@ interface Props extends ComponentProps<typeof TouchableOpacity> { anchorNoUnderline?: boolean navigationAction?: 'push' | 'replace' | 'navigate' onPointerEnter?: () => void + onBeforePress?: () => void } export const Link = memo(function Link({ @@ -60,6 +61,7 @@ export const Link = memo(function Link({ accessible, anchorNoUnderline, navigationAction, + onBeforePress, ...props }: Props) { const t = useTheme() @@ -70,6 +72,7 @@ export const Link = memo(function Link({ const onPress = React.useCallback( (e?: Event) => { + onBeforePress?.() if (typeof href === 'string') { return onPressInner( closeModal, @@ -81,7 +84,7 @@ export const Link = memo(function Link({ ) } }, - [closeModal, navigation, navigationAction, href, openLink], + [closeModal, navigation, navigationAction, href, openLink, onBeforePress], ) if (noFeedback) { @@ -262,6 +265,7 @@ interface TextLinkOnWebOnlyProps extends TextProps { accessibilityHint?: string title?: string navigationAction?: 'push' | 'replace' | 'navigate' + disableMismatchWarning?: boolean onPointerEnter?: () => void } export const TextLinkOnWebOnly = memo(function DesktopWebTextLink({ @@ -273,6 +277,7 @@ export const TextLinkOnWebOnly = memo(function DesktopWebTextLink({ numberOfLines, lineHeight, navigationAction, + disableMismatchWarning, ...props }: TextLinkOnWebOnlyProps) { if (isWeb) { @@ -287,6 +292,7 @@ export const TextLinkOnWebOnly = memo(function DesktopWebTextLink({ lineHeight={lineHeight} title={props.title} navigationAction={navigationAction} + disableMismatchWarning={disableMismatchWarning} {...props} /> ) diff --git a/src/view/com/util/PostMeta.tsx b/src/view/com/util/PostMeta.tsx index 3795dcf136..53dc20e714 100644 --- a/src/view/com/util/PostMeta.tsx +++ b/src/view/com/util/PostMeta.tsx @@ -11,7 +11,7 @@ import {sanitizeHandle} from 'lib/strings/handles' import {isAndroid, isWeb} from 'platform/detection' import {TimeElapsed} from './TimeElapsed' import {makeProfileLink} from 'lib/routes/links' -import {ModerationUI} from '@atproto/api' +import {ModerationDecision, ModerationUI} from '@atproto/api' import {usePrefetchProfileQuery} from '#/state/queries/profile' interface PostMetaOpts { @@ -21,6 +21,7 @@ interface PostMetaOpts { handle: string displayName?: string | undefined } + moderation: ModerationDecision | undefined authorHasWarning: boolean postHref: string timestamp: string @@ -55,9 +56,14 @@ let PostMeta = (opts: PostMetaOpts): React.ReactNode => { style={[pal.text, opts.displayNameStyle]} numberOfLines={1} lineHeight={1.2} + disableMismatchWarning text={ <> - {sanitizeDisplayName(displayName)}  + {sanitizeDisplayName( + displayName, + opts.moderation?.ui('displayName'), + )} +   <Text type="md" numberOfLines={1} diff --git a/src/view/com/util/UserAvatar.tsx b/src/view/com/util/UserAvatar.tsx index 4132373974..39bc723032 100644 --- a/src/view/com/util/UserAvatar.tsx +++ b/src/view/com/util/UserAvatar.tsx @@ -24,9 +24,9 @@ import { } from '#/components/icons/Camera' import {StreamingLive_Stroke2_Corner0_Rounded as Library} from '#/components/icons/StreamingLive' import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash' -import {useTheme} from '#/alf' +import {useTheme, tokens} from '#/alf' -export type UserAvatarType = 'user' | 'algo' | 'list' +export type UserAvatarType = 'user' | 'algo' | 'list' | 'labeler' interface BaseUserAvatarProps { type?: UserAvatarType @@ -101,6 +101,29 @@ let DefaultAvatar = ({ </Svg> ) } + if (type === 'labeler') { + return ( + <Svg + testID="userAvatarFallback" + width={size} + height={size} + viewBox="0 0 32 32" + fill="none" + stroke="none"> + <Path + d="M28 0H4C1.79086 0 0 1.79086 0 4V28C0 30.2091 1.79086 32 4 32H28C30.2091 32 32 30.2091 32 28V4C32 1.79086 30.2091 0 28 0Z" + fill={tokens.color.temp_purple} + /> + <Path + d="M24 9.75L16 7L8 9.75V15.9123C8 20.8848 12 23 16 25.1579C20 23 24 20.8848 24 15.9123V9.75Z" + stroke="white" + strokeWidth="2" + strokeLinecap="square" + strokeLinejoin="round" + /> + </Svg> + ) + } return ( <Svg testID="userAvatarFallback" @@ -134,7 +157,7 @@ let UserAvatar = ({ const backgroundColor = pal.colors.backgroundLight const aviStyle = useMemo(() => { - if (type === 'algo' || type === 'list') { + if (type === 'algo' || type === 'list' || type === 'labeler') { return { width: size, height: size, diff --git a/src/view/com/util/UserBanner.tsx b/src/view/com/util/UserBanner.tsx index a5ddfee8ac..4fb3726cd7 100644 --- a/src/view/com/util/UserBanner.tsx +++ b/src/view/com/util/UserBanner.tsx @@ -7,7 +7,7 @@ import {msg, Trans} from '@lingui/macro' import {colors} from 'lib/styles' import {useTheme} from 'lib/ThemeContext' -import {useTheme as useAlfTheme} from '#/alf' +import {useTheme as useAlfTheme, tokens} from '#/alf' import {openCamera, openCropper, openPicker} from '../../../lib/media/picker' import { usePhotoLibraryPermission, @@ -26,10 +26,12 @@ import {StreamingLive_Stroke2_Corner0_Rounded as Library} from '#/components/ico import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash' export function UserBanner({ + type, banner, moderation, onSelectNewBanner, }: { + type?: 'labeler' | 'default' banner?: string | null moderation?: ModerationUI onSelectNewBanner?: (img: RNImage | null) => void @@ -167,7 +169,10 @@ export function UserBanner({ ) : ( <View testID="userBannerFallback" - style={[styles.bannerImage, styles.defaultBanner]} + style={[ + styles.bannerImage, + type === 'labeler' ? styles.labelerBanner : styles.defaultBanner, + ]} /> ) } @@ -191,4 +196,7 @@ const styles = StyleSheet.create({ defaultBanner: { backgroundColor: '#0070ff', }, + labelerBanner: { + backgroundColor: tokens.color.temp_purple, + }, }) diff --git a/src/view/com/util/forms/PostDropdownBtn.tsx b/src/view/com/util/forms/PostDropdownBtn.tsx index 8fc3d9ea62..70fbb907f7 100644 --- a/src/view/com/util/forms/PostDropdownBtn.tsx +++ b/src/view/com/util/forms/PostDropdownBtn.tsx @@ -16,7 +16,6 @@ import * as Toast from '../Toast' import {EventStopper} from '../EventStopper' import {useDialogControl} from '#/components/Dialog' import * as Prompt from '#/components/Prompt' -import {useModalControls} from '#/state/modals' import {makeProfileLink} from '#/lib/routes/links' import {CommonNavigatorParams} from '#/lib/routes/types' import {getCurrentRoute} from 'lib/routes/helpers' @@ -33,6 +32,7 @@ import {useSession} from '#/state/session' import {isWeb} from '#/platform/detection' import {richTextToString} from '#/lib/strings/rich-text-helpers' import {useGlobalDialogsControlContext} from '#/components/dialogs/Context' +import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog' import {atoms as a, useTheme as useAlf} from '#/alf' import * as Menu from '#/components/Menu' @@ -45,7 +45,6 @@ import {SpeakerVolumeFull_Stroke2_Corner0_Rounded as Unmute} from '#/components/ import {BubbleQuestion_Stroke2_Corner0_Rounded as Translate} from '#/components/icons/Bubble' import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning' import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash' -import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' let PostDropdownBtn = ({ testID, @@ -55,7 +54,6 @@ let PostDropdownBtn = ({ record, richText, style, - showAppealLabelItem, hitSlop, }: { testID: string @@ -65,7 +63,6 @@ let PostDropdownBtn = ({ record: AppBskyFeedPost.Record richText: RichTextAPI style?: StyleProp<ViewStyle> - showAppealLabelItem?: boolean hitSlop?: PressableProps['hitSlop'] }): React.ReactNode => { const {hasSession, currentAccount} = useSession() @@ -73,7 +70,6 @@ let PostDropdownBtn = ({ const alf = useAlf() const {_} = useLingui() const defaultCtrlColor = theme.palette.default.postCtrl - const {openModal} = useModalControls() const langPrefs = useLanguagePrefs() const mutedThreads = useMutedThreads() const toggleThreadMute = useToggleThreadMute() @@ -83,6 +79,7 @@ let PostDropdownBtn = ({ const openLink = useOpenLink() const navigation = useNavigation() const {mutedWordsDialogControl} = useGlobalDialogsControlContext() + const reportDialogControl = useReportDialogControl() const deletePromptControl = useDialogControl() const hidePromptControl = useDialogControl() const loggedOutWarningPromptControl = useDialogControl() @@ -293,13 +290,7 @@ let PostDropdownBtn = ({ <Menu.Item testID="postDropdownReportBtn" label={_(msg`Report post`)} - onPress={() => { - openModal({ - name: 'report', - uri: postUri, - cid: postCid, - }) - }}> + onPress={() => reportDialogControl.open()}> <Menu.ItemText>{_(msg`Report post`)}</Menu.ItemText> <Menu.ItemIcon icon={Warning} position="right" /> </Menu.Item> @@ -314,28 +305,6 @@ let PostDropdownBtn = ({ <Menu.ItemIcon icon={Trash} position="right" /> </Menu.Item> )} - - {showAppealLabelItem && ( - <> - <Menu.Divider /> - - <Menu.Item - testID="postDropdownAppealBtn" - label={_(msg`Appeal content warning`)} - onPress={() => { - openModal({ - name: 'appeal-label', - uri: postUri, - cid: postCid, - }) - }}> - <Menu.ItemText> - {_(msg`Appeal content warning`)} - </Menu.ItemText> - <Menu.ItemIcon icon={CircleInfo} position="right" /> - </Menu.Item> - </> - )} </Menu.Group> </Menu.Outer> </Menu.Root> @@ -359,6 +328,15 @@ let PostDropdownBtn = ({ confirmButtonCta={_(msg`Hide`)} /> + <ReportDialog + control={reportDialogControl} + params={{ + type: 'post', + uri: postUri, + cid: postCid, + }} + /> + <Prompt.Basic control={loggedOutWarningPromptControl} title={_(msg`Note about sharing`)} diff --git a/src/view/com/util/moderation/ContentHider.tsx b/src/view/com/util/moderation/ContentHider.tsx deleted file mode 100644 index cd25452904..0000000000 --- a/src/view/com/util/moderation/ContentHider.tsx +++ /dev/null @@ -1,145 +0,0 @@ -import React from 'react' -import {Pressable, StyleProp, StyleSheet, View, ViewStyle} from 'react-native' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {usePalette} from 'lib/hooks/usePalette' -import {ModerationUI, PostModeration} from '@atproto/api' -import {Text} from '../text/Text' -import {ShieldExclamation} from 'lib/icons' -import {describeModerationCause} from 'lib/moderation' -import {useLingui} from '@lingui/react' -import {msg, Trans} from '@lingui/macro' -import {useModalControls} from '#/state/modals' -import {isPostMediaBlurred} from 'lib/moderation' - -export function ContentHider({ - testID, - moderation, - moderationDecisions, - ignoreMute, - ignoreQuoteDecisions, - style, - childContainerStyle, - children, -}: React.PropsWithChildren<{ - testID?: string - moderation: ModerationUI - moderationDecisions?: PostModeration['decisions'] - ignoreMute?: boolean - ignoreQuoteDecisions?: boolean - style?: StyleProp<ViewStyle> - childContainerStyle?: StyleProp<ViewStyle> -}>) { - const pal = usePalette('default') - const {_} = useLingui() - const [override, setOverride] = React.useState(false) - const {openModal} = useModalControls() - - if ( - !moderation.blur || - (ignoreMute && moderation.cause?.type === 'muted') || - shouldIgnoreQuote(moderationDecisions, ignoreQuoteDecisions) - ) { - return ( - <View testID={testID} style={[styles.outer, style]}> - {children} - </View> - ) - } - - const isMute = ['muted', 'muted-word'].includes(moderation.cause?.type || '') - const desc = describeModerationCause(moderation.cause, 'content') - return ( - <View testID={testID} style={[styles.outer, style]}> - <Pressable - onPress={() => { - if (!moderation.noOverride) { - setOverride(v => !v) - } else { - openModal({ - name: 'moderation-details', - context: 'content', - moderation, - }) - } - }} - accessibilityRole="button" - accessibilityHint={ - override ? _(msg`Hide the content`) : _(msg`Show the content`) - } - accessibilityLabel="" - style={[ - styles.cover, - moderation.noOverride - ? {borderWidth: 1, borderColor: pal.colors.borderDark} - : pal.viewLight, - ]}> - <Pressable - onPress={() => { - openModal({ - name: 'moderation-details', - context: 'content', - moderation, - }) - }} - accessibilityRole="button" - accessibilityLabel={_(msg`Learn more about this warning`)} - accessibilityHint=""> - {isMute ? ( - <FontAwesomeIcon - icon={['far', 'eye-slash']} - size={18} - color={pal.colors.textLight} - /> - ) : ( - <ShieldExclamation size={18} style={pal.textLight} /> - )} - </Pressable> - <Text type="md" style={[pal.text, {flex: 1}]} numberOfLines={2}> - {desc.name} - </Text> - <View style={styles.showBtn}> - <Text type="lg" style={pal.link}> - {moderation.noOverride ? ( - <Trans>Learn more</Trans> - ) : override ? ( - <Trans>Hide</Trans> - ) : ( - <Trans>Show</Trans> - )} - </Text> - </View> - </Pressable> - {override && <View style={childContainerStyle}>{children}</View>} - </View> - ) -} - -function shouldIgnoreQuote( - decisions: PostModeration['decisions'] | undefined, - ignore: boolean | undefined, -): boolean { - if (!decisions || !ignore) { - return false - } - return !isPostMediaBlurred(decisions) -} - -const styles = StyleSheet.create({ - outer: { - overflow: 'hidden', - }, - cover: { - flexDirection: 'row', - alignItems: 'center', - gap: 6, - borderRadius: 8, - marginTop: 4, - paddingVertical: 14, - paddingLeft: 14, - paddingRight: 18, - }, - showBtn: { - marginLeft: 'auto', - alignSelf: 'center', - }, -}) diff --git a/src/view/com/util/moderation/LabelInfo.tsx b/src/view/com/util/moderation/LabelInfo.tsx deleted file mode 100644 index 970338752c..0000000000 --- a/src/view/com/util/moderation/LabelInfo.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import React from 'react' -import {Pressable, StyleProp, View, ViewStyle} from 'react-native' -import {ComAtprotoLabelDefs} from '@atproto/api' -import {Text} from '../text/Text' -import {usePalette} from 'lib/hooks/usePalette' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' -import {useModalControls} from '#/state/modals' - -export function LabelInfo({ - details, - labels, - style, -}: { - details: {did: string} | {uri: string; cid: string} - labels: ComAtprotoLabelDefs.Label[] | undefined - style?: StyleProp<ViewStyle> -}) { - const pal = usePalette('default') - const {_} = useLingui() - const {openModal} = useModalControls() - - if (!labels) { - return null - } - labels = labels.filter(l => !l.val.startsWith('!')) - if (!labels.length) { - return null - } - - return ( - <View - style={[ - pal.viewLight, - { - flexDirection: 'row', - flexWrap: 'wrap', - paddingHorizontal: 12, - paddingVertical: 10, - borderRadius: 8, - }, - style, - ]}> - <Text type="sm" style={pal.text}> - <Trans> - A content warning has been applied to this{' '} - {'did' in details ? 'account' : 'post'}. - </Trans>{' '} - </Text> - <Pressable - accessibilityRole="button" - accessibilityLabel={_(msg`Appeal this decision`)} - accessibilityHint="" - onPress={() => openModal({name: 'appeal-label', ...details})}> - <Text type="sm" style={pal.link}> - <Trans>Appeal this decision.</Trans> - </Text> - </Pressable> - </View> - ) -} diff --git a/src/view/com/util/moderation/PostAlerts.tsx b/src/view/com/util/moderation/PostAlerts.tsx deleted file mode 100644 index bc5bf9b325..0000000000 --- a/src/view/com/util/moderation/PostAlerts.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import React from 'react' -import {Pressable, StyleProp, StyleSheet, ViewStyle} from 'react-native' -import {ModerationUI} from '@atproto/api' -import {Text} from '../text/Text' -import {usePalette} from 'lib/hooks/usePalette' -import {ShieldExclamation} from 'lib/icons' -import {describeModerationCause} from 'lib/moderation' -import {Trans, msg} from '@lingui/macro' -import {useLingui} from '@lingui/react' -import {useModalControls} from '#/state/modals' - -export function PostAlerts({ - moderation, - style, -}: { - moderation: ModerationUI - includeMute?: boolean - style?: StyleProp<ViewStyle> -}) { - const pal = usePalette('default') - const {_} = useLingui() - const {openModal} = useModalControls() - - const shouldAlert = !!moderation.cause && moderation.alert - if (!shouldAlert) { - return null - } - - const desc = describeModerationCause(moderation.cause, 'content') - return ( - <Pressable - onPress={() => { - openModal({ - name: 'moderation-details', - context: 'content', - moderation, - }) - }} - accessibilityRole="button" - accessibilityLabel={_(msg`Learn more about this warning`)} - accessibilityHint="" - style={[styles.container, pal.viewLight, style]}> - <ShieldExclamation style={pal.text} size={16} /> - <Text type="lg" style={[pal.text]}> - {desc.name}{' '} - <Text type="lg" style={[pal.link, styles.learnMoreBtn]}> - <Trans>Learn More</Trans> - </Text> - </Text> - </Pressable> - ) -} - -const styles = StyleSheet.create({ - container: { - flexDirection: 'row', - alignItems: 'center', - gap: 4, - paddingVertical: 8, - paddingLeft: 14, - paddingHorizontal: 16, - borderRadius: 8, - }, - learnMoreBtn: { - marginLeft: 'auto', - }, -}) diff --git a/src/view/com/util/moderation/ProfileHeaderAlerts.tsx b/src/view/com/util/moderation/ProfileHeaderAlerts.tsx deleted file mode 100644 index 0f07b679ba..0000000000 --- a/src/view/com/util/moderation/ProfileHeaderAlerts.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import React from 'react' -import {Pressable, StyleProp, StyleSheet, View, ViewStyle} from 'react-native' -import {ProfileModeration} from '@atproto/api' -import {Text} from '../text/Text' -import {usePalette} from 'lib/hooks/usePalette' -import {ShieldExclamation} from 'lib/icons' -import { - describeModerationCause, - getProfileModerationCauses, -} from 'lib/moderation' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {useModalControls} from '#/state/modals' - -export function ProfileHeaderAlerts({ - moderation, - style, -}: { - moderation: ProfileModeration - style?: StyleProp<ViewStyle> -}) { - const pal = usePalette('default') - const {_} = useLingui() - const {openModal} = useModalControls() - - const causes = getProfileModerationCauses(moderation) - if (!causes.length) { - return null - } - - return ( - <View style={styles.grid}> - {causes.map(cause => { - const isMute = cause.type === 'muted' - const desc = describeModerationCause(cause, 'account') - return ( - <Pressable - testID="profileHeaderAlert" - key={desc.name} - onPress={() => { - openModal({ - name: 'moderation-details', - context: 'content', - moderation: {cause}, - }) - }} - accessibilityRole="button" - accessibilityLabel={_(msg`Learn more about this warning`)} - accessibilityHint="" - style={[styles.container, pal.viewLight, style]}> - {isMute ? ( - <FontAwesomeIcon - icon={['far', 'eye-slash']} - size={14} - color={pal.colors.textLight} - /> - ) : ( - <ShieldExclamation style={pal.text} size={18} /> - )} - <Text type="sm" style={[{flex: 1}, pal.text]}> - {desc.name} - </Text> - <Text type="sm" style={[pal.link, styles.learnMoreBtn]}> - <Trans>Learn More</Trans> - </Text> - </Pressable> - ) - })} - </View> - ) -} - -const styles = StyleSheet.create({ - grid: { - gap: 4, - }, - container: { - flexDirection: 'row', - alignItems: 'center', - gap: 8, - paddingVertical: 12, - paddingHorizontal: 16, - borderRadius: 8, - }, - learnMoreBtn: { - marginLeft: 'auto', - }, -}) diff --git a/src/view/com/util/moderation/ScreenHider.tsx b/src/view/com/util/moderation/ScreenHider.tsx deleted file mode 100644 index 86f0cbf7bf..0000000000 --- a/src/view/com/util/moderation/ScreenHider.tsx +++ /dev/null @@ -1,180 +0,0 @@ -import React from 'react' -import { - TouchableWithoutFeedback, - StyleProp, - StyleSheet, - View, - ViewStyle, -} from 'react-native' -import { - FontAwesomeIcon, - FontAwesomeIconStyle, -} from '@fortawesome/react-native-fontawesome' -import {useNavigation} from '@react-navigation/native' -import {ModerationUI} from '@atproto/api' -import {usePalette} from 'lib/hooks/usePalette' -import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {NavigationProp} from 'lib/routes/types' -import {Text} from '../text/Text' -import {Button} from '../forms/Button' -import {describeModerationCause} from 'lib/moderation' -import {Trans, msg} from '@lingui/macro' -import {useLingui} from '@lingui/react' -import {useModalControls} from '#/state/modals' -import {s} from '#/lib/styles' -import {CenteredView} from '../Views' - -export function ScreenHider({ - testID, - screenDescription, - moderation, - style, - containerStyle, - children, -}: React.PropsWithChildren<{ - testID?: string - screenDescription: string - moderation: ModerationUI - style?: StyleProp<ViewStyle> - containerStyle?: StyleProp<ViewStyle> -}>) { - const pal = usePalette('default') - const palInverted = usePalette('inverted') - const {_} = useLingui() - const [override, setOverride] = React.useState(false) - const navigation = useNavigation<NavigationProp>() - const {isMobile} = useWebMediaQueries() - const {openModal} = useModalControls() - - if (!moderation.blur || override) { - return ( - <View testID={testID} style={style}> - {children} - </View> - ) - } - - const isNoPwi = - moderation.cause?.type === 'label' && - moderation.cause?.labelDef.id === '!no-unauthenticated' - const desc = describeModerationCause(moderation.cause, 'account') - return ( - <CenteredView - style={[styles.container, pal.view, containerStyle]} - sideBorders> - <View style={styles.iconContainer}> - <View style={[styles.icon, palInverted.view]}> - <FontAwesomeIcon - icon={isNoPwi ? ['far', 'eye-slash'] : 'exclamation'} - style={pal.textInverted as FontAwesomeIconStyle} - size={24} - /> - </View> - </View> - <Text type="title-2xl" style={[styles.title, pal.text]}> - {isNoPwi ? ( - <Trans>Sign-in Required</Trans> - ) : ( - <Trans>Content Warning</Trans> - )} - </Text> - <Text type="2xl" style={[styles.description, pal.textLight]}> - {isNoPwi ? ( - <Trans> - This account has requested that users sign in to view their profile. - </Trans> - ) : ( - <> - <Trans>This {screenDescription} has been flagged:</Trans> - <Text type="2xl-medium" style={[pal.text, s.ml5]}> - {desc.name}. - </Text> - <TouchableWithoutFeedback - onPress={() => { - openModal({ - name: 'moderation-details', - context: 'account', - moderation, - }) - }} - accessibilityRole="button" - accessibilityLabel={_(msg`Learn more about this warning`)} - accessibilityHint=""> - <Text type="2xl" style={pal.link}> - <Trans>Learn More</Trans> - </Text> - </TouchableWithoutFeedback> - </> - )}{' '} - </Text> - {isMobile && <View style={styles.spacer} />} - <View style={styles.btnContainer}> - <Button - type="inverted" - onPress={() => { - if (navigation.canGoBack()) { - navigation.goBack() - } else { - navigation.navigate('Home') - } - }} - style={styles.btn}> - <Text type="button-lg" style={pal.textInverted}> - <Trans>Go back</Trans> - </Text> - </Button> - {!moderation.noOverride && ( - <Button - type="default" - onPress={() => setOverride(v => !v)} - style={styles.btn}> - <Text type="button-lg" style={pal.text}> - <Trans>Show anyway</Trans> - </Text> - </Button> - )} - </View> - </CenteredView> - ) -} - -const styles = StyleSheet.create({ - spacer: { - flex: 1, - }, - container: { - flex: 1, - paddingTop: 100, - paddingBottom: 150, - }, - iconContainer: { - alignItems: 'center', - marginBottom: 10, - }, - icon: { - borderRadius: 25, - width: 50, - height: 50, - alignItems: 'center', - justifyContent: 'center', - }, - title: { - textAlign: 'center', - marginBottom: 10, - }, - description: { - marginBottom: 10, - paddingHorizontal: 20, - textAlign: 'center', - }, - btnContainer: { - flexDirection: 'row', - justifyContent: 'center', - marginVertical: 10, - gap: 10, - }, - btn: { - paddingHorizontal: 20, - paddingVertical: 14, - }, -}) diff --git a/src/view/com/util/post-ctrls/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx index c96954a114..3fa347a6d8 100644 --- a/src/view/com/util/post-ctrls/PostCtrls.tsx +++ b/src/view/com/util/post-ctrls/PostCtrls.tsx @@ -41,7 +41,6 @@ let PostCtrls = ({ post, record, richText, - showAppealLabelItem, style, onPressReply, logContext, @@ -50,7 +49,6 @@ let PostCtrls = ({ post: Shadow<AppBskyFeedDefs.PostView> record: AppBskyFeedPost.Record richText: RichTextAPI - showAppealLabelItem?: boolean style?: StyleProp<ViewStyle> onPressReply: () => void logContext: 'FeedItem' | 'PostThreadItem' | 'Post' @@ -232,7 +230,6 @@ let PostCtrls = ({ postUri={post.uri} record={record} richText={richText} - showAppealLabelItem={showAppealLabelItem} style={styles.btnPad} hitSlop={big ? HITSLOP_20 : HITSLOP_10} /> diff --git a/src/view/com/util/post-embeds/QuoteEmbed.tsx b/src/view/com/util/post-embeds/QuoteEmbed.tsx index 35b0912698..2b1c3e6179 100644 --- a/src/view/com/util/post-embeds/QuoteEmbed.tsx +++ b/src/view/com/util/post-embeds/QuoteEmbed.tsx @@ -1,13 +1,15 @@ import React from 'react' import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native' import { + AppBskyFeedDefs, AppBskyEmbedRecord, AppBskyFeedPost, AppBskyEmbedImages, AppBskyEmbedRecordWithMedia, - ModerationUI, AppBskyEmbedExternal, RichText as RichTextAPI, + moderatePost, + ModerationDecision, } from '@atproto/api' import {AtUri} from '@atproto/api' import {PostMeta} from '../PostMeta' @@ -16,20 +18,20 @@ import {Text} from '../text/Text' import {usePalette} from 'lib/hooks/usePalette' import {ComposerOptsQuote} from 'state/shell/composer' import {PostEmbeds} from '.' -import {PostAlerts} from '../moderation/PostAlerts' +import {PostAlerts} from '../../../../components/moderation/PostAlerts' import {makeProfileLink} from 'lib/routes/links' import {InfoCircleIcon} from 'lib/icons' import {Trans} from '@lingui/macro' +import {useModerationOpts} from '#/state/queries/preferences' +import {ContentHider} from '../../../../components/moderation/ContentHider' import {RichText} from '#/components/RichText' import {atoms as a} from '#/alf' export function MaybeQuoteEmbed({ embed, - moderation, style, }: { embed: AppBskyEmbedRecord.View - moderation: ModerationUI style?: StyleProp<ViewStyle> }) { const pal = usePalette('default') @@ -39,17 +41,9 @@ export function MaybeQuoteEmbed({ AppBskyFeedPost.validateRecord(embed.record.value).success ) { return ( - <QuoteEmbed - quote={{ - author: embed.record.author, - cid: embed.record.cid, - uri: embed.record.uri, - indexedAt: embed.record.indexedAt, - text: embed.record.value.text, - facets: embed.record.value.facets, - embeds: embed.record.embeds, - }} - moderation={moderation} + <QuoteEmbedModerated + viewRecord={embed.record} + postRecord={embed.record.value} style={style} /> ) @@ -75,19 +69,49 @@ export function MaybeQuoteEmbed({ return null } +function QuoteEmbedModerated({ + viewRecord, + postRecord, + style, +}: { + viewRecord: AppBskyEmbedRecord.ViewRecord + postRecord: AppBskyFeedPost.Record + style?: StyleProp<ViewStyle> +}) { + const moderationOpts = useModerationOpts() + const moderation = React.useMemo(() => { + return moderationOpts + ? moderatePost(viewRecordToPostView(viewRecord), moderationOpts) + : undefined + }, [viewRecord, moderationOpts]) + + const quote = { + author: viewRecord.author, + cid: viewRecord.cid, + uri: viewRecord.uri, + indexedAt: viewRecord.indexedAt, + text: postRecord.text, + facets: postRecord.facets, + embeds: viewRecord.embeds, + } + + return <QuoteEmbed quote={quote} moderation={moderation} style={style} /> +} + export function QuoteEmbed({ quote, moderation, style, }: { quote: ComposerOptsQuote - moderation?: ModerationUI + moderation?: ModerationDecision style?: StyleProp<ViewStyle> }) { const pal = usePalette('default') const itemUrip = new AtUri(quote.uri) const itemHref = makeProfileLink(quote.author, 'post', itemUrip.rkey) const itemTitle = `Post by ${quote.author.handle}` + const richText = React.useMemo( () => quote.text.trim() @@ -95,6 +119,7 @@ export function QuoteEmbed({ : undefined, [quote.text, quote.facets], ) + const embed = React.useMemo(() => { const e = quote.embeds?.[0] @@ -108,40 +133,52 @@ export function QuoteEmbed({ return e.media } }, [quote.embeds]) + return ( - <Link - style={[styles.container, pal.borderDark, style]} - hoverStyle={{borderColor: pal.colors.borderLinkHover}} - href={itemHref} - title={itemTitle}> - <View pointerEvents="none"> - <PostMeta - author={quote.author} - showAvatar - authorHasWarning={false} - postHref={itemHref} - timestamp={quote.indexedAt} - /> - </View> - {moderation ? ( - <PostAlerts moderation={moderation} style={styles.alert} /> - ) : null} - {richText ? ( - <RichText - enableTags - value={richText} - style={[a.text_md]} - numberOfLines={20} - disableLinks - authorHandle={quote.author.handle} - /> - ) : null} - {embed && <PostEmbeds embed={embed} moderation={{}} />} - </Link> + <ContentHider modui={moderation?.ui('contentList')}> + <Link + style={[styles.container, pal.borderDark, style]} + hoverStyle={{borderColor: pal.colors.borderLinkHover}} + href={itemHref} + title={itemTitle}> + <View pointerEvents="none"> + <PostMeta + author={quote.author} + moderation={moderation} + showAvatar + authorHasWarning={false} + postHref={itemHref} + timestamp={quote.indexedAt} + /> + </View> + {moderation ? ( + <PostAlerts modui={moderation.ui('contentView')} style={[a.py_xs]} /> + ) : null} + {richText ? ( + <RichText + value={richText} + style={[a.text_md]} + numberOfLines={20} + disableLinks + /> + ) : null} + {embed && <PostEmbeds embed={embed} moderation={moderation} />} + </Link> + </ContentHider> ) } -export default QuoteEmbed +function viewRecordToPostView( + viewRecord: AppBskyEmbedRecord.ViewRecord, +): AppBskyFeedDefs.PostView { + const {value, embeds, ...rest} = viewRecord + return { + ...rest, + $type: 'app.bsky.feed.defs#postView', + record: value, + embed: embeds?.[0], + } +} const styles = StyleSheet.create({ container: { diff --git a/src/view/com/util/post-embeds/index.tsx b/src/view/com/util/post-embeds/index.tsx index 7e235babb6..47091fbb07 100644 --- a/src/view/com/util/post-embeds/index.tsx +++ b/src/view/com/util/post-embeds/index.tsx @@ -15,8 +15,7 @@ import { AppBskyEmbedRecordWithMedia, AppBskyFeedDefs, AppBskyGraphDefs, - ModerationUI, - PostModeration, + ModerationDecision, } from '@atproto/api' import {Link} from '../Link' import {ImageLayoutGrid} from '../images/ImageLayoutGrid' @@ -26,9 +25,8 @@ import {ExternalLinkEmbed} from './ExternalLinkEmbed' import {MaybeQuoteEmbed} from './QuoteEmbed' import {AutoSizedImage} from '../images/AutoSizedImage' import {ListEmbed} from './ListEmbed' -import {isCauseALabelOnUri, isQuoteBlurred} from 'lib/moderation' import {FeedSourceCard} from 'view/com/feeds/FeedSourceCard' -import {ContentHider} from '../moderation/ContentHider' +import {ContentHider} from '../../../../components/moderation/ContentHider' import {isNative} from '#/platform/detection' import {shareUrl} from '#/lib/sharing' @@ -42,12 +40,10 @@ type Embed = export function PostEmbeds({ embed, moderation, - moderationDecisions, style, }: { embed?: Embed - moderation: ModerationUI - moderationDecisions?: PostModeration['decisions'] + moderation?: ModerationDecision style?: StyleProp<ViewStyle> }) { const pal = usePalette('default') @@ -66,18 +62,10 @@ export function PostEmbeds({ // quote post with media // = if (AppBskyEmbedRecordWithMedia.isView(embed)) { - const isModOnQuote = - (AppBskyEmbedRecord.isViewRecord(embed.record.record) && - isCauseALabelOnUri(moderation.cause, embed.record.record.uri)) || - (moderationDecisions && isQuoteBlurred(moderationDecisions)) - const mediaModeration = isModOnQuote ? {} : moderation - const quoteModeration = isModOnQuote ? moderation : {} return ( <View style={style}> - <PostEmbeds embed={embed.media} moderation={mediaModeration} /> - <ContentHider moderation={quoteModeration}> - <MaybeQuoteEmbed embed={embed.record} moderation={quoteModeration} /> - </ContentHider> + <PostEmbeds embed={embed.media} moderation={moderation} /> + <MaybeQuoteEmbed embed={embed.record} /> </View> ) } @@ -86,6 +74,7 @@ export function PostEmbeds({ // custom feed embed (i.e. generator view) // = if (AppBskyFeedDefs.isGeneratorView(embed.record)) { + // TODO moderation return ( <FeedSourceCard feedUri={embed.record.uri} @@ -97,16 +86,13 @@ export function PostEmbeds({ // list embed if (AppBskyGraphDefs.isListView(embed.record)) { + // TODO moderation return <ListEmbed item={embed.record} /> } // quote post // = - return ( - <ContentHider moderation={moderation}> - <MaybeQuoteEmbed embed={embed} style={style} moderation={moderation} /> - </ContentHider> - ) + return <MaybeQuoteEmbed embed={embed} style={style} /> } // image embed @@ -132,35 +118,41 @@ export function PostEmbeds({ if (images.length === 1) { const {alt, thumb, aspectRatio} = images[0] return ( - <View style={[styles.imagesContainer, style]}> - <AutoSizedImage - alt={alt} - uri={thumb} - dimensionsHint={aspectRatio} - onPress={() => _openLightbox(0)} - onPressIn={() => onPressIn(0)} - style={[styles.singleImage]}> - {alt === '' ? null : ( - <View style={styles.altContainer}> - <Text style={styles.alt} accessible={false}> - ALT - </Text> - </View> - )} - </AutoSizedImage> - </View> + <ContentHider modui={moderation?.ui('contentMedia')}> + <View style={[styles.imagesContainer, style]}> + <AutoSizedImage + alt={alt} + uri={thumb} + dimensionsHint={aspectRatio} + onPress={() => _openLightbox(0)} + onPressIn={() => onPressIn(0)} + style={[styles.singleImage]}> + {alt === '' ? null : ( + <View style={styles.altContainer}> + <Text style={styles.alt} accessible={false}> + ALT + </Text> + </View> + )} + </AutoSizedImage> + </View> + </ContentHider> ) } return ( - <View style={[styles.imagesContainer, style]}> - <ImageLayoutGrid - images={embed.images} - onPress={_openLightbox} - onPressIn={onPressIn} - style={embed.images.length === 1 ? [styles.singleImage] : undefined} - /> - </View> + <ContentHider modui={moderation?.ui('contentMedia')}> + <View style={[styles.imagesContainer, style]}> + <ImageLayoutGrid + images={embed.images} + onPress={_openLightbox} + onPressIn={onPressIn} + style={ + embed.images.length === 1 ? [styles.singleImage] : undefined + } + /> + </View> + </ContentHider> ) } } @@ -171,15 +163,17 @@ export function PostEmbeds({ const link = embed.external return ( - <Link - asAnchor - anchorNoUnderline - href={link.uri} - style={[styles.extOuter, pal.view, pal.borderDark, style]} - hoverStyle={{borderColor: pal.colors.borderLinkHover}} - onLongPress={onShareExternal}> - <ExternalLinkEmbed link={link} /> - </Link> + <ContentHider modui={moderation?.ui('contentMedia')}> + <Link + asAnchor + anchorNoUnderline + href={link.uri} + style={[styles.extOuter, pal.view, pal.borderDark, style]} + hoverStyle={{borderColor: pal.colors.borderLinkHover}} + onLongPress={onShareExternal}> + <ExternalLinkEmbed link={link} /> + </Link> + </ContentHider> ) } diff --git a/src/view/screens/DebugMod.tsx b/src/view/screens/DebugMod.tsx new file mode 100644 index 0000000000..64f2376a43 --- /dev/null +++ b/src/view/screens/DebugMod.tsx @@ -0,0 +1,923 @@ +import React from 'react' +import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types' +import {View} from 'react-native' +import { + LABELS, + mock, + moderatePost, + moderateProfile, + ModerationOpts, + AppBskyActorDefs, + AppBskyFeedDefs, + AppBskyFeedPost, + LabelPreference, + ModerationDecision, + ModerationBehavior, + RichText, + ComAtprotoLabelDefs, + interpretLabelValueDefinition, +} from '@atproto/api' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {moderationOptsOverrideContext} from '#/state/queries/preferences' +import {useSession} from '#/state/session' +import {FeedNotification} from '#/state/queries/notifications/types' +import { + groupNotifications, + shouldFilterNotif, +} from '#/state/queries/notifications/util' + +import {atoms as a, useTheme} from '#/alf' +import {CenteredView, ScrollView} from '#/view/com/util/Views' +import {H1, H3, P, Text} from '#/components/Typography' +import {useGlobalLabelStrings} from '#/lib/moderation/useGlobalLabelStrings' +import * as Toggle from '#/components/forms/Toggle' +import * as ToggleButton from '#/components/forms/ToggleButton' +import {Button, ButtonIcon, ButtonText} from '#/components/Button' +import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check' +import { + ChevronBottom_Stroke2_Corner0_Rounded as ChevronBottom, + ChevronTop_Stroke2_Corner0_Rounded as ChevronTop, +} from '#/components/icons/Chevron' +import {ScreenHider} from '../../components/moderation/ScreenHider' +import {ProfileHeaderStandard} from '#/screens/Profile/Header/ProfileHeaderStandard' +import {ProfileCard} from '../com/profile/ProfileCard' +import {FeedItem} from '../com/posts/FeedItem' +import {FeedItem as NotifFeedItem} from '../com/notifications/FeedItem' +import {PostThreadItem} from '../com/post-thread/PostThreadItem' +import {Divider} from '#/components/Divider' + +const LABEL_VALUES: (keyof typeof LABELS)[] = Object.keys( + LABELS, +) as (keyof typeof LABELS)[] + +export const DebugModScreen = ({}: NativeStackScreenProps< + CommonNavigatorParams, + 'DebugMod' +>) => { + const t = useTheme() + const [scenario, setScenario] = React.useState<string[]>(['label']) + const [scenarioSwitches, setScenarioSwitches] = React.useState<string[]>([]) + const [label, setLabel] = React.useState<string[]>([LABEL_VALUES[0]]) + const [target, setTarget] = React.useState<string[]>(['account']) + const [visibility, setVisiblity] = React.useState<string[]>(['warn']) + const [customLabelDef, setCustomLabelDef] = + React.useState<ComAtprotoLabelDefs.LabelValueDefinition>({ + identifier: 'custom', + blurs: 'content', + severity: 'alert', + defaultSetting: 'warn', + locales: [ + { + lang: 'en', + name: 'Custom label', + description: 'A custom label created in this test environment', + }, + ], + }) + const [view, setView] = React.useState<string[]>(['post']) + const labelStrings = useGlobalLabelStrings() + const {currentAccount} = useSession() + + const isTargetMe = + scenario[0] === 'label' && scenarioSwitches.includes('targetMe') + const isSelfLabel = + scenario[0] === 'label' && scenarioSwitches.includes('selfLabel') + const noAdult = + scenario[0] === 'label' && scenarioSwitches.includes('noAdult') + const isLoggedOut = + scenario[0] === 'label' && scenarioSwitches.includes('loggedOut') + const isFollowing = scenarioSwitches.includes('following') + + const did = + isTargetMe && currentAccount ? currentAccount.did : 'did:web:bob.test' + + const profile = React.useMemo(() => { + const mockedProfile = mock.profileViewBasic({ + handle: `bob.test`, + displayName: 'Bob Robertson', + description: 'User with this as their bio', + labels: + scenario[0] === 'label' && target[0] === 'account' + ? [ + mock.label({ + src: isSelfLabel ? did : undefined, + val: label[0], + uri: `at://${did}/`, + }), + ] + : scenario[0] === 'label' && target[0] === 'profile' + ? [ + mock.label({ + src: isSelfLabel ? did : undefined, + val: label[0], + uri: `at://${did}/app.bsky.actor.profile/self`, + }), + ] + : undefined, + viewer: mock.actorViewerState({ + following: isFollowing + ? `at://${currentAccount?.did || ''}/app.bsky.graph.follow/1234` + : undefined, + muted: scenario[0] === 'mute', + mutedByList: undefined, + blockedBy: undefined, + blocking: + scenario[0] === 'block' + ? `at://did:web:alice.test/app.bsky.actor.block/fake` + : undefined, + blockingByList: undefined, + }), + }) + mockedProfile.did = did + mockedProfile.avatar = 'https://bsky.social/about/images/favicon-32x32.png' + mockedProfile.banner = + 'https://bsky.social/about/images/social-card-default-gradient.png' + return mockedProfile + }, [scenario, target, label, isSelfLabel, did, isFollowing, currentAccount]) + + const post = React.useMemo(() => { + return mock.postView({ + record: mock.post({ + text: "This is the body of the post. It's where the text goes. You get the idea.", + }), + author: profile, + labels: + scenario[0] === 'label' && target[0] === 'post' + ? [ + mock.label({ + src: isSelfLabel ? did : undefined, + val: label[0], + uri: `at://${did}/app.bsky.feed.post/fake`, + }), + ] + : undefined, + embed: + target[0] === 'embed' + ? mock.embedRecordView({ + record: mock.post({ + text: 'Embed', + }), + labels: + scenario[0] === 'label' && target[0] === 'embed' + ? [ + mock.label({ + src: isSelfLabel ? did : undefined, + val: label[0], + uri: `at://${did}/app.bsky.feed.post/fake`, + }), + ] + : undefined, + author: profile, + }) + : { + $type: 'app.bsky.embed.images#view', + images: [ + { + thumb: + 'https://bsky.social/about/images/social-card-default-gradient.png', + fullsize: + 'https://bsky.social/about/images/social-card-default-gradient.png', + alt: '', + }, + ], + }, + }) + }, [scenario, label, target, profile, isSelfLabel, did]) + + const replyNotif = React.useMemo(() => { + const notif = mock.replyNotification({ + record: mock.post({ + text: "This is the body of the post. It's where the text goes. You get the idea.", + reply: { + parent: { + uri: `at://${did}/app.bsky.feed.post/fake-parent`, + cid: 'bafyreiclp443lavogvhj3d2ob2cxbfuscni2k5jk7bebjzg7khl3esabwq', + }, + root: { + uri: `at://${did}/app.bsky.feed.post/fake-parent`, + cid: 'bafyreiclp443lavogvhj3d2ob2cxbfuscni2k5jk7bebjzg7khl3esabwq', + }, + }, + }), + author: profile, + labels: + scenario[0] === 'label' && target[0] === 'post' + ? [ + mock.label({ + src: isSelfLabel ? did : undefined, + val: label[0], + uri: `at://${did}/app.bsky.feed.post/fake`, + }), + ] + : undefined, + }) + const [item] = groupNotifications([notif]) + item.subject = mock.postView({ + record: notif.record as AppBskyFeedPost.Record, + author: profile, + labels: notif.labels, + }) + return item + }, [scenario, label, target, profile, isSelfLabel, did]) + + const followNotif = React.useMemo(() => { + const notif = mock.followNotification({ + author: profile, + subjectDid: currentAccount?.did || '', + }) + const [item] = groupNotifications([notif]) + return item + }, [profile, currentAccount]) + + const modOpts = React.useMemo(() => { + return { + userDid: isLoggedOut ? '' : isTargetMe ? did : 'did:web:alice.test', + prefs: { + adultContentEnabled: !noAdult, + labels: { + [label[0]]: visibility[0] as LabelPreference, + }, + labelers: [ + { + did: 'did:plc:fake-labeler', + labels: {[label[0]]: visibility[0] as LabelPreference}, + }, + ], + mutedWords: [], + hiddenPosts: [], + }, + labelDefs: { + 'did:plc:fake-labeler': [ + interpretLabelValueDefinition(customLabelDef, 'did:plc:fake-labeler'), + ], + }, + } + }, [label, visibility, noAdult, isLoggedOut, isTargetMe, did, customLabelDef]) + + const profileModeration = React.useMemo(() => { + return moderateProfile(profile, modOpts) + }, [profile, modOpts]) + const postModeration = React.useMemo(() => { + return moderatePost(post, modOpts) + }, [post, modOpts]) + + return ( + <moderationOptsOverrideContext.Provider value={modOpts}> + <ScrollView> + <CenteredView style={[t.atoms.bg, a.px_lg, a.py_lg]}> + <H1 style={[a.text_5xl, a.font_bold, a.pb_lg]}>Moderation states</H1> + + <Heading title="" subtitle="Scenario" /> + <ToggleButton.Group + label="Scenario" + values={scenario} + onChange={setScenario}> + <ToggleButton.Button name="label" label="Label"> + Label + </ToggleButton.Button> + <ToggleButton.Button name="block" label="Block"> + Block + </ToggleButton.Button> + <ToggleButton.Button name="mute" label="Mute"> + Mute + </ToggleButton.Button> + </ToggleButton.Group> + + {scenario[0] === 'label' && ( + <> + <View + style={[ + a.border, + a.rounded_sm, + a.mt_lg, + a.mb_lg, + a.p_lg, + t.atoms.border_contrast_medium, + ]}> + <Toggle.Group + label="Toggle" + type="radio" + values={label} + onChange={setLabel}> + <View style={[a.flex_row, a.gap_md, a.flex_wrap]}> + {LABEL_VALUES.map(labelValue => { + let targetFixed = target[0] + if ( + targetFixed !== 'account' && + targetFixed !== 'profile' + ) { + targetFixed = 'content' + } + const disabled = + isSelfLabel && + LABELS[labelValue].flags.includes('no-self') + return ( + <Toggle.Item + key={labelValue} + name={labelValue} + label={labelStrings[labelValue].name} + disabled={disabled} + style={disabled ? {opacity: 0.5} : undefined}> + <Toggle.Radio /> + <Toggle.Label>{labelValue}</Toggle.Label> + </Toggle.Item> + ) + })} + <Toggle.Item + name="custom" + label="Custom label" + disabled={isSelfLabel} + style={isSelfLabel ? {opacity: 0.5} : undefined}> + <Toggle.Radio /> + <Toggle.Label>Custom label</Toggle.Label> + </Toggle.Item> + </View> + </Toggle.Group> + + {label[0] === 'custom' ? ( + <CustomLabelForm + def={customLabelDef} + setDef={setCustomLabelDef} + /> + ) : ( + <> + <View style={{height: 10}} /> + <Divider /> + </> + )} + + <View style={{height: 10}} /> + + <SmallToggler label="Advanced"> + <Toggle.Group + label="Toggle" + type="checkbox" + values={scenarioSwitches} + onChange={setScenarioSwitches}> + <View style={[a.gap_md, a.flex_row, a.flex_wrap, a.pt_md]}> + <Toggle.Item name="targetMe" label="Target is me"> + <Toggle.Checkbox /> + <Toggle.Label>Target is me</Toggle.Label> + </Toggle.Item> + <Toggle.Item name="following" label="Following target"> + <Toggle.Checkbox /> + <Toggle.Label>Following target</Toggle.Label> + </Toggle.Item> + <Toggle.Item name="selfLabel" label="Self label"> + <Toggle.Checkbox /> + <Toggle.Label>Self label</Toggle.Label> + </Toggle.Item> + <Toggle.Item name="noAdult" label="Adult disabled"> + <Toggle.Checkbox /> + <Toggle.Label>Adult disabled</Toggle.Label> + </Toggle.Item> + <Toggle.Item name="loggedOut" label="Logged out"> + <Toggle.Checkbox /> + <Toggle.Label>Logged out</Toggle.Label> + </Toggle.Item> + </View> + </Toggle.Group> + + {LABELS[label[0] as keyof typeof LABELS]?.configurable !== + false && ( + <View style={[a.mt_md]}> + <Text + style={[a.font_bold, a.text_xs, t.atoms.text, a.pb_sm]}> + Preference + </Text> + <Toggle.Group + label="Preference" + type="radio" + values={visibility} + onChange={setVisiblity}> + <View + style={[ + a.flex_row, + a.gap_md, + a.flex_wrap, + a.align_center, + ]}> + <Toggle.Item name="hide" label="Hide"> + <Toggle.Radio /> + <Toggle.Label>Hide</Toggle.Label> + </Toggle.Item> + <Toggle.Item name="warn" label="Warn"> + <Toggle.Radio /> + <Toggle.Label>Warn</Toggle.Label> + </Toggle.Item> + <Toggle.Item name="ignore" label="Ignore"> + <Toggle.Radio /> + <Toggle.Label>Ignore</Toggle.Label> + </Toggle.Item> + </View> + </Toggle.Group> + </View> + )} + </SmallToggler> + </View> + + <View style={[a.flex_row, a.flex_wrap, a.gap_md]}> + <View> + <Text + style={[ + a.font_bold, + a.text_xs, + t.atoms.text, + a.pl_md, + a.pb_xs, + ]}> + Target + </Text> + <View + style={[ + a.border, + a.rounded_full, + a.px_md, + a.py_sm, + t.atoms.border_contrast_medium, + t.atoms.bg, + ]}> + <Toggle.Group + label="Target" + type="radio" + values={target} + onChange={setTarget}> + <View style={[a.flex_row, a.gap_md, a.flex_wrap]}> + <Toggle.Item name="account" label="Account"> + <Toggle.Radio /> + <Toggle.Label>Account</Toggle.Label> + </Toggle.Item> + <Toggle.Item name="profile" label="Profile"> + <Toggle.Radio /> + <Toggle.Label>Profile</Toggle.Label> + </Toggle.Item> + <Toggle.Item name="post" label="Post"> + <Toggle.Radio /> + <Toggle.Label>Post</Toggle.Label> + </Toggle.Item> + <Toggle.Item name="embed" label="Embed"> + <Toggle.Radio /> + <Toggle.Label>Embed</Toggle.Label> + </Toggle.Item> + </View> + </Toggle.Group> + </View> + </View> + </View> + </> + )} + + <Spacer /> + + <Heading title="" subtitle="Results" /> + + <ToggleButton.Group label="Results" values={view} onChange={setView}> + <ToggleButton.Button name="post" label="Post"> + Post + </ToggleButton.Button> + <ToggleButton.Button name="notifications" label="Notifications"> + Notifications + </ToggleButton.Button> + <ToggleButton.Button name="account" label="Account"> + Account + </ToggleButton.Button> + <ToggleButton.Button name="data" label="Data"> + Data + </ToggleButton.Button> + </ToggleButton.Group> + + <View + style={[ + a.border, + a.rounded_sm, + a.mt_lg, + a.p_md, + t.atoms.border_contrast_medium, + ]}> + {view[0] === 'post' && ( + <> + <Heading title="Post" subtitle="in feed" /> + <MockPostFeedItem post={post} moderation={postModeration} /> + + <Heading title="Post" subtitle="viewed directly" /> + <MockPostThreadItem post={post} moderation={postModeration} /> + + <Heading title="Post" subtitle="reply in thread" /> + <MockPostThreadItem + post={post} + moderation={postModeration} + reply + /> + </> + )} + + {view[0] === 'notifications' && ( + <> + <Heading title="Notification" subtitle="quote or reply" /> + <MockNotifItem notif={replyNotif} moderationOpts={modOpts} /> + <View style={{height: 20}} /> + <Heading title="Notification" subtitle="follow or like" /> + <MockNotifItem notif={followNotif} moderationOpts={modOpts} /> + </> + )} + + {view[0] === 'account' && ( + <> + <Heading title="Account" subtitle="in listing" /> + <MockAccountCard + profile={profile} + moderation={profileModeration} + /> + + <Heading title="Account" subtitle="viewing directly" /> + <MockAccountScreen + profile={profile} + moderation={profileModeration} + moderationOpts={modOpts} + /> + </> + )} + + {view[0] === 'data' && ( + <> + <ModerationUIView + label="Profile Moderation UI" + mod={profileModeration} + /> + <ModerationUIView + label="Post Moderation UI" + mod={postModeration} + /> + <DataView + label={label[0]} + data={LABELS[label[0] as keyof typeof LABELS]} + /> + <DataView + label="Profile Moderation Data" + data={profileModeration} + /> + <DataView label="Post Moderation Data" data={postModeration} /> + </> + )} + </View> + + <View style={{height: 400}} /> + </CenteredView> + </ScrollView> + </moderationOptsOverrideContext.Provider> + ) +} + +function Heading({title, subtitle}: {title: string; subtitle?: string}) { + const t = useTheme() + return ( + <H3 style={[a.text_3xl, a.font_bold, a.pb_md]}> + {title}{' '} + {!!subtitle && ( + <H3 style={[t.atoms.text_contrast_medium, a.text_lg]}>{subtitle}</H3> + )} + </H3> + ) +} + +function CustomLabelForm({ + def, + setDef, +}: { + def: ComAtprotoLabelDefs.LabelValueDefinition + setDef: React.Dispatch< + React.SetStateAction<ComAtprotoLabelDefs.LabelValueDefinition> + > +}) { + const t = useTheme() + return ( + <View + style={[ + a.flex_row, + a.flex_wrap, + a.gap_md, + t.atoms.bg_contrast_25, + a.rounded_md, + a.p_md, + a.mt_md, + ]}> + <View> + <Text style={[a.font_bold, a.text_xs, t.atoms.text, a.pl_md, a.pb_xs]}> + Blurs + </Text> + <View + style={[ + a.border, + a.rounded_full, + a.px_md, + a.py_sm, + t.atoms.border_contrast_medium, + t.atoms.bg, + ]}> + <Toggle.Group + label="Blurs" + type="radio" + values={[def.blurs]} + onChange={values => setDef(v => ({...v, blurs: values[0]}))}> + <View style={[a.flex_row, a.gap_md, a.flex_wrap]}> + <Toggle.Item name="content" label="Content"> + <Toggle.Radio /> + <Toggle.Label>Content</Toggle.Label> + </Toggle.Item> + <Toggle.Item name="media" label="Media"> + <Toggle.Radio /> + <Toggle.Label>Media</Toggle.Label> + </Toggle.Item> + <Toggle.Item name="none" label="None"> + <Toggle.Radio /> + <Toggle.Label>None</Toggle.Label> + </Toggle.Item> + </View> + </Toggle.Group> + </View> + </View> + <View> + <Text style={[a.font_bold, a.text_xs, t.atoms.text, a.pl_md, a.pb_xs]}> + Severity + </Text> + <View + style={[ + a.border, + a.rounded_full, + a.px_md, + a.py_sm, + t.atoms.border_contrast_medium, + t.atoms.bg, + ]}> + <Toggle.Group + label="Severity" + type="radio" + values={[def.severity]} + onChange={values => setDef(v => ({...v, severity: values[0]}))}> + <View style={[a.flex_row, a.gap_md, a.flex_wrap, a.align_center]}> + <Toggle.Item name="alert" label="Alert"> + <Toggle.Radio /> + <Toggle.Label>Alert</Toggle.Label> + </Toggle.Item> + <Toggle.Item name="inform" label="Inform"> + <Toggle.Radio /> + <Toggle.Label>Inform</Toggle.Label> + </Toggle.Item> + <Toggle.Item name="none" label="None"> + <Toggle.Radio /> + <Toggle.Label>None</Toggle.Label> + </Toggle.Item> + </View> + </Toggle.Group> + </View> + </View> + </View> + ) +} + +function Toggler({label, children}: React.PropsWithChildren<{label: string}>) { + const t = useTheme() + const [show, setShow] = React.useState(false) + return ( + <View style={a.mb_md}> + <View + style={[ + t.atoms.border_contrast_medium, + a.border, + a.rounded_sm, + a.p_xs, + ]}> + <Button + variant="solid" + color="secondary" + label="Toggle visibility" + size="small" + onPress={() => setShow(!show)}> + <ButtonText>{label}</ButtonText> + <ButtonIcon + icon={show ? ChevronTop : ChevronBottom} + position="right" + /> + </Button> + {show && children} + </View> + </View> + ) +} + +function SmallToggler({ + label, + children, +}: React.PropsWithChildren<{label: string}>) { + const [show, setShow] = React.useState(false) + return ( + <View> + <View style={[a.flex_row]}> + <Button + variant="ghost" + color="secondary" + label="Toggle visibility" + size="tiny" + onPress={() => setShow(!show)}> + <ButtonText>{label}</ButtonText> + <ButtonIcon + icon={show ? ChevronTop : ChevronBottom} + position="right" + /> + </Button> + </View> + {show && children} + </View> + ) +} + +function DataView({label, data}: {label: string; data: any}) { + return ( + <Toggler label={label}> + <Text style={[{fontFamily: 'monospace'}, a.p_md]}> + {JSON.stringify(data, null, 2)} + </Text> + </Toggler> + ) +} + +function ModerationUIView({ + mod, + label, +}: { + mod: ModerationDecision + label: string +}) { + return ( + <Toggler label={label}> + <View style={a.p_lg}> + {[ + 'profileList', + 'profileView', + 'avatar', + 'banner', + 'displayName', + 'contentList', + 'contentView', + 'contentMedia', + ].map(key => { + const ui = mod.ui(key as keyof ModerationBehavior) + return ( + <View key={key} style={[a.flex_row, a.gap_md]}> + <Text style={[a.font_bold, {width: 100}]}>{key}</Text> + <Flag v={ui.filter} label="Filter" /> + <Flag v={ui.blur} label="Blur" /> + <Flag v={ui.alert} label="Alert" /> + <Flag v={ui.inform} label="Inform" /> + <Flag v={ui.noOverride} label="No-override" /> + </View> + ) + })} + </View> + </Toggler> + ) +} + +function Spacer() { + return <View style={{height: 30}} /> +} + +function MockPostFeedItem({ + post, + moderation, +}: { + post: AppBskyFeedDefs.PostView + moderation: ModerationDecision +}) { + const t = useTheme() + if (moderation.ui('contentList').filter) { + return ( + <P style={[t.atoms.bg_contrast_25, a.px_lg, a.py_md, a.mb_lg]}> + Filtered from the feed + </P> + ) + } + return ( + <FeedItem + post={post} + record={post.record as AppBskyFeedPost.Record} + moderation={moderation} + reason={undefined} + /> + ) +} + +function MockPostThreadItem({ + post, + reply, +}: { + post: AppBskyFeedDefs.PostView + moderation: ModerationDecision + reply?: boolean +}) { + return ( + <PostThreadItem + // @ts-ignore + post={post} + record={post.record as AppBskyFeedPost.Record} + depth={reply ? 1 : 0} + isHighlightedPost={!reply} + treeView={false} + prevPost={undefined} + nextPost={undefined} + hasPrecedingItem={false} + onPostReply={() => {}} + /> + ) +} + +function MockNotifItem({ + notif, + moderationOpts, +}: { + notif: FeedNotification + moderationOpts: ModerationOpts +}) { + const t = useTheme() + if (shouldFilterNotif(notif.notification, moderationOpts)) { + return ( + <P style={[t.atoms.bg_contrast_25, a.px_lg, a.py_md]}> + Filtered from the feed + </P> + ) + } + return <NotifFeedItem item={notif} moderationOpts={moderationOpts} /> +} + +function MockAccountCard({ + profile, + moderation, +}: { + profile: AppBskyActorDefs.ProfileViewBasic + moderation: ModerationDecision +}) { + const t = useTheme() + + if (moderation.ui('profileList').filter) { + return ( + <P style={[t.atoms.bg_contrast_25, a.px_lg, a.py_md, a.mb_lg]}> + Filtered from the listing + </P> + ) + } + + return <ProfileCard profile={profile} /> +} + +function MockAccountScreen({ + profile, + moderation, + moderationOpts, +}: { + profile: AppBskyActorDefs.ProfileViewBasic + moderation: ModerationDecision + moderationOpts: ModerationOpts +}) { + const t = useTheme() + const {_} = useLingui() + return ( + <View style={[t.atoms.border_contrast_medium, a.border, a.mb_md]}> + <ScreenHider + style={{}} + screenDescription={_(msg`profile`)} + modui={moderation.ui('profileView')}> + <ProfileHeaderStandard + // @ts-ignore ProfileViewBasic is close enough -prf + profile={profile} + moderationOpts={moderationOpts} + descriptionRT={new RichText({text: profile.description as string})} + /> + </ScreenHider> + </View> + ) +} + +function Flag({v, label}: {v: boolean | undefined; label: string}) { + const t = useTheme() + return ( + <View style={[a.flex_row, a.align_center, a.gap_xs]}> + <View + style={[ + a.justify_center, + a.align_center, + a.rounded_xs, + a.border, + t.atoms.border_contrast_medium, + { + backgroundColor: t.palette.contrast_25, + width: 14, + height: 14, + }, + ]}> + {v && <Check size="xs" fill={t.palette.contrast_900} />} + </View> + <P style={a.text_xs}>{label}</P> + </View> + ) +} diff --git a/src/view/screens/Moderation.tsx b/src/view/screens/Moderation.tsx deleted file mode 100644 index 928766c304..0000000000 --- a/src/view/screens/Moderation.tsx +++ /dev/null @@ -1,304 +0,0 @@ -import React from 'react' -import { - ActivityIndicator, - StyleSheet, - TouchableOpacity, - View, -} from 'react-native' -import {useFocusEffect} from '@react-navigation/native' -import { - FontAwesomeIcon, - FontAwesomeIconStyle, -} from '@fortawesome/react-native-fontawesome' -import {ComAtprotoLabelDefs} from '@atproto/api' -import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types' -import {s} from 'lib/styles' -import {CenteredView} from '../com/util/Views' -import {ViewHeader} from '../com/util/ViewHeader' -import {Link, TextLink} from '../com/util/Link' -import {Text} from '../com/util/text/Text' -import {usePalette} from 'lib/hooks/usePalette' -import {useAnalytics} from 'lib/analytics/analytics' -import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {useSetMinimalShellMode} from '#/state/shell' -import {useModalControls} from '#/state/modals' -import {Trans, msg} from '@lingui/macro' -import {useLingui} from '@lingui/react' -import {ToggleButton} from '../com/util/forms/ToggleButton' -import {useSession} from '#/state/session' -import { - useProfileQuery, - useProfileUpdateMutation, -} from '#/state/queries/profile' -import {ScrollView} from '../com/util/Views' -import {useGlobalDialogsControlContext} from '#/components/dialogs/Context' - -type Props = NativeStackScreenProps<CommonNavigatorParams, 'Moderation'> -export function ModerationScreen({}: Props) { - const pal = usePalette('default') - const {_} = useLingui() - const setMinimalShellMode = useSetMinimalShellMode() - const {screen, track} = useAnalytics() - const {isTabletOrDesktop} = useWebMediaQueries() - const {openModal} = useModalControls() - const {mutedWordsDialogControl} = useGlobalDialogsControlContext() - - useFocusEffect( - React.useCallback(() => { - screen('Moderation') - setMinimalShellMode(false) - }, [screen, setMinimalShellMode]), - ) - - const onPressContentFiltering = React.useCallback(() => { - track('Moderation:ContentfilteringButtonClicked') - openModal({name: 'content-filtering-settings'}) - }, [track, openModal]) - - return ( - <CenteredView - style={[ - s.hContentRegion, - pal.border, - isTabletOrDesktop ? styles.desktopContainer : pal.viewLight, - ]} - testID="moderationScreen"> - <ViewHeader title={_(msg`Moderation`)} showOnDesktop /> - <ScrollView contentContainerStyle={[styles.noBorder]}> - <View style={styles.spacer} /> - <TouchableOpacity - testID="contentFilteringBtn" - style={[styles.linkCard, pal.view]} - onPress={onPressContentFiltering} - accessibilityRole="tab" - accessibilityHint="" - accessibilityLabel={_(msg`Open content filtering settings`)}> - <View style={[styles.iconContainer, pal.btn]}> - <FontAwesomeIcon - icon="eye" - style={pal.text as FontAwesomeIconStyle} - /> - </View> - <Text type="lg" style={pal.text}> - <Trans>Content filtering</Trans> - </Text> - </TouchableOpacity> - <TouchableOpacity - testID="mutedWordsBtn" - style={[styles.linkCard, pal.view]} - onPress={() => mutedWordsDialogControl.open()} - accessibilityRole="tab" - accessibilityHint="" - accessibilityLabel={_(msg`Open muted words settings`)}> - <View style={[styles.iconContainer, pal.btn]}> - <FontAwesomeIcon - icon="filter" - style={pal.text as FontAwesomeIconStyle} - /> - </View> - <Text type="lg" style={pal.text}> - <Trans>Muted words & tags</Trans> - </Text> - </TouchableOpacity> - <Link - testID="moderationlistsBtn" - style={[styles.linkCard, pal.view]} - href="/moderation/modlists"> - <View style={[styles.iconContainer, pal.btn]}> - <FontAwesomeIcon - icon="users-slash" - style={pal.text as FontAwesomeIconStyle} - /> - </View> - <Text type="lg" style={pal.text}> - <Trans>Moderation lists</Trans> - </Text> - </Link> - <Link - testID="mutedAccountsBtn" - style={[styles.linkCard, pal.view]} - href="/moderation/muted-accounts"> - <View style={[styles.iconContainer, pal.btn]}> - <FontAwesomeIcon - icon="user-slash" - style={pal.text as FontAwesomeIconStyle} - /> - </View> - <Text type="lg" style={pal.text}> - <Trans>Muted accounts</Trans> - </Text> - </Link> - <Link - testID="blockedAccountsBtn" - style={[styles.linkCard, pal.view]} - href="/moderation/blocked-accounts"> - <View style={[styles.iconContainer, pal.btn]}> - <FontAwesomeIcon - icon="ban" - style={pal.text as FontAwesomeIconStyle} - /> - </View> - <Text type="lg" style={pal.text}> - <Trans>Blocked accounts</Trans> - </Text> - </Link> - <Text - type="xl-bold" - style={[ - pal.text, - { - paddingHorizontal: 18, - paddingTop: 18, - paddingBottom: 6, - }, - ]}> - <Trans>Logged-out visibility</Trans> - </Text> - <PwiOptOut /> - </ScrollView> - </CenteredView> - ) -} - -function PwiOptOut() { - const pal = usePalette('default') - const {_} = useLingui() - const {currentAccount} = useSession() - const {data: profile} = useProfileQuery({did: currentAccount?.did}) - const updateProfile = useProfileUpdateMutation() - - const isOptedOut = - profile?.labels?.some(l => l.val === '!no-unauthenticated') || false - const canToggle = profile && !updateProfile.isPending - - const onToggleOptOut = React.useCallback(() => { - if (!profile) { - return - } - let wasAdded = false - updateProfile.mutate({ - profile, - updates: existing => { - // create labels attr if needed - existing.labels = ComAtprotoLabelDefs.isSelfLabels(existing.labels) - ? existing.labels - : { - $type: 'com.atproto.label.defs#selfLabels', - values: [], - } - - // toggle the label - const hasLabel = existing.labels.values.some( - l => l.val === '!no-unauthenticated', - ) - if (hasLabel) { - wasAdded = false - existing.labels.values = existing.labels.values.filter( - l => l.val !== '!no-unauthenticated', - ) - } else { - wasAdded = true - existing.labels.values.push({val: '!no-unauthenticated'}) - } - - // delete if no longer needed - if (existing.labels.values.length === 0) { - delete existing.labels - } - return existing - }, - checkCommitted: res => { - const exists = !!res.data.labels?.some( - l => l.val === '!no-unauthenticated', - ) - return exists === wasAdded - }, - }) - }, [updateProfile, profile]) - - return ( - <View style={[pal.view, styles.toggleCard]}> - <View - style={{flexDirection: 'row', alignItems: 'center', paddingRight: 14}}> - <ToggleButton - type="default-light" - label={_( - msg`Discourage apps from showing my account to logged-out users`, - )} - labelType="lg" - isSelected={isOptedOut} - onPress={canToggle ? onToggleOptOut : undefined} - style={[canToggle ? undefined : {opacity: 0.5}, {flex: 1}]} - /> - {updateProfile.isPending && <ActivityIndicator />} - </View> - <View - style={{ - flexDirection: 'column', - gap: 10, - paddingLeft: 66, - paddingRight: 12, - paddingBottom: 10, - marginBottom: 64, - }}> - <Text style={pal.textLight}> - <Trans> - Bluesky will not show your profile and posts to logged-out users. - Other apps may not honor this request. This does not make your - account private. - </Trans> - </Text> - <Text style={[pal.textLight, {fontWeight: '500'}]}> - <Trans> - Note: Bluesky is an open and public network. This setting only - limits the visibility of your content on the Bluesky app and - website, and other apps may not respect this setting. Your content - may still be shown to logged-out users by other apps and websites. - </Trans> - </Text> - <TextLink - style={pal.link} - href="https://blueskyweb.zendesk.com/hc/en-us/articles/15835264007693-Data-Privacy" - text={_(msg`Learn more about what is public on Bluesky.`)} - /> - </View> - </View> - ) -} - -const styles = StyleSheet.create({ - desktopContainer: { - borderLeftWidth: 1, - borderRightWidth: 1, - }, - spacer: { - height: 6, - }, - linkCard: { - flexDirection: 'row', - alignItems: 'center', - paddingVertical: 12, - paddingHorizontal: 18, - marginBottom: 1, - }, - toggleCard: { - paddingVertical: 8, - paddingTop: 2, - paddingHorizontal: 6, - marginBottom: 1, - }, - iconContainer: { - alignItems: 'center', - justifyContent: 'center', - width: 40, - height: 40, - borderRadius: 30, - marginRight: 12, - }, - noBorder: { - borderBottomWidth: 0, - borderRightWidth: 0, - borderLeftWidth: 0, - borderTopWidth: 0, - }, -}) diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx index b30b4491bd..d5a46c5c98 100644 --- a/src/view/screens/Profile.tsx +++ b/src/view/screens/Profile.tsx @@ -1,5 +1,5 @@ import React, {useMemo} from 'react' -import {StyleSheet, View} from 'react-native' +import {StyleSheet} from 'react-native' import {useFocusEffect} from '@react-navigation/native' import { AppBskyActorDefs, @@ -7,48 +7,39 @@ import { ModerationOpts, RichText as RichTextAPI, } from '@atproto/api' -import {msg, Trans} from '@lingui/macro' +import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types' import {CenteredView} from '../com/util/Views' import {ListRef} from '../com/util/List' -import {ScreenHider} from 'view/com/util/moderation/ScreenHider' -import {Feed} from 'view/com/posts/Feed' +import {ScreenHider} from '#/components/moderation/ScreenHider' import {ProfileLists} from '../com/lists/ProfileLists' import {ProfileFeedgens} from '../com/feeds/ProfileFeedgens' -import {ProfileHeader, ProfileHeaderLoading} from '../com/profile/ProfileHeader' import {PagerWithHeader} from 'view/com/pager/PagerWithHeader' import {ErrorScreen} from '../com/util/error/ErrorScreen' -import {EmptyState} from '../com/util/EmptyState' import {FAB} from '../com/util/fab/FAB' import {s, colors} from 'lib/styles' import {useAnalytics} from 'lib/analytics/analytics' import {ComposeIcon2} from 'lib/icons' import {useSetTitle} from 'lib/hooks/useSetTitle' import {combinedDisplayName} from 'lib/strings/display-names' -import { - FeedDescriptor, - resetProfilePostsQueries, -} from '#/state/queries/post-feed' +import {resetProfilePostsQueries} from '#/state/queries/post-feed' import {useResolveDidQuery} from '#/state/queries/resolve-uri' import {useProfileQuery} from '#/state/queries/profile' import {useProfileShadow} from '#/state/cache/profile-shadow' import {useSession, getAgent} from '#/state/session' import {useModerationOpts} from '#/state/queries/preferences' -import {useProfileExtraInfoQuery} from '#/state/queries/profile-extra-info' -import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed' +import {useLabelerInfoQuery} from '#/state/queries/labeler' import {useSetDrawerSwipeDisabled, useSetMinimalShellMode} from '#/state/shell' import {cleanError} from '#/lib/strings/errors' -import {LoadLatestBtn} from '../com/util/load-latest/LoadLatestBtn' -import {useQueryClient} from '@tanstack/react-query' import {useComposerControls} from '#/state/shell/composer' import {listenSoftReset} from '#/state/events' -import {truncateAndInvalidate} from '#/state/queries/util' -import {Text} from '#/view/com/util/text/Text' -import {usePalette} from 'lib/hooks/usePalette' -import {isNative} from '#/platform/detection' import {isInvalidHandle} from '#/lib/strings/handles' +import {ProfileFeedSection} from '#/screens/Profile/Sections/Feed' +import {ProfileLabelsSection} from '#/screens/Profile/Sections/Labels' +import {ProfileHeader, ProfileHeaderLoading} from '#/screens/Profile/Header' + interface SectionRef { scrollToTop: () => void } @@ -148,16 +139,24 @@ function ProfileScreenLoaded({ const setMinimalShellMode = useSetMinimalShellMode() const {openComposer} = useComposerControls() const {screen, track} = useAnalytics() + const { + data: labelerInfo, + error: labelerError, + isLoading: isLabelerLoading, + } = useLabelerInfoQuery({ + did: profile.did, + enabled: !!profile.associated?.labeler, + }) const [currentPage, setCurrentPage] = React.useState(0) const {_} = useLingui() const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled() - const extraInfoQuery = useProfileExtraInfoQuery(profile.did) const postsSectionRef = React.useRef<SectionRef>(null) const repliesSectionRef = React.useRef<SectionRef>(null) const mediaSectionRef = React.useRef<SectionRef>(null) const likesSectionRef = React.useRef<SectionRef>(null) const feedsSectionRef = React.useRef<SectionRef>(null) const listsSectionRef = React.useRef<SectionRef>(null) + const labelsSectionRef = React.useRef<SectionRef>(null) useSetTitle(combinedDisplayName(profile)) @@ -171,44 +170,75 @@ function ProfileScreenLoaded({ ) const isMe = profile.did === currentAccount?.did + const hasLabeler = !!profile.associated?.labeler + const showFiltersTab = hasLabeler + const showPostsTab = true const showRepliesTab = hasSession + const showMediaTab = !hasLabeler const showLikesTab = isMe - const showFeedsTab = hasSession && (isMe || extraInfoQuery.data?.hasFeedgens) - const showListsTab = hasSession && (isMe || extraInfoQuery.data?.hasLists) + const showFeedsTab = + hasSession && (isMe || (profile.associated?.feedgens || 0) > 0) + const showListsTab = + hasSession && (isMe || (profile.associated?.lists || 0) > 0) + const sectionTitles = useMemo<string[]>(() => { return [ - _(msg`Posts`), + showFiltersTab ? _(msg`Labels`) : undefined, + showListsTab && hasLabeler ? _(msg`Lists`) : undefined, + showPostsTab ? _(msg`Posts`) : undefined, showRepliesTab ? _(msg`Replies`) : undefined, - _(msg`Media`), + showMediaTab ? _(msg`Media`) : undefined, showLikesTab ? _(msg`Likes`) : undefined, showFeedsTab ? _(msg`Feeds`) : undefined, - showListsTab ? _(msg`Lists`) : undefined, + showListsTab && !hasLabeler ? _(msg`Lists`) : undefined, ].filter(Boolean) as string[] - }, [showRepliesTab, showLikesTab, showFeedsTab, showListsTab, _]) + }, [ + showPostsTab, + showRepliesTab, + showMediaTab, + showLikesTab, + showFeedsTab, + showListsTab, + showFiltersTab, + hasLabeler, + _, + ]) let nextIndex = 0 - const postsIndex = nextIndex++ + let filtersIndex: number | null = null + let postsIndex: number | null = null let repliesIndex: number | null = null + let mediaIndex: number | null = null + let likesIndex: number | null = null + let feedsIndex: number | null = null + let listsIndex: number | null = null + if (showFiltersTab) { + filtersIndex = nextIndex++ + } + if (showPostsTab) { + postsIndex = nextIndex++ + } if (showRepliesTab) { repliesIndex = nextIndex++ } - const mediaIndex = nextIndex++ - let likesIndex: number | null = null + if (showMediaTab) { + mediaIndex = nextIndex++ + } if (showLikesTab) { likesIndex = nextIndex++ } - let feedsIndex: number | null = null if (showFeedsTab) { feedsIndex = nextIndex++ } - let listsIndex: number | null = null if (showListsTab) { listsIndex = nextIndex++ } const scrollSectionToTop = React.useCallback( (index: number) => { - if (index === postsIndex) { + if (index === filtersIndex) { + labelsSectionRef.current?.scrollToTop() + } else if (index === postsIndex) { postsSectionRef.current?.scrollToTop() } else if (index === repliesIndex) { repliesSectionRef.current?.scrollToTop() @@ -222,7 +252,15 @@ function ProfileScreenLoaded({ listsSectionRef.current?.scrollToTop() } }, - [postsIndex, repliesIndex, mediaIndex, likesIndex, feedsIndex, listsIndex], + [ + filtersIndex, + postsIndex, + repliesIndex, + mediaIndex, + likesIndex, + feedsIndex, + listsIndex, + ], ) useFocusEffect( @@ -278,6 +316,7 @@ function ProfileScreenLoaded({ return ( <ProfileHeader profile={profile} + labeler={labelerInfo} descriptionRT={hasDescription ? descriptionRT : null} moderationOpts={moderationOpts} hideBackButton={hideBackButton} @@ -286,6 +325,7 @@ function ProfileScreenLoaded({ ) }, [ profile, + labelerInfo, descriptionRT, hasDescription, moderationOpts, @@ -297,8 +337,8 @@ function ProfileScreenLoaded({ <ScreenHider testID="profileView" style={styles.container} - screenDescription="profile" - moderation={moderation.account}> + screenDescription={_(msg`profile`)} + modui={moderation.ui('profileView')}> <PagerWithHeader testID="profilePager" isHeaderReady={!showPlaceholder} @@ -306,19 +346,45 @@ function ProfileScreenLoaded({ onPageSelected={onPageSelected} onCurrentPageSelected={onCurrentPageSelected} renderHeader={renderHeader}> - {({headerHeight, isFocused, scrollElRef}) => ( - <FeedSection - ref={postsSectionRef} - feed={`author|${profile.did}|posts_and_author_threads`} - headerHeight={headerHeight} - isFocused={isFocused} - scrollElRef={scrollElRef as ListRef} - ignoreFilterFor={profile.did} - /> - )} + {showFiltersTab + ? ({headerHeight, scrollElRef}) => ( + <ProfileLabelsSection + ref={labelsSectionRef} + labelerInfo={labelerInfo} + labelerError={labelerError} + isLabelerLoading={isLabelerLoading} + moderationOpts={moderationOpts} + scrollElRef={scrollElRef as ListRef} + headerHeight={headerHeight} + /> + ) + : null} + {showListsTab && !!profile.associated?.labeler + ? ({headerHeight, isFocused, scrollElRef}) => ( + <ProfileLists + ref={listsSectionRef} + did={profile.did} + scrollElRef={scrollElRef as ListRef} + headerOffset={headerHeight} + enabled={isFocused} + /> + ) + : null} + {showPostsTab + ? ({headerHeight, isFocused, scrollElRef}) => ( + <ProfileFeedSection + ref={postsSectionRef} + feed={`author|${profile.did}|posts_and_author_threads`} + headerHeight={headerHeight} + isFocused={isFocused} + scrollElRef={scrollElRef as ListRef} + ignoreFilterFor={profile.did} + /> + ) + : null} {showRepliesTab ? ({headerHeight, isFocused, scrollElRef}) => ( - <FeedSection + <ProfileFeedSection ref={repliesSectionRef} feed={`author|${profile.did}|posts_with_replies`} headerHeight={headerHeight} @@ -328,19 +394,21 @@ function ProfileScreenLoaded({ /> ) : null} - {({headerHeight, isFocused, scrollElRef}) => ( - <FeedSection - ref={mediaSectionRef} - feed={`author|${profile.did}|posts_with_media`} - headerHeight={headerHeight} - isFocused={isFocused} - scrollElRef={scrollElRef as ListRef} - ignoreFilterFor={profile.did} - /> - )} + {showMediaTab + ? ({headerHeight, isFocused, scrollElRef}) => ( + <ProfileFeedSection + ref={mediaSectionRef} + feed={`author|${profile.did}|posts_with_media`} + headerHeight={headerHeight} + isFocused={isFocused} + scrollElRef={scrollElRef as ListRef} + ignoreFilterFor={profile.did} + /> + ) + : null} {showLikesTab ? ({headerHeight, isFocused, scrollElRef}) => ( - <FeedSection + <ProfileFeedSection ref={likesSectionRef} feed={`likes|${profile.did}`} headerHeight={headerHeight} @@ -361,7 +429,7 @@ function ProfileScreenLoaded({ /> ) : null} - {showListsTab + {showListsTab && !profile.associated?.labeler ? ({headerHeight, isFocused, scrollElRef}) => ( <ProfileLists ref={listsSectionRef} @@ -387,77 +455,6 @@ function ProfileScreenLoaded({ ) } -interface FeedSectionProps { - feed: FeedDescriptor - headerHeight: number - isFocused: boolean - scrollElRef: ListRef - ignoreFilterFor?: string -} -const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>( - function FeedSectionImpl( - {feed, headerHeight, isFocused, scrollElRef, ignoreFilterFor}, - ref, - ) { - const {_} = useLingui() - const queryClient = useQueryClient() - const [hasNew, setHasNew] = React.useState(false) - const [isScrolledDown, setIsScrolledDown] = React.useState(false) - - const onScrollToTop = React.useCallback(() => { - scrollElRef.current?.scrollToOffset({ - animated: isNative, - offset: -headerHeight, - }) - truncateAndInvalidate(queryClient, FEED_RQKEY(feed)) - setHasNew(false) - }, [scrollElRef, headerHeight, queryClient, feed, setHasNew]) - React.useImperativeHandle(ref, () => ({ - scrollToTop: onScrollToTop, - })) - - const renderPostsEmpty = React.useCallback(() => { - return <EmptyState icon="feed" message={_(msg`This feed is empty!`)} /> - }, [_]) - - return ( - <View> - <Feed - testID="postsFeed" - enabled={isFocused} - feed={feed} - scrollElRef={scrollElRef} - onHasNew={setHasNew} - onScrolledDownChange={setIsScrolledDown} - renderEmptyState={renderPostsEmpty} - headerOffset={headerHeight} - renderEndOfFeed={ProfileEndOfFeed} - ignoreFilterFor={ignoreFilterFor} - /> - {(isScrolledDown || hasNew) && ( - <LoadLatestBtn - onPress={onScrollToTop} - label={_(msg`Load new posts`)} - showIndicator={hasNew} - /> - )} - </View> - ) - }, -) - -function ProfileEndOfFeed() { - const pal = usePalette('default') - - return ( - <View style={[pal.border, {paddingTop: 32, borderTopWidth: 1}]}> - <Text style={[pal.textLight, pal.border, {textAlign: 'center'}]}> - <Trans>End of feed</Trans> - </Text> - </View> - ) -} - function useRichText(text: string): [RichTextAPI, boolean] { const [prevText, setPrevText] = React.useState(text) const [rawRT, setRawRT] = React.useState(() => new RichTextAPI({text})) diff --git a/src/view/screens/ProfileFeed.tsx b/src/view/screens/ProfileFeed.tsx index b3a7328c17..416bbc30e2 100644 --- a/src/view/screens/ProfileFeed.tsx +++ b/src/view/screens/ProfileFeed.tsx @@ -35,7 +35,7 @@ import {ComposeIcon2} from 'lib/icons' import {logger} from '#/logger' import {Trans, msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {useModalControls} from '#/state/modals' +import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog' import {useFeedSourceInfoQuery, FeedSourceFeedInfo} from '#/state/queries/feed' import {useResolveUriQuery} from '#/state/queries/resolve-uri' import { @@ -155,7 +155,7 @@ export function ProfileFeedScreenInner({ const {_} = useLingui() const t = useTheme() const {hasSession, currentAccount} = useSession() - const {openModal} = useModalControls() + const reportDialogControl = useReportDialogControl() const {openComposer} = useComposerControls() const {track} = useAnalytics() const feedSectionRef = React.useRef<SectionRef>(null) @@ -253,13 +253,8 @@ export function ProfileFeedScreenInner({ }, [feedInfo, track]) const onPressReport = React.useCallback(() => { - if (!feedInfo) return - openModal({ - name: 'report', - uri: feedInfo.uri, - cid: feedInfo.cid, - }) - }, [openModal, feedInfo]) + reportDialogControl.open() + }, [reportDialogControl]) const onCurrentPageSelected = React.useCallback( (index: number) => { @@ -400,6 +395,14 @@ export function ProfileFeedScreenInner({ return ( <View style={s.hContentRegion}> + <ReportDialog + control={reportDialogControl} + params={{ + type: 'feedgen', + uri: feedInfo.uri, + cid: feedInfo.cid, + }} + /> <PagerWithHeader items={SECTION_TITLES} isHeaderReady={true} diff --git a/src/view/screens/ProfileList.tsx b/src/view/screens/ProfileList.tsx index 95046e5b41..3515212650 100644 --- a/src/view/screens/ProfileList.tsx +++ b/src/view/screens/ProfileList.tsx @@ -39,6 +39,7 @@ import {Trans, msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useSetMinimalShellMode} from '#/state/shell' import {useModalControls} from '#/state/modals' +import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog' import {useResolveUriQuery} from '#/state/queries/resolve-uri' import { useListQuery, @@ -236,6 +237,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) { const {_} = useLingui() const navigation = useNavigation<NavigationProp>() const {currentAccount} = useSession() + const reportDialogControl = useReportDialogControl() const {openModal} = useModalControls() const listMuteMutation = useListMuteMutation() const listBlockMutation = useListBlockMutation() @@ -370,12 +372,8 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) { ]) const onPressReport = useCallback(() => { - openModal({ - name: 'report', - uri: list.uri, - cid: list.cid, - }) - }, [openModal, list]) + reportDialogControl.open() + }, [reportDialogControl]) const onPressShare = useCallback(() => { const url = toShareUrl(`/profile/${list.creator.did}/lists/${rkey}`) @@ -550,6 +548,14 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) { isOwner={list.creator.did === currentAccount?.did} creator={list.creator} avatarType="list"> + <ReportDialog + control={reportDialogControl} + params={{ + type: 'list', + uri: list.uri, + cid: list.cid, + }} + /> {isCurateList || isPinned ? ( <Button testID={isPinned ? 'unpinBtn' : 'pinBtn'} diff --git a/src/view/screens/Settings/index.tsx b/src/view/screens/Settings/index.tsx index 3b5e190c12..1b96a09aff 100644 --- a/src/view/screens/Settings/index.tsx +++ b/src/view/screens/Settings/index.tsx @@ -267,6 +267,10 @@ export function SettingsScreen({}: Props) { navigation.navigate('Debug') }, [navigation]) + const onPressDebugModeration = React.useCallback(() => { + navigation.navigate('DebugMod') + }, [navigation]) + const onPressSavedFeeds = React.useCallback(() => { navigation.navigate('SavedFeeds') }, [navigation]) @@ -821,6 +825,16 @@ export function SettingsScreen({}: Props) { <Trans>Storybook</Trans> </Text> </TouchableOpacity> + <TouchableOpacity + style={[pal.view, styles.linkCardNoIcon]} + onPress={onPressDebugModeration} + accessibilityRole="button" + accessibilityLabel={_(msg`Open storybook page`)} + accessibilityHint={_(msg`Opens the storybook page`)}> + <Text type="lg" style={pal.text}> + <Trans>Debug Moderation</Trans> + </Text> + </TouchableOpacity> <TouchableOpacity style={[pal.view, styles.linkCardNoIcon]} onPress={onPressResetPreferences} diff --git a/src/view/screens/Storybook/Buttons.tsx b/src/view/screens/Storybook/Buttons.tsx index 320db13ff8..ad2fff3f4a 100644 --- a/src/view/screens/Storybook/Buttons.tsx +++ b/src/view/screens/Storybook/Buttons.tsx @@ -129,6 +129,15 @@ export function Buttons() { <ButtonIcon icon={Globe} position="left" /> <ButtonText>Link out</ButtonText> </Button> + + <Button + variant="gradient" + color="gradient_sky" + size="tiny" + label="Link out"> + <ButtonIcon icon={Globe} position="left" /> + <ButtonText>Link out</ButtonText> + </Button> </View> <View style={[a.flex_row, a.gap_md, a.align_start]}> @@ -148,6 +157,14 @@ export function Buttons() { label="Link out"> <ButtonIcon icon={ChevronLeft} /> </Button> + <Button + variant="gradient" + color="gradient_sunset" + size="tiny" + shape="round" + label="Link out"> + <ButtonIcon icon={ChevronLeft} /> + </Button> <Button variant="outline" color="primary" @@ -164,6 +181,14 @@ export function Buttons() { label="Link out"> <ButtonIcon icon={ChevronLeft} /> </Button> + <Button + variant="ghost" + color="primary" + size="tiny" + shape="round" + label="Link out"> + <ButtonIcon icon={ChevronLeft} /> + </Button> </View> <View style={[a.flex_row, a.gap_md, a.align_start]}> @@ -183,6 +208,14 @@ export function Buttons() { label="Link out"> <ButtonIcon icon={ChevronLeft} /> </Button> + <Button + variant="gradient" + color="gradient_sunset" + size="tiny" + shape="square" + label="Link out"> + <ButtonIcon icon={ChevronLeft} /> + </Button> <Button variant="outline" color="primary" @@ -199,6 +232,14 @@ export function Buttons() { label="Link out"> <ButtonIcon icon={ChevronLeft} /> </Button> + <Button + variant="ghost" + color="primary" + size="tiny" + shape="square" + label="Link out"> + <ButtonIcon icon={ChevronLeft} /> + </Button> </View> </View> ) diff --git a/src/view/screens/Storybook/index.tsx b/src/view/screens/Storybook/index.tsx index e43d756de5..3a2e2f3696 100644 --- a/src/view/screens/Storybook/index.tsx +++ b/src/view/screens/Storybook/index.tsx @@ -67,6 +67,7 @@ export function Storybook() { </Button> </View> + <Dialogs /> <ThemeProvider theme="light"> <Theming /> </ThemeProvider> diff --git a/src/view/shell/desktop/Search.tsx b/src/view/shell/desktop/Search.tsx index 4a94837338..8933324eed 100644 --- a/src/view/shell/desktop/Search.tsx +++ b/src/view/shell/desktop/Search.tsx @@ -11,7 +11,7 @@ import {useNavigation, StackActions} from '@react-navigation/native' import { AppBskyActorDefs, moderateProfile, - ProfileModeration, + ModerationDecision, } from '@atproto/api' import {Trans, msg} from '@lingui/macro' import {useLingui} from '@lingui/react' @@ -86,7 +86,7 @@ export function SearchProfileCard({ moderation, }: { profile: AppBskyActorDefs.ProfileViewBasic - moderation: ProfileModeration + moderation: ModerationDecision }) { const pal = usePalette('default') @@ -111,7 +111,7 @@ export function SearchProfileCard({ <UserAvatar size={40} avatar={profile.avatar} - moderation={moderation.avatar} + moderation={moderation.ui('avatar')} /> <View style={{flex: 1}}> <Text @@ -121,7 +121,7 @@ export function SearchProfileCard({ lineHeight={1.2}> {sanitizeDisplayName( profile.displayName || sanitizeHandle(profile.handle), - moderation.profile, + moderation.ui('displayName'), )} </Text> <Text type="md" style={[pal.textLight]} numberOfLines={1}> diff --git a/src/view/shell/index.tsx b/src/view/shell/index.tsx index 76a7f8fb3a..f29183095a 100644 --- a/src/view/shell/index.tsx +++ b/src/view/shell/index.tsx @@ -101,8 +101,8 @@ function ShellInner() { <Composer winHeight={winDim.height} /> <ModalsContainer /> <MutedWordsDialog /> - <PortalOutlet /> <Lightbox /> + <PortalOutlet /> </> ) } diff --git a/src/view/shell/index.web.tsx b/src/view/shell/index.web.tsx index 24024e6e61..02993ac462 100644 --- a/src/view/shell/index.web.tsx +++ b/src/view/shell/index.web.tsx @@ -45,8 +45,9 @@ function ShellInner() { <Composer winHeight={0} /> <ModalsContainer /> <MutedWordsDialog /> - <PortalOutlet /> <Lightbox /> + <PortalOutlet /> + {!isDesktop && isDrawerOpen && ( <TouchableOpacity onPress={() => setDrawerOpen(false)} diff --git a/yarn.lock b/yarn.lock index 28d8210285..83dee81cdc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,15 +34,15 @@ jsonpointer "^5.0.0" leven "^3.1.0" -"@atproto/api@^0.10.5": - version "0.10.5" - resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.10.5.tgz#e778e2843d08690df8df81f24028a7578e9b3cb4" - integrity sha512-GYdST5sPKU2JnPmm8x3KqjOSlDiYXrp4GkW7bpQTVLPabnUNq5NLN6HJEoJABjjOAsaLF12rBoV+JpRb1UjNsQ== +"@atproto/api@^0.11.2": + version "0.11.2" + resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.11.2.tgz#33432cdaeff674d8b21a28601542884bbe1473b2" + integrity sha512-VYpavKaEfuXhce9mP/+boZ7BNglnKSReFCRNXhFpa1KnAvWFHGsf+2jP69skEEnZ1XY4/lQhXdDzZdUIqXn2aA== dependencies: - "@atproto/common-web" "^0.2.3" - "@atproto/lexicon" "^0.3.2" - "@atproto/syntax" "^0.2.0" - "@atproto/xrpc" "^0.4.2" + "@atproto/common-web" "^0.2.4" + "@atproto/lexicon" "^0.3.3" + "@atproto/syntax" "^0.2.1" + "@atproto/xrpc" "^0.4.3" multiformats "^9.9.0" tlds "^1.234.0" typed-emitter "^2.1.0" @@ -144,6 +144,16 @@ uint8arrays "3.0.0" zod "^3.21.4" +"@atproto/common-web@^0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@atproto/common-web/-/common-web-0.2.4.tgz#a77e0a7f8f025115b3db4f7c530b934b10ab3d82" + integrity sha512-6+DOhQcTklFmeiSkZRx6iFeqi4OFtGl4yEDGATk00q4tEcPoPvyOBtYHN6+G9lrfJIfx5RfmggamvXlJv1PxxA== + dependencies: + graphemer "^1.4.0" + multiformats "^9.9.0" + uint8arrays "3.0.0" + zod "^3.21.4" + "@atproto/common@0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@atproto/common/-/common-0.1.0.tgz#4216a8fef5b985ab62ac21252a0f8ca0f4a0f210" @@ -245,13 +255,13 @@ multiformats "^9.9.0" zod "^3.21.4" -"@atproto/lexicon@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.3.2.tgz#0085a3acd3a77867b8efe188297a1bbacc55ce5c" - integrity sha512-kmGCkrRwpWIqmn/KO4BZwUf8Nmfndk3XvFC06V0ygCWc42g6+t4QP/6ywNW4PgqfZY0Q5aW4EuDfD7KjAFkFtQ== +"@atproto/lexicon@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.3.3.tgz#e242bf8b024661b3312a8da5b84fe2cd627a6ab1" + integrity sha512-6FOjdc3V05JKrtkhjfhHMS7f/4hMJOeHNtoE3Na7iFMpzBz0Lw5sw8kIFKY8pc8IG79qGcFgELyHLsljZYX+5A== dependencies: - "@atproto/common-web" "^0.2.3" - "@atproto/syntax" "^0.2.0" + "@atproto/common-web" "^0.2.4" + "@atproto/syntax" "^0.2.1" iso-datestring-validator "^2.2.2" multiformats "^9.9.0" zod "^3.21.4" @@ -351,12 +361,12 @@ dependencies: "@atproto/common-web" "^0.2.3" -"@atproto/syntax@^0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@atproto/syntax/-/syntax-0.2.0.tgz#4bab724c02e11f8943b8ec101251082cf55067e9" - integrity sha512-K+9jl6mtxC9ytlR7msSiP9jVNqtdxEBSt0kOfsC924lqGwuD8nlUAMi1GSMgAZJGg/Rd+0MKXh789heTdeL3HQ== +"@atproto/syntax@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@atproto/syntax/-/syntax-0.2.1.tgz#3abcb050c122e7ce80fc25b49cd7d86c63dc6c2e" + integrity sha512-ImOuiICtB5h78j90hAYOfTYzr5q5Wut0irNdELiogA3i74a8EXThe+j6Tj8snanYggrShbu5c6BDc1tVj477Yw== dependencies: - "@atproto/common-web" "^0.2.3" + "@atproto/common-web" "^0.2.4" "@atproto/xrpc-server@^0.4.2": version "0.4.2" @@ -383,12 +393,12 @@ "@atproto/lexicon" "^0.3.1" zod "^3.21.4" -"@atproto/xrpc@^0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.4.2.tgz#57812e0624be597b85f21471acf336513f35ccda" - integrity sha512-x4x2QB4nWmLjIpz2Ue9n/QVbVyJkk6tQMhvmDQaVFF89E3FcVI4rxF4uhzSxaLpbNtyVQBNEEmNHOr5EJLeHVA== +"@atproto/xrpc@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.4.3.tgz#19d85cb7f343369363e664917945dec1f89fde97" + integrity sha512-0rn3abHORG0T93mci8WW97Cpg2ClU2aCtTq5rxdCPRsl9P4tyP+8F4snbkrIaMbVO05Rd9D9gFwtWs5Z473pCQ== dependencies: - "@atproto/lexicon" "^0.3.2" + "@atproto/lexicon" "^0.3.3" zod "^3.21.4" "@aws-crypto/crc32@3.0.0": @@ -7244,11 +7254,37 @@ dependencies: "@tamagui/constants" "1.84.1" +"@tanstack/query-async-storage-persister@^5.25.0": + version "5.25.0" + resolved "https://registry.yarnpkg.com/@tanstack/query-async-storage-persister/-/query-async-storage-persister-5.25.0.tgz#0e8a2a781b8e32a81a5d02a688d6fcdfd055235b" + integrity sha512-58UTp1CuLr2mehsJRMOd8IZPtYGHFeL+uHnHyRd1kmbwo7wDaa8HXstiBdTRq5KokxIXy9FiFbA06LtKuOiwMQ== + dependencies: + "@tanstack/query-persist-client-core" "5.25.0" + +"@tanstack/query-core@5.25.0": + version "5.25.0" + resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.25.0.tgz#e08ed0a9fad34c8005d1a282e57280031ac50cdc" + integrity sha512-vlobHP64HTuSE68lWF1mEhwSRC5Q7gaT+a/m9S+ItuN+ruSOxe1rFnR9j0ACWQ314BPhBEVKfBQ6mHL0OWfdbQ== + "@tanstack/query-core@5.8.1": version "5.8.1" resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.8.1.tgz#5215a028370d9b2f32e83787a0ea119e2f977996" integrity sha512-Y0enatz2zQXBAsd7XmajlCs+WaitdR7dIFkqz9Xd7HL4KV04JOigWVreYseTmNH7YFSBSC/BJ9uuNp1MAf+GfA== +"@tanstack/query-persist-client-core@5.25.0": + version "5.25.0" + resolved "https://registry.yarnpkg.com/@tanstack/query-persist-client-core/-/query-persist-client-core-5.25.0.tgz#52fa634a8067d7b965854a532a33077fd4df0eff" + integrity sha512-sEUsEZ/XWkOosO45CDBI5nj5woCS+DUd9Dk8pGpU8MkeH0EVd3p4N5CdbjNhrreyy5Krf3rpNaiRN9ygLX/rWA== + dependencies: + "@tanstack/query-core" "5.25.0" + +"@tanstack/react-query-persist-client@^5.25.0": + version "5.25.0" + resolved "https://registry.yarnpkg.com/@tanstack/react-query-persist-client/-/react-query-persist-client-5.25.0.tgz#ecbd1362cd6fd94e723d54f5af477d0812852dab" + integrity sha512-j1+GyFj4UQGWuiFZoDUVJZS+wxqKd9SGvPlyHG619zzYNN+QQu4B5uvvHc6U8MroM377EOBOuLKK3W6qsAdahQ== + dependencies: + "@tanstack/query-persist-client-core" "5.25.0" + "@tanstack/react-query@^5.8.1": version "5.8.1" resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.8.1.tgz#22a122016e23a39acd90341954a895980ec21ade" From 63fee70dfe26556a4ab196fa579afde3d2dbe085 Mon Sep 17 00:00:00 2001 From: Samuel Newman <mozzius@protonmail.com> Date: Sun, 17 Mar 2024 15:01:26 +0000 Subject: [PATCH 076/109] change outer border radius to 10 --- src/screens/Profile/Header/Shell.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screens/Profile/Header/Shell.tsx b/src/screens/Profile/Header/Shell.tsx index 1348b394cd..c470cb2861 100644 --- a/src/screens/Profile/Header/Shell.tsx +++ b/src/screens/Profile/Header/Shell.tsx @@ -159,6 +159,6 @@ const styles = StyleSheet.create({ borderWidth: 2, }, aviLabeler: { - borderRadius: 12, + borderRadius: 10, }, }) From 248f51a977302f3393c8f07c715d00c4e54fbfae Mon Sep 17 00:00:00 2001 From: Samuel Newman <mozzius@protonmail.com> Date: Sun, 17 Mar 2024 15:01:49 +0000 Subject: [PATCH 077/109] change default avi to use a rect instead of a path --- src/view/com/util/UserAvatar.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/view/com/util/UserAvatar.tsx b/src/view/com/util/UserAvatar.tsx index 39bc723032..8656c3f518 100644 --- a/src/view/com/util/UserAvatar.tsx +++ b/src/view/com/util/UserAvatar.tsx @@ -110,8 +110,12 @@ let DefaultAvatar = ({ viewBox="0 0 32 32" fill="none" stroke="none"> - <Path - d="M28 0H4C1.79086 0 0 1.79086 0 4V28C0 30.2091 1.79086 32 4 32H28C30.2091 32 32 30.2091 32 28V4C32 1.79086 30.2091 0 28 0Z" + <Rect + x="0" + y="0" + width="32" + height="32" + rx="3" fill={tokens.color.temp_purple} /> <Path From 1b10c7bc08cf517d2b3a943d8f8949ccc012028b Mon Sep 17 00:00:00 2001 From: Paul Frazee <pfrazee@gmail.com> Date: Mon, 18 Mar 2024 14:58:02 -0700 Subject: [PATCH 078/109] Use entryway for labeler getServices (#3256) --- src/state/queries/labeler.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/state/queries/labeler.ts b/src/state/queries/labeler.ts index c405a6b575..b2f93c4a4a 100644 --- a/src/state/queries/labeler.ts +++ b/src/state/queries/labeler.ts @@ -4,7 +4,7 @@ import {AppBskyLabelerDefs} from '@atproto/api' import {getAgent} from '#/state/session' import {preferencesQueryKey} from '#/state/queries/preferences' -import {STALE, PUBLIC_BSKY_AGENT} from '#/state/queries' +import {STALE} from '#/state/queries' export const labelerInfoQueryKey = (did: string) => ['labeler-info', did] export const labelersInfoQueryKey = (dids: string[]) => [ @@ -27,7 +27,7 @@ export function useLabelerInfoQuery({ enabled: !!did && enabled !== false, queryKey: labelerInfoQueryKey(did as string), queryFn: async () => { - const res = await PUBLIC_BSKY_AGENT.app.bsky.labeler.getServices({ + const res = await getAgent().app.bsky.labeler.getServices({ dids: [did as string], detailed: true, }) @@ -41,7 +41,7 @@ export function useLabelersInfoQuery({dids}: {dids: string[]}) { enabled: !!dids.length, queryKey: labelersInfoQueryKey(dids), queryFn: async () => { - const res = await PUBLIC_BSKY_AGENT.app.bsky.labeler.getServices({dids}) + const res = await getAgent().app.bsky.labeler.getServices({dids}) return res.data.views as AppBskyLabelerDefs.LabelerView[] }, }) @@ -54,7 +54,7 @@ export function useLabelersDetailedInfoQuery({dids}: {dids: string[]}) { gcTime: 1000 * 60 * 60 * 6, // 6 hours staleTime: STALE.MINUTES.ONE, queryFn: async () => { - const res = await PUBLIC_BSKY_AGENT.app.bsky.labeler.getServices({ + const res = await getAgent().app.bsky.labeler.getServices({ dids, detailed: true, }) From 959121f394cd92a5931d618d1cadf6315663c59c Mon Sep 17 00:00:00 2001 From: Paul Frazee <pfrazee@gmail.com> Date: Mon, 18 Mar 2024 16:15:57 -0700 Subject: [PATCH 079/109] Update the reporting flow to first select a recipient if the user has multiple labelers (#3258) --- .../ReportDialog/SelectLabelerView.tsx | 115 ++++++++++++++++++ .../ReportDialog/SelectReportOptionView.tsx | 18 ++- src/components/ReportDialog/SubmitView.tsx | 8 +- src/components/ReportDialog/index.tsx | 54 +++++--- 4 files changed, 175 insertions(+), 20 deletions(-) create mode 100644 src/components/ReportDialog/SelectLabelerView.tsx diff --git a/src/components/ReportDialog/SelectLabelerView.tsx b/src/components/ReportDialog/SelectLabelerView.tsx new file mode 100644 index 0000000000..300114fc4f --- /dev/null +++ b/src/components/ReportDialog/SelectLabelerView.tsx @@ -0,0 +1,115 @@ +import React from 'react' +import {View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {AppBskyLabelerDefs} from '@atproto/api' + +export {useDialogControl as useReportDialogControl} from '#/components/Dialog' + +import {atoms as a, useTheme} from '#/alf' +import {Text} from '#/components/Typography' +import {Button, useButtonContext} from '#/components/Button' +import {Divider} from '#/components/Divider' +import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' + +import {ReportDialogProps} from './types' + +export function SelectLabelerView({ + ...props +}: ReportDialogProps & { + labelers: AppBskyLabelerDefs.LabelerViewDetailed[] + onSelectLabeler: (v: string) => void +}) { + const t = useTheme() + const {_} = useLingui() + + return ( + <View style={[a.gap_lg]}> + <View style={[a.justify_center, a.gap_sm]}> + <Text style={[a.text_2xl, a.font_bold]}> + <Trans>Select moderation service</Trans> + </Text> + <Text style={[a.text_md, t.atoms.text_contrast_medium]}> + <Trans>Who do you want to send this report to?</Trans> + </Text> + </View> + + <Divider /> + + <View style={[a.gap_sm, {marginHorizontal: a.p_md.padding * -1}]}> + {props.labelers.map(labeler => { + return ( + <Button + key={labeler.creator.did} + label={_(msg`Send report to ${labeler.creator.displayName}`)} + onPress={() => props.onSelectLabeler(labeler.creator.did)}> + <LabelerButton + title={labeler.creator.displayName || labeler.creator.handle} + description={labeler.creator.description || ''} + /> + </Button> + ) + })} + </View> + </View> + ) +} + +function LabelerButton({ + title, + description, +}: { + title: string + description: string +}) { + const t = useTheme() + const {hovered, pressed} = useButtonContext() + const interacted = hovered || pressed + + const styles = React.useMemo(() => { + return { + interacted: { + backgroundColor: t.palette.contrast_50, + }, + } + }, [t]) + + return ( + <View + style={[ + a.w_full, + a.flex_row, + a.align_center, + a.justify_between, + a.p_md, + a.rounded_md, + {paddingRight: 70}, + interacted && styles.interacted, + ]}> + <View style={[a.flex_1, a.gap_xs]}> + <Text style={[a.text_md, a.font_bold, t.atoms.text_contrast_medium]}> + {title} + </Text> + <Text style={[a.leading_tight, {maxWidth: 400}]} numberOfLines={3}> + {description} + </Text> + </View> + + <View + style={[ + a.absolute, + a.inset_0, + a.justify_center, + a.pr_md, + {left: 'auto'}, + ]}> + <ChevronRight + size="md" + fill={ + hovered ? t.palette.primary_500 : t.atoms.text_contrast_low.color + } + /> + </View> + </View> + ) +} diff --git a/src/components/ReportDialog/SelectReportOptionView.tsx b/src/components/ReportDialog/SelectReportOptionView.tsx index 8ae0b52ecb..037a62fceb 100644 --- a/src/components/ReportDialog/SelectReportOptionView.tsx +++ b/src/components/ReportDialog/SelectReportOptionView.tsx @@ -18,7 +18,10 @@ import { useButtonContext, } from '#/components/Button' import {Divider} from '#/components/Divider' -import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' +import { + ChevronRight_Stroke2_Corner0_Rounded as ChevronRight, + ChevronLeft_Stroke2_Corner0_Rounded as ChevronLeft, +} from '#/components/icons/Chevron' import {SquareArrowTopRight_Stroke2_Corner0_Rounded as SquareArrowTopRight} from '#/components/icons/SquareArrowTopRight' import {ReportDialogProps} from './types' @@ -28,6 +31,7 @@ export function SelectReportOptionView({ }: ReportDialogProps & { labelers: AppBskyLabelerDefs.LabelerViewDetailed[] onSelectReportOption: (reportOption: ReportOption) => void + goBack: () => void }) { const t = useTheme() const {_} = useLingui() @@ -60,6 +64,18 @@ export function SelectReportOptionView({ return ( <View style={[a.gap_lg]}> + {props.labelers?.length > 1 ? ( + <Button + size="small" + variant="solid" + color="secondary" + shape="round" + label={_(msg`Go back to previous step`)} + onPress={props.goBack}> + <ButtonIcon icon={ChevronLeft} /> + </Button> + ) : null} + <View style={[a.justify_center, a.gap_sm]}> <Text style={[a.text_2xl, a.font_bold]}>{i18n.title}</Text> <Text style={[a.text_md, t.atoms.text_contrast_medium]}> diff --git a/src/components/ReportDialog/SubmitView.tsx b/src/components/ReportDialog/SubmitView.tsx index 99af64a2a6..d47211c81c 100644 --- a/src/components/ReportDialog/SubmitView.tsx +++ b/src/components/ReportDialog/SubmitView.tsx @@ -24,11 +24,13 @@ import {getAgent} from '#/state/session' export function SubmitView({ params, labelers, + selectedLabeler, selectedReportOption, goBack, onSubmitComplete, }: ReportDialogProps & { labelers: AppBskyLabelerDefs.LabelerViewDetailed[] + selectedLabeler: string selectedReportOption: ReportOption goBack: () => void onSubmitComplete: () => void @@ -37,9 +39,9 @@ export function SubmitView({ const {_} = useLingui() const [details, setDetails] = React.useState<string>('') const [submitting, setSubmitting] = React.useState<boolean>(false) - const [selectedServices, setSelectedServices] = React.useState<string[]>( - labelers?.map(labeler => labeler.creator.did) || [], - ) + const [selectedServices, setSelectedServices] = React.useState<string[]>([ + selectedLabeler, + ]) const [error, setError] = React.useState('') const submit = React.useCallback(async () => { diff --git a/src/components/ReportDialog/index.tsx b/src/components/ReportDialog/index.tsx index b35727c7dd..f01ff3f3b1 100644 --- a/src/components/ReportDialog/index.tsx +++ b/src/components/ReportDialog/index.tsx @@ -12,9 +12,11 @@ import * as Dialog from '#/components/Dialog' import {Text} from '#/components/Typography' import {ReportDialogProps} from './types' +import {SelectLabelerView} from './SelectLabelerView' import {SelectReportOptionView} from './SelectReportOptionView' import {SubmitView} from './SubmitView' import {useDelayedLoading} from '#/components/hooks/useDelayedLoading' +import {AppBskyLabelerDefs} from '@atproto/api' export function ReportDialog(props: ReportDialogProps) { return ( @@ -33,9 +35,6 @@ function ReportDialogInner(props: ReportDialogProps) { error, } = useMyLabelersQuery() const isLoading = useDelayedLoading(500, isLabelerLoading) - const [selectedReportOption, setSelectedReportOption] = React.useState< - ReportOption | undefined - >() return ( <Dialog.ScrollableInner label="Report Dialog"> @@ -51,23 +50,46 @@ function ReportDialogInner(props: ReportDialogProps) { <Trans>Something went wrong, please try again.</Trans> </Text> </View> - ) : selectedReportOption ? ( - <SubmitView - {...props} - labelers={labelers} - selectedReportOption={selectedReportOption} - goBack={() => setSelectedReportOption(undefined)} - onSubmitComplete={() => props.control.close()} - /> ) : ( - <SelectReportOptionView - {...props} - labelers={labelers} - onSelectReportOption={setSelectedReportOption} - /> + <ReportDialogLoaded labelers={labelers} {...props} /> )} <Dialog.Close /> </Dialog.ScrollableInner> ) } + +function ReportDialogLoaded( + props: ReportDialogProps & { + labelers: AppBskyLabelerDefs.LabelerViewDetailed[] + }, +) { + const [selectedLabeler, setSelectedLabeler] = React.useState< + string | undefined + >(props.labelers.length === 1 ? props.labelers[0].creator.did : undefined) + const [selectedReportOption, setSelectedReportOption] = React.useState< + ReportOption | undefined + >() + + if (selectedReportOption && selectedLabeler) { + return ( + <SubmitView + {...props} + selectedLabeler={selectedLabeler} + selectedReportOption={selectedReportOption} + goBack={() => setSelectedReportOption(undefined)} + onSubmitComplete={() => props.control.close()} + /> + ) + } + if (selectedLabeler) { + return ( + <SelectReportOptionView + {...props} + goBack={() => setSelectedLabeler(undefined)} + onSelectReportOption={setSelectedReportOption} + /> + ) + } + return <SelectLabelerView {...props} onSelectLabeler={setSelectedLabeler} /> +} From 3abf302b0b189c50acf11489bf60bdaeb187b722 Mon Sep 17 00:00:00 2001 From: Paul Frazee <pfrazee@gmail.com> Date: Mon, 18 Mar 2024 17:46:25 -0700 Subject: [PATCH 080/109] Bump @atproto/api@0.12.0 (#3260) * Bump @atproto/api@0.12.0 * Fix unit tests --- jest/jestSetup.js | 2 ++ package.json | 2 +- yarn.lock | 58 ++++++++++++++++++++++------------------------- 3 files changed, 30 insertions(+), 32 deletions(-) diff --git a/jest/jestSetup.js b/jest/jestSetup.js index d8cee9bfda..e690e813a9 100644 --- a/jest/jestSetup.js +++ b/jest/jestSetup.js @@ -88,3 +88,5 @@ jest.mock('sentry-expo', () => ({ ReactNavigationInstrumentation: jest.fn(), }, })) + +jest.mock('crypto', () => ({})) diff --git a/package.json b/package.json index 30df66950a..b526825fbd 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "update-extensions": "scripts/updateExtensions.sh" }, "dependencies": { - "@atproto/api": "^0.11.2", + "@atproto/api": "^0.12.0", "@bam.tech/react-native-image-resizer": "^3.0.4", "@braintree/sanitize-url": "^6.0.2", "@emoji-mart/react": "^1.1.1", diff --git a/yarn.lock b/yarn.lock index 83dee81cdc..266734cdc1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,19 +34,17 @@ jsonpointer "^5.0.0" leven "^3.1.0" -"@atproto/api@^0.11.2": - version "0.11.2" - resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.11.2.tgz#33432cdaeff674d8b21a28601542884bbe1473b2" - integrity sha512-VYpavKaEfuXhce9mP/+boZ7BNglnKSReFCRNXhFpa1KnAvWFHGsf+2jP69skEEnZ1XY4/lQhXdDzZdUIqXn2aA== +"@atproto/api@^0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.0.tgz#69e52f8761dc7d76c675fa7284bd49240bb0df64" + integrity sha512-nSWiad1Z6IC/oVFSVxD5gZLhkD+J4EW2CFqAqIhklJNc0cjFKdmf8D56Pac6Ktm1sJoM6TVZ8GEeuEG6bJS/aQ== dependencies: - "@atproto/common-web" "^0.2.4" - "@atproto/lexicon" "^0.3.3" - "@atproto/syntax" "^0.2.1" - "@atproto/xrpc" "^0.4.3" + "@atproto/common-web" "^0.3.0" + "@atproto/lexicon" "^0.4.0" + "@atproto/syntax" "^0.3.0" + "@atproto/xrpc" "^0.5.0" multiformats "^9.9.0" tlds "^1.234.0" - typed-emitter "^2.1.0" - zod "^3.21.4" "@atproto/api@^0.9.5": version "0.9.5" @@ -144,10 +142,10 @@ uint8arrays "3.0.0" zod "^3.21.4" -"@atproto/common-web@^0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@atproto/common-web/-/common-web-0.2.4.tgz#a77e0a7f8f025115b3db4f7c530b934b10ab3d82" - integrity sha512-6+DOhQcTklFmeiSkZRx6iFeqi4OFtGl4yEDGATk00q4tEcPoPvyOBtYHN6+G9lrfJIfx5RfmggamvXlJv1PxxA== +"@atproto/common-web@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@atproto/common-web/-/common-web-0.3.0.tgz#36da8c2c31d8cf8a140c3c8f03223319bf4430bb" + integrity sha512-67VnV6JJyX+ZWyjV7xFQMypAgDmjVaR9ZCuU/QW+mqlqI7fex2uL4Fv+7/jHadgzhuJHVd6OHOvNn0wR5WZYtA== dependencies: graphemer "^1.4.0" multiformats "^9.9.0" @@ -255,13 +253,13 @@ multiformats "^9.9.0" zod "^3.21.4" -"@atproto/lexicon@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.3.3.tgz#e242bf8b024661b3312a8da5b84fe2cd627a6ab1" - integrity sha512-6FOjdc3V05JKrtkhjfhHMS7f/4hMJOeHNtoE3Na7iFMpzBz0Lw5sw8kIFKY8pc8IG79qGcFgELyHLsljZYX+5A== +"@atproto/lexicon@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.4.0.tgz#63e8829945d80c25524882caa8ed27b1151cc576" + integrity sha512-RvCBKdSI4M8qWm5uTNz1z3R2yIvIhmOsMuleOj8YR6BwRD+QbtUBy3l+xQ7iXf4M5fdfJFxaUNa6Ty0iRwdKqQ== dependencies: - "@atproto/common-web" "^0.2.4" - "@atproto/syntax" "^0.2.1" + "@atproto/common-web" "^0.3.0" + "@atproto/syntax" "^0.3.0" iso-datestring-validator "^2.2.2" multiformats "^9.9.0" zod "^3.21.4" @@ -361,12 +359,10 @@ dependencies: "@atproto/common-web" "^0.2.3" -"@atproto/syntax@^0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@atproto/syntax/-/syntax-0.2.1.tgz#3abcb050c122e7ce80fc25b49cd7d86c63dc6c2e" - integrity sha512-ImOuiICtB5h78j90hAYOfTYzr5q5Wut0irNdELiogA3i74a8EXThe+j6Tj8snanYggrShbu5c6BDc1tVj477Yw== - dependencies: - "@atproto/common-web" "^0.2.4" +"@atproto/syntax@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@atproto/syntax/-/syntax-0.3.0.tgz#fafa2dbea9add37253005cb663e7373e05e618b3" + integrity sha512-Weq0ZBxffGHDXHl9U7BQc2BFJi/e23AL+k+i5+D9hUq/bzT4yjGsrCejkjq0xt82xXDjmhhvQSZ0LqxyZ5woxA== "@atproto/xrpc-server@^0.4.2": version "0.4.2" @@ -393,12 +389,12 @@ "@atproto/lexicon" "^0.3.1" zod "^3.21.4" -"@atproto/xrpc@^0.4.3": - version "0.4.3" - resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.4.3.tgz#19d85cb7f343369363e664917945dec1f89fde97" - integrity sha512-0rn3abHORG0T93mci8WW97Cpg2ClU2aCtTq5rxdCPRsl9P4tyP+8F4snbkrIaMbVO05Rd9D9gFwtWs5Z473pCQ== +"@atproto/xrpc@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.5.0.tgz#dacbfd8f7b13f0ab5bd56f8fdd4b460e132a6032" + integrity sha512-swu+wyOLvYW4l3n+VAuJbHcPcES+tin2Lsrp8Bw5aIXIICiuFn1YMFlwK9JwVUzTH21Py1s1nHEjr4CJeElJog== dependencies: - "@atproto/lexicon" "^0.3.3" + "@atproto/lexicon" "^0.4.0" zod "^3.21.4" "@aws-crypto/crc32@3.0.0": From 4de8e8fa14774e753dea94a8fc01a5847c5dfcd2 Mon Sep 17 00:00:00 2001 From: Hailey <me@haileyok.com> Date: Tue, 19 Mar 2024 07:56:28 -0700 Subject: [PATCH 081/109] fix borders for labels tab (#3261) * fix borders for labels tab * rm entire wrapping view --- src/screens/Profile/Sections/Labels.tsx | 60 +++++++++---------------- 1 file changed, 21 insertions(+), 39 deletions(-) diff --git a/src/screens/Profile/Sections/Labels.tsx b/src/screens/Profile/Sections/Labels.tsx index 07beb95294..08db4a861d 100644 --- a/src/screens/Profile/Sections/Labels.tsx +++ b/src/screens/Profile/Sections/Labels.tsx @@ -48,7 +48,6 @@ export const ProfileLabelsSection = React.forwardRef< }, ref, ) { - const t = useTheme() const {_} = useLingui() const {height: minHeight} = useSafeAreaFrame() @@ -66,37 +65,26 @@ export const ProfileLabelsSection = React.forwardRef< })) return ( - <CenteredView> - <View - style={[ - a.border_l, - a.border_r, - a.border_t, - t.atoms.border_contrast_low, - { - minHeight, - }, - ]}> - {isLabelerLoading ? ( - <View style={[a.w_full, a.align_center]}> - <Loader size="xl" /> - </View> - ) : labelerError || !labelerInfo ? ( - <ErrorState - error={ - labelerError?.toString() || - _(msg`Something went wrong, please try again.`) - } - /> - ) : ( - <ProfileLabelsSectionInner - moderationOpts={moderationOpts} - labelerInfo={labelerInfo} - scrollElRef={scrollElRef} - headerHeight={headerHeight} - /> - )} - </View> + <CenteredView style={{flex: 1, minHeight}} sideBorders> + {isLabelerLoading ? ( + <View style={[a.w_full, a.align_center]}> + <Loader size="xl" /> + </View> + ) : labelerError || !labelerInfo ? ( + <ErrorState + error={ + labelerError?.toString() || + _(msg`Something went wrong, please try again.`) + } + /> + ) : ( + <ProfileLabelsSectionInner + moderationOpts={moderationOpts} + labelerInfo={labelerInfo} + scrollElRef={scrollElRef} + headerHeight={headerHeight} + /> + )} </CenteredView> ) }) @@ -149,13 +137,7 @@ export function ProfileLabelsSectionInner({ }} contentOffset={{x: 0, y: headerHeight * -1}} onScroll={scrollHandler}> - <View - style={[ - a.pt_xl, - a.px_lg, - isNative && a.border_t, - t.atoms.border_contrast_low, - ]}> + <View style={[a.pt_xl, a.px_lg, a.border_t, t.atoms.border_contrast_low]}> <View> <Text style={[t.atoms.text_contrast_high, a.leading_snug, a.text_sm]}> <Trans> From 8ac5144a584450f037771de4da775d545b70ffa3 Mon Sep 17 00:00:00 2001 From: Eric Bailey <git@esb.lol> Date: Tue, 19 Mar 2024 09:57:14 -0500 Subject: [PATCH 082/109] Bday modal tweaks (#3252) * Smol tweaks to bday dialog * Juse use existing DateInput for now * Remove unused code * Remove passed-in prefs * Adjust load state * Revert "Adjust load state" This reverts commit 802459fd044b380ccc4f96432af416996219a0de. * Fix type error --- src/components/dialogs/BirthDateSettings.tsx | 74 +++++++++++--------- src/screens/Moderation/index.tsx | 5 +- src/view/screens/Settings/index.tsx | 11 +-- 3 files changed, 44 insertions(+), 46 deletions(-) diff --git a/src/components/dialogs/BirthDateSettings.tsx b/src/components/dialogs/BirthDateSettings.tsx index 62c95c78d6..4a3e96e56d 100644 --- a/src/components/dialogs/BirthDateSettings.tsx +++ b/src/components/dialogs/BirthDateSettings.tsx @@ -1,48 +1,64 @@ import React from 'react' import {useLingui} from '@lingui/react' import {Trans, msg} from '@lingui/macro' +import {View} from 'react-native' import * as Dialog from '#/components/Dialog' import {Text} from '../Typography' import {DateInput} from '#/view/com/util/forms/DateInput' import {logger} from '#/logger' import { + usePreferencesQuery, usePreferencesSetBirthDateMutation, UsePreferencesQueryResponse, } from '#/state/queries/preferences' -import {Button, ButtonText} from '../Button' +import {Button, ButtonIcon, ButtonText} from '../Button' import {atoms as a, useTheme} from '#/alf' import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' import {cleanError} from '#/lib/strings/errors' -import {ActivityIndicator, View} from 'react-native' import {isIOS, isWeb} from '#/platform/detection' +import {Loader} from '#/components/Loader' export function BirthDateSettingsDialog({ control, - preferences, }: { control: Dialog.DialogControlProps - preferences: UsePreferencesQueryResponse | undefined }) { + const t = useTheme() const {_} = useLingui() - const {isPending, isError, error, mutateAsync} = - usePreferencesSetBirthDateMutation() + const {isLoading, error, data: preferences} = usePreferencesQuery() return ( <Dialog.Outer control={control}> <Dialog.Handle /> + <Dialog.ScrollableInner label={_(msg`My Birthday`)}> - {preferences && !isPending ? ( - <BirthdayInner - control={control} - preferences={preferences} - isError={isError} - error={error} - setBirthDate={mutateAsync} + <View style={[a.gap_sm, a.pb_lg]}> + <Text style={[a.text_2xl, a.font_bold]}> + <Trans>My Birthday</Trans> + </Text> + <Text style={[a.text_md, t.atoms.text_contrast_medium]}> + <Trans>This information is not shared with other users.</Trans> + </Text> + </View> + + {isLoading ? ( + <Loader size="xl" /> + ) : error || !preferences ? ( + <ErrorMessage + message={ + error?.toString() || + _( + msg`We were unable to load your birth date preferences. Please try again.`, + ) + } + style={[a.rounded_sm]} /> ) : ( - <ActivityIndicator size="large" style={a.my_5xl} /> + <BirthdayInner control={control} preferences={preferences} /> )} + + <Dialog.Close /> </Dialog.ScrollableInner> </Dialog.Outer> ) @@ -51,20 +67,18 @@ export function BirthDateSettingsDialog({ function BirthdayInner({ control, preferences, - isError, - error, - setBirthDate, }: { control: Dialog.DialogControlProps preferences: UsePreferencesQueryResponse - isError: boolean - error: unknown - setBirthDate: (args: {birthDate: Date}) => Promise<unknown> }) { const {_} = useLingui() const [date, setDate] = React.useState(preferences.birthDate || new Date()) - const t = useTheme() - + const { + isPending, + isError, + error, + mutateAsync: setBirthDate, + } = usePreferencesSetBirthDateMutation() const hasChanged = date !== preferences.birthDate const onSave = React.useCallback(async () => { @@ -74,21 +88,13 @@ function BirthdayInner({ await setBirthDate({birthDate: date}) } control.close() - } catch (e) { - logger.error(`setBirthDate failed`, {message: e}) + } catch (e: any) { + logger.error(`setBirthDate failed`, {message: e.message}) } }, [date, setBirthDate, control, hasChanged]) return ( <View style={a.gap_lg} testID="birthDateSettingsDialog"> - <View style={[a.gap_sm]}> - <Text style={[a.text_2xl, a.font_bold]}> - <Trans>My Birthday</Trans> - </Text> - <Text style={t.atoms.text_contrast_medium}> - <Trans>This information is not shared with other users.</Trans> - </Text> - </View> <View style={isIOS && [a.w_full, a.align_center]}> <DateInput handleAsUTC @@ -103,6 +109,7 @@ function BirthdayInner({ accessibilityLabelledBy="birthDate" /> </View> + {isError ? ( <ErrorMessage message={cleanError(error)} style={[a.rounded_sm]} /> ) : undefined} @@ -110,13 +117,14 @@ function BirthdayInner({ <View style={isWeb && [a.flex_row, a.justify_end]}> <Button label={hasChanged ? _(msg`Save birthday`) : _(msg`Done`)} - size={isWeb ? 'small' : 'medium'} + size="medium" onPress={onSave} variant="solid" color="primary"> <ButtonText> {hasChanged ? <Trans>Save</Trans> : <Trans>Done</Trans>} </ButtonText> + {isPending && <ButtonIcon icon={Loader} />} </Button> </View> </View> diff --git a/src/screens/Moderation/index.tsx b/src/screens/Moderation/index.tsx index 26fa9ec77c..d0bfaeade8 100644 --- a/src/screens/Moderation/index.tsx +++ b/src/screens/Moderation/index.tsx @@ -308,10 +308,7 @@ export function ModerationScreenInner({ </ButtonText> </Button> - <BirthDateSettingsDialog - control={birthdateDialogControl} - preferences={preferences} - /> + <BirthDateSettingsDialog control={birthdateDialogControl} /> </> )} <View diff --git a/src/view/screens/Settings/index.tsx b/src/view/screens/Settings/index.tsx index 1b96a09aff..21225f5813 100644 --- a/src/view/screens/Settings/index.tsx +++ b/src/view/screens/Settings/index.tsx @@ -40,10 +40,7 @@ import { } from '#/state/preferences' import {useSession, useSessionApi, SessionAccount} from '#/state/session' import {useProfileQuery} from '#/state/queries/profile' -import { - useClearPreferencesMutation, - usePreferencesQuery, -} from '#/state/queries/preferences' +import {useClearPreferencesMutation} from '#/state/queries/preferences' // TODO import {useInviteCodesQuery} from '#/state/queries/invites' import {clear as clearStorage} from '#/state/persisted/store' import {clearLegacyStorage} from '#/state/persisted/legacy' @@ -156,7 +153,6 @@ export function SettingsScreen({}: Props) { const {screen, track} = useAnalytics() const {openModal} = useModalControls() const {isSwitchingAccounts, accounts, currentAccount} = useSession() - const {data: preferences} = usePreferencesQuery() const {mutate: clearPreferences} = useClearPreferencesMutation() // TODO // const {data: invites} = useInviteCodesQuery() @@ -295,10 +291,7 @@ export function SettingsScreen({}: Props) { return ( <View style={s.hContentRegion} testID="settingsScreen"> <ExportCarDialog control={exportCarControl} /> - <BirthDateSettingsDialog - control={birthdayControl} - preferences={preferences} - /> + <BirthDateSettingsDialog control={birthdayControl} /> <SimpleViewHeader showBackButton={isMobile} From 2a5b0ab2acb707a9d87da9e8da403d54734d72e8 Mon Sep 17 00:00:00 2001 From: Hailey <me@haileyok.com> Date: Tue, 19 Mar 2024 08:14:29 -0700 Subject: [PATCH 083/109] add `Partial<GestureResponderEvent>` to `.open()` (#3227) --- src/components/Dialog/types.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/Dialog/types.ts b/src/components/Dialog/types.ts index 9e7ad3c048..b1a46f8536 100644 --- a/src/components/Dialog/types.ts +++ b/src/components/Dialog/types.ts @@ -1,5 +1,5 @@ import React from 'react' -import type {AccessibilityProps} from 'react-native' +import type {AccessibilityProps, GestureResponderEvent} from 'react-native' import {BottomSheetProps} from '@gorhom/bottom-sheet' import {ViewStyleProp} from '#/alf' @@ -10,9 +10,15 @@ type A11yProps = Required<AccessibilityProps> * Mutated by useImperativeHandle to provide a public API for controlling the * dialog. The methods here will actually become the handlers defined within * the `Dialog.Outer` component. + * + * `Partial<GestureResponderEvent>` here allows us to add this directly to the + * `onPress` prop of a button, for example. If this type was not added, we + * would need to create a function to wrap `.open()` with. */ export type DialogControlRefProps = { - open: (options?: DialogControlOpenOptions) => void + open: ( + options?: DialogControlOpenOptions & Partial<GestureResponderEvent>, + ) => void close: (callback?: () => void) => void } From 877eab0fe327ad4bd30a871c4cb605e79243d0d0 Mon Sep 17 00:00:00 2001 From: Eric Bailey <git@esb.lol> Date: Tue, 19 Mar 2024 11:04:41 -0500 Subject: [PATCH 084/109] Fix space on bottom of mod screen (#3266) * Fix space on bottom of mod screen * fix PWI label overflow + center loader (#3268) --------- Co-authored-by: Samuel Newman <mozzius@protonmail.com> --- src/screens/Moderation/index.tsx | 457 +++++++++++++++---------------- 1 file changed, 228 insertions(+), 229 deletions(-) diff --git a/src/screens/Moderation/index.tsx b/src/screens/Moderation/index.tsx index d0bfaeade8..50e5ee3b9e 100644 --- a/src/screens/Moderation/index.tsx +++ b/src/screens/Moderation/index.tsx @@ -205,19 +205,111 @@ export function ModerationScreenInner({ ) return ( - <View> - <ScrollView - contentContainerStyle={[ - a.border_0, - a.pt_2xl, - a.px_lg, - gtMobile && a.px_2xl, - ]}> - <Text - style={[a.text_md, a.font_bold, a.pb_md, t.atoms.text_contrast_high]}> - <Trans>Moderation tools</Trans> - </Text> + <ScrollView + contentContainerStyle={[ + a.border_0, + a.pt_2xl, + a.px_lg, + gtMobile && a.px_2xl, + ]}> + <Text + style={[a.text_md, a.font_bold, a.pb_md, t.atoms.text_contrast_high]}> + <Trans>Moderation tools</Trans> + </Text> + <View + style={[ + a.w_full, + a.rounded_md, + a.overflow_hidden, + t.atoms.bg_contrast_25, + ]}> + <Button + testID="mutedWordsBtn" + label={_(msg`Open muted words and tags settings`)} + onPress={() => mutedWordsDialogControl.open()}> + {state => ( + <SubItem + title={_(msg`Muted words & tags`)} + icon={Filter} + style={[ + (state.hovered || state.pressed) && [t.atoms.bg_contrast_50], + ]} + /> + )} + </Button> + <Divider /> + <Link testID="moderationlistsBtn" to="/moderation/modlists"> + {state => ( + <SubItem + title={_(msg`Moderation lists`)} + icon={Group} + style={[ + (state.hovered || state.pressed) && [t.atoms.bg_contrast_50], + ]} + /> + )} + </Link> + <Divider /> + <Link testID="mutedAccountsBtn" to="/moderation/muted-accounts"> + {state => ( + <SubItem + title={_(msg`Muted accounts`)} + icon={Person} + style={[ + (state.hovered || state.pressed) && [t.atoms.bg_contrast_50], + ]} + /> + )} + </Link> + <Divider /> + <Link testID="blockedAccountsBtn" to="/moderation/blocked-accounts"> + {state => ( + <SubItem + title={_(msg`Blocked accounts`)} + icon={CircleBanSign} + style={[ + (state.hovered || state.pressed) && [t.atoms.bg_contrast_50], + ]} + /> + )} + </Link> + </View> + + <Text + style={[ + a.pt_2xl, + a.pb_md, + a.text_md, + a.font_bold, + t.atoms.text_contrast_high, + ]}> + <Trans>Content filters</Trans> + </Text> + + <View style={[a.gap_md]}> + {ageNotSet && ( + <> + <Button + label={_(msg`Confirm your birthdate`)} + size="small" + variant="solid" + color="secondary" + onPress={() => { + birthdateDialogControl.open() + }} + style={[a.justify_between, a.rounded_md, a.px_lg, a.py_lg]}> + <ButtonText> + <Trans>Confirm your age:</Trans> + </ButtonText> + <ButtonText> + <Trans>Set birthdate</Trans> + </ButtonText> + </Button> + + <BirthDateSettingsDialog control={birthdateDialogControl} /> + </> + )} <View style={[ a.w_full, @@ -225,231 +317,137 @@ export function ModerationScreenInner({ a.overflow_hidden, t.atoms.bg_contrast_25, ]}> - <Button - testID="mutedWordsBtn" - label={_(msg`Open muted words and tags settings`)} - onPress={() => mutedWordsDialogControl.open()}> - {state => ( - <SubItem - title={_(msg`Muted words & tags`)} - icon={Filter} - style={[ - (state.hovered || state.pressed) && [t.atoms.bg_contrast_50], - ]} - /> - )} - </Button> - <Divider /> - <Link testID="moderationlistsBtn" to="/moderation/modlists"> - {state => ( - <SubItem - title={_(msg`Moderation lists`)} - icon={Group} - style={[ - (state.hovered || state.pressed) && [t.atoms.bg_contrast_50], - ]} - /> - )} - </Link> - <Divider /> - <Link testID="mutedAccountsBtn" to="/moderation/muted-accounts"> - {state => ( - <SubItem - title={_(msg`Muted accounts`)} - icon={Person} - style={[ - (state.hovered || state.pressed) && [t.atoms.bg_contrast_50], - ]} - /> - )} - </Link> - <Divider /> - <Link testID="blockedAccountsBtn" to="/moderation/blocked-accounts"> - {state => ( - <SubItem - title={_(msg`Blocked accounts`)} - icon={CircleBanSign} - style={[ - (state.hovered || state.pressed) && [t.atoms.bg_contrast_50], - ]} - /> - )} - </Link> - </View> - - <Text - style={[ - a.pt_2xl, - a.pb_md, - a.text_md, - a.font_bold, - t.atoms.text_contrast_high, - ]}> - <Trans>Content filters</Trans> - </Text> - - <View style={[a.gap_md]}> - {ageNotSet && ( + {!ageNotSet && !isUnderage && ( <> - <Button - label={_(msg`Confirm your birthdate`)} - size="small" - variant="solid" - color="secondary" - onPress={() => { - birthdateDialogControl.open() - }} - style={[a.justify_between, a.rounded_md, a.px_lg, a.py_lg]}> - <ButtonText> - <Trans>Confirm your age:</Trans> - </ButtonText> - <ButtonText> - <Trans>Set birthdate</Trans> - </ButtonText> - </Button> - - <BirthDateSettingsDialog control={birthdateDialogControl} /> + <View + style={[ + a.py_lg, + a.px_lg, + a.flex_row, + a.align_center, + a.justify_between, + ]}> + <Text style={[a.font_semibold, t.atoms.text_contrast_high]}> + <Trans>Enable adult content</Trans> + </Text> + <Toggle.Item + label={_(msg`Toggle to enable or disable adult content`)} + name="adultContent" + value={adultContentEnabled} + onChange={onToggleAdultContentEnabled}> + <View style={[a.flex_row, a.align_center, a.gap_sm]}> + <Text style={[t.atoms.text_contrast_medium]}> + {adultContentEnabled ? ( + <Trans>Enabled</Trans> + ) : ( + <Trans>Disabled</Trans> + )} + </Text> + <Toggle.Switch /> + </View> + </Toggle.Item> + </View> + <Divider /> </> )} - <View - style={[ - a.w_full, - a.rounded_md, - a.overflow_hidden, - t.atoms.bg_contrast_25, - ]}> - {!ageNotSet && !isUnderage && ( - <> - <View - style={[ - a.py_lg, - a.px_lg, - a.flex_row, - a.align_center, - a.justify_between, - ]}> - <Text style={[a.font_semibold, t.atoms.text_contrast_high]}> - <Trans>Enable adult content</Trans> - </Text> - <Toggle.Item - label={_(msg`Toggle to enable or disable adult content`)} - name="adultContent" - value={adultContentEnabled} - onChange={onToggleAdultContentEnabled}> - <View style={[a.flex_row, a.align_center, a.gap_sm]}> - <Text style={[t.atoms.text_contrast_medium]}> - {adultContentEnabled ? ( - <Trans>Enabled</Trans> - ) : ( - <Trans>Disabled</Trans> - )} - </Text> - <Toggle.Switch /> - </View> - </Toggle.Item> - </View> - <Divider /> - </> - )} - {!isUnderage && adultContentEnabled && ( - <> - <GlobalModerationLabelPref labelValueDefinition={LABELS.porn} /> - <Divider /> - <GlobalModerationLabelPref - labelValueDefinition={LABELS.sexual} - /> - <Divider /> - <GlobalModerationLabelPref - labelValueDefinition={LABELS['graphic-media']} - /> - <Divider /> - </> - )} - <GlobalModerationLabelPref labelValueDefinition={LABELS.nudity} /> - </View> + {!isUnderage && adultContentEnabled && ( + <> + <GlobalModerationLabelPref labelValueDefinition={LABELS.porn} /> + <Divider /> + <GlobalModerationLabelPref labelValueDefinition={LABELS.sexual} /> + <Divider /> + <GlobalModerationLabelPref + labelValueDefinition={LABELS['graphic-media']} + /> + <Divider /> + </> + )} + <GlobalModerationLabelPref labelValueDefinition={LABELS.nudity} /> </View> + </View> - <Text - style={[ - a.text_md, - a.font_bold, - a.pt_2xl, - a.pb_md, - t.atoms.text_contrast_high, - ]}> - <Trans>Advanced</Trans> - </Text> + <Text + style={[ + a.text_md, + a.font_bold, + a.pt_2xl, + a.pb_md, + t.atoms.text_contrast_high, + ]}> + <Trans>Advanced</Trans> + </Text> - {isLabelersLoading ? ( - <Loader /> - ) : labelersError || !labelers ? ( - <View style={[a.p_lg, a.rounded_sm, t.atoms.bg_contrast_25]}> - <Text> - <Trans> - We were unable to load your configured labelers at this time. - </Trans> - </Text> - </View> - ) : ( - <View style={[a.rounded_sm, t.atoms.bg_contrast_25]}> - {labelers.map((labeler, i) => { - return ( - <React.Fragment key={labeler.creator.did}> - {i !== 0 && <Divider />} - <LabelingService.Link labeler={labeler}> - {state => ( - <LabelingService.Outer - style={[ - i === 0 && { - borderTopLeftRadius: a.rounded_sm.borderRadius, - borderTopRightRadius: a.rounded_sm.borderRadius, - }, - i === labelers.length - 1 && { - borderBottomLeftRadius: a.rounded_sm.borderRadius, - borderBottomRightRadius: a.rounded_sm.borderRadius, - }, - (state.hovered || state.pressed) && [ - t.atoms.bg_contrast_50, - ], - ]}> - <LabelingService.Avatar /> - <LabelingService.Content> - <LabelingService.Title - value={getLabelingServiceTitle({ - displayName: labeler.creator.displayName, - handle: labeler.creator.handle, - })} - /> - <LabelingService.Description - value={labeler.creator.description} - handle={labeler.creator.handle} - /> - </LabelingService.Content> - </LabelingService.Outer> - )} - </LabelingService.Link> - </React.Fragment> - ) - })} - </View> - )} + {isLabelersLoading ? ( + <View style={[a.w_full, a.align_center, a.p_lg]}> + <Loader size="xl" /> + </View> + ) : labelersError || !labelers ? ( + <View style={[a.p_lg, a.rounded_sm, t.atoms.bg_contrast_25]}> + <Text> + <Trans> + We were unable to load your configured labelers at this time. + </Trans> + </Text> + </View> + ) : ( + <View style={[a.rounded_sm, t.atoms.bg_contrast_25]}> + {labelers.map((labeler, i) => { + return ( + <React.Fragment key={labeler.creator.did}> + {i !== 0 && <Divider />} + <LabelingService.Link labeler={labeler}> + {state => ( + <LabelingService.Outer + style={[ + i === 0 && { + borderTopLeftRadius: a.rounded_sm.borderRadius, + borderTopRightRadius: a.rounded_sm.borderRadius, + }, + i === labelers.length - 1 && { + borderBottomLeftRadius: a.rounded_sm.borderRadius, + borderBottomRightRadius: a.rounded_sm.borderRadius, + }, + (state.hovered || state.pressed) && [ + t.atoms.bg_contrast_50, + ], + ]}> + <LabelingService.Avatar /> + <LabelingService.Content> + <LabelingService.Title + value={getLabelingServiceTitle({ + displayName: labeler.creator.displayName, + handle: labeler.creator.handle, + })} + /> + <LabelingService.Description + value={labeler.creator.description} + handle={labeler.creator.handle} + /> + </LabelingService.Content> + </LabelingService.Outer> + )} + </LabelingService.Link> + </React.Fragment> + ) + })} + </View> + )} - <Text - style={[ - a.text_md, - a.font_bold, - a.pt_2xl, - a.pb_md, - t.atoms.text_contrast_high, - ]}> - <Trans>Logged-out visibility</Trans> - </Text> + <Text + style={[ + a.text_md, + a.font_bold, + a.pt_2xl, + a.pb_md, + t.atoms.text_contrast_high, + ]}> + <Trans>Logged-out visibility</Trans> + </Text> - <PwiOptOut /> + <PwiOptOut /> - <View style={{height: 200}} /> - </ScrollView> - </View> + <View style={{height: 200}} /> + </ScrollView> ) } @@ -517,11 +515,12 @@ function PwiOptOut() { value={isOptedOut} onChange={onToggleOptOut} name="logged_out_visibility" + style={a.flex_1} label={_( msg`Discourage apps from showing my account to logged-out users`, )}> <Toggle.Switch /> - <Toggle.Label style={[a.text_md]}> + <Toggle.Label style={[a.text_md, a.flex_1]}> <Trans> Discourage apps from showing my account to logged-out users </Trans> From b622f6391805f9499034b2ba497dbb9b5c19bd93 Mon Sep 17 00:00:00 2001 From: Eric Bailey <git@esb.lol> Date: Tue, 19 Mar 2024 11:56:11 -0500 Subject: [PATCH 085/109] Mobile mod label setting component (#3267) * Mobile mod label setting component * Bump label title size * Dont show disabled label config on mobile --------- Co-authored-by: Paul Frazee <pfrazee@gmail.com> --- src/alf/index.tsx | 4 + .../moderation/ModerationLabelPref.tsx | 97 ++++++++++++------- 2 files changed, 64 insertions(+), 37 deletions(-) diff --git a/src/alf/index.tsx b/src/alf/index.tsx index 27738e91de..f0a0ede7a3 100644 --- a/src/alf/index.tsx +++ b/src/alf/index.tsx @@ -16,6 +16,7 @@ type BreakpointName = keyof typeof breakpoints const breakpoints: { [key: string]: number } = { + gtPhone: 500, gtMobile: 800, gtTablet: 1300, } @@ -26,6 +27,7 @@ function getActiveBreakpoints({width}: {width: number}) { return { active: active[active.length - 1], + gtPhone: active.includes('gtPhone'), gtMobile: active.includes('gtMobile'), gtTablet: active.includes('gtTablet'), } @@ -39,6 +41,7 @@ export const Context = React.createContext<{ theme: themes.Theme breakpoints: { active: BreakpointName | undefined + gtPhone: boolean gtMobile: boolean gtTablet: boolean } @@ -47,6 +50,7 @@ export const Context = React.createContext<{ theme: themes.light, breakpoints: { active: undefined, + gtPhone: false, gtMobile: false, gtTablet: false, }, diff --git a/src/components/moderation/ModerationLabelPref.tsx b/src/components/moderation/ModerationLabelPref.tsx index f145504881..b16c248592 100644 --- a/src/components/moderation/ModerationLabelPref.tsx +++ b/src/components/moderation/ModerationLabelPref.tsx @@ -12,7 +12,7 @@ import { } from '#/state/queries/preferences' import {getLabelStrings} from '#/lib/moderation/useLabelInfo' -import {useTheme, atoms as a} from '#/alf' +import {useTheme, atoms as a, useBreakpoints} from '#/alf' import {Text} from '#/components/Typography' import {InlineLink} from '#/components/Link' import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '../icons/CircleInfo' @@ -29,6 +29,7 @@ export function ModerationLabelPref({ }) { const {_, i18n} = useLingui() const t = useTheme() + const {gtPhone} = useBreakpoints() const isGlobalLabel = !labelValueDefinition.definedBy const {identifier} = labelValueDefinition @@ -57,6 +58,7 @@ export function ModerationLabelPref({ adultOnly && !preferences?.moderationPrefs.adultContentEnabled // are there any reasons we cant configure this label here? const cantConfigure = isGlobalLabel || adultDisabled + const showConfig = !disabled && (gtPhone || !cantConfigure) // adjust the pref based on whether warn is available let prefAdjusted = pref @@ -85,9 +87,19 @@ export function ModerationLabelPref({ ) return ( - <View style={[a.flex_row, a.gap_sm, a.px_lg, a.py_lg, a.justify_between]}> + <View + style={[ + a.flex_row, + a.gap_md, + a.px_lg, + a.py_lg, + a.justify_between, + a.flex_wrap, + ]}> <View style={[a.gap_xs, a.flex_1]}> - <Text style={[a.font_bold]}>{labelStrings.name}</Text> + <Text style={[a.font_bold, gtPhone ? a.text_sm : a.text_md]}> + {labelStrings.name} + </Text> <Text style={[t.atoms.text_contrast_medium, a.leading_snug]}> {labelStrings.description} </Text> @@ -113,40 +125,51 @@ export function ModerationLabelPref({ </View> )} </View> - {disabled ? ( - <></> - ) : cantConfigure ? ( - <View style={[{minHeight: 35}, a.px_sm, a.py_md]}> - <Text style={[a.font_bold, t.atoms.text_contrast_medium]}> - {currentPrefLabel} - </Text> - </View> - ) : ( - <View style={[{minHeight: 35}]}> - <ToggleButton.Group - label={_( - msg`Configure content filtering setting for category: ${labelStrings.name.toLowerCase()}`, - )} - values={[prefAdjusted]} - onChange={newPref => - mutate({ - label: identifier, - visibility: newPref[0] as LabelPreference, - labelerDid, - }) - }> - <ToggleButton.Button name="ignore" label={ignoreLabel}> - {ignoreLabel} - </ToggleButton.Button> - {canWarn && ( - <ToggleButton.Button name="warn" label={warnLabel}> - {warnLabel} - </ToggleButton.Button> - )} - <ToggleButton.Button name="hide" label={hideLabel}> - {hideLabel} - </ToggleButton.Button> - </ToggleButton.Group> + + {showConfig && ( + <View style={[gtPhone ? undefined : a.w_full]}> + {cantConfigure ? ( + <View + style={[ + {minHeight: 35}, + a.px_md, + a.py_md, + a.rounded_sm, + a.border, + t.atoms.border_contrast_low, + ]}> + <Text style={[a.font_bold, t.atoms.text_contrast_low]}> + {currentPrefLabel} + </Text> + </View> + ) : ( + <View style={[{minHeight: 35}]}> + <ToggleButton.Group + label={_( + msg`Configure content filtering setting for category: ${labelStrings.name.toLowerCase()}`, + )} + values={[prefAdjusted]} + onChange={newPref => + mutate({ + label: identifier, + visibility: newPref[0] as LabelPreference, + labelerDid, + }) + }> + <ToggleButton.Button name="ignore" label={ignoreLabel}> + {ignoreLabel} + </ToggleButton.Button> + {canWarn && ( + <ToggleButton.Button name="warn" label={warnLabel}> + {warnLabel} + </ToggleButton.Button> + )} + <ToggleButton.Button name="hide" label={hideLabel}> + {hideLabel} + </ToggleButton.Button> + </ToggleButton.Group> + </View> + )} </View> )} </View> From 1cefe70ebe242e5b5a12137340066c177997b2c5 Mon Sep 17 00:00:00 2001 From: surfdude29 <149612116+surfdude29@users.noreply.github.com> Date: Tue, 19 Mar 2024 18:07:26 +0000 Subject: [PATCH 086/109] Update German translations (#2917) * Update German translations * Apply suggestions from code review Co-authored-by: Felix Siebeneicker <felix.siebeneicker@outlook.de> * Further suggestions from code review * Apply further suggested change * Apply suggestions from code review * Apply suggested changes from PythooonUser * Update src/locale/locales/de/messages.po * Apply suggestions from code review Co-authored-by: cdfzo <cdfzo@pm.me> * Apply suggestions from @cdfzo's code review manually * Apply suggestion from @cdfzo's code review manually * Update messages.po * Update src/locale/locales/de/messages.po Co-authored-by: Felix Siebeneicker <felix.siebeneicker@outlook.de> * Update messages.po * Apply suggestions from code review Co-authored-by: Felix Siebeneicker <felix.siebeneicker@outlook.de> * Update src/locale/locales/de/messages.po * Update messages.po * Change `Benachrichtigungen` to `Mitteilungen` in line with #2805 * Apply suggestions from code review Co-authored-by: Felix Siebeneicker <felix.siebeneicker@outlook.de> * Apply suggestions from code review Co-authored-by: Felix Siebeneicker <felix.siebeneicker@outlook.de> * Change four usages of Benutzerhandle * Update messages.po * Update src/locale/locales/de/messages.po * Add credits * Update messages.po * Add new translated strings following merge * Update messages.po * Update messages.po * Update german translations by @cdfzo * Update german translations * Apply suggestions from code review Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Correct translations from pr review --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update revision date of messages.po * Update messages.po * Update messages.po * Delete superseded strings * Add new translations * Update messages.po * Apply suggestions from code review Co-authored-by: cdfzo <cdfzo@pm.me> * Apply suggested change from code review by @cdfzo * Update revision date of messages.po --------- Co-authored-by: Felix Siebeneicker <felix.siebeneicker@outlook.de> Co-authored-by: cdfzo <cdfzo@pm.me> --- src/locale/locales/de/messages.po | 1466 ++++++++++++----------------- 1 file changed, 585 insertions(+), 881 deletions(-) diff --git a/src/locale/locales/de/messages.po b/src/locale/locales/de/messages.po index 5182cf581c..503d656eee 100644 --- a/src/locale/locales/de/messages.po +++ b/src/locale/locales/de/messages.po @@ -8,40 +8,22 @@ msgstr "" "Language: de\n" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: \n" +"PO-Revision-Date: 2024-03-12 13:00+0000\n" "Last-Translator: \n" -"Language-Team: \n" +"Language-Team: Translators in PR 2319, PythooonUser, cdfzo\n" "Plural-Forms: \n" #: src/view/com/modals/VerifyEmail.tsx:142 msgid "(no email)" -msgstr "" - -#: src/view/shell/desktop/RightNav.tsx:168 -#~ msgid "{0, plural, one {# invite code available} other {# invite codes available}}" -#~ msgstr "" +msgstr "(keine E-Mail)" #: src/view/com/profile/ProfileHeader.tsx:593 msgid "{following} following" -msgstr "" - -#: src/view/shell/desktop/RightNav.tsx:151 -#~ msgid "{invitesAvailable, plural, one {Invite codes: # available} other {Invite codes: # available}}" -#~ msgstr "" - -#: src/view/screens/Settings.tsx:435 -#: src/view/shell/Drawer.tsx:664 -#~ msgid "{invitesAvailable} invite code available" -#~ msgstr "{invitesAvailable} Einladungscode verfügbar" - -#: src/view/screens/Settings.tsx:437 -#: src/view/shell/Drawer.tsx:666 -#~ msgid "{invitesAvailable} invite codes available" -#~ msgstr "{invitesAvailable} Einladungscodes verfügbar" +msgstr "{following} folge ich" #: src/view/shell/Drawer.tsx:440 msgid "{numUnreadNotifications} unread" -msgstr "" +msgstr "{numUnreadNotifications} ungelesen" #: src/view/com/threadgate/WhoCanReply.tsx:158 msgid "<0/> members" @@ -49,7 +31,7 @@ msgstr "<0/> Mitglieder" #: src/view/com/profile/ProfileHeader.tsx:595 msgid "<0>{following} </0><1>following</1>" -msgstr "" +msgstr "<0>{following} </0><1>folge ich</1>" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:30 msgid "<0>Choose your</0><1>Recommended</1><2>Feeds</2>" @@ -61,11 +43,11 @@ msgstr "<0>Folge einigen</0><1>empfohlenen</1><2>Nutzern</2>" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:21 msgid "<0>Welcome to</0><1>Bluesky</1>" -msgstr "" +msgstr "<0>Willkommen bei</0><1>Bluesky</1>" #: src/view/com/profile/ProfileHeader.tsx:558 msgid "⚠Invalid Handle" -msgstr "" +msgstr "⚠Ungültiger Handle" #: src/view/com/util/moderation/LabelInfo.tsx:45 msgid "A content warning has been applied to this {0}." @@ -78,11 +60,11 @@ msgstr "Eine neue Version der App ist verfügbar. Bitte aktualisiere die App, um #: src/view/com/util/ViewHeader.tsx:89 #: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" -msgstr "" +msgstr "Zugriff auf Navigationslinks und Einstellungen" #: src/view/com/home/HomeHeaderLayoutMobile.tsx:52 msgid "Access profile and other navigation links" -msgstr "" +msgstr "Zugang zum Profil und anderen Navigationslinks" #: src/view/com/modals/EditImage.tsx:299 #: src/view/screens/Settings/index.tsx:451 @@ -97,19 +79,19 @@ msgstr "Konto" #: src/view/com/profile/ProfileHeader.tsx:246 msgid "Account blocked" -msgstr "" +msgstr "Konto blockiert" #: src/view/com/profile/ProfileHeader.tsx:213 msgid "Account muted" -msgstr "" +msgstr "Konto stummgeschaltet" #: src/view/com/modals/ModerationDetails.tsx:86 msgid "Account Muted" -msgstr "" +msgstr "Konto Stummgeschaltet" #: src/view/com/modals/ModerationDetails.tsx:72 msgid "Account Muted by List" -msgstr "" +msgstr "Konto stummgeschaltet nach Liste" #: src/view/com/util/AccountDropdownBtn.tsx:41 msgid "Account options" @@ -117,15 +99,15 @@ msgstr "Kontoeinstellungen" #: src/view/com/util/AccountDropdownBtn.tsx:25 msgid "Account removed from quick access" -msgstr "" +msgstr "Konto aus dem Schnellzugriff entfernt" #: src/view/com/profile/ProfileHeader.tsx:268 msgid "Account unblocked" -msgstr "" +msgstr "Konto entblockiert" #: src/view/com/profile/ProfileHeader.tsx:226 msgid "Account unmuted" -msgstr "" +msgstr "Konto Stummschaltung aufgehoben" #: src/components/dialogs/MutedWords.tsx:165 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 @@ -158,7 +140,7 @@ msgstr "Alt-Text hinzufügen" #: src/view/screens/AppPasswords.tsx:143 #: src/view/screens/AppPasswords.tsx:156 msgid "Add App Password" -msgstr "" +msgstr "App-Passwort hinzufügen" #: src/view/com/modals/report/InputIssueDetails.tsx:41 #: src/view/com/modals/report/Modal.tsx:191 @@ -179,11 +161,11 @@ msgstr "Link-Karte hinzufügen:" #: src/components/dialogs/MutedWords.tsx:158 msgid "Add mute word for configured settings" -msgstr "" +msgstr "Stummgeschaltetes Wort für konfigurierte Einstellungen hinzufügen" #: src/components/dialogs/MutedWords.tsx:87 msgid "Add muted words and tags" -msgstr "" +msgstr "Füge stummgeschaltete Wörter und Tags hinzu" #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" @@ -200,7 +182,7 @@ msgstr "Zu meinen Feeds hinzufügen" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:139 msgid "Added" -msgstr "" +msgstr "Hinzugefügt" #: src/view/com/modals/ListAddRemoveUsers.tsx:191 #: src/view/com/modals/UserAddRemoveLists.tsx:144 @@ -209,7 +191,7 @@ msgstr "Zur Liste hinzugefügt" #: src/view/com/feeds/FeedSourceCard.tsx:127 msgid "Added to my feeds" -msgstr "" +msgstr "Zu meinen Feeds hinzugefügt" #: src/view/screens/PreferencesFollowingFeed.tsx:173 msgid "Adjust the number of likes a reply must have to be shown in your feed." @@ -221,11 +203,7 @@ msgstr "Inhalt für Erwachsene" #: src/view/com/modals/ContentFilteringSettings.tsx:141 msgid "Adult content can only be enabled via the Web at <0/>." -msgstr "" - -#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:78 -#~ msgid "Adult content can only be enabled via the Web at <0>bsky.app</0>." -#~ msgstr "" +msgstr "Inhalte für Erwachsene können nur über das Web unter <0/> aktiviert werden." #: src/view/screens/Settings/index.tsx:664 msgid "Advanced" @@ -233,16 +211,16 @@ msgstr "Erweitert" #: src/view/screens/Feeds.tsx:666 msgid "All the feeds you've saved, right in one place." -msgstr "" +msgstr "All deine gespeicherten Feeds an einem Ort." #: src/view/com/auth/login/ForgotPasswordForm.tsx:221 #: src/view/com/modals/ChangePassword.tsx:168 msgid "Already have a code?" -msgstr "" +msgstr "Hast du bereits einen Code?" #: src/view/com/auth/login/ChooseAccountForm.tsx:98 msgid "Already signed in as @{0}" -msgstr "" +msgstr "Bereits angemeldet als @{0}" #: src/view/com/composer/photos/Gallery.tsx:130 msgid "ALT" @@ -258,7 +236,7 @@ msgstr "Alt-Text beschreibt Bilder für blinde und sehbehinderte Nutzer und hilf #: src/view/com/modals/VerifyEmail.tsx:124 msgid "An email has been sent to {0}. It includes a confirmation code which you can enter below." -msgstr "Eine E-Mail wurde an {0} gesendet . Sie enthält einen Bestätigungscode, den du unten eingeben kannst." +msgstr "Eine E-Mail wurde an {0} gesendet. Sie enthält einen Bestätigungscode, den du unten eingeben kannst." #: src/view/com/modals/ChangeEmail.tsx:119 msgid "An email has been sent to your previous address, {0}. It includes a confirmation code which you can enter below." @@ -267,7 +245,7 @@ msgstr "Eine E-Mail wurde an deine vorherige Adresse {0} gesendet. Sie enthält #: src/view/com/profile/FollowButton.tsx:30 #: src/view/com/profile/FollowButton.tsx:40 msgid "An issue occurred, please try again." -msgstr "" +msgstr "Es ist ein Problem aufgetreten, bitte versuche es erneut." #: src/view/com/notifications/FeedItem.tsx:237 #: src/view/com/threadgate/WhoCanReply.tsx:178 @@ -276,7 +254,7 @@ msgstr "und" #: src/screens/Onboarding/index.tsx:32 msgid "Animals" -msgstr "" +msgstr "Tiere" #: src/view/screens/LanguageSettings.tsx:95 msgid "App Language" @@ -284,23 +262,19 @@ msgstr "App-Sprache" #: src/view/screens/AppPasswords.tsx:228 msgid "App password deleted" -msgstr "" +msgstr "App-Passwort gelöscht" #: src/view/com/modals/AddAppPasswords.tsx:134 msgid "App Password names can only contain letters, numbers, spaces, dashes, and underscores." -msgstr "" +msgstr "App-Passwortnamen dürfen nur Buchstaben, Zahlen, Leerzeichen, Bindestriche und Unterstriche enthalten." #: src/view/com/modals/AddAppPasswords.tsx:99 msgid "App Password names must be at least 4 characters long." -msgstr "" +msgstr "App-Passwortnamen müssen mindestens 4 Zeichen lang sein." #: src/view/screens/Settings/index.tsx:675 msgid "App password settings" -msgstr "" - -#: src/view/screens/Settings.tsx:650 -#~ msgid "App passwords" -#~ msgstr "App-Passwörter" +msgstr "App-Passwort-Einstellungen" #: src/Navigation.tsx:239 #: src/view/screens/AppPasswords.tsx:187 @@ -311,11 +285,11 @@ msgstr "App-Passwörter" #: src/view/com/util/forms/PostDropdownBtn.tsx:337 #: src/view/com/util/forms/PostDropdownBtn.tsx:346 msgid "Appeal content warning" -msgstr "" +msgstr "Inhaltswarnungseinspruch" #: src/view/com/modals/AppealLabel.tsx:65 msgid "Appeal Content Warning" -msgstr "" +msgstr "Inhaltswarnungseinspruch" #: src/view/com/util/moderation/LabelInfo.tsx:52 msgid "Appeal this decision" @@ -348,11 +322,11 @@ msgstr "Bist du sicher? Dies kann nicht rückgängig gemacht werden." #: src/view/com/composer/select-language/SuggestedLanguage.tsx:60 msgid "Are you writing in <0>{0}</0>?" -msgstr "" +msgstr "Schreibst du auf <0>{0}</0>?" #: src/screens/Onboarding/index.tsx:26 msgid "Art" -msgstr "" +msgstr "Kunst" #: src/view/com/modals/SelfLabel.tsx:123 msgid "Artistic or non-erotic nudity." @@ -375,11 +349,11 @@ msgstr "Zurück" #: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" -msgstr "" +msgstr "Zurück" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:136 msgid "Based on your interest in {interestsText}" -msgstr "" +msgstr "Ausgehend von deinem Interesse an {interestsText}" #: src/view/screens/Settings/index.tsx:523 msgid "Basics" @@ -397,11 +371,11 @@ msgstr "Geburtstag:" #: src/view/com/profile/ProfileHeader.tsx:239 #: src/view/com/profile/ProfileHeader.tsx:346 msgid "Block Account" -msgstr "" +msgstr "Konto blockieren" #: src/view/screens/ProfileList.tsx:556 msgid "Block accounts" -msgstr "" +msgstr "Konten blockieren" #: src/view/screens/ProfileList.tsx:506 msgid "Block list" @@ -413,12 +387,12 @@ msgstr "Diese Konten blockieren?" #: src/view/screens/ProfileList.tsx:320 msgid "Block this List" -msgstr "" +msgstr "Diese Liste blockieren" #: src/view/com/lists/ListCard.tsx:110 #: src/view/com/util/post-embeds/QuoteEmbed.tsx:61 msgid "Blocked" -msgstr "" +msgstr "Blockiert" #: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" @@ -458,7 +432,7 @@ msgstr "Bluesky" #: src/view/com/auth/server-input/index.tsx:150 msgid "Bluesky is an open network where you can choose your hosting provider. Custom hosting is now available in beta for developers." -msgstr "" +msgstr "Bluesky ist ein offenes Netzwerk, in dem du deinen Hosting-Anbieter wählen kannst. Benutzerdefiniertes Hosting ist jetzt in der Beta-Phase für Entwickler verfügbar." #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:80 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:80 @@ -475,21 +449,13 @@ msgstr "Bluesky ist offen." msgid "Bluesky is public." msgstr "Bluesky ist öffentlich." -#: src/view/com/modals/Waitlist.tsx:70 -#~ msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." -#~ msgstr "Bluesky nutzt Einladungen, um eine gesündere Community aufzubauen. Wenn du niemanden kennst, der eine Einladung hat, kannst du dich auf die Warteliste setzen lassen und wir schicken dir bald eine zu." - #: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "Bluesky zeigt dein Profil und deine Beiträge nicht für abgemeldete Nutzer an. Andere Apps kommen dieser Aufforderung möglicherweise nicht nach." -#: src/view/com/modals/ServerInput.tsx:78 -#~ msgid "Bluesky.Social" -#~ msgstr "Bluesky.Social" - #: src/screens/Onboarding/index.tsx:33 msgid "Books" -msgstr "" +msgstr "Bücher" #: src/view/screens/Settings/index.tsx:859 msgid "Build version {0} {1}" @@ -500,25 +466,21 @@ msgstr "Build-Version {0} {1}" msgid "Business" msgstr "Business" -#: src/view/com/modals/ServerInput.tsx:115 -#~ msgid "Button disabled. Input custom domain to proceed." -#~ msgstr "" - #: src/view/com/profile/ProfileSubpageHeader.tsx:157 msgid "by —" -msgstr "" +msgstr "von —" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:100 msgid "by {0}" -msgstr "" +msgstr "von {0}" #: src/view/com/profile/ProfileSubpageHeader.tsx:161 msgid "by <0/>" -msgstr "" +msgstr "von <0/>" #: src/view/com/profile/ProfileSubpageHeader.tsx:159 msgid "by you" -msgstr "" +msgstr "von dir" #: src/view/com/composer/photos/OpenCameraBtn.tsx:60 #: src/view/com/util/UserAvatar.tsx:224 @@ -557,7 +519,7 @@ msgstr "Abbrechen" #: src/view/com/modals/DeleteAccount.tsx:234 msgctxt "action" msgid "Cancel" -msgstr "" +msgstr "Abbrechen" #: src/view/com/modals/DeleteAccount.tsx:152 #: src/view/com/modals/DeleteAccount.tsx:230 @@ -566,29 +528,25 @@ msgstr "Konto-Löschung abbrechen" #: src/view/com/modals/ChangeHandle.tsx:149 msgid "Cancel change handle" -msgstr "" +msgstr "Handle ändern abbrechen" #: src/view/com/modals/crop-image/CropImage.web.tsx:134 msgid "Cancel image crop" -msgstr "" +msgstr "Bildbeschneidung abbrechen" #: src/view/com/modals/EditProfile.tsx:244 msgid "Cancel profile editing" -msgstr "" +msgstr "Profilbearbeitung abbrechen" #: src/view/com/modals/Repost.tsx:78 msgid "Cancel quote post" -msgstr "" +msgstr "Beitrag zitieren abbrechen" #: src/view/com/modals/ListAddRemoveUsers.tsx:87 #: src/view/shell/desktop/Search.tsx:234 msgid "Cancel search" msgstr "Suche abbrechen" -#: src/view/com/modals/Waitlist.tsx:136 -#~ msgid "Cancel waitlist signup" -#~ msgstr "Anmeldung zur Warteliste abbrechen" - #: src/view/screens/Settings/index.tsx:334 msgctxt "action" msgid "Change" @@ -609,19 +567,19 @@ msgstr "Meine E-Mail ändern" #: src/view/screens/Settings/index.tsx:732 msgid "Change password" -msgstr "" +msgstr "Passwort ändern" #: src/view/screens/Settings/index.tsx:741 msgid "Change Password" -msgstr "" +msgstr "Passwort Ändern" #: src/view/com/composer/select-language/SuggestedLanguage.tsx:73 msgid "Change post language to {0}" -msgstr "" +msgstr "Beitragssprache in {0} ändern" #: src/view/screens/Settings/index.tsx:733 msgid "Change your Bluesky password" -msgstr "" +msgstr "Ändere dein Bluesky-Passwort" #: src/view/com/modals/ChangeEmail.tsx:109 msgid "Change Your Email" @@ -630,7 +588,7 @@ msgstr "Deine E-Mail ändern" #: src/screens/Deactivated.tsx:72 #: src/screens/Deactivated.tsx:76 msgid "Check my status" -msgstr "" +msgstr "Meinen Status prüfen" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:121 msgid "Check out some recommended feeds. Tap + to add them to your list of pinned feeds." @@ -646,11 +604,11 @@ msgstr "Überprüfe deinen Posteingang auf eine E-Mail mit dem Bestätigungscode #: src/view/com/modals/Threadgate.tsx:72 msgid "Choose \"Everybody\" or \"Nobody\"" -msgstr "" +msgstr "Wähle \"Alle\" oder \"Niemand\"" #: src/view/screens/Settings/index.tsx:697 msgid "Choose a new Bluesky username or create" -msgstr "" +msgstr "Wähle oder erstelle einen neuen Bluesky-Benutzernamen" #: src/view/com/auth/server-input/index.tsx:79 msgid "Choose Service" @@ -658,20 +616,16 @@ msgstr "Service wählen" #: src/screens/Onboarding/StepFinished.tsx:135 msgid "Choose the algorithms that power your custom feeds." -msgstr "" +msgstr "Wähle die Algorithmen aus, welche deine benutzerdefinierten Feeds generieren." #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:83 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:83 msgid "Choose the algorithms that power your experience with custom feeds." -msgstr "" - -#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 -#~ msgid "Choose your algorithmic feeds" -#~ msgstr "" +msgstr "Wähle die Algorithmen aus, welche dein Erlebnis mit benutzerdefinierten Feeds unterstützen." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 msgid "Choose your main feeds" -msgstr "" +msgstr "Wähle deine Haupt-Feeds" #: src/view/com/auth/create/Step1.tsx:196 msgid "Choose your password" @@ -702,37 +656,37 @@ msgstr "Suchanfrage löschen" #: src/view/screens/Support.tsx:40 msgid "click here" -msgstr "" +msgstr "hier klicken" #: src/components/TagMenu/index.web.tsx:138 msgid "Click here to open tag menu for {tag}" -msgstr "" +msgstr "Klicke hier, um das Tag-Menü für {tag} zu öffnen" #: src/components/RichText.tsx:191 msgid "Click here to open tag menu for #{tag}" -msgstr "" +msgstr "Klicke hier, um das Tag-Menü für #{tag} zu öffnen" #: src/screens/Onboarding/index.tsx:35 msgid "Climate" -msgstr "" +msgstr "Klima" #: src/view/com/modals/ChangePassword.tsx:265 #: src/view/com/modals/ChangePassword.tsx:268 msgid "Close" -msgstr "" +msgstr "Schließen" #: src/components/Dialog/index.web.tsx:84 #: src/components/Dialog/index.web.tsx:198 msgid "Close active dialog" -msgstr "" +msgstr "Aktiven Dialog schließen" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:38 msgid "Close alert" -msgstr "" +msgstr "Meldung schließen" #: src/view/com/util/BottomSheetCustomBackdrop.tsx:33 msgid "Close bottom drawer" -msgstr "" +msgstr "Untere Schublade schließen" #: src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx:26 msgid "Close image" @@ -740,43 +694,43 @@ msgstr "Bild schließen" #: src/view/com/lightbox/Lightbox.web.tsx:119 msgid "Close image viewer" -msgstr "" +msgstr "Bildbetrachter schließen" #: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" -msgstr "" +msgstr "Fußzeile der Navigation schließen" #: src/components/TagMenu/index.tsx:262 msgid "Close this dialog" -msgstr "" +msgstr "Diesen Dialog schließen" #: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" -msgstr "" +msgstr "Schließt die untere Navigationsleiste" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:39 msgid "Closes password update alert" -msgstr "" +msgstr "Schließt die Kennwortaktualisierungsmeldung" #: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" -msgstr "" +msgstr "Schließt den Beitragsverfasser und verwirft den Beitragsentwurf" #: src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx:27 msgid "Closes viewer for header image" -msgstr "" +msgstr "Schließt den Betrachter für das Banner" #: src/view/com/notifications/FeedItem.tsx:318 msgid "Collapses list of users for a given notification" -msgstr "" +msgstr "Klappt die Liste der Benutzer für eine bestimmte Meldung zusammen" #: src/screens/Onboarding/index.tsx:41 msgid "Comedy" -msgstr "" +msgstr "Komödie" #: src/screens/Onboarding/index.tsx:27 msgid "Comics" -msgstr "" +msgstr "Comics" #: src/Navigation.tsx:229 #: src/view/screens/CommunityGuidelines.tsx:32 @@ -785,15 +739,15 @@ msgstr "Community-Richtlinien" #: src/screens/Onboarding/StepFinished.tsx:148 msgid "Complete onboarding and start using your account" -msgstr "" +msgstr "Schließe das Onboarding ab und nutze dein Konto" #: src/view/com/auth/create/Step3.tsx:73 msgid "Complete the challenge" -msgstr "" +msgstr "Beende die Herausforderung" #: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" -msgstr "" +msgstr "Verfasse Beiträge mit einer Länge von bis zu {MAX_GRAPHEME_LENGTH} Zeichen" #: src/view/com/composer/Prompt.tsx:24 msgid "Compose reply" @@ -801,7 +755,7 @@ msgstr "Antwort verfassen" #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:67 msgid "Configure content filtering setting for category: {0}" -msgstr "" +msgstr "Inhaltsfilterungseinstellung der Kategorie {0} konfigurieren" #: src/components/Prompt.tsx:124 #: src/view/com/modals/AppealLabel.tsx:98 @@ -817,7 +771,7 @@ msgstr "Bestätigen" #: src/view/com/modals/Confirm.tsx:78 msgctxt "action" msgid "Confirm" -msgstr "" +msgstr "Bestätigen" #: src/view/com/modals/ChangeEmail.tsx:193 #: src/view/com/modals/ChangeEmail.tsx:195 @@ -834,7 +788,7 @@ msgstr "Bestätige das Löschen des Kontos" #: src/view/com/modals/ContentFilteringSettings.tsx:156 msgid "Confirm your age to enable adult content." -msgstr "" +msgstr "Bestätige dein Alter, um Inhalte für Erwachsene zu aktivieren." #: src/view/com/modals/ChangeEmail.tsx:157 #: src/view/com/modals/DeleteAccount.tsx:182 @@ -842,10 +796,6 @@ msgstr "" msgid "Confirmation code" msgstr "Bestätigungscode" -#: src/view/com/modals/Waitlist.tsx:120 -#~ msgid "Confirms signing up {email} to the waitlist" -#~ msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:193 #: src/view/com/auth/login/LoginForm.tsx:278 msgid "Connecting..." @@ -853,7 +803,7 @@ msgstr "Verbinden..." #: src/view/com/auth/create/CreateAccount.tsx:213 msgid "Contact support" -msgstr "" +msgstr "Support kontaktieren" #: src/view/screens/Moderation.tsx:83 msgid "Content filtering" @@ -866,11 +816,11 @@ msgstr "Inhaltsfilterung" #: src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx:74 #: src/view/screens/LanguageSettings.tsx:278 msgid "Content Languages" -msgstr "" +msgstr "Inhaltssprachen" #: src/view/com/modals/ModerationDetails.tsx:65 msgid "Content Not Available" -msgstr "" +msgstr "Inhalt nicht verfügbar" #: src/view/com/modals/ModerationDetails.tsx:33 #: src/view/com/util/moderation/ScreenHider.tsx:78 @@ -896,19 +846,19 @@ msgstr "Fortfahren" #: src/screens/Onboarding/StepModeration/index.tsx:115 #: src/screens/Onboarding/StepTopicalFeeds.tsx:111 msgid "Continue to next step" -msgstr "" +msgstr "Weiter zum nächsten Schritt" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:167 msgid "Continue to the next step" -msgstr "" +msgstr "Weiter zum nächsten Schritt" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:191 msgid "Continue to the next step without following any accounts" -msgstr "" +msgstr "Fahre mit dem nächsten Schritt fort, ohne Konten zu folgen" #: src/screens/Onboarding/index.tsx:44 msgid "Cooking" -msgstr "" +msgstr "Kochen" #: src/view/com/modals/AddAppPasswords.tsx:195 #: src/view/com/modals/InviteCodes.tsx:182 @@ -917,17 +867,17 @@ msgstr "Kopiert" #: src/view/screens/Settings/index.tsx:241 msgid "Copied build version to clipboard" -msgstr "" +msgstr "Die Build-Version wurde in die Zwischenablage kopiert" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 #: src/view/com/util/forms/PostDropdownBtn.tsx:161 msgid "Copied to clipboard" -msgstr "" +msgstr "In die Zwischenablage kopiert" #: src/view/com/modals/AddAppPasswords.tsx:189 msgid "Copies app password" -msgstr "" +msgstr "Kopiert das App-Passwort" #: src/view/com/modals/AddAppPasswords.tsx:188 msgid "Copy" @@ -949,12 +899,12 @@ msgstr "Link zum Profil kopieren" #: src/view/com/util/forms/PostDropdownBtn.tsx:223 #: src/view/com/util/forms/PostDropdownBtn.tsx:225 msgid "Copy post text" -msgstr "" +msgstr "Beitragstext kopieren" #: src/Navigation.tsx:234 #: src/view/screens/CopyrightPolicy.tsx:29 msgid "Copyright Policy" -msgstr "" +msgstr "Urheberrechtsbestimmungen" #: src/view/screens/ProfileFeed.tsx:97 msgid "Could not load feed" @@ -964,10 +914,6 @@ msgstr "Feed konnte nicht geladen werden" msgid "Could not load list" msgstr "Liste konnte nicht geladen werden" -#: src/view/com/auth/create/Step2.tsx:91 -#~ msgid "Country" -#~ msgstr "" - #: src/view/com/auth/HomeLoggedOutCTA.tsx:62 #: src/view/com/auth/SplashScreen.tsx:71 #: src/view/com/auth/SplashScreen.web.tsx:81 @@ -976,7 +922,7 @@ msgstr "Ein neues Konto erstellen" #: src/view/screens/Settings/index.tsx:384 msgid "Create a new Bluesky account" -msgstr "" +msgstr "Erstelle ein neues Bluesky-Konto" #: src/view/com/auth/create/CreateAccount.tsx:133 msgid "Create Account" @@ -984,7 +930,7 @@ msgstr "Konto erstellen" #: src/view/com/modals/AddAppPasswords.tsx:226 msgid "Create App Password" -msgstr "" +msgstr "App-Passwort erstellen" #: src/view/com/auth/HomeLoggedOutCTA.tsx:54 #: src/view/com/auth/SplashScreen.tsx:68 @@ -997,24 +943,24 @@ msgstr "Erstellt {0}" #: src/view/screens/ProfileFeed.tsx:616 msgid "Created by <0/>" -msgstr "" +msgstr "Erstellt von <0/>" #: src/view/screens/ProfileFeed.tsx:614 msgid "Created by you" -msgstr "" +msgstr "Erstellt von dir" #: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" -msgstr "" +msgstr "Erzeugt eine Karte mit Vorschaubild und verlinkt auf {url}" #: src/screens/Onboarding/index.tsx:29 msgid "Culture" -msgstr "" +msgstr "Kultur" #: src/view/com/auth/server-input/index.tsx:95 #: src/view/com/auth/server-input/index.tsx:96 msgid "Custom" -msgstr "" +msgstr "Benutzerdefiniert" #: src/view/com/modals/ChangeHandle.tsx:389 msgid "Custom domain" @@ -1023,32 +969,28 @@ msgstr "Benutzerdefinierte Domain" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 #: src/view/screens/Feeds.tsx:692 msgid "Custom feeds built by the community bring you new experiences and help you find the content you love." -msgstr "" +msgstr "Benutzerdefinierte Feeds, die von der Community erstellt wurden, bringen dir neue Erfahrungen und helfen dir, die Inhalte zu finden, die du liebst." #: src/view/screens/PreferencesExternalEmbeds.tsx:55 msgid "Customize media from external sites." -msgstr "" - -#: src/view/screens/Settings.tsx:687 -#~ msgid "Danger Zone" -#~ msgstr "" +msgstr "Passe die Einstellungen für Medien von externen Websites an." #: src/view/screens/Settings/index.tsx:485 #: src/view/screens/Settings/index.tsx:511 msgid "Dark" -msgstr "" +msgstr "Dunkel" #: src/view/screens/Debug.tsx:63 msgid "Dark mode" -msgstr "" +msgstr "Dunkelmodus" #: src/view/screens/Settings/index.tsx:498 msgid "Dark Theme" -msgstr "" +msgstr "Dunkles Thema" #: src/view/screens/Debug.tsx:83 msgid "Debug panel" -msgstr "" +msgstr "Debug-Panel" #: src/view/screens/Settings/index.tsx:772 msgid "Delete account" @@ -1072,13 +1014,9 @@ msgstr "Liste löschen" msgid "Delete my account" msgstr "Mein Konto löschen" -#: src/view/screens/Settings.tsx:706 -#~ msgid "Delete my account…" -#~ msgstr "Mein Konto löschen…" - #: src/view/screens/Settings/index.tsx:784 msgid "Delete My Account…" -msgstr "" +msgstr "Mein Konto Löschen…" #: src/view/com/util/forms/PostDropdownBtn.tsx:317 #: src/view/com/util/forms/PostDropdownBtn.tsx:326 @@ -1091,7 +1029,7 @@ msgstr "Diesen Beitrag löschen?" #: src/view/com/util/post-embeds/QuoteEmbed.tsx:70 msgid "Deleted" -msgstr "" +msgstr "Gelöscht" #: src/view/com/post-thread/PostThread.tsx:316 msgid "Deleted post." @@ -1104,17 +1042,13 @@ msgstr "Gelöschter Beitrag." msgid "Description" msgstr "Beschreibung" -#: src/view/screens/Settings.tsx:760 -#~ msgid "Developer Tools" -#~ msgstr "Entwickler-Tools" - #: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" -msgstr "" +msgstr "Wolltest du etwas sagen?" #: src/view/screens/Settings/index.tsx:504 msgid "Dim" -msgstr "" +msgstr "Dimmen" #: src/view/com/composer/Composer.tsx:151 msgid "Discard" @@ -1131,15 +1065,11 @@ msgstr "Apps daran hindern, abgemeldeten Nutzern mein Konto zu zeigen" #: src/view/com/posts/FollowingEmptyState.tsx:74 #: src/view/com/posts/FollowingEndOfFeed.tsx:75 msgid "Discover new custom feeds" -msgstr "" - -#: src/view/screens/Feeds.tsx:473 -#~ msgid "Discover new feeds" -#~ msgstr "Entdecke neue Feeds" +msgstr "Entdecke neue benutzerdefinierte Feeds" #: src/view/screens/Feeds.tsx:689 msgid "Discover New Feeds" -msgstr "" +msgstr "Entdecke neue Feeds" #: src/view/com/modals/EditProfile.tsx:192 msgid "Display name" @@ -1153,10 +1083,6 @@ msgstr "Anzeigename" msgid "Domain verified!" msgstr "Domain verifiziert!" -#: src/view/com/auth/create/Step1.tsx:170 -#~ msgid "Don't have an invite code?" -#~ msgstr "" - #: src/view/com/auth/onboarding/RecommendedFollows.tsx:86 #: src/view/com/modals/EditImage.tsx:333 #: src/view/com/modals/ListAddRemoveUsers.tsx:144 @@ -1168,7 +1094,7 @@ msgstr "Domain verifiziert!" #: src/view/screens/PreferencesThreads.tsx:162 msgctxt "action" msgid "Done" -msgstr "" +msgstr "Erledigt" #: src/view/com/auth/server-input/index.tsx:165 #: src/view/com/auth/server-input/index.tsx:166 @@ -1192,48 +1118,48 @@ msgstr "Erledigt{extraText}" #: src/view/com/auth/login/ChooseAccountForm.tsx:45 msgid "Double tap to sign in" -msgstr "" +msgstr "Doppeltippen zum Anmelden" #: src/view/screens/Settings/index.tsx:755 msgid "Download Bluesky account data (repository)" -msgstr "" +msgstr "Öffnet ein Modal zum Herunterladen deiner Bluesky-Kontodaten (Kontodepot)" #: src/view/screens/Settings/ExportCarDialog.tsx:59 #: src/view/screens/Settings/ExportCarDialog.tsx:63 msgid "Download CAR file" -msgstr "" +msgstr "CAR-Datei herunterladen" #: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" -msgstr "" +msgstr "Ablegen zum Hinzufügen von Bildern" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:111 msgid "Due to Apple policies, adult content can only be enabled on the web after completing sign up." -msgstr "" +msgstr "Aufgrund der Apple-Richtlinien können Inhalte für Erwachsene erst nach Abschluss der Registrierung auf der Website aktiviert werden." #: src/view/com/modals/EditProfile.tsx:185 msgid "e.g. Alice Roberts" -msgstr "" +msgstr "z.B. Alice Roberts" #: src/view/com/modals/EditProfile.tsx:203 msgid "e.g. Artist, dog-lover, and avid reader." -msgstr "" +msgstr "z.B. Künstlerin, Hundeliebhaberin und begeisterte Leserin." #: src/view/com/modals/CreateOrEditList.tsx:283 msgid "e.g. Great Posters" -msgstr "" +msgstr "z.B. Große Poster" #: src/view/com/modals/CreateOrEditList.tsx:284 msgid "e.g. Spammers" -msgstr "" +msgstr "z.B. Spammer" #: src/view/com/modals/CreateOrEditList.tsx:312 msgid "e.g. The posters who never miss." -msgstr "" +msgstr "z.B. Die Poster, die immer ins Schwarze treffen." #: src/view/com/modals/CreateOrEditList.tsx:313 msgid "e.g. Users that repeatedly reply with ads." -msgstr "" +msgstr "z.B. Nutzer, die wiederholt mit Werbung antworten." #: src/view/com/modals/InviteCodes.tsx:96 msgid "Each code works once. You'll receive more invite codes periodically." @@ -1242,7 +1168,7 @@ msgstr "Jeder Code funktioniert einmal. Du erhältst regelmäßig neue Einladung #: src/view/com/lists/ListMembers.tsx:149 msgctxt "action" msgid "Edit" -msgstr "" +msgstr "Bearbeiten" #: src/view/com/composer/photos/Gallery.tsx:144 #: src/view/com/modals/EditImage.tsx:207 @@ -1255,7 +1181,7 @@ msgstr "Details der Liste bearbeiten" #: src/view/com/modals/CreateOrEditList.tsx:250 msgid "Edit Moderation List" -msgstr "" +msgstr "Moderationsliste bearbeiten" #: src/Navigation.tsx:244 #: src/view/screens/Feeds.tsx:434 @@ -1282,19 +1208,19 @@ msgstr "Gespeicherte Feeds bearbeiten" #: src/view/com/modals/CreateOrEditList.tsx:245 msgid "Edit User List" -msgstr "" +msgstr "Benutzerliste bearbeiten" #: src/view/com/modals/EditProfile.tsx:193 msgid "Edit your display name" -msgstr "" +msgstr "Bearbeite deinen Anzeigenamen" #: src/view/com/modals/EditProfile.tsx:211 msgid "Edit your profile description" -msgstr "" +msgstr "Bearbeite deine Profilbeschreibung" #: src/screens/Onboarding/index.tsx:34 msgid "Education" -msgstr "" +msgstr "Bildung" #: src/view/com/auth/create/Step1.tsx:176 #: src/view/com/auth/login/ForgotPasswordForm.tsx:156 @@ -1310,7 +1236,7 @@ msgstr "E-Mail-Adresse" #: src/view/com/modals/ChangeEmail.tsx:56 #: src/view/com/modals/ChangeEmail.tsx:88 msgid "Email updated" -msgstr "" +msgstr "E-Mail aktualisiert" #: src/view/com/modals/ChangeEmail.tsx:111 msgid "Email Updated" @@ -1318,7 +1244,7 @@ msgstr "E-Mail aktualisiert" #: src/view/com/modals/VerifyEmail.tsx:78 msgid "Email verified" -msgstr "" +msgstr "E-Mail verifiziert" #: src/view/screens/Settings/index.tsx:312 msgid "Email:" @@ -1326,24 +1252,24 @@ msgstr "E-Mail:" #: src/view/com/modals/EmbedConsent.tsx:113 msgid "Enable {0} only" -msgstr "" +msgstr "Nur {0} aktivieren" #: src/view/com/modals/ContentFilteringSettings.tsx:167 msgid "Enable Adult Content" -msgstr "" +msgstr "Inhalte für Erwachsene aktivieren" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:76 #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:77 msgid "Enable adult content in your feeds" -msgstr "" +msgstr "Aktiviere Inhalte für Erwachsene in deinen Feeds" #: src/view/com/modals/EmbedConsent.tsx:97 msgid "Enable External Media" -msgstr "" +msgstr "Externe Medien aktivieren" #: src/view/screens/PreferencesExternalEmbeds.tsx:75 msgid "Enable media players for" -msgstr "" +msgstr "Aktiviere Medienplayer für" #: src/view/screens/PreferencesFollowingFeed.tsx:147 msgid "Enable this setting to only see replies between people you follow." @@ -1355,20 +1281,20 @@ msgstr "Ende des Feeds" #: src/view/com/modals/AddAppPasswords.tsx:166 msgid "Enter a name for this App Password" -msgstr "" +msgstr "Gebe einen Namen für dieses App-Passwort ein" #: src/components/dialogs/MutedWords.tsx:100 #: src/components/dialogs/MutedWords.tsx:101 msgid "Enter a word or tag" -msgstr "" +msgstr "Gib ein Wort oder einen Tag ein" #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" -msgstr "" +msgstr "Bestätigungscode eingeben" #: src/view/com/modals/ChangePassword.tsx:151 msgid "Enter the code you received to change your password." -msgstr "" +msgstr "Gib den Code ein, welchen du erhalten hast, um dein Passwort zu ändern." #: src/view/com/modals/ChangeHandle.tsx:371 msgid "Enter the domain you want to use" @@ -1381,11 +1307,7 @@ msgstr "Gib die E-Mail ein, die du zur Erstellung deines Kontos verwendet hast. #: src/view/com/auth/create/Step1.tsx:228 #: src/view/com/modals/BirthDateSettings.tsx:74 msgid "Enter your birth date" -msgstr "" - -#: src/view/com/modals/Waitlist.tsx:78 -#~ msgid "Enter your email" -#~ msgstr "" +msgstr "Gib dein Geburtsdatum ein" #: src/view/com/auth/create/Step1.tsx:172 msgid "Enter your email address" @@ -1393,23 +1315,19 @@ msgstr "Gib deine E-Mail-Adresse ein" #: src/view/com/modals/ChangeEmail.tsx:41 msgid "Enter your new email above" -msgstr "" +msgstr "Gib oben deine neue E-Mail-Adresse ein" #: src/view/com/modals/ChangeEmail.tsx:117 msgid "Enter your new email address below." msgstr "Gib unten deine neue E-Mail-Adresse ein." -#: src/view/com/auth/create/Step2.tsx:188 -#~ msgid "Enter your phone number" -#~ msgstr "" - #: src/view/com/auth/login/Login.tsx:99 msgid "Enter your username and password" msgstr "Gib deinen Benutzernamen und dein Passwort ein" #: src/view/com/auth/create/Step3.tsx:67 msgid "Error receiving captcha response." -msgstr "" +msgstr "Fehler beim Empfang der Captcha-Antwort." #: src/view/screens/Search/Search.tsx:110 msgid "Error:" @@ -1421,20 +1339,16 @@ msgstr "Alle" #: src/view/com/modals/ChangeHandle.tsx:150 msgid "Exits handle change process" -msgstr "" +msgstr "Beendet den Prozess des Handle-Wechsels" #: src/view/com/lightbox/Lightbox.web.tsx:120 msgid "Exits image view" -msgstr "" +msgstr "Beendet die Bildansicht" #: src/view/com/modals/ListAddRemoveUsers.tsx:88 #: src/view/shell/desktop/Search.tsx:235 msgid "Exits inputting search query" -msgstr "" - -#: src/view/com/modals/Waitlist.tsx:138 -#~ msgid "Exits signing up for waitlist with {email}" -#~ msgstr "" +msgstr "Beendet die Eingabe der Suchanfrage" #: src/view/com/lightbox/Lightbox.web.tsx:163 msgid "Expand alt text" @@ -1443,48 +1357,48 @@ msgstr "Alt-Text erweitern" #: src/view/com/composer/ComposerReplyTo.tsx:81 #: src/view/com/composer/ComposerReplyTo.tsx:84 msgid "Expand or collapse the full post you are replying to" -msgstr "" +msgstr "Erweitere oder reduziere den gesamten Beitrag, auf den du antwortest" #: src/view/screens/Settings/index.tsx:753 msgid "Export my data" -msgstr "" +msgstr "Exportiere meine Daten" #: src/view/screens/Settings/ExportCarDialog.tsx:44 #: src/view/screens/Settings/index.tsx:764 msgid "Export My Data" -msgstr "" +msgstr "Exportiere meine Daten" #: src/view/com/modals/EmbedConsent.tsx:64 msgid "External Media" -msgstr "" +msgstr "Externe Medien" #: src/view/com/modals/EmbedConsent.tsx:75 #: src/view/screens/PreferencesExternalEmbeds.tsx:66 msgid "External media may allow websites to collect information about you and your device. No information is sent or requested until you press the \"play\" button." -msgstr "" +msgstr "Externe Medien können es Websites ermöglichen, Informationen über dich und dein Gerät zu sammeln. Es werden keine Informationen gesendet oder angefordert, bis du die Schaltfläche \"Abspielen\" drückst." #: src/Navigation.tsx:263 #: src/view/screens/PreferencesExternalEmbeds.tsx:52 #: src/view/screens/Settings/index.tsx:657 msgid "External Media Preferences" -msgstr "" +msgstr "Externe Medienpräferenzen" #: src/view/screens/Settings/index.tsx:648 msgid "External media settings" -msgstr "" +msgstr "Externe Medienpräferenzen" #: src/view/com/modals/AddAppPasswords.tsx:115 #: src/view/com/modals/AddAppPasswords.tsx:119 msgid "Failed to create app password." -msgstr "" +msgstr "Das App-Passwort konnte nicht erstellt werden." #: src/view/com/modals/CreateOrEditList.tsx:206 msgid "Failed to create the list. Check your internet connection and try again." -msgstr "" +msgstr "Die Liste konnte nicht erstellt werden. Überprüfe deine Internetverbindung und versuche es erneut." #: src/view/com/util/forms/PostDropdownBtn.tsx:128 msgid "Failed to delete post, please try again" -msgstr "" +msgstr "Beitrag konnte nicht gelöscht werden, bitte versuche es erneut" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:109 #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:141 @@ -1493,20 +1407,16 @@ msgstr "Empfohlene Feeds konnten nicht geladen werden" #: src/Navigation.tsx:194 msgid "Feed" -msgstr "" +msgstr "Feed" #: src/view/com/feeds/FeedSourceCard.tsx:231 msgid "Feed by {0}" -msgstr "" +msgstr "Feed von {0}" #: src/view/screens/Feeds.tsx:605 msgid "Feed offline" msgstr "Feed offline" -#: src/view/com/feeds/FeedPage.tsx:143 -#~ msgid "Feed Preferences" -#~ msgstr "Feed-Einstellungen" - #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 msgid "Feedback" @@ -1523,14 +1433,6 @@ msgstr "Feedback" msgid "Feeds" msgstr "Feeds" -#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 -#~ msgid "Feeds are created by users and can give you entirely new experiences." -#~ msgstr "" - -#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 -#~ msgid "Feeds are created by users and organizations. They offer you varied experiences and suggest content you may like using algorithms." -#~ msgstr "" - #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:57 msgid "Feeds are created by users to curate content. Choose some feeds that you find interesting." msgstr "Feeds werden von Nutzern erstellt, um Inhalte zu kuratieren. Wähle einige Feeds aus, die du interessant findest." @@ -1541,17 +1443,17 @@ msgstr "Feeds sind benutzerdefinierte Algorithmen, die Nutzer mit ein wenig Prog #: src/screens/Onboarding/StepTopicalFeeds.tsx:76 msgid "Feeds can be topical as well!" -msgstr "" +msgstr "Die Feeds können auch auf einem Thema basieren!" #: src/screens/Onboarding/StepFinished.tsx:151 msgid "Finalizing" -msgstr "" +msgstr "Abschließen" #: src/view/com/posts/CustomFeedEmptyState.tsx:47 #: src/view/com/posts/FollowingEmptyState.tsx:57 #: src/view/com/posts/FollowingEndOfFeed.tsx:58 msgid "Find accounts to follow" -msgstr "" +msgstr "Konten zum Folgen finden" #: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" @@ -1567,32 +1469,28 @@ msgstr "Suche nach ähnlichen Konten..." #: src/view/screens/PreferencesFollowingFeed.tsx:111 msgid "Fine-tune the content you see on your Following feed." -msgstr "" - -#: src/view/screens/PreferencesHomeFeed.tsx:111 -#~ msgid "Fine-tune the content you see on your home screen." -#~ msgstr "" +msgstr "Passe die Inhalte auf Deinem Following-Feed an." #: src/view/screens/PreferencesThreads.tsx:60 msgid "Fine-tune the discussion threads." -msgstr "" +msgstr "Passe die Diskussionsstränge an." #: src/screens/Onboarding/index.tsx:38 msgid "Fitness" -msgstr "" +msgstr "Fitness" #: src/screens/Onboarding/StepFinished.tsx:131 msgid "Flexible" -msgstr "" +msgstr "Flexibel" #: src/view/com/modals/EditImage.tsx:115 msgid "Flip horizontal" -msgstr "" +msgstr "Horizontal drehen" #: src/view/com/modals/EditImage.tsx:120 #: src/view/com/modals/EditImage.tsx:287 msgid "Flip vertically" -msgstr "" +msgstr "Vertikal drehen" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:181 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:136 @@ -1603,21 +1501,21 @@ msgstr "Folgen" #: src/view/com/profile/FollowButton.tsx:64 msgctxt "action" msgid "Follow" -msgstr "" +msgstr "Folgen" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:58 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:122 #: src/view/com/profile/ProfileHeader.tsx:504 msgid "Follow {0}" -msgstr "" +msgstr "{0} folgen" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:179 msgid "Follow All" -msgstr "" +msgstr "Allen folgen" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:174 msgid "Follow selected accounts and continue to the next step" -msgstr "" +msgstr "Ausgewählten Konten folgen und mit dem nächsten Schritt fortfahren" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:64 msgid "Follow some users to get started. We can recommend you more users based on who you find interesting." @@ -1625,19 +1523,19 @@ msgstr "Folge einigen Nutzern, um loszulegen. Wir können dir weitere Nutzer emp #: src/view/com/profile/ProfileCard.tsx:194 msgid "Followed by {0}" -msgstr "" +msgstr "Gefolgt von {0}" #: src/view/com/modals/Threadgate.tsx:98 msgid "Followed users" -msgstr "" +msgstr "Benutzer, denen ich folge" #: src/view/screens/PreferencesFollowingFeed.tsx:154 msgid "Followed users only" -msgstr "" +msgstr "Nur Benutzer, denen ich folge" #: src/view/com/notifications/FeedItem.tsx:166 msgid "followed you" -msgstr "" +msgstr "folgte dir" #: src/view/screens/ProfileFollowers.tsx:25 msgid "Followers" @@ -1651,7 +1549,7 @@ msgstr "Folge ich" #: src/view/com/profile/ProfileHeader.tsx:149 msgid "Following {0}" -msgstr "" +msgstr "ich folge {0}" #: src/Navigation.tsx:250 #: src/view/com/home/HomeHeaderLayout.web.tsx:50 @@ -1659,7 +1557,7 @@ msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 msgid "Following Feed Preferences" -msgstr "" +msgstr "Following-Feed-Einstellungen" #: src/view/com/profile/ProfileHeader.tsx:546 msgid "Follows you" @@ -1667,11 +1565,11 @@ msgstr "Folgt dir" #: src/view/com/profile/ProfileCard.tsx:141 msgid "Follows You" -msgstr "" +msgstr "Folgt dir" #: src/screens/Onboarding/index.tsx:43 msgid "Food" -msgstr "" +msgstr "Essen" #: src/view/com/modals/DeleteAccount.tsx:111 msgid "For security reasons, we'll need to send a confirmation code to your email address." @@ -1697,12 +1595,12 @@ msgstr "Passwort vergessen" #: src/screens/Hashtag.tsx:108 #: src/screens/Hashtag.tsx:148 msgid "From @{sanitizedAuthor}" -msgstr "" +msgstr "Von @{sanitizedAuthor}" #: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" -msgstr "" +msgstr "Aus <0/>" #: src/view/com/composer/photos/SelectPhotoBtn.tsx:43 msgid "Gallery" @@ -1730,12 +1628,12 @@ msgstr "Gehe zurück" #: src/screens/Onboarding/Layout.tsx:104 #: src/screens/Onboarding/Layout.tsx:193 msgid "Go back to previous step" -msgstr "" +msgstr "Zum vorherigen Schritt zurückkehren" #: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" -msgstr "" +msgstr "Gehe zu @{queryMaybeHandle}" #: src/view/com/auth/login/ForgotPasswordForm.tsx:189 #: src/view/com/auth/login/ForgotPasswordForm.tsx:218 @@ -1751,19 +1649,15 @@ msgstr "Handle" #: src/Navigation.tsx:270 msgid "Hashtag" -msgstr "" - -#: src/components/RichText.tsx:188 -#~ msgid "Hashtag: {tag}" -#~ msgstr "" +msgstr "Hashtag" #: src/components/RichText.tsx:190 msgid "Hashtag: #{tag}" -msgstr "" +msgstr "Hashtag: #{tag}" #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" -msgstr "" +msgstr "Hast du Probleme?" #: src/view/shell/desktop/RightNav.tsx:90 #: src/view/shell/Drawer.tsx:321 @@ -1772,15 +1666,15 @@ msgstr "Hilfe" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:132 msgid "Here are some accounts for you to follow" -msgstr "" +msgstr "Hier sind einige Konten, denen du folgen könntest" #: src/screens/Onboarding/StepTopicalFeeds.tsx:85 msgid "Here are some popular topical feeds. You can choose to follow as many as you like." -msgstr "" +msgstr "Hier sind einige beliebte thematische Feeds. Du kannst so vielen folgen, wie du möchtest." #: src/screens/Onboarding/StepTopicalFeeds.tsx:80 msgid "Here are some topical feeds based on your interests: {interestsText}. You can choose to follow as many as you like." -msgstr "" +msgstr "Hier sind einige thematische Feeds, die auf deinen Interessen basieren: {interestsText}. Du kannst so vielen Feeds folgen, wie du möchtest." #: src/view/com/modals/AddAppPasswords.tsx:153 msgid "Here is your app password." @@ -1797,7 +1691,7 @@ msgstr "Ausblenden" #: src/view/com/notifications/FeedItem.tsx:326 msgctxt "action" msgid "Hide" -msgstr "" +msgstr "Ausblenden" #: src/view/com/util/forms/PostDropdownBtn.tsx:276 #: src/view/com/util/forms/PostDropdownBtn.tsx:287 @@ -1807,7 +1701,7 @@ msgstr "Beitrag ausblenden" #: src/view/com/util/moderation/ContentHider.tsx:67 #: src/view/com/util/moderation/PostHider.tsx:61 msgid "Hide the content" -msgstr "" +msgstr "Den Inhalt ausblenden" #: src/view/com/util/forms/PostDropdownBtn.tsx:280 msgid "Hide this post?" @@ -1819,19 +1713,19 @@ msgstr "Benutzerliste ausblenden" #: src/view/com/profile/ProfileHeader.tsx:487 msgid "Hides posts from {0} in your feed" -msgstr "" +msgstr "Blendet Beiträge von {0} in Deinem Feed aus" #: src/view/com/posts/FeedErrorMessage.tsx:111 msgid "Hmm, some kind of issue occurred when contacting the feed server. Please let the feed owner know about this issue." -msgstr "Hm, beim Kontakt mit dem Feed-Server ist ein Problem aufgetreten. Bitte informiere den Eigentümer des Feeds über dieses Problem." +msgstr "Hmm, beim Kontakt mit dem Feed-Server ist ein Problem aufgetreten. Bitte informiere den Eigentümer des Feeds über dieses Problem." #: src/view/com/posts/FeedErrorMessage.tsx:99 msgid "Hmm, the feed server appears to be misconfigured. Please let the feed owner know about this issue." -msgstr "Hm, der Feed-Server scheint falsch konfiguriert zu sein. Bitte informiere den Eigentümer des Feeds über dieses Problem." +msgstr "Hmm, der Feed-Server scheint falsch konfiguriert zu sein. Bitte informiere den Eigentümer des Feeds über dieses Problem." #: src/view/com/posts/FeedErrorMessage.tsx:105 msgid "Hmm, the feed server appears to be offline. Please let the feed owner know about this issue." -msgstr "Hm, der Feed-Server scheint offline zu sein. Bitte informiere den Eigentümer des Feeds über dieses Problem." +msgstr "Hmm, der Feed-Server scheint offline zu sein. Bitte informiere den Eigentümer des Feeds über dieses Problem." #: src/view/com/posts/FeedErrorMessage.tsx:102 msgid "Hmm, the feed server gave a bad response. Please let the feed owner know about this issue." @@ -1839,7 +1733,7 @@ msgstr "Hmm, der Feed-Server hat eine schlechte Antwort gegeben. Bitte informier #: src/view/com/posts/FeedErrorMessage.tsx:96 msgid "Hmm, we're having trouble finding this feed. It may have been deleted." -msgstr "Hm, wir haben Probleme, diesen Feed zu finden. Möglicherweise wurde er gelöscht." +msgstr "Hmm, wir haben Probleme, diesen Feed zu finden. Möglicherweise wurde er gelöscht." #: src/Navigation.tsx:442 #: src/view/shell/bottom-bar/BottomBar.tsx:137 @@ -1849,13 +1743,6 @@ msgstr "Hm, wir haben Probleme, diesen Feed zu finden. Möglicherweise wurde er msgid "Home" msgstr "Home" -#: src/Navigation.tsx:247 -#: src/view/com/pager/FeedsTabBarMobile.tsx:123 -#: src/view/screens/PreferencesHomeFeed.tsx:104 -#: src/view/screens/Settings/index.tsx:543 -#~ msgid "Home Feed Preferences" -#~ msgstr "Home-Feed-Einstellungen" - #: src/view/com/auth/create/Step1.tsx:75 #: src/view/com/auth/login/ForgotPasswordForm.tsx:120 msgid "Hosting provider" @@ -1863,7 +1750,7 @@ msgstr "Hosting-Anbieter" #: src/view/com/modals/InAppBrowserConsent.tsx:44 msgid "How should we open this link?" -msgstr "" +msgstr "Wie sollen wir diesen Link öffnen?" #: src/view/com/modals/VerifyEmail.tsx:214 msgid "I have a code" @@ -1871,7 +1758,7 @@ msgstr "Ich habe einen Code" #: src/view/com/modals/VerifyEmail.tsx:216 msgid "I have a confirmation code" -msgstr "" +msgstr "Ich habe einen Bestätigungscode" #: src/view/com/modals/ChangeHandle.tsx:283 msgid "I have my own domain" @@ -1879,7 +1766,7 @@ msgstr "Ich habe meine eigene Domain" #: src/view/com/lightbox/Lightbox.web.tsx:165 msgid "If alt text is long, toggles alt text expanded state" -msgstr "" +msgstr "Schaltet den erweiterten Status des Alt-Textes um, wenn dieser lang ist" #: src/view/com/modals/SelfLabel.tsx:127 msgid "If none are selected, suitable for all ages." @@ -1887,11 +1774,11 @@ msgstr "Wenn keine ausgewählt werden, sind sie für alle Altersgruppen geeignet #: src/view/com/modals/ChangePassword.tsx:146 msgid "If you want to change your password, we will send you a code to verify that this is your account." -msgstr "" +msgstr "Wenn du dein Passwort ändern möchtest, senden wir dir einen Code, um zu bestätigen, dass es sich um dein Konto handelt." #: src/view/com/util/images/Gallery.tsx:38 msgid "Image" -msgstr "" +msgstr "Bild" #: src/view/com/modals/AltImage.tsx:120 msgid "Image alt text" @@ -1904,72 +1791,56 @@ msgstr "Bild-Optionen" #: src/view/com/auth/login/SetNewPasswordForm.tsx:138 msgid "Input code sent to your email for password reset" -msgstr "" +msgstr "Gib den Code ein, den du per E-Mail erhalten hast, um dein Passwort zurückzusetzen." #: src/view/com/modals/DeleteAccount.tsx:184 msgid "Input confirmation code for account deletion" -msgstr "" +msgstr "Bestätigungscode für die Kontolöschung eingeben" #: src/view/com/auth/create/Step1.tsx:177 msgid "Input email for Bluesky account" -msgstr "" +msgstr "E-Mail für Bluesky-Konto eingeben" #: src/view/com/auth/create/Step1.tsx:151 msgid "Input invite code to proceed" -msgstr "" +msgstr "Einladungscode eingeben, um fortzufahren" #: src/view/com/modals/AddAppPasswords.tsx:180 msgid "Input name for app password" -msgstr "" +msgstr "Namen für das App-Passwort eingeben" #: src/view/com/auth/login/SetNewPasswordForm.tsx:162 msgid "Input new password" -msgstr "" +msgstr "Neues Passwort eingeben" #: src/view/com/modals/DeleteAccount.tsx:203 msgid "Input password for account deletion" -msgstr "" - -#: src/view/com/auth/create/Step2.tsx:196 -#~ msgid "Input phone number for SMS verification" -#~ msgstr "" +msgstr "Passwort für die Kontolöschung eingeben" #: src/view/com/auth/login/LoginForm.tsx:230 msgid "Input the password tied to {identifier}" -msgstr "" +msgstr "Passwort, das an {identifier} gebunden ist, eingeben" #: src/view/com/auth/login/LoginForm.tsx:197 msgid "Input the username or email address you used at signup" -msgstr "" - -#: src/view/com/auth/create/Step2.tsx:271 -#~ msgid "Input the verification code we have texted to you" -#~ msgstr "" - -#: src/view/com/modals/Waitlist.tsx:90 -#~ msgid "Input your email to get on the Bluesky waitlist" -#~ msgstr "" +msgstr "Benutzernamen oder E-Mail-Adresse eingeben, die du bei der Anmeldung verwendet hast" #: src/view/com/auth/login/LoginForm.tsx:229 msgid "Input your password" -msgstr "" +msgstr "Gib dein Passwort ein" #: src/view/com/auth/create/Step2.tsx:80 msgid "Input your user handle" -msgstr "" +msgstr "Gib deinen Handle ein" #: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" -msgstr "" +msgstr "Ungültiger oder nicht unterstützter Beitragrekord" #: src/view/com/auth/login/LoginForm.tsx:113 msgid "Invalid username or password" msgstr "Ungültiger Benutzername oder Passwort" -#: src/view/screens/Settings.tsx:411 -#~ msgid "Invite" -#~ msgstr "Einladen" - #: src/view/com/modals/InviteCodes.tsx:93 msgid "Invite a Friend" msgstr "Einen Freund einladen" @@ -1985,41 +1856,24 @@ msgstr "Einladungscode nicht akzeptiert. Überprüfe, ob du ihn richtig eingegeb #: src/view/com/modals/InviteCodes.tsx:170 msgid "Invite codes: {0} available" -msgstr "" - -#: src/view/shell/Drawer.tsx:645 -#~ msgid "Invite codes: {invitesAvailable} available" -#~ msgstr "Einladungscodes: {invitesAvailable} verfügbar" +msgstr "Einladungscodes: {0} verfügbar" #: src/view/com/modals/InviteCodes.tsx:169 msgid "Invite codes: 1 available" -msgstr "" +msgstr "Einladungscodes: 1 verfügbar" #: src/screens/Onboarding/StepFollowingFeed.tsx:64 msgid "It shows posts from the people you follow as they happen." -msgstr "" +msgstr "Es zeigt die Beiträge der Personen an, denen du folgst, sobald sie erscheinen." #: src/view/com/auth/HomeLoggedOutCTA.tsx:99 #: src/view/com/auth/SplashScreen.web.tsx:138 msgid "Jobs" msgstr "Jobs" -#: src/view/com/modals/Waitlist.tsx:67 -#~ msgid "Join the waitlist" -#~ msgstr "Der Warteliste beitreten" - -#: src/view/com/auth/create/Step1.tsx:174 -#: src/view/com/auth/create/Step1.tsx:178 -#~ msgid "Join the waitlist." -#~ msgstr "Der Warteliste beitreten." - -#: src/view/com/modals/Waitlist.tsx:128 -#~ msgid "Join Waitlist" -#~ msgstr "Warteliste beitreten" - #: src/screens/Onboarding/index.tsx:24 msgid "Journalism" -msgstr "" +msgstr "Journalismus" #: src/view/com/composer/select-language/SelectLangBtn.tsx:104 msgid "Language selection" @@ -2027,7 +1881,7 @@ msgstr "Sprachauswahl" #: src/view/screens/Settings/index.tsx:594 msgid "Language settings" -msgstr "" +msgstr "Spracheinstellungen" #: src/Navigation.tsx:142 #: src/view/screens/LanguageSettings.tsx:89 @@ -2040,7 +1894,7 @@ msgstr "Sprachen" #: src/view/com/auth/create/StepHeader.tsx:20 msgid "Last step!" -msgstr "" +msgstr "Letzter Schritt!" #: src/view/com/util/moderation/ContentHider.tsx:103 msgid "Learn more" @@ -2074,11 +1928,11 @@ msgstr "Bluesky verlassen" #: src/screens/Deactivated.tsx:128 msgid "left to go." -msgstr "" +msgstr "noch übrig." #: src/view/screens/Settings/index.tsx:278 msgid "Legacy storage cleared, you need to restart the app now." -msgstr "" +msgstr "Der Legacy-Speicher wurde gelöscht, du musst die App jetzt neu starten." #: src/view/com/auth/login/Login.tsx:128 #: src/view/com/auth/login/Login.tsx:144 @@ -2087,7 +1941,7 @@ msgstr "Lass uns dein Passwort zurücksetzen!" #: src/screens/Onboarding/StepFinished.tsx:151 msgid "Let's go!" -msgstr "" +msgstr "Los geht's!" #: src/view/com/util/UserAvatar.tsx:248 #: src/view/com/util/UserBanner.tsx:62 @@ -2096,84 +1950,84 @@ msgstr "Bibliothek" #: src/view/screens/Settings/index.tsx:479 msgid "Light" -msgstr "" +msgstr "Licht" #: src/view/com/util/post-ctrls/PostCtrls.tsx:182 msgid "Like" -msgstr "" +msgstr "Liken" #: src/view/screens/ProfileFeed.tsx:591 msgid "Like this feed" -msgstr "" +msgstr "Diesen Feed liken" #: src/Navigation.tsx:199 msgid "Liked by" -msgstr "" +msgstr "Gelikt von" #: src/view/screens/PostLikedBy.tsx:27 #: src/view/screens/ProfileFeedLikedBy.tsx:27 msgid "Liked By" -msgstr "" +msgstr "Gelikt von" #: src/view/com/feeds/FeedSourceCard.tsx:279 msgid "Liked by {0} {1}" -msgstr "" +msgstr "Von {0} {1} gelikt" #: src/view/screens/ProfileFeed.tsx:606 msgid "Liked by {likeCount} {0}" -msgstr "" +msgstr "Von {likeCount} {0} gelikt" #: src/view/com/notifications/FeedItem.tsx:170 msgid "liked your custom feed" -msgstr "" +msgstr "hat deinen benutzerdefinierten Feed gelikt" #: src/view/com/notifications/FeedItem.tsx:155 msgid "liked your post" -msgstr "" +msgstr "hat deinen Beitrag gelikt" #: src/view/screens/Profile.tsx:183 msgid "Likes" -msgstr "" +msgstr "Likes" #: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" -msgstr "" +msgstr "Likes für diesen Beitrag" #: src/Navigation.tsx:168 msgid "List" -msgstr "" +msgstr "Liste" #: src/view/com/modals/CreateOrEditList.tsx:261 msgid "List Avatar" -msgstr "" +msgstr "Avatar auflisten" #: src/view/screens/ProfileList.tsx:324 msgid "List blocked" -msgstr "" +msgstr "Liste blockiert" #: src/view/com/feeds/FeedSourceCard.tsx:233 msgid "List by {0}" -msgstr "" +msgstr "Liste von {0}" #: src/view/screens/ProfileList.tsx:378 msgid "List deleted" -msgstr "" +msgstr "Liste gelöscht" #: src/view/screens/ProfileList.tsx:283 msgid "List muted" -msgstr "" +msgstr "Liste stummgeschaltet" #: src/view/com/modals/CreateOrEditList.tsx:275 msgid "List Name" -msgstr "" +msgstr "Name der Liste" #: src/view/screens/ProfileList.tsx:343 msgid "List unblocked" -msgstr "" +msgstr "Liste entblockiert" #: src/view/screens/ProfileList.tsx:302 msgid "List unmuted" -msgstr "" +msgstr "Listenstummschaltung aufgehoben" #: src/Navigation.tsx:112 #: src/view/screens/Profile.tsx:185 @@ -2190,7 +2044,7 @@ msgstr "Mehr Beiträge laden" #: src/view/screens/Notifications.tsx:159 msgid "Load new notifications" -msgstr "Neue Benachrichtigungen laden" +msgstr "Neue Mitteilungen laden" #: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 @@ -2203,24 +2057,20 @@ msgstr "Neue Beiträge laden" msgid "Loading..." msgstr "Wird geladen..." -#: src/view/com/modals/ServerInput.tsx:50 -#~ msgid "Local dev server" -#~ msgstr "Lokaler Entwicklungsserver" - #: src/Navigation.tsx:209 msgid "Log" -msgstr "" +msgstr "Systemprotokoll" #: src/screens/Deactivated.tsx:149 #: src/screens/Deactivated.tsx:152 #: src/screens/Deactivated.tsx:178 #: src/screens/Deactivated.tsx:181 msgid "Log out" -msgstr "" +msgstr "Abmelden" #: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" -msgstr "" +msgstr "Sichtbarkeit für abgemeldete Benutzer" #: src/view/com/auth/login/ChooseAccountForm.tsx:133 msgid "Login to account that is not listed" @@ -2232,15 +2082,15 @@ msgstr "Vergewissere dich, dass du auch wirklich dorthin gehen willst!" #: src/components/dialogs/MutedWords.tsx:83 msgid "Manage your muted words and tags" -msgstr "" +msgstr "Verwalte deine stummgeschalteten Wörter und Tags" #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" -msgstr "" +msgstr "Darf nicht länger als 253 Zeichen sein" #: src/view/com/auth/create/Step2.tsx:109 msgid "May only contain letters and numbers" -msgstr "" +msgstr "Darf nur Buchstaben und Zahlen enthalten" #: src/view/screens/Profile.tsx:182 msgid "Media" @@ -2275,25 +2125,25 @@ msgstr "Moderation" #: src/view/com/lists/ListCard.tsx:93 #: src/view/com/modals/UserAddRemoveLists.tsx:206 msgid "Moderation list by {0}" -msgstr "" +msgstr "Moderationsliste von {0}" #: src/view/screens/ProfileList.tsx:775 msgid "Moderation list by <0/>" -msgstr "" +msgstr "Moderationsliste von <0/>" #: src/view/com/lists/ListCard.tsx:91 #: src/view/com/modals/UserAddRemoveLists.tsx:204 #: src/view/screens/ProfileList.tsx:773 msgid "Moderation list by you" -msgstr "" +msgstr "Moderationsliste von dir" #: src/view/com/modals/CreateOrEditList.tsx:197 msgid "Moderation list created" -msgstr "" +msgstr "Moderationsliste erstellt" #: src/view/com/modals/CreateOrEditList.tsx:183 msgid "Moderation list updated" -msgstr "" +msgstr "Moderationsliste aktualisiert" #: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" @@ -2306,11 +2156,11 @@ msgstr "Moderationslisten" #: src/view/screens/Settings/index.tsx:619 msgid "Moderation settings" -msgstr "" +msgstr "Moderationseinstellungen" #: src/view/com/modals/ModerationDetails.tsx:35 msgid "Moderator has chosen to set a general warning on the content." -msgstr "" +msgstr "Der Moderator hat beschlossen, eine allgemeine Warnung vor dem Inhalt auszusprechen." #: src/view/shell/desktop/Feeds.tsx:65 msgid "More feeds" @@ -2322,25 +2172,21 @@ msgstr "Mehr Feeds" msgid "More options" msgstr "Mehr Optionen" -#: src/view/com/util/forms/PostDropdownBtn.tsx:315 -#~ msgid "More post options" -#~ msgstr "" - #: src/view/screens/PreferencesThreads.tsx:82 msgid "Most-liked replies first" -msgstr "" +msgstr "Beliebteste Antworten zuerst" #: src/view/com/auth/create/Step2.tsx:122 msgid "Must be at least 3 characters" -msgstr "" +msgstr "Muss mindestens 3 Zeichen lang sein" #: src/components/TagMenu/index.tsx:249 msgid "Mute" -msgstr "" +msgstr "Stummschalten" #: src/components/TagMenu/index.web.tsx:105 msgid "Mute {truncatedTag}" -msgstr "" +msgstr "{truncatedTag} stummschalten" #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" @@ -2352,23 +2198,19 @@ msgstr "Konten stummschalten" #: src/components/TagMenu/index.tsx:209 msgid "Mute all {displayTag} posts" -msgstr "" - -#: src/components/TagMenu/index.tsx:211 -#~ msgid "Mute all {tag} posts" -#~ msgstr "" +msgstr "Alle {displayTag}-Beiträge stummschalten" #: src/components/dialogs/MutedWords.tsx:149 msgid "Mute in tags only" -msgstr "" +msgstr "Nur in Tags stummschalten" #: src/components/dialogs/MutedWords.tsx:134 msgid "Mute in text & tags" -msgstr "" +msgstr "In Text und Tags stummschalten" #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" -msgstr "" +msgstr "Liste stummschalten" #: src/view/screens/ProfileList.tsx:275 msgid "Mute these accounts?" @@ -2376,15 +2218,15 @@ msgstr "Diese Konten stummschalten?" #: src/view/screens/ProfileList.tsx:279 msgid "Mute this List" -msgstr "" +msgstr "Diese Liste stummschalten" #: src/components/dialogs/MutedWords.tsx:127 msgid "Mute this word in post text and tags" -msgstr "" +msgstr "Dieses Wort in Beitragstexten und Tags stummschalten" #: src/components/dialogs/MutedWords.tsx:142 msgid "Mute this word in tags only" -msgstr "" +msgstr "Dieses Wort nur in Tags stummschalten" #: src/view/com/util/forms/PostDropdownBtn.tsx:251 #: src/view/com/util/forms/PostDropdownBtn.tsx:257 @@ -2394,11 +2236,11 @@ msgstr "Thread stummschalten" #: src/view/com/util/forms/PostDropdownBtn.tsx:267 #: src/view/com/util/forms/PostDropdownBtn.tsx:269 msgid "Mute words & tags" -msgstr "" +msgstr "Wörter und Tags stummschalten" #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" -msgstr "" +msgstr "Stummgeschaltet" #: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" @@ -2411,15 +2253,15 @@ msgstr "Stummgeschaltete Konten" #: src/view/screens/ModerationMutedAccounts.tsx:115 msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." -msgstr "Bei stummgeschalteten Konten werden ihre Beiträge aus deinem Feed und deinen Benachrichtigungen entfernt. Stummschaltungen sind völlig privat." +msgstr "Bei stummgeschalteten Konten werden dazugehörige Beiträge aus deinem Feed und deinen Mitteilungen entfernt. Stummschaltungen sind völlig privat." #: src/view/screens/Moderation.tsx:100 msgid "Muted words & tags" -msgstr "" +msgstr "Stummgeschaltete Wörter und Tags" #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." -msgstr "Stummschaltung ist privat. Stummgeschaltete Konten können mit dir interagieren, aber du siehst ihre Beiträge nicht und erhältst keine Benachrichtigungen von ihnen." +msgstr "Stummschaltung ist privat. Stummgeschaltete Konten können mit dir interagieren, aber du siehst ihre Beiträge nicht und erhältst keine Mitteilungen von ihnen." #: src/view/com/modals/BirthDateSettings.tsx:56 msgid "My Birthday" @@ -2439,7 +2281,7 @@ msgstr "Meine gespeicherten Feeds" #: src/view/com/auth/server-input/index.tsx:118 msgid "my-server.com" -msgstr "" +msgstr "mein-server.de" #: src/view/com/modals/AddAppPasswords.tsx:179 #: src/view/com/modals/CreateOrEditList.tsx:290 @@ -2448,11 +2290,11 @@ msgstr "Name" #: src/view/com/modals/CreateOrEditList.tsx:145 msgid "Name is required" -msgstr "" +msgstr "Name ist erforderlich" #: src/screens/Onboarding/index.tsx:25 msgid "Nature" -msgstr "" +msgstr "Natur" #: src/view/com/auth/login/ForgotPasswordForm.tsx:190 #: src/view/com/auth/login/ForgotPasswordForm.tsx:219 @@ -2460,16 +2302,16 @@ msgstr "" #: src/view/com/auth/login/SetNewPasswordForm.tsx:196 #: src/view/com/modals/ChangePassword.tsx:166 msgid "Navigates to the next screen" -msgstr "" +msgstr "Navigiert zum nächsten Bildschirm" #: src/view/shell/Drawer.tsx:71 msgid "Navigates to your profile" -msgstr "" +msgstr "Navigiert zu Deinem Profil" #: src/view/com/modals/EmbedConsent.tsx:107 #: src/view/com/modals/EmbedConsent.tsx:123 msgid "Never load embeds from {0}" -msgstr "" +msgstr "Lade niemals eingebettete Medien von {0}" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:72 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:72 @@ -2478,16 +2320,16 @@ msgstr "Verliere nie den Zugriff auf deine Follower und Daten." #: src/screens/Onboarding/StepFinished.tsx:119 msgid "Never lose access to your followers or data." -msgstr "" +msgstr "Verliere nie den Zugriff auf deine Follower oder Daten." #: src/components/dialogs/MutedWords.tsx:293 msgid "Nevermind" -msgstr "" +msgstr "Egal" #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" -msgstr "" +msgstr "Neu" #: src/view/screens/ModerationModlists.tsx:78 msgid "New" @@ -2495,20 +2337,20 @@ msgstr "Neu" #: src/view/com/modals/CreateOrEditList.tsx:252 msgid "New Moderation List" -msgstr "" +msgstr "Neue Moderationsliste" #: src/view/com/auth/login/SetNewPasswordForm.tsx:150 msgid "New password" -msgstr "" +msgstr "Neues Passwort" #: src/view/com/modals/ChangePassword.tsx:215 msgid "New Password" -msgstr "" +msgstr "Neues Passwort" #: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" -msgstr "" +msgstr "Neuer Beitrag" #: src/view/screens/Feeds.tsx:555 #: src/view/screens/Notifications.tsx:168 @@ -2527,15 +2369,15 @@ msgstr "Neuer Beitrag" #: src/view/com/modals/CreateOrEditList.tsx:247 msgid "New User List" -msgstr "" +msgstr "Neue Benutzerliste" #: src/view/screens/PreferencesThreads.tsx:79 msgid "Newest replies first" -msgstr "" +msgstr "Neueste Antworten zuerst" #: src/screens/Onboarding/index.tsx:23 msgid "News" -msgstr "" +msgstr "Aktuelles" #: src/view/com/auth/create/CreateAccount.tsx:172 #: src/view/com/auth/login/ForgotPasswordForm.tsx:182 @@ -2552,7 +2394,7 @@ msgstr "Nächste" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 msgctxt "action" msgid "Next" -msgstr "" +msgstr "Nächste" #: src/view/com/lightbox/Lightbox.web.tsx:149 msgid "Next image" @@ -2574,11 +2416,11 @@ msgstr "Keine Beschreibung" #: src/view/com/profile/ProfileHeader.tsx:170 msgid "No longer following {0}" -msgstr "" +msgstr "{0} wird nicht mehr gefolgt" #: src/view/com/notifications/Feed.tsx:109 msgid "No notifications yet!" -msgstr "" +msgstr "Noch keine Mitteilungen!" #: src/view/com/composer/text-input/mobile/Autocomplete.tsx:97 #: src/view/com/composer/text-input/web/Autocomplete.tsx:191 @@ -2587,7 +2429,7 @@ msgstr "Kein Ergebnis" #: src/components/Lists.tsx:192 msgid "No results found" -msgstr "" +msgstr "Keine Ergebnisse gefunden" #: src/view/screens/Feeds.tsx:495 msgid "No results found for \"{query}\"" @@ -2601,7 +2443,7 @@ msgstr "Keine Ergebnisse für {query} gefunden" #: src/view/com/modals/EmbedConsent.tsx:129 msgid "No thanks" -msgstr "" +msgstr "Nein danke" #: src/view/com/modals/Threadgate.tsx:82 msgid "Nobody" @@ -2614,12 +2456,12 @@ msgstr "Unzutreffend." #: src/Navigation.tsx:107 #: src/view/screens/Profile.tsx:106 msgid "Not Found" -msgstr "" +msgstr "Nicht gefunden" #: src/view/com/modals/VerifyEmail.tsx:246 #: src/view/com/modals/VerifyEmail.tsx:252 msgid "Not right now" -msgstr "" +msgstr "Im Moment nicht" #: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." @@ -2637,7 +2479,7 @@ msgstr "Mitteilungen" #: src/view/com/modals/SelfLabel.tsx:103 msgid "Nudity" -msgstr "" +msgstr "Nacktheit" #: src/view/com/util/ErrorBoundary.tsx:35 msgid "Oh no!" @@ -2645,7 +2487,7 @@ msgstr "Oh nein!" #: src/screens/Onboarding/StepInterests/index.tsx:128 msgid "Oh no! Something went wrong." -msgstr "" +msgstr "Oh nein, da ist etwas schief gelaufen." #: src/view/com/auth/login/PasswordUpdatedForm.tsx:41 msgid "Okay" @@ -2653,11 +2495,11 @@ msgstr "Okay" #: src/view/screens/PreferencesThreads.tsx:78 msgid "Oldest replies first" -msgstr "" +msgstr "Älteste Antworten zuerst" #: src/view/screens/Settings/index.tsx:234 msgid "Onboarding reset" -msgstr "" +msgstr "Onboarding zurücksetzen" #: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." @@ -2669,34 +2511,34 @@ msgstr "Nur {0} kann antworten." #: src/components/Lists.tsx:82 msgid "Oops, something went wrong!" -msgstr "" +msgstr "Ups, da ist etwas schief gelaufen!" #: src/components/Lists.tsx:188 #: src/view/screens/AppPasswords.tsx:65 #: src/view/screens/Profile.tsx:106 msgid "Oops!" -msgstr "" +msgstr "Huch!" #: src/screens/Onboarding/StepFinished.tsx:115 msgid "Open" -msgstr "" +msgstr "Öffnen" #: src/view/screens/Moderation.tsx:75 msgid "Open content filtering settings" -msgstr "" +msgstr "Inhaltsfiltereinstellungen öffnen" #: src/view/com/composer/Composer.tsx:477 #: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" -msgstr "" +msgstr "Emoji-Picker öffnen" #: src/view/screens/Settings/index.tsx:712 msgid "Open links with in-app browser" -msgstr "" +msgstr "Links mit In-App-Browser öffnen" #: src/view/screens/Moderation.tsx:92 msgid "Open muted words settings" -msgstr "" +msgstr "Einstellungen für stummgeschaltete Wörter öffnen" #: src/view/com/home/HomeHeaderLayoutMobile.tsx:50 msgid "Open navigation" @@ -2704,31 +2546,31 @@ msgstr "Navigation öffnen" #: src/view/com/util/forms/PostDropdownBtn.tsx:175 msgid "Open post options menu" -msgstr "" +msgstr "Beitragsoptionsmenü öffnen" #: src/view/screens/Settings/index.tsx:804 msgid "Open storybook page" -msgstr "" +msgstr "Geschichtenbuch öffnen" #: src/view/com/util/forms/DropdownButton.tsx:154 msgid "Opens {numItems} options" -msgstr "" +msgstr "Öffnet {numItems} Optionen" #: src/view/screens/Log.tsx:54 msgid "Opens additional details for a debug entry" -msgstr "" +msgstr "Öffnet zusätzliche Details für einen Debug-Eintrag" #: src/view/com/notifications/FeedItem.tsx:349 msgid "Opens an expanded list of users in this notification" -msgstr "" +msgstr "Öffnet eine erweiterte Liste der Benutzer in dieser Meldung" #: src/view/com/composer/photos/OpenCameraBtn.tsx:61 msgid "Opens camera on device" -msgstr "" +msgstr "Öffnet die Kamera auf dem Gerät" #: src/view/com/composer/Prompt.tsx:25 msgid "Opens composer" -msgstr "" +msgstr "Öffnet den Beitragsverfasser" #: src/view/screens/Settings/index.tsx:595 msgid "Opens configurable language settings" @@ -2736,27 +2578,23 @@ msgstr "Öffnet die konfigurierbaren Spracheinstellungen" #: src/view/com/composer/photos/SelectPhotoBtn.tsx:44 msgid "Opens device photo gallery" -msgstr "" +msgstr "Öffnet die Gerätefotogalerie" #: src/view/com/profile/ProfileHeader.tsx:420 msgid "Opens editor for profile display name, avatar, background image, and description" -msgstr "" +msgstr "Öffnet den Editor für Profilanzeige, Avatar, Hintergrundbild und Beschreibung" #: src/view/screens/Settings/index.tsx:649 msgid "Opens external embeds settings" -msgstr "" +msgstr "Öffnet die Einstellungen für externe eingebettete Medien" #: src/view/com/profile/ProfileHeader.tsx:575 msgid "Opens followers list" -msgstr "" +msgstr "Öffnet die Follower-Liste" #: src/view/com/profile/ProfileHeader.tsx:594 msgid "Opens following list" -msgstr "" - -#: src/view/screens/Settings.tsx:412 -#~ msgid "Opens invite code list" -#~ msgstr "" +msgstr "Öffnet folgende Liste" #: src/view/com/modals/InviteCodes.tsx:172 msgid "Opens list of invite codes" @@ -2764,7 +2602,7 @@ msgstr "Öffnet die Liste der Einladungscodes" #: src/view/screens/Settings/index.tsx:774 msgid "Opens modal for account deletion confirmation. Requires email code." -msgstr "" +msgstr "Öffnet ein Modal, um die Löschung des Kontos zu bestätigen. Erfordert einen E-Mail-Code." #: src/view/com/modals/ChangeHandle.tsx:281 msgid "Opens modal for using custom domain" @@ -2776,12 +2614,12 @@ msgstr "Öffnet die Moderationseinstellungen" #: src/view/com/auth/login/LoginForm.tsx:239 msgid "Opens password reset form" -msgstr "" +msgstr "Öffnet das Formular zum Zurücksetzen des Passworts" #: src/view/com/home/HomeHeaderLayout.web.tsx:63 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" -msgstr "" +msgstr "Öffnet den Bildschirm zum Bearbeiten gespeicherten Feeds" #: src/view/screens/Settings/index.tsx:576 msgid "Opens screen with all saved feeds" @@ -2797,7 +2635,7 @@ msgstr "Öffnet die Home-Feed-Einstellungen" #: src/view/screens/Settings/index.tsx:805 msgid "Opens the storybook page" -msgstr "" +msgstr "Öffnet die Geschichtenbuch" #: src/view/screens/Settings/index.tsx:793 msgid "Opens the system log page" @@ -2809,20 +2647,16 @@ msgstr "Öffnet die Thread-Einstellungen" #: src/view/com/util/forms/DropdownButton.tsx:280 msgid "Option {0} of {numItems}" -msgstr "" +msgstr "Option {0} von {numItems}" #: src/view/com/modals/Threadgate.tsx:89 msgid "Or combine these options:" -msgstr "" +msgstr "Oder kombiniere diese Optionen:" #: src/view/com/auth/login/ChooseAccountForm.tsx:138 msgid "Other account" msgstr "Anderes Konto" -#: src/view/com/modals/ServerInput.tsx:88 -#~ msgid "Other service" -#~ msgstr "Anderer Service" - #: src/view/com/composer/select-language/SelectLangBtn.tsx:91 msgid "Other..." msgstr "Andere..." @@ -2834,7 +2668,7 @@ msgstr "Seite nicht gefunden" #: src/view/screens/NotFound.tsx:42 msgid "Page Not Found" -msgstr "" +msgstr "Seite nicht gefunden" #: src/view/com/auth/create/Step1.tsx:191 #: src/view/com/auth/create/Step1.tsx:201 @@ -2854,27 +2688,23 @@ msgstr "Passwort aktualisiert!" #: src/Navigation.tsx:162 msgid "People followed by @{0}" -msgstr "" +msgstr "Personen gefolgt von @{0}" #: src/Navigation.tsx:155 msgid "People following @{0}" -msgstr "" +msgstr "Personen, die @{0} folgen" #: src/view/com/lightbox/Lightbox.tsx:66 msgid "Permission to access camera roll is required." -msgstr "" +msgstr "Die Erlaubnis zum Zugriff auf die Kamerarolle ist erforderlich." #: src/view/com/lightbox/Lightbox.tsx:72 msgid "Permission to access camera roll was denied. Please enable it in your system settings." -msgstr "" +msgstr "Die Berechtigung zum Zugriff auf die Kamerarolle wurde verweigert. Bitte aktiviere sie in deinen Systemeinstellungen." #: src/screens/Onboarding/index.tsx:31 msgid "Pets" -msgstr "" - -#: src/view/com/auth/create/Step2.tsx:183 -#~ msgid "Phone number" -#~ msgstr "" +msgstr "Haustiere" #: src/view/com/modals/SelfLabel.tsx:121 msgid "Pictures meant for adults." @@ -2883,7 +2713,7 @@ msgstr "Bilder, die für Erwachsene bestimmt sind." #: src/view/screens/ProfileFeed.tsx:354 #: src/view/screens/ProfileList.tsx:581 msgid "Pin to home" -msgstr "" +msgstr "An die Startseite anheften" #: src/view/screens/SavedFeeds.tsx:88 msgid "Pinned Feeds" @@ -2891,16 +2721,16 @@ msgstr "Angeheftete Feeds" #: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:111 msgid "Play {0}" -msgstr "" +msgstr "{0} abspielen" #: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:54 #: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:55 msgid "Play Video" -msgstr "" +msgstr "Video abspielen" #: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:110 msgid "Plays the GIF" -msgstr "" +msgstr "Spielt das GIF ab" #: src/view/com/auth/create/state.ts:124 msgid "Please choose your handle." @@ -2912,7 +2742,7 @@ msgstr "Bitte wähle dein Passwort." #: src/view/com/auth/create/state.ts:131 msgid "Please complete the verification captcha." -msgstr "" +msgstr "Bitte fülle das Verifizierungs-Captcha aus." #: src/view/com/modals/ChangeEmail.tsx:67 msgid "Please confirm your email before changing it. This is a temporary requirement while email-updating tools are added, and it will soon be removed." @@ -2920,27 +2750,15 @@ msgstr "Bitte bestätige deine E-Mail, bevor du sie änderst. Dies ist eine vor #: src/view/com/modals/AddAppPasswords.tsx:90 msgid "Please enter a name for your app password. All spaces is not allowed." -msgstr "" - -#: src/view/com/auth/create/Step2.tsx:206 -#~ msgid "Please enter a phone number that can receive SMS text messages." -#~ msgstr "" +msgstr "Bitte gib einen Namen für dein App-Passwort ein. Nur Leerzeichen sind nicht erlaubt." #: src/view/com/modals/AddAppPasswords.tsx:145 msgid "Please enter a unique name for this App Password or use our randomly generated one." -msgstr "" +msgstr "Bitte gib einen eindeutigen Namen für dieses App-Passwort ein oder verwende unseren zufällig generierten Namen." #: src/components/dialogs/MutedWords.tsx:68 msgid "Please enter a valid word, tag, or phrase to mute" -msgstr "" - -#: src/view/com/auth/create/state.ts:170 -#~ msgid "Please enter the code you received by SMS." -#~ msgstr "" - -#: src/view/com/auth/create/Step2.tsx:282 -#~ msgid "Please enter the verification code sent to {phoneNumberFormatted}." -#~ msgstr "" +msgstr "Bitte gib ein gültiges Wort, einen Tag oder eine Phrase zum Stummschalten ein" #: src/view/com/auth/create/state.ts:103 msgid "Please enter your email." @@ -2957,25 +2775,25 @@ msgstr "Bitte teile uns mit, warum du denkst, dass diese Inhaltswarnung falsch a #: src/view/com/modals/VerifyEmail.tsx:101 msgid "Please Verify Your Email" -msgstr "" +msgstr "Bitte verifiziere deine E-Mail" #: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" -msgstr "" +msgstr "Bitte warte, bis deine Link-karte vollständig geladen ist" #: src/screens/Onboarding/index.tsx:37 msgid "Politics" -msgstr "" +msgstr "Politik" #: src/view/com/modals/SelfLabel.tsx:111 msgid "Porn" -msgstr "" +msgstr "Porno" #: src/view/com/composer/Composer.tsx:357 #: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" -msgstr "" +msgstr "Beitrag" #: src/view/com/post-thread/PostThread.tsx:303 msgctxt "description" @@ -2984,17 +2802,17 @@ msgstr "Beitrag" #: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" -msgstr "" +msgstr "Beitrag von {0}" #: src/Navigation.tsx:174 #: src/Navigation.tsx:181 #: src/Navigation.tsx:188 msgid "Post by @{0}" -msgstr "" +msgstr "Beitrag von @{0}" #: src/view/com/util/forms/PostDropdownBtn.tsx:108 msgid "Post deleted" -msgstr "" +msgstr "Beitrag gelöscht" #: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" @@ -3014,7 +2832,7 @@ msgstr "Beitrag nicht gefunden" #: src/components/TagMenu/index.tsx:253 msgid "posts" -msgstr "" +msgstr "Beiträge" #: src/view/screens/Profile.tsx:180 msgid "Posts" @@ -3022,11 +2840,11 @@ msgstr "Beiträge" #: src/components/dialogs/MutedWords.tsx:90 msgid "Posts can be muted based on their text, their tags, or both." -msgstr "" +msgstr "Beiträge können basierend auf ihrem Text, ihren Tags oder beidem stummgeschaltet werden." #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" -msgstr "" +msgstr "Ausgeblendete Beiträge" #: src/view/com/modals/LinkWarning.tsx:46 msgid "Potentially Misleading Link" @@ -3070,7 +2888,7 @@ msgstr "Profil" #: src/view/com/modals/EditProfile.tsx:128 msgid "Profile updated" -msgstr "" +msgstr "Profil aktualisiert" #: src/view/screens/Settings/index.tsx:949 msgid "Protect your account by verifying your email." @@ -3078,7 +2896,7 @@ msgstr "Schütze dein Konto, indem du deine E-Mail bestätigst." #: src/screens/Onboarding/StepFinished.tsx:101 msgid "Public" -msgstr "" +msgstr "Öffentlich" #: src/view/screens/ModerationModlists.tsx:61 msgid "Public, shareable lists of users to mute or block in bulk." @@ -3090,11 +2908,11 @@ msgstr "Öffentliche, gemeinsam nutzbare Listen, die Feeds steuern können." #: src/view/com/composer/Composer.tsx:342 msgid "Publish post" -msgstr "" +msgstr "Beitrag veröffentlichen" #: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" -msgstr "" +msgstr "Antwort veröffentlichen" #: src/view/com/modals/Repost.tsx:65 msgctxt "action" @@ -3112,11 +2930,11 @@ msgstr "Beitrag zitieren" #: src/view/screens/PreferencesThreads.tsx:86 msgid "Random (aka \"Poster's Roulette\")" -msgstr "" +msgstr "Zufällig (alias \"Poster's Roulette\")" #: src/view/com/modals/EditImage.tsx:236 msgid "Ratios" -msgstr "" +msgstr "Verhältnisse" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:116 msgid "Recommended Feeds" @@ -3166,11 +2984,11 @@ msgstr "Bildvorschau entfernen" #: src/components/dialogs/MutedWords.tsx:343 msgid "Remove mute word from your list" -msgstr "" +msgstr "Stummgeschaltetes Wort aus deiner Liste entfernen" #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" -msgstr "" +msgstr "Repost entfernen" #: src/view/com/feeds/FeedSourceCard.tsx:175 msgid "Remove this feed from my feeds?" @@ -3188,11 +3006,11 @@ msgstr "Aus der Liste entfernt" #: src/view/com/feeds/FeedSourceCard.tsx:113 #: src/view/com/feeds/FeedSourceCard.tsx:180 msgid "Removed from my feeds" -msgstr "" +msgstr "Aus meinen Feeds entfernt" #: src/view/com/composer/ExternalEmbed.tsx:71 msgid "Removes default thumbnail from {0}" -msgstr "" +msgstr "Entfernt Standard-Miniaturansicht von {0}" #: src/view/screens/Profile.tsx:181 msgid "Replies" @@ -3205,7 +3023,7 @@ msgstr "Antworten auf diesen Thread sind deaktiviert" #: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" -msgstr "" +msgstr "Antworten" #: src/view/screens/PreferencesFollowingFeed.tsx:144 msgid "Reply Filters" @@ -3215,7 +3033,7 @@ msgstr "Antwortfilter" #: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" -msgstr "" +msgstr "Antwort an <0/>" #: src/view/com/modals/report/Modal.tsx:166 msgid "Report {collectionName}" @@ -3245,7 +3063,7 @@ msgstr "Beitrag melden" #: src/view/com/util/post-ctrls/RepostButton.tsx:61 msgctxt "action" msgid "Repost" -msgstr "" +msgstr "Repost" #: src/view/com/util/post-ctrls/RepostButton.web.tsx:48 msgid "Repost" @@ -3254,45 +3072,41 @@ msgstr "Erneut veröffentlichen" #: src/view/com/util/post-ctrls/RepostButton.web.tsx:94 #: src/view/com/util/post-ctrls/RepostButton.web.tsx:105 msgid "Repost or quote post" -msgstr "" +msgstr "Reposten oder Beitrag zitieren" #: src/view/screens/PostRepostedBy.tsx:27 msgid "Reposted By" -msgstr "" +msgstr "Repostet von" #: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" -msgstr "" +msgstr "Repostet von {0}" #: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" -msgstr "" +msgstr "Repostet von <0/>" #: src/view/com/notifications/FeedItem.tsx:162 msgid "reposted your post" -msgstr "" +msgstr "hat deinen Beitrag repostet" #: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" -msgstr "" +msgstr "Reposts von diesem Beitrag" #: src/view/com/modals/ChangeEmail.tsx:181 #: src/view/com/modals/ChangeEmail.tsx:183 msgid "Request Change" msgstr "Änderung anfordern" -#: src/view/com/auth/create/Step2.tsx:219 -#~ msgid "Request code" -#~ msgstr "" - #: src/view/com/modals/ChangePassword.tsx:239 #: src/view/com/modals/ChangePassword.tsx:241 msgid "Request Code" -msgstr "" +msgstr "Einen Code anfordern" #: src/view/screens/Settings/index.tsx:456 msgid "Require alt text before posting" -msgstr "" +msgstr "Alt-Text vor der Veröffentlichung erforderlich machen" #: src/view/com/auth/create/Step1.tsx:146 msgid "Required for this provider" @@ -3305,15 +3119,15 @@ msgstr "Code zurücksetzen" #: src/view/com/modals/ChangePassword.tsx:190 msgid "Reset Code" -msgstr "" +msgstr "Code zurücksetzen" #: src/view/screens/Settings/index.tsx:824 msgid "Reset onboarding" -msgstr "" +msgstr "Onboarding zurücksetzen" #: src/view/screens/Settings/index.tsx:827 msgid "Reset onboarding state" -msgstr "" +msgstr "Onboarding-Status zurücksetzen" #: src/view/com/auth/login/ForgotPasswordForm.tsx:104 msgid "Reset password" @@ -3321,28 +3135,28 @@ msgstr "Passwort zurücksetzen" #: src/view/screens/Settings/index.tsx:814 msgid "Reset preferences" -msgstr "" +msgstr "Einstellungen zurücksetzen" #: src/view/screens/Settings/index.tsx:817 msgid "Reset preferences state" -msgstr "" +msgstr "Einstellungen zurücksetzen" #: src/view/screens/Settings/index.tsx:825 msgid "Resets the onboarding state" -msgstr "" +msgstr "Setzt den Onboarding-Status zurück" #: src/view/screens/Settings/index.tsx:815 msgid "Resets the preferences state" -msgstr "" +msgstr "Einstellungen zurücksetzen" #: src/view/com/auth/login/LoginForm.tsx:269 msgid "Retries login" -msgstr "" +msgstr "Versucht die Anmeldung erneut" #: src/view/com/util/error/ErrorMessage.tsx:57 #: src/view/com/util/error/ErrorScreen.tsx:74 msgid "Retries the last action, which errored out" -msgstr "" +msgstr "Wiederholung der letzten Aktion, bei der ein Fehler aufgetreten ist" #: src/screens/Onboarding/StepInterests/index.tsx:221 #: src/screens/Onboarding/StepInterests/index.tsx:224 @@ -3355,23 +3169,15 @@ msgstr "" msgid "Retry" msgstr "Wiederholen" -#: src/view/com/auth/create/Step2.tsx:247 -#~ msgid "Retry." -#~ msgstr "" - #: src/view/screens/ProfileList.tsx:903 msgid "Return to previous page" -msgstr "" - -#: src/view/shell/desktop/RightNav.tsx:55 -#~ msgid "SANDBOX. Posts and accounts are not permanent." -#~ msgstr "" +msgstr "Zurück zur vorherigen Seite" #: src/view/com/lightbox/Lightbox.tsx:132 #: src/view/com/modals/CreateOrEditList.tsx:345 msgctxt "action" msgid "Save" -msgstr "" +msgstr "Speichern" #: src/view/com/modals/BirthDateSettings.tsx:94 #: src/view/com/modals/BirthDateSettings.tsx:97 @@ -3404,19 +3210,19 @@ msgstr "Gespeicherte Feeds" #: src/view/com/modals/EditProfile.tsx:225 msgid "Saves any changes to your profile" -msgstr "" +msgstr "Speichert alle Änderungen an Deinem Profil" #: src/view/com/modals/ChangeHandle.tsx:171 msgid "Saves handle change to {handle}" -msgstr "" +msgstr "Speichert Handle-Änderung in {handle}" #: src/screens/Onboarding/index.tsx:36 msgid "Science" -msgstr "" +msgstr "Wissenschaft" #: src/view/screens/ProfileList.tsx:859 msgid "Scroll to top" -msgstr "" +msgstr "Zum Anfang blättern" #: src/Navigation.tsx:447 #: src/view/com/auth/LoggedOut.tsx:122 @@ -3438,23 +3244,15 @@ msgstr "Suche" #: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" -msgstr "" +msgstr "Suche nach \"{query}\"" #: src/components/TagMenu/index.tsx:145 msgid "Search for all posts by @{authorHandle} with tag {displayTag}" -msgstr "" - -#: src/components/TagMenu/index.tsx:145 -#~ msgid "Search for all posts by @{authorHandle} with tag {tag}" -#~ msgstr "" +msgstr "Nach allen Beiträgen von @{authorHandle} mit dem Tag {displayTag} suchen" #: src/components/TagMenu/index.tsx:94 msgid "Search for all posts with tag {displayTag}" -msgstr "" - -#: src/components/TagMenu/index.tsx:90 -#~ msgid "Search for all posts with tag {tag}" -#~ msgstr "" +msgstr "Nach allen Beiträgen mit dem Tag {displayTag} suchen" #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 @@ -3468,31 +3266,23 @@ msgstr "Sicherheitsschritt erforderlich" #: src/components/TagMenu/index.web.tsx:66 msgid "See {truncatedTag} posts" -msgstr "" +msgstr "Siehe {truncatedTag}-Beiträge" #: src/components/TagMenu/index.web.tsx:83 msgid "See {truncatedTag} posts by user" -msgstr "" +msgstr "Siehe {truncatedTag}-Beiträge des Benutzers" #: src/components/TagMenu/index.tsx:128 msgid "See <0>{displayTag}</0> posts" -msgstr "" +msgstr "Siehe <0>{displayTag}</0>-Beiträge" #: src/components/TagMenu/index.tsx:187 msgid "See <0>{displayTag}</0> posts by this user" -msgstr "" - -#: src/components/TagMenu/index.tsx:128 -#~ msgid "See <0>{tag}</0> posts" -#~ msgstr "" - -#: src/components/TagMenu/index.tsx:189 -#~ msgid "See <0>{tag}</0> posts by this user" -#~ msgstr "" +msgstr "Siehe <0>{displayTag}</0>-Beiträge von diesem Benutzer" #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" -msgstr "" +msgstr "Siehe diesen Leitfaden" #: src/view/com/auth/HomeLoggedOutCTA.tsx:39 msgid "See what's next" @@ -3500,11 +3290,7 @@ msgstr "Schau, was als nächstes kommt" #: src/view/com/util/Selector.tsx:106 msgid "Select {item}" -msgstr "" - -#: src/view/com/modals/ServerInput.tsx:75 -#~ msgid "Select Bluesky Social" -#~ msgstr "Wähle Bluesky Social" +msgstr "Wähle {item}" #: src/view/com/auth/login/Login.tsx:117 msgid "Select from an existing account" @@ -3512,7 +3298,7 @@ msgstr "Von einem bestehenden Konto auswählen" #: src/view/com/util/Selector.tsx:107 msgid "Select option {i} of {numItems}" -msgstr "" +msgstr "Wähle Option {i} von {numItems}" #: src/view/com/auth/create/Step1.tsx:96 #: src/view/com/auth/login/LoginForm.tsx:150 @@ -3521,23 +3307,19 @@ msgstr "Service auswählen" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:52 msgid "Select some accounts below to follow" -msgstr "" +msgstr "Wähle unten einige Konten aus, denen du folgen möchtest" #: src/view/com/auth/server-input/index.tsx:82 msgid "Select the service that hosts your data." -msgstr "" - -#: src/screens/Onboarding/StepModeration/index.tsx:49 -#~ msgid "Select the types of content that you want to see (or not see), and we'll handle the rest." -#~ msgstr "" +msgstr "Wähle den Dienst aus, der deine Daten hostet." #: src/screens/Onboarding/StepTopicalFeeds.tsx:96 msgid "Select topical feeds to follow from the list below" -msgstr "" +msgstr "Wähle aus der folgenden Liste die themenbezogenen Feeds aus, die du verfolgen möchtest" #: src/screens/Onboarding/StepModeration/index.tsx:75 msgid "Select what you want to see (or not see), and we’ll handle the rest." -msgstr "" +msgstr "Wähle aus, was du sehen (oder nicht sehen) möchtest, und wir kümmern uns um den Rest." #: src/view/screens/LanguageSettings.tsx:281 msgid "Select which languages you want your subscribed feeds to include. If none are selected, all languages will be shown." @@ -3549,11 +3331,7 @@ msgstr "Wählen deine App-Sprache für den Standardtext aus, der in der App ange #: src/screens/Onboarding/StepInterests/index.tsx:196 msgid "Select your interests from the options below" -msgstr "" - -#: src/view/com/auth/create/Step2.tsx:155 -#~ msgid "Select your phone's country" -#~ msgstr "" +msgstr "Wähle aus den folgenden Optionen deine Interessen aus" #: src/view/screens/LanguageSettings.tsx:190 msgid "Select your preferred language for translations in your feed." @@ -3561,11 +3339,11 @@ msgstr "Wähle deine bevorzugte Sprache für die Übersetzungen in deinem Feed a #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:116 msgid "Select your primary algorithmic feeds" -msgstr "" +msgstr "Wähle deine primären algorithmischen Feeds" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:142 msgid "Select your secondary algorithmic feeds" -msgstr "" +msgstr "Wähle deine sekundären algorithmischen Feeds" #: src/view/com/modals/VerifyEmail.tsx:202 #: src/view/com/modals/VerifyEmail.tsx:204 @@ -3588,45 +3366,45 @@ msgstr "Feedback senden" #: src/view/com/modals/report/SendReportButton.tsx:45 msgid "Send Report" -msgstr "" +msgstr "Bericht senden" #: src/view/com/modals/DeleteAccount.tsx:133 msgid "Sends email with confirmation code for account deletion" -msgstr "" +msgstr "Sendet eine E-Mail mit Bestätigungscode für die Kontolöschung" #: src/view/com/auth/server-input/index.tsx:110 msgid "Server address" -msgstr "" +msgstr "Server-Adresse" #: src/view/com/modals/ContentFilteringSettings.tsx:311 msgid "Set {value} for {labelGroup} content moderation policy" -msgstr "" +msgstr "Legt {value} für die {labelGroup} Inhaltsmoderationsrichtlinie fest" #: src/view/com/modals/ContentFilteringSettings.tsx:160 #: src/view/com/modals/ContentFilteringSettings.tsx:179 msgctxt "action" msgid "Set Age" -msgstr "" +msgstr "Alter festlegen" #: src/view/screens/Settings/index.tsx:488 msgid "Set color theme to dark" -msgstr "" +msgstr "Farbthema auf dunkel einstellen" #: src/view/screens/Settings/index.tsx:481 msgid "Set color theme to light" -msgstr "" +msgstr "Farbthema auf hell einstellen" #: src/view/screens/Settings/index.tsx:475 msgid "Set color theme to system setting" -msgstr "" +msgstr "Farbthema auf Systemeinstellung setzen" #: src/view/screens/Settings/index.tsx:514 msgid "Set dark theme to the dark theme" -msgstr "" +msgstr "Dunkles Thema auf das dunkle Thema einstellen" #: src/view/screens/Settings/index.tsx:507 msgid "Set dark theme to the dim theme" -msgstr "" +msgstr "Dunkles Thema auf das gedämpfte Thema einstellen" #: src/view/com/auth/login/SetNewPasswordForm.tsx:104 msgid "Set new password" @@ -3634,7 +3412,7 @@ msgstr "Neues Passwort festlegen" #: src/view/com/auth/create/Step1.tsx:202 msgid "Set password" -msgstr "" +msgstr "Passwort festlegen" #: src/view/screens/PreferencesFollowingFeed.tsx:225 msgid "Set this setting to \"No\" to hide all quote posts from your feed. Reposts will still be visible." @@ -3652,34 +3430,30 @@ msgstr "Setze diese Einstellung auf \"Nein\", um alle Reposts aus deinem Feed au msgid "Set this setting to \"Yes\" to show replies in a threaded view. This is an experimental feature." msgstr "Setze diese Einstellung auf \"Ja\", um Antworten in einer Thread-Ansicht anzuzeigen. Dies ist eine experimentelle Funktion." -#: src/view/screens/PreferencesHomeFeed.tsx:261 -#~ msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your following feed. This is an experimental feature." -#~ msgstr "Setze diese Einstellung auf \"Ja\", um Beispiele für deine gespeicherten Feeds in deinem folgenden Feed anzuzeigen. Dies ist eine experimentelle Funktion." - #: src/view/screens/PreferencesFollowingFeed.tsx:261 msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your Following feed. This is an experimental feature." -msgstr "" +msgstr "Setze diese Einstellung auf \"Ja\", um Beispiele für deine gespeicherten Feeds in deinem Following-Feed anzuzeigen. Dies ist eine experimentelle Funktion." #: src/screens/Onboarding/Layout.tsx:50 msgid "Set up your account" -msgstr "" +msgstr "Dein Konto einrichten" #: src/view/com/modals/ChangeHandle.tsx:266 msgid "Sets Bluesky username" -msgstr "" +msgstr "Legt deinen Bluesky-Benutzernamen fest" #: src/view/com/auth/login/ForgotPasswordForm.tsx:157 msgid "Sets email for password reset" -msgstr "" +msgstr "Legt die E-Mail für das Zurücksetzen des Passworts fest" #: src/view/com/auth/login/ForgotPasswordForm.tsx:122 msgid "Sets hosting provider for password reset" -msgstr "" +msgstr "Legt den Hosting-Anbieter für das Zurücksetzen des Passworts fest" #: src/view/com/auth/create/Step1.tsx:97 #: src/view/com/auth/login/LoginForm.tsx:151 msgid "Sets server for the Bluesky client" -msgstr "" +msgstr "Setzt den Server für den Bluesky-Client" #: src/Navigation.tsx:137 #: src/view/screens/Settings/index.tsx:294 @@ -3696,7 +3470,7 @@ msgstr "Sexuelle Aktivitäten oder erotische Nacktheit." #: src/view/com/lightbox/Lightbox.tsx:141 msgctxt "action" msgid "Share" -msgstr "" +msgstr "Teilen" #: src/view/com/profile/ProfileHeader.tsx:295 #: src/view/com/util/forms/PostDropdownBtn.tsx:231 @@ -3720,7 +3494,7 @@ msgstr "Anzeigen" #: src/view/screens/PreferencesFollowingFeed.tsx:68 msgid "Show all replies" -msgstr "" +msgstr "Alle Antworten anzeigen" #: src/view/com/util/moderation/ScreenHider.tsx:132 msgid "Show anyway" @@ -3728,17 +3502,17 @@ msgstr "Trotzdem anzeigen" #: src/view/com/modals/EmbedConsent.tsx:87 msgid "Show embeds from {0}" -msgstr "" +msgstr "Eingebettete Medien von {0} anzeigen" #: src/view/com/profile/ProfileHeader.tsx:459 msgid "Show follows similar to {0}" -msgstr "" +msgstr "Zeige ähnliche Konten wie {0}" #: src/view/com/post-thread/PostThreadItem.tsx:538 #: src/view/com/post/Post.tsx:198 #: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" -msgstr "" +msgstr "Mehr anzeigen" #: src/view/screens/PreferencesFollowingFeed.tsx:258 msgid "Show Posts from My Feeds" @@ -3746,19 +3520,19 @@ msgstr "Beiträge aus meinen Feeds anzeigen" #: src/view/screens/PreferencesFollowingFeed.tsx:222 msgid "Show Quote Posts" -msgstr "" +msgstr "Zitierte Beiträge anzeigen" #: src/screens/Onboarding/StepFollowingFeed.tsx:118 msgid "Show quote-posts in Following feed" -msgstr "" +msgstr "Zitierte Beiträge im Following Feed anzeigen" #: src/screens/Onboarding/StepFollowingFeed.tsx:134 msgid "Show quotes in Following" -msgstr "" +msgstr "Zitierte Beiträge im Following Feed anzeigen" #: src/screens/Onboarding/StepFollowingFeed.tsx:94 msgid "Show re-posts in Following feed" -msgstr "" +msgstr "Reposts im Following-Feed anzeigen" #: src/view/screens/PreferencesFollowingFeed.tsx:119 msgid "Show Replies" @@ -3770,15 +3544,15 @@ msgstr "Zeige Antworten von Personen, denen du folgst, vor allen anderen Antwort #: src/screens/Onboarding/StepFollowingFeed.tsx:86 msgid "Show replies in Following" -msgstr "" +msgstr "Antworten in folgendem Feed anzeigen" #: src/screens/Onboarding/StepFollowingFeed.tsx:70 msgid "Show replies in Following feed" -msgstr "" +msgstr "Antworten in folgendem Feed anzeigen" #: src/view/screens/PreferencesFollowingFeed.tsx:70 msgid "Show replies with at least {value} {0}" -msgstr "" +msgstr "Antworten mit mindestens {value} {0} anzeigen" #: src/view/screens/PreferencesFollowingFeed.tsx:188 msgid "Show Reposts" @@ -3786,12 +3560,12 @@ msgstr "Reposts anzeigen" #: src/screens/Onboarding/StepFollowingFeed.tsx:110 msgid "Show reposts in Following" -msgstr "" +msgstr "Reposts im Following-Feed anzeigen" #: src/view/com/util/moderation/ContentHider.tsx:67 #: src/view/com/util/moderation/PostHider.tsx:61 msgid "Show the content" -msgstr "" +msgstr "Den Inhalt anzeigen" #: src/view/com/notifications/FeedItem.tsx:347 msgid "Show users" @@ -3799,12 +3573,12 @@ msgstr "Nutzer anzeigen" #: src/view/com/profile/ProfileHeader.tsx:462 msgid "Shows a list of users similar to this user." -msgstr "" +msgstr "Zeigt eine Liste von Benutzern, die diesem Benutzer ähnlich sind." #: src/view/com/post-thread/PostThreadFollowBtn.tsx:124 #: src/view/com/profile/ProfileHeader.tsx:506 msgid "Shows posts from {0} in your feed" -msgstr "" +msgstr "Zeigt Beiträge von {0} in deinem Feed" #: src/view/com/auth/HomeLoggedOutCTA.tsx:70 #: src/view/com/auth/login/Login.tsx:98 @@ -3872,11 +3646,11 @@ msgstr "Angemeldet als" #: src/view/com/auth/login/ChooseAccountForm.tsx:103 msgid "Signed in as @{0}" -msgstr "" +msgstr "Angemeldet als @{0}" #: src/view/com/modals/SwitchAccount.tsx:66 msgid "Signs {0} out of Bluesky" -msgstr "" +msgstr "Meldet {0} von Bluesky ab" #: src/screens/Onboarding/StepInterests/index.tsx:235 #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:195 @@ -3886,31 +3660,19 @@ msgstr "Überspringen" #: src/screens/Onboarding/StepInterests/index.tsx:232 msgid "Skip this flow" -msgstr "" - -#: src/view/com/auth/create/Step2.tsx:82 -#~ msgid "SMS verification" -#~ msgstr "" +msgstr "Diesen Schritt überspringen" #: src/screens/Onboarding/index.tsx:40 msgid "Software Dev" -msgstr "" - -#: src/view/com/modals/ProfilePreview.tsx:62 -#~ msgid "Something went wrong and we're not sure what." -#~ msgstr "" +msgstr "Software-Entwicklung" #: src/components/Lists.tsx:203 msgid "Something went wrong!" -msgstr "" - -#: src/view/com/modals/Waitlist.tsx:51 -#~ msgid "Something went wrong. Check your email and try again." -#~ msgstr "" +msgstr "Es ist ein Fehler aufgetreten." #: src/App.native.tsx:66 msgid "Sorry! Your session expired. Please log in again." -msgstr "" +msgstr "Entschuldigung! Deine Sitzung ist abgelaufen. Bitte logge dich erneut ein." #: src/view/screens/PreferencesThreads.tsx:69 msgid "Sort Replies" @@ -3922,15 +3684,11 @@ msgstr "Antworten auf denselben Beitrag sortieren nach:" #: src/screens/Onboarding/index.tsx:30 msgid "Sports" -msgstr "" +msgstr "Sport" #: src/view/com/modals/crop-image/CropImage.web.tsx:122 msgid "Square" -msgstr "" - -#: src/view/com/modals/ServerInput.tsx:62 -#~ msgid "Staging" -#~ msgstr "Staging" +msgstr "Quadratische" #: src/view/screens/Settings/index.tsx:871 msgid "Status page" @@ -3938,16 +3696,16 @@ msgstr "Status-Seite" #: src/view/com/auth/create/StepHeader.tsx:22 msgid "Step {0} of {numSteps}" -msgstr "" +msgstr "Schritt {0} von {numSteps}" #: src/view/screens/Settings/index.tsx:274 msgid "Storage cleared, you need to restart the app now." -msgstr "" +msgstr "Der Speicher wurde gelöscht, du musst die App jetzt neu starten." #: src/Navigation.tsx:204 #: src/view/screens/Settings/index.tsx:807 msgid "Storybook" -msgstr "" +msgstr "Geschichtenbuch" #: src/view/com/modals/AppealLabel.tsx:101 msgid "Submit" @@ -3960,7 +3718,7 @@ msgstr "Abonnieren" #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:173 #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:308 msgid "Subscribe to the {0} feed" -msgstr "" +msgstr "Abonniere den {0} Feed" #: src/view/screens/ProfileList.tsx:604 msgid "Subscribe to this list" @@ -3972,11 +3730,11 @@ msgstr "Vorgeschlagene Follower" #: src/view/com/profile/ProfileHeaderSuggestedFollows.tsx:64 msgid "Suggested for you" -msgstr "" +msgstr "Vorgeschlagen für dich" #: src/view/com/modals/SelfLabel.tsx:95 msgid "Suggestive" -msgstr "" +msgstr "Suggestiv" #: src/Navigation.tsx:214 #: src/view/screens/Support.tsx:30 @@ -3984,10 +3742,6 @@ msgstr "" msgid "Support" msgstr "Support" -#: src/view/com/modals/ProfilePreview.tsx:110 -#~ msgid "Swipe up to see more" -#~ msgstr "" - #: src/view/com/modals/SwitchAccount.tsx:117 msgid "Switch Account" msgstr "Konto wechseln" @@ -3995,16 +3749,16 @@ msgstr "Konto wechseln" #: src/view/com/modals/SwitchAccount.tsx:97 #: src/view/screens/Settings/index.tsx:130 msgid "Switch to {0}" -msgstr "" +msgstr "Wechseln zu {0}" #: src/view/com/modals/SwitchAccount.tsx:98 #: src/view/screens/Settings/index.tsx:131 msgid "Switches the account you are logged in to" -msgstr "" +msgstr "Wechselt das Konto, in das du eingeloggt bist" #: src/view/screens/Settings/index.tsx:472 msgid "System" -msgstr "" +msgstr "System" #: src/view/screens/Settings/index.tsx:795 msgid "System log" @@ -4012,15 +3766,11 @@ msgstr "Systemprotokoll" #: src/components/dialogs/MutedWords.tsx:337 msgid "tag" -msgstr "" +msgstr "Tag" #: src/components/TagMenu/index.tsx:78 msgid "Tag menu: {displayTag}" -msgstr "" - -#: src/components/TagMenu/index.tsx:74 -#~ msgid "Tag menu: {tag}" -#~ msgstr "" +msgstr "Tag-Menü: {displayTag}" #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" @@ -4028,11 +3778,11 @@ msgstr "Groß" #: src/view/com/util/images/AutoSizedImage.tsx:70 msgid "Tap to view fully" -msgstr "" +msgstr "Tippe, um die vollständige Ansicht anzuzeigen" #: src/screens/Onboarding/index.tsx:39 msgid "Tech" -msgstr "" +msgstr "Technik" #: src/view/shell/desktop/RightNav.tsx:81 msgid "Terms" @@ -4047,7 +3797,7 @@ msgstr "Nutzungsbedingungen" #: src/components/dialogs/MutedWords.tsx:337 msgid "text" -msgstr "" +msgstr "Text" #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 @@ -4056,11 +3806,11 @@ msgstr "Text-Eingabefeld" #: src/view/com/auth/create/CreateAccount.tsx:94 msgid "That handle is already taken." -msgstr "" +msgstr "Dieser Handle ist bereits besetzt." #: src/view/com/profile/ProfileHeader.tsx:263 msgid "The account will be able to interact with you after unblocking." -msgstr "" +msgstr "Das Konto kann nach der Entblockiert mit dir interagieren." #: src/view/screens/CommunityGuidelines.tsx:36 msgid "The Community Guidelines have been moved to <0/>" @@ -4068,11 +3818,11 @@ msgstr "Die Community-Richtlinien wurden nach <0/> verschoben" #: src/view/screens/CopyrightPolicy.tsx:33 msgid "The Copyright Policy has been moved to <0/>" -msgstr "" +msgstr "Die Copyright-Richtlinie wurde nach <0/> verschoben" #: src/screens/Onboarding/Layout.tsx:60 msgid "The following steps will help customize your Bluesky experience." -msgstr "" +msgstr "Die folgenden Schritte helfen dir, dein Bluesky-Erlebnis anzupassen." #: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." @@ -4088,23 +3838,23 @@ msgstr "Das Support-Formular wurde verschoben. Wenn du Hilfe benötigst, wende d #: src/view/screens/TermsOfService.tsx:33 msgid "The Terms of Service have been moved to" -msgstr "" +msgstr "Die Allgemeinen Geschäftsbedingungen wurden verschoben nach" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:150 msgid "There are many feeds to try:" -msgstr "" +msgstr "Es gibt viele Feeds zum Ausprobieren:" #: src/view/screens/ProfileFeed.tsx:550 msgid "There was an an issue contacting the server, please check your internet connection and try again." -msgstr "" +msgstr "Es gab ein Problem bei der Kontaktaufnahme mit dem Server. Bitte überprüfe deine Internetverbindung und versuche es erneut." #: src/view/com/posts/FeedErrorMessage.tsx:139 msgid "There was an an issue removing this feed. Please check your internet connection and try again." -msgstr "" +msgstr "Es gab ein Problem beim Entfernen dieses Feeds. Bitte überprüfe deine Internetverbindung und versuche es erneut." #: src/view/screens/ProfileFeed.tsx:210 msgid "There was an an issue updating your feeds, please check your internet connection and try again." -msgstr "" +msgstr "Es gab ein Problem bei der Aktualisierung deines Feeds. Bitte überprüfe deine Internetverbindung und versuche es erneut." #: src/view/screens/ProfileFeed.tsx:237 #: src/view/screens/ProfileList.tsx:267 @@ -4112,7 +3862,7 @@ msgstr "" #: src/view/screens/SavedFeeds.tsx:231 #: src/view/screens/SavedFeeds.tsx:252 msgid "There was an issue contacting the server" -msgstr "" +msgstr "Es gab ein Problem bei der Kontaktaufnahme mit dem Server" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:57 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:66 @@ -4120,33 +3870,33 @@ msgstr "" #: src/view/com/feeds/FeedSourceCard.tsx:129 #: src/view/com/feeds/FeedSourceCard.tsx:183 msgid "There was an issue contacting your server" -msgstr "" +msgstr "Es gab ein Problem bei der Kontaktaufnahme mit deinem Server" #: src/view/com/notifications/Feed.tsx:117 msgid "There was an issue fetching notifications. Tap here to try again." -msgstr "" +msgstr "Es gab ein Problem beim Abrufen von Mitteilungen. Tippe hier, um es erneut zu versuchen." #: src/view/com/posts/Feed.tsx:265 msgid "There was an issue fetching posts. Tap here to try again." -msgstr "" +msgstr "Es gab ein Problem beim Abrufen der Beiträge. Tippe hier, um es erneut zu versuchen." #: src/view/com/lists/ListMembers.tsx:172 msgid "There was an issue fetching the list. Tap here to try again." -msgstr "" +msgstr "Es gab ein Problem beim Abrufen der Liste. Tippe hier, um es erneut zu versuchen." #: src/view/com/feeds/ProfileFeedgens.tsx:148 #: src/view/com/lists/ProfileLists.tsx:155 msgid "There was an issue fetching your lists. Tap here to try again." -msgstr "" +msgstr "Es gab ein Problem beim Abrufen deiner Listen. Tippe hier, um es erneut zu versuchen." #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:63 #: src/view/com/modals/ContentFilteringSettings.tsx:126 msgid "There was an issue syncing your preferences with the server" -msgstr "" +msgstr "Es gab ein Problem bei der Synchronisierung deiner Einstellungen mit dem Server" #: src/view/screens/AppPasswords.tsx:66 msgid "There was an issue with fetching your app passwords" -msgstr "" +msgstr "Es gab ein Problem beim Abrufen deiner App-Passwörter" #: src/view/com/post-thread/PostThreadFollowBtn.tsx:93 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:105 @@ -4157,46 +3907,42 @@ msgstr "" #: src/view/com/profile/ProfileHeader.tsx:250 #: src/view/com/profile/ProfileHeader.tsx:272 msgid "There was an issue! {0}" -msgstr "" +msgstr "Es gab ein Problem! {0}" #: src/view/screens/ProfileList.tsx:288 #: src/view/screens/ProfileList.tsx:307 #: src/view/screens/ProfileList.tsx:329 #: src/view/screens/ProfileList.tsx:348 msgid "There was an issue. Please check your internet connection and try again." -msgstr "" +msgstr "Es ist ein Problem aufgetreten. Bitte überprüfe deine Internetverbindung und versuche es erneut." #: src/view/com/util/ErrorBoundary.tsx:36 msgid "There was an unexpected issue in the application. Please let us know if this happened to you!" -msgstr "" +msgstr "Es gab ein unerwartetes Problem in der Anwendung. Bitte teile uns mit, wenn dies bei dir der Fall ist!" #: src/screens/Deactivated.tsx:106 msgid "There's been a rush of new users to Bluesky! We'll activate your account as soon as we can." -msgstr "" - -#: src/view/com/auth/create/Step2.tsx:55 -#~ msgid "There's something wrong with this number. Please choose your country and enter your full phone number!" -#~ msgstr "" +msgstr "Es gab einen Ansturm neuer Nutzer auf Bluesky! Wir werden dein Konto so schnell wie möglich aktivieren." #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:138 msgid "These are popular accounts you might like:" -msgstr "" +msgstr "Dies sind beliebte Konten, die dir gefallen könnten:" #: src/view/com/util/moderation/ScreenHider.tsx:88 msgid "This {screenDescription} has been flagged:" -msgstr "" +msgstr "Diese {screenDescription} wurde gekennzeichnet:" #: src/view/com/util/moderation/ScreenHider.tsx:83 msgid "This account has requested that users sign in to view their profile." -msgstr "" +msgstr "Dieses Konto hat die Benutzer aufgefordert, sich anzumelden, um dein Profil zu sehen." #: src/view/com/modals/EmbedConsent.tsx:68 msgid "This content is hosted by {0}. Do you want to enable external media?" -msgstr "" +msgstr "Dieser Inhalt wird von {0} gehostet. Möchtest du externe Medien aktivieren?" #: src/view/com/modals/ModerationDetails.tsx:67 msgid "This content is not available because one of the users involved has blocked the other." -msgstr "" +msgstr "Dieser Inhalt ist nicht verfügbar, weil einer der beteiligten Nutzer den anderen blockiert hat." #: src/view/com/posts/FeedErrorMessage.tsx:108 msgid "This content is not viewable without a Bluesky account." @@ -4204,7 +3950,7 @@ msgstr "Dieser Inhalt ist ohne ein Bluesky-Konto nicht sichtbar." #: src/view/screens/Settings/ExportCarDialog.tsx:75 msgid "This feature is in beta. You can read more about repository exports in <0>this blogpost.</0>" -msgstr "" +msgstr "Diese Funktion befindet sich in der Beta-Phase. Du kannst mehr über Kontodepot-Exporte in <0>diesem Blogpost lesen.</0>" #: src/view/com/posts/FeedErrorMessage.tsx:114 msgid "This feed is currently receiving high traffic and is temporarily unavailable. Please try again later." @@ -4214,11 +3960,11 @@ msgstr "Dieser Feed wird derzeit stark frequentiert und ist vorübergehend nicht #: src/view/screens/ProfileFeed.tsx:476 #: src/view/screens/ProfileList.tsx:661 msgid "This feed is empty!" -msgstr "" +msgstr "Dieser Feed ist leer!" #: src/view/com/posts/CustomFeedEmptyState.tsx:37 msgid "This feed is empty! You may need to follow more users or tune your language settings." -msgstr "" +msgstr "Dieser Feed ist leer! Möglicherweise musst du mehr Benutzern folgen oder deine Spracheinstellungen anpassen." #: src/view/com/modals/BirthDateSettings.tsx:61 msgid "This information is not shared with other users." @@ -4234,11 +3980,11 @@ msgstr "Dieser Link führt dich auf die folgende Website:" #: src/view/screens/ProfileList.tsx:839 msgid "This list is empty!" -msgstr "" +msgstr "Diese Liste ist leer!" #: src/view/com/modals/AddAppPasswords.tsx:106 msgid "This name is already in use" -msgstr "" +msgstr "Dieser Name ist bereits in Gebrauch" #: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." @@ -4246,19 +3992,15 @@ msgstr "Dieser Beitrag wurde gelöscht." #: src/view/com/modals/ModerationDetails.tsx:62 msgid "This user has blocked you. You cannot view their content." -msgstr "" +msgstr "Dieser Benutzer hat dich blockiert. Du kannst deren Inhalte nicht sehen." #: src/view/com/modals/ModerationDetails.tsx:42 msgid "This user is included in the <0/> list which you have blocked." -msgstr "" +msgstr "Dieser Benutzer ist in der Liste <0/> enthalten, die du blockiert hast." #: src/view/com/modals/ModerationDetails.tsx:74 msgid "This user is included in the <0/> list which you have muted." -msgstr "" - -#: src/view/com/modals/ModerationDetails.tsx:74 -#~ msgid "This user is included the <0/> list which you have muted." -#~ msgstr "" +msgstr "Dieser Benutzer ist in der Liste <0/> enthalten, die du stummgeschaltet haben." #: src/view/com/modals/SelfLabel.tsx:137 msgid "This warning is only available for posts with media attached." @@ -4266,7 +4008,7 @@ msgstr "Diese Warnung ist nur für Beiträge mit angehängten Medien verfügbar. #: src/components/dialogs/MutedWords.tsx:285 msgid "This will delete {0} from your muted words. You can always add it back later." -msgstr "" +msgstr "Dies wird {0} aus deinen stummgeschalteten Wörtern löschen. Du kannst es später jederzeit wieder hinzufügen." #: src/view/com/util/forms/PostDropdownBtn.tsx:282 msgid "This will hide this post from your feeds." @@ -4279,23 +4021,23 @@ msgstr "Thread-Einstellungen" #: src/view/screens/PreferencesThreads.tsx:119 msgid "Threaded Mode" -msgstr "" +msgstr "Gewindemodus" #: src/Navigation.tsx:257 msgid "Threads Preferences" -msgstr "" +msgstr "Thread-Einstellungen" #: src/components/dialogs/MutedWords.tsx:113 msgid "Toggle between muted word options." -msgstr "" +msgstr "Zwischen den Optionen für stummgeschaltete Wörter wechseln." #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" -msgstr "" +msgstr "Dieses Dropdown umschalten" #: src/view/com/modals/EditImage.tsx:271 msgid "Transformations" -msgstr "" +msgstr "Verwandlungen" #: src/view/com/post-thread/PostThreadItem.tsx:685 #: src/view/com/post-thread/PostThreadItem.tsx:687 @@ -4311,11 +4053,11 @@ msgstr "Erneut versuchen" #: src/view/screens/ProfileList.tsx:506 msgid "Un-block list" -msgstr "" +msgstr "Liste entblocken" #: src/view/screens/ProfileList.tsx:491 msgid "Un-mute list" -msgstr "" +msgstr "Stummschaltung von Liste aufheben" #: src/view/com/auth/create/CreateAccount.tsx:58 #: src/view/com/auth/login/ForgotPasswordForm.tsx:87 @@ -4323,22 +4065,22 @@ msgstr "" #: src/view/com/auth/login/LoginForm.tsx:118 #: src/view/com/modals/ChangePassword.tsx:70 msgid "Unable to contact your service. Please check your Internet connection." -msgstr "" +msgstr "Es ist uns nicht gelungen, deinen Dienst zu kontaktieren. Bitte überprüfe deine Internetverbindung." #: src/view/com/profile/ProfileHeader.tsx:433 #: src/view/screens/ProfileList.tsx:590 msgid "Unblock" -msgstr "" +msgstr "Entblocken" #: src/view/com/profile/ProfileHeader.tsx:436 msgctxt "action" msgid "Unblock" -msgstr "" +msgstr "Entblocken" #: src/view/com/profile/ProfileHeader.tsx:261 #: src/view/com/profile/ProfileHeader.tsx:345 msgid "Unblock Account" -msgstr "" +msgstr "Konto entblocken" #: src/view/com/modals/Repost.tsx:42 #: src/view/com/modals/Repost.tsx:55 @@ -4350,11 +4092,11 @@ msgstr "Repost rückgängig machen" #: src/view/com/profile/FollowButton.tsx:55 msgctxt "action" msgid "Unfollow" -msgstr "" +msgstr "Nicht mehr folgen" #: src/view/com/profile/ProfileHeader.tsx:485 msgid "Unfollow {0}" -msgstr "" +msgstr "{0} nicht mehr folgen" #: src/view/com/auth/create/state.ts:262 msgid "Unfortunately, you do not meet the requirements to create an account." @@ -4362,50 +4104,46 @@ msgstr "Leider erfüllst du nicht die Voraussetzungen, um einen Account zu erste #: src/view/com/util/post-ctrls/PostCtrls.tsx:182 msgid "Unlike" -msgstr "" +msgstr "Like aufheben" #: src/components/TagMenu/index.tsx:249 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" -msgstr "" +msgstr "Stummschaltung aufheben" #: src/components/TagMenu/index.web.tsx:104 msgid "Unmute {truncatedTag}" -msgstr "" +msgstr "Stummschaltung von {truncatedTag} aufheben" #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" -msgstr "" +msgstr "Stummschaltung von Konto aufheben" #: src/components/TagMenu/index.tsx:208 msgid "Unmute all {displayTag} posts" -msgstr "" - -#: src/components/TagMenu/index.tsx:210 -#~ msgid "Unmute all {tag} posts" -#~ msgstr "" +msgstr "Stummschaltung aller {displayTag}-Beiträge aufheben" #: src/view/com/util/forms/PostDropdownBtn.tsx:251 #: src/view/com/util/forms/PostDropdownBtn.tsx:256 msgid "Unmute thread" -msgstr "" +msgstr "Stummschaltung von Thread aufheben" #: src/view/screens/ProfileFeed.tsx:354 #: src/view/screens/ProfileList.tsx:581 msgid "Unpin" -msgstr "" +msgstr "Anheften aufheben" #: src/view/screens/ProfileList.tsx:474 msgid "Unpin moderation list" -msgstr "" +msgstr "Anheften der Moderationsliste aufheben" #: src/view/screens/ProfileFeed.tsx:346 msgid "Unsave" -msgstr "" +msgstr "Speicherung aufheben" #: src/view/com/modals/UserAddRemoveLists.tsx:70 msgid "Update {displayName} in Lists" -msgstr "" +msgstr "{displayName} in Listen aktualisieren" #: src/lib/hooks/useOTAUpdate.ts:15 msgid "Update Available" @@ -4417,7 +4155,7 @@ msgstr "Aktualisieren..." #: src/view/com/modals/ChangeHandle.tsx:455 msgid "Upload a text file to:" -msgstr "" +msgstr "Hochladen einer Textdatei auf:" #: src/view/screens/AppPasswords.tsx:195 msgid "Use app passwords to login to other Bluesky clients without giving full access to your account or password." @@ -4430,36 +4168,32 @@ msgstr "Standardanbieter verwenden" #: src/view/com/modals/InAppBrowserConsent.tsx:56 #: src/view/com/modals/InAppBrowserConsent.tsx:58 msgid "Use in-app browser" -msgstr "" +msgstr "In-App-Browser verwenden" #: src/view/com/modals/InAppBrowserConsent.tsx:66 #: src/view/com/modals/InAppBrowserConsent.tsx:68 msgid "Use my default browser" -msgstr "" +msgstr "Meinen Standardbrowser verwenden" #: src/view/com/modals/AddAppPasswords.tsx:155 msgid "Use this to sign into the other app along with your handle." msgstr "Verwenden dies, um dich mit deinem Handle bei der anderen App einzuloggen." -#: src/view/com/modals/ServerInput.tsx:105 -#~ msgid "Use your domain as your Bluesky client service provider" -#~ msgstr "" - #: src/view/com/modals/InviteCodes.tsx:200 msgid "Used by:" msgstr "Verwendet von:" #: src/view/com/modals/ModerationDetails.tsx:54 msgid "User Blocked" -msgstr "" +msgstr "Benutzer blockiert" #: src/view/com/modals/ModerationDetails.tsx:40 msgid "User Blocked by List" -msgstr "" +msgstr "Benutzer durch der Liste blockiert" #: src/view/com/modals/ModerationDetails.tsx:60 msgid "User Blocks You" -msgstr "" +msgstr "Benutzer blockiert dich" #: src/view/com/auth/create/Step2.tsx:79 msgid "User handle" @@ -4468,25 +4202,25 @@ msgstr "Benutzerhandle" #: src/view/com/lists/ListCard.tsx:85 #: src/view/com/modals/UserAddRemoveLists.tsx:198 msgid "User list by {0}" -msgstr "" +msgstr "Benutzerliste von {0}" #: src/view/screens/ProfileList.tsx:763 msgid "User list by <0/>" -msgstr "" +msgstr "Benutzerliste von <0/>" #: src/view/com/lists/ListCard.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:196 #: src/view/screens/ProfileList.tsx:761 msgid "User list by you" -msgstr "" +msgstr "Benutzerliste von dir" #: src/view/com/modals/CreateOrEditList.tsx:196 msgid "User list created" -msgstr "" +msgstr "Benutzerliste erstellt" #: src/view/com/modals/CreateOrEditList.tsx:182 msgid "User list updated" -msgstr "" +msgstr "Benutzerliste aktualisiert" #: src/view/screens/Lists.tsx:58 msgid "User Lists" @@ -4507,11 +4241,7 @@ msgstr "Nutzer gefolgt von <0/>" #: src/view/com/modals/Threadgate.tsx:106 msgid "Users in \"{0}\"" -msgstr "" - -#: src/view/com/auth/create/Step2.tsx:243 -#~ msgid "Verification code" -#~ msgstr "" +msgstr "Benutzer in \"{0}\"" #: src/view/screens/Settings/index.tsx:910 msgid "Verify email" @@ -4532,15 +4262,15 @@ msgstr "Neue E-Mail bestätigen" #: src/view/com/modals/VerifyEmail.tsx:103 msgid "Verify Your Email" -msgstr "" +msgstr "Überprüfe deine E-Mail" #: src/screens/Onboarding/index.tsx:42 msgid "Video Games" -msgstr "" +msgstr "Videospiele" #: src/view/com/profile/ProfileHeader.tsx:662 msgid "View {0}'s avatar" -msgstr "" +msgstr "Avatar {0} ansehen" #: src/view/screens/Log.tsx:52 msgid "View debug entry" @@ -4548,11 +4278,11 @@ msgstr "Debug-Eintrag anzeigen" #: src/view/com/posts/FeedSlice.tsx:103 msgid "View full thread" -msgstr "" +msgstr "Vollständigen Thread ansehen" #: src/view/com/posts/FeedErrorMessage.tsx:172 msgid "View profile" -msgstr "" +msgstr "Profil ansehen" #: src/view/com/profile/ProfileSubpageHeader.tsx:128 msgid "View the avatar" @@ -4565,55 +4295,51 @@ msgstr "Seite ansehen" #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:42 #: src/view/com/modals/ContentFilteringSettings.tsx:259 msgid "Warn" -msgstr "" +msgstr "Warnen" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:134 msgid "We also think you'll like \"For You\" by Skygaze:" -msgstr "" +msgstr "Wir glauben auch, dass dir \"For You\" von Skygaze gefallen wird:" #: src/screens/Hashtag.tsx:132 msgid "We couldn't find any results for that hashtag." -msgstr "" +msgstr "Wir konnten keine Ergebnisse für diesen Hashtag finden." #: src/screens/Deactivated.tsx:133 msgid "We estimate {estimatedTime} until your account is ready." -msgstr "" +msgstr "Wir schätzen {estimatedTime} bis dein Konto bereit ist." #: src/screens/Onboarding/StepFinished.tsx:93 msgid "We hope you have a wonderful time. Remember, Bluesky is:" -msgstr "" +msgstr "Wir hoffen, dass du eine schöne Zeit hast. Denke daran, Bluesky ist:" #: src/view/com/posts/DiscoverFallbackHeader.tsx:29 msgid "We ran out of posts from your follows. Here's the latest from <0/>." -msgstr "" - -#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:118 -#~ msgid "We recommend \"For You\" by Skygaze:" -#~ msgstr "" +msgstr "Wir haben keine Beiträge mehr von den Konten, denen du folgst. Hier ist das Neueste von <0/>." #: src/components/dialogs/MutedWords.tsx:204 msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." -msgstr "" +msgstr "Wir empfehlen, gebräuchliche Wörter zu vermeiden, die in vielen Beiträgen vorkommen, da dies dazu führen kann, dass keine Beiträge angezeigt werden." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" -msgstr "" +msgstr "Wir empfehlen unser \"Discover\" Feed:" #: src/screens/Onboarding/StepInterests/index.tsx:133 msgid "We weren't able to connect. Please try again to continue setting up your account. If it continues to fail, you can skip this flow." -msgstr "" +msgstr "Die Verbindung konnte nicht hergestellt werden. Bitte versuche es erneut, um mit der Einrichtung deines Kontos fortzufahren. Wenn der Versuch weiterhin fehlschlägt, kannst du diesen Schritt überspringen." #: src/screens/Deactivated.tsx:137 msgid "We will let you know when your account is ready." -msgstr "" +msgstr "Wir werden dich benachrichtigen, wenn dein Konto bereit ist." #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." -msgstr "" +msgstr "Wir werden deinen Widerspruch unverzüglich prüfen." #: src/screens/Onboarding/StepInterests/index.tsx:138 msgid "We'll use this to help customize your experience." -msgstr "" +msgstr "Wir verwenden diese Informationen, um dein Erlebnis individuell zu gestalten." #: src/view/com/auth/create/CreateAccount.tsx:134 msgid "We're so excited to have you join us!" @@ -4621,11 +4347,11 @@ msgstr "Wir freuen uns sehr, dass du dabei bist!" #: src/view/screens/ProfileList.tsx:86 msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." -msgstr "" +msgstr "Es tut uns leid, aber wir waren nicht in der Lage, diese Liste aufzulösen. Wenn das Problem weiterhin besteht, kontaktiere bitte den Ersteller der Liste, @{handleOrDid}." #: src/components/dialogs/MutedWords.tsx:230 msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." -msgstr "" +msgstr "Es tut uns leid, aber wir konnten deine stummgeschalteten Wörter nicht laden. Bitte versuche es erneut." #: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." @@ -4642,11 +4368,11 @@ msgstr "Willkommen bei <0>Bluesky</0>" #: src/screens/Onboarding/StepInterests/index.tsx:130 msgid "What are your interests?" -msgstr "" +msgstr "Was sind deine Interessen?" #: src/view/com/modals/report/Modal.tsx:169 msgid "What is the issue with this {collectionName}?" -msgstr "" +msgstr "Was ist das Problem mit diesem {collectionName}?" #: src/view/com/auth/SplashScreen.tsx:59 #: src/view/com/composer/Composer.tsx:286 @@ -4681,11 +4407,7 @@ msgstr "Schreibe deine Antwort" #: src/screens/Onboarding/index.tsx:28 msgid "Writers" -msgstr "" - -#: src/view/com/auth/create/Step2.tsx:263 -#~ msgid "XXXXXX" -#~ msgstr "" +msgstr "Schriftsteller" #: src/view/com/composer/select-language/SuggestedLanguage.tsx:77 #: src/view/screens/PreferencesFollowingFeed.tsx:129 @@ -4697,26 +4419,18 @@ msgstr "" msgid "Yes" msgstr "Ja" -#: src/screens/Onboarding/StepModeration/index.tsx:46 -#~ msgid "You are in control" -#~ msgstr "" - #: src/screens/Deactivated.tsx:130 msgid "You are in line." -msgstr "" +msgstr "Du befindest dich in der Warteschlange." #: src/view/com/posts/FollowingEmptyState.tsx:67 #: src/view/com/posts/FollowingEndOfFeed.tsx:68 msgid "You can also discover new Custom Feeds to follow." -msgstr "" - -#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:123 -#~ msgid "You can also try our \"Discover\" algorithm:" -#~ msgstr "" +msgstr "Du kannst auch neue benutzerdefinierte Feeds entdecken und ihnen folgen." #: src/screens/Onboarding/StepFollowingFeed.tsx:142 msgid "You can change these settings later." -msgstr "" +msgstr "Du kannst diese Einstellungen später ändern." #: src/view/com/auth/login/Login.tsx:158 #: src/view/com/auth/login/PasswordUpdatedForm.tsx:31 @@ -4745,18 +4459,18 @@ msgstr "Du hast den Verfasser blockiert oder du wurdest vom Verfasser blockiert. #: src/view/com/modals/ModerationDetails.tsx:56 msgid "You have blocked this user. You cannot view their content." -msgstr "" +msgstr "Du hast diesen Benutzer blockiert und kannst seine Inhalte nicht sehen." #: src/view/com/auth/login/SetNewPasswordForm.tsx:57 #: src/view/com/auth/login/SetNewPasswordForm.tsx:92 #: src/view/com/modals/ChangePassword.tsx:87 #: src/view/com/modals/ChangePassword.tsx:121 msgid "You have entered an invalid code. It should look like XXXXX-XXXXX." -msgstr "" +msgstr "Du hast einen ungültigen Code eingegeben. Er sollte wie XXXXX-XXXXX aussehen." #: src/view/com/modals/ModerationDetails.tsx:87 msgid "You have muted this user." -msgstr "" +msgstr "Du hast diesen Benutzer stummgeschaltet." #: src/view/com/feeds/ProfileFeedgens.tsx:136 msgid "You have no feeds." @@ -4769,7 +4483,7 @@ msgstr "Du hast keine Listen." #: src/view/screens/ModerationBlockedAccounts.tsx:132 msgid "You have not blocked any accounts yet. To block an account, go to their profile and selected \"Block account\" from the menu on their account." -msgstr "" +msgstr "Du hast noch keine Konten blockiert. Um ein Konto zu blockieren, gehe auf dessen Profil und wähle \"Konto blockieren\" aus dem Menü des Kontos aus." #: src/view/screens/AppPasswords.tsx:87 msgid "You have not created any app passwords yet. You can create one by pressing the button below." @@ -4777,27 +4491,27 @@ msgstr "Du hast noch keine App-Passwörter erstellt. Du kannst eines erstellen, #: src/view/screens/ModerationMutedAccounts.tsx:131 msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." -msgstr "" +msgstr "Du hast noch keine Konten stummgeschaltet. Um ein Konto stumm zu schalten, gehe auf dessen Profil und wähle \"Konto stummschalten\" aus dem Menü des Kontos aus." #: src/components/dialogs/MutedWords.tsx:250 msgid "You haven't muted any words or tags yet" -msgstr "" +msgstr "Du hast noch keine Wörter oder Tags stummgeschaltet" #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." -msgstr "" +msgstr "Du musst 18 Jahre oder älter sein, um Inhalte für Erwachsene zu aktivieren." #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:103 msgid "You must be 18 years or older to enable adult content" -msgstr "" +msgstr "Du musst 18 Jahre oder älter sein, um Inhalte für Erwachsene zu aktivieren." #: src/view/com/util/forms/PostDropdownBtn.tsx:147 msgid "You will no longer receive notifications for this thread" -msgstr "" +msgstr "Du wirst keine Mitteilungen mehr für diesen Thread erhalten" #: src/view/com/util/forms/PostDropdownBtn.tsx:150 msgid "You will now receive notifications for this thread" -msgstr "" +msgstr "Du erhälst nun Mitteilungen für dieses Thread" #: src/view/com/auth/login/SetNewPasswordForm.tsx:107 msgid "You will receive an email with a \"reset code.\" Enter that code here, then enter your new password." @@ -4805,21 +4519,21 @@ msgstr "Du erhältst eine E-Mail mit einem \"Reset-Code\". Gib diesen Code hier #: src/screens/Onboarding/StepModeration/index.tsx:72 msgid "You're in control" -msgstr "" +msgstr "Du hast die Kontrolle" #: src/screens/Deactivated.tsx:87 #: src/screens/Deactivated.tsx:88 #: src/screens/Deactivated.tsx:103 msgid "You're in line" -msgstr "" +msgstr "Du bist in der Warteschlange" #: src/screens/Onboarding/StepFinished.tsx:90 msgid "You're ready to go!" -msgstr "" +msgstr "Du kannst loslegen!" #: src/view/com/posts/FollowingEndOfFeed.tsx:48 msgid "You've reached the end of your feed! Find some more accounts to follow." -msgstr "" +msgstr "Du hast das Ende deines Feeds erreicht! Finde weitere Konten, denen du folgen kannst." #: src/view/com/auth/create/Step1.tsx:67 msgid "Your account" @@ -4827,11 +4541,11 @@ msgstr "Dein Konto" #: src/view/com/modals/DeleteAccount.tsx:67 msgid "Your account has been deleted" -msgstr "" +msgstr "Dein Konto wurde gelöscht" #: src/view/screens/Settings/ExportCarDialog.tsx:47 msgid "Your account repository, containing all public data records, can be downloaded as a \"CAR\" file. This file does not include media embeds, such as images, or your private data, which must be fetched separately." -msgstr "" +msgstr "Dein Kontodepot, das alle öffentlichen Datensätze enthält, kann als \"CAR\"-Datei heruntergeladen werden. Diese Datei enthält keine Medieneinbettungen, wie z. B. Bilder, oder deine privaten Daten, welche separat abgerufen werden müssen." #: src/view/com/auth/create/Step1.tsx:215 msgid "Your birth date" @@ -4839,11 +4553,11 @@ msgstr "Dein Geburtsdatum" #: src/view/com/modals/InAppBrowserConsent.tsx:47 msgid "Your choice will be saved, but can be changed later in settings." -msgstr "" +msgstr "Deine Wahl wird gespeichert, kann aber später in den Einstellungen geändert werden." #: src/screens/Onboarding/StepFollowingFeed.tsx:61 msgid "Your default feed is \"Following\"" -msgstr "" +msgstr "Dein Standard-Feed ist \"Following\"" #: src/view/com/auth/create/state.ts:110 #: src/view/com/auth/login/ForgotPasswordForm.tsx:70 @@ -4851,10 +4565,6 @@ msgstr "" msgid "Your email appears to be invalid." msgstr "Deine E-Mail scheint ungültig zu sein." -#: src/view/com/modals/Waitlist.tsx:109 -#~ msgid "Your email has been saved! We'll be in touch soon." -#~ msgstr "Deine E-Mail wurde gespeichert! Wir werden uns bald bei dir melden." - #: src/view/com/modals/ChangeEmail.tsx:125 msgid "Your email has been updated but not verified. As a next step, please verify your new email." msgstr "Deine E-Mail wurde aktualisiert, aber nicht bestätigt. Als nächsten Schritt bestätige bitte deine neue E-Mail." @@ -4865,33 +4575,27 @@ msgstr "Deine E-Mail wurde noch nicht bestätigt. Dies ist ein wichtiger Sicherh #: src/view/com/posts/FollowingEmptyState.tsx:47 msgid "Your following feed is empty! Follow more users to see what's happening." -msgstr "" +msgstr "Dein Following-Feed ist leer! Folge mehr Benutzern, um auf dem Laufenden zu bleiben." #: src/view/com/auth/create/Step2.tsx:83 msgid "Your full handle will be" -msgstr "" +msgstr "Dein vollständiger Handle lautet" #: src/view/com/modals/ChangeHandle.tsx:270 msgid "Your full handle will be <0>@{0}</0>" -msgstr "" - -#: src/view/screens/Settings.tsx:430 -#: src/view/shell/desktop/RightNav.tsx:137 -#: src/view/shell/Drawer.tsx:660 -#~ msgid "Your invite codes are hidden when logged in using an App Password" -#~ msgstr "Deine Einladungscodes werden ausgeblendet, wenn du dich mit einem App-Passwort anmeldest" +msgstr "Dein vollständiger Handle lautet <0>@{0}</0>" #: src/components/dialogs/MutedWords.tsx:221 msgid "Your muted words" -msgstr "" +msgstr "Deine stummgeschalteten Wörter" #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" -msgstr "" +msgstr "Dein Passwort wurde erfolgreich geändert!" #: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" -msgstr "" +msgstr "Dein Beitrag wurde veröffentlicht" #: src/screens/Onboarding/StepFinished.tsx:105 #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:59 @@ -4906,7 +4610,7 @@ msgstr "Dein Profil" #: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" -msgstr "" +msgstr "Deine Antwort wurde veröffentlicht" #: src/view/com/auth/create/Step2.tsx:65 msgid "Your user handle" From a02d5f9eb98ae0c7a3402b02b01cebaa56ce1776 Mon Sep 17 00:00:00 2001 From: surfdude29 <149612116+surfdude29@users.noreply.github.com> Date: Tue, 19 Mar 2024 18:08:33 +0000 Subject: [PATCH 087/109] Update French translation (#3117) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update French translation * Apply suggestions from code review Co-authored-by: Stanislas Signoud <signez@stanisoft.net> * Update src/locale/locales/fr/messages.po Co-authored-by: Stanislas Signoud <signez@stanisoft.net> * Change `étiquette` to `mot-clé` * Change other usages of `actualité` to `actu` * Update messages.po * Change certain space characters to non-breaking spaces * Update src/locale/locales/fr/messages.po * Update src/locale/locales/fr/messages.po Co-authored-by: Stanislas Signoud <signez@stanisoft.net> * Update messages.po * Remove superseded strings and match some * Add new translations * Update revision date --------- Co-authored-by: Stanislas Signoud <signez@stanisoft.net> --- src/locale/locales/fr/messages.po | 848 ++++++++++-------------------- 1 file changed, 274 insertions(+), 574 deletions(-) diff --git a/src/locale/locales/fr/messages.po b/src/locale/locales/fr/messages.po index 2351ecb3a8..37af8b3862 100644 --- a/src/locale/locales/fr/messages.po +++ b/src/locale/locales/fr/messages.po @@ -8,41 +8,19 @@ msgstr "" "Language: fr\n" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: \n" -"Last-Translator: Stanislas Signoud (@signez.fr)\n" -"Language-Team: \n" +"PO-Revision-Date: 2024-03-12 09:00+0000\n" +"Last-Translator: surfdude29\n" +"Language-Team: Stanislas Signoud (@signez.fr), surfdude29\n" "Plural-Forms: \n" #: src/view/com/modals/VerifyEmail.tsx:142 msgid "(no email)" msgstr "(pas d’e-mail)" -#: src/view/shell/desktop/RightNav.tsx:168 -#~ msgid "{0, plural, one {# invite code available} other {# invite codes available}}" -#~ msgstr "{0, plural, one {# code d’invitation disponible} other {# codes d’invitations disponibles}}" - #: src/view/com/profile/ProfileHeader.tsx:593 msgid "{following} following" msgstr "{following} abonnements" -#: src/view/shell/desktop/RightNav.tsx:151 -#~ msgid "{invitesAvailable, plural, one {Invite codes: # available} other {Invite codes: # available}}" -#~ msgstr "{invitesAvailable, plural, one {Code d’invitation : # disponible} other {Codes d’invitation : # disponibles}}" - -#: src/view/screens/Settings.tsx:435 -#: src/view/shell/Drawer.tsx:664 -#~ msgid "{invitesAvailable} invite code available" -#~ msgstr "{invitesAvailable} code d’invitation disponible" - -#: src/view/screens/Settings.tsx:437 -#: src/view/shell/Drawer.tsx:666 -#~ msgid "{invitesAvailable} invite codes available" -#~ msgstr "{invitesAvailable} codes d’invitation disponibles" - -#: src/view/screens/Search/Search.tsx:87 -#~ msgid "{message}" -#~ msgstr "{message}" - #: src/view/shell/Drawer.tsx:440 msgid "{numUnreadNotifications} unread" msgstr "{numUnreadNotifications} non lus" @@ -57,7 +35,7 @@ msgstr "<0>{following} </0><1>abonnements</1>" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:30 msgid "<0>Choose your</0><1>Recommended</1><2>Feeds</2>" -msgstr "<0>Choisissez vos</0><1>fils d’actualité</1><2>recommandés</2>" +msgstr "<0>Choisissez vos</0><1>fils d’actu</1><2>recommandés</2>" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:37 msgid "<0>Follow some</0><1>Recommended</1><2>Users</2>" @@ -179,19 +157,19 @@ msgstr "Ajouter une carte de lien" #: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" -msgstr "Ajouter une carte de lien :" +msgstr "Ajouter une carte de lien :" #: src/components/dialogs/MutedWords.tsx:158 msgid "Add mute word for configured settings" -msgstr "" +msgstr "Ajouter un mot masqué pour les paramètres configurés" #: src/components/dialogs/MutedWords.tsx:87 msgid "Add muted words and tags" -msgstr "" +msgstr "Ajouter des mots et des mots-clés masqués" #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" -msgstr "Ajoutez l’enregistrement DNS suivant à votre domaine :" +msgstr "Ajoutez l’enregistrement DNS suivant à votre domaine :" #: src/view/com/profile/ProfileHeader.tsx:310 msgid "Add to Lists" @@ -217,7 +195,7 @@ msgstr "Ajouté à mes fils d’actu" #: src/view/screens/PreferencesFollowingFeed.tsx:173 msgid "Adjust the number of likes a reply must have to be shown in your feed." -msgstr "Définissez le nombre de likes qu’une réponse doit avoir pour être affichée dans votre fil d’actualité." +msgstr "Définissez le nombre de likes qu’une réponse doit avoir pour être affichée dans votre fil d’actu." #: src/view/com/modals/SelfLabel.tsx:75 msgid "Adult Content" @@ -227,22 +205,18 @@ msgstr "Contenu pour adultes" msgid "Adult content can only be enabled via the Web at <0/>." msgstr "Le contenu pour adultes ne peut être activé que via le Web à <0/>." -#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:78 -#~ msgid "Adult content can only be enabled via the Web at <0>bsky.app</0>." -#~ msgstr "" - #: src/view/screens/Settings/index.tsx:664 msgid "Advanced" msgstr "Avancé" #: src/view/screens/Feeds.tsx:666 msgid "All the feeds you've saved, right in one place." -msgstr "" +msgstr "Tous les fils d’actu que vous avez enregistrés, au même endroit." #: src/view/com/auth/login/ForgotPasswordForm.tsx:221 #: src/view/com/modals/ChangePassword.tsx:168 msgid "Already have a code?" -msgstr "" +msgstr "Avez-vous déjà un code ?" #: src/view/com/auth/login/ChooseAccountForm.tsx:98 msgid "Already signed in as @{0}" @@ -280,7 +254,7 @@ msgstr "et" #: src/screens/Onboarding/index.tsx:32 msgid "Animals" -msgstr "" +msgstr "Animaux" #: src/view/screens/LanguageSettings.tsx:95 msgid "App Language" @@ -302,10 +276,6 @@ msgstr "Les noms de mots de passe d’application doivent comporter au moins 4 c msgid "App password settings" msgstr "Paramètres de mot de passe d’application" -#: src/view/screens/Settings.tsx:650 -#~ msgid "App passwords" -#~ msgstr "Mots de passe d’application" - #: src/Navigation.tsx:239 #: src/view/screens/AppPasswords.tsx:187 #: src/view/screens/Settings/index.tsx:684 @@ -319,7 +289,7 @@ msgstr "Faire appel de l’avertissement sur le contenu" #: src/view/com/modals/AppealLabel.tsx:65 msgid "Appeal Content Warning" -msgstr "Appel de l’avertissement sur le contenu" +msgstr "Faire appel de l’avertissement sur le contenu" #: src/view/com/util/moderation/LabelInfo.tsx:52 msgid "Appeal this decision" @@ -335,28 +305,28 @@ msgstr "Affichage" #: src/view/screens/AppPasswords.tsx:224 msgid "Are you sure you want to delete the app password \"{name}\"?" -msgstr "Êtes-vous sûr de vouloir supprimer le mot de passe de l’application « {name} » ?" +msgstr "Êtes-vous sûr de vouloir supprimer le mot de passe de l’application « {name} » ?" #: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" -msgstr "Êtes-vous sûr de vouloir rejeter ce brouillon ?" +msgstr "Êtes-vous sûr de vouloir rejeter ce brouillon ?" #: src/components/dialogs/MutedWords.tsx:282 #: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" -msgstr "Vous confirmez ?" +msgstr "Vous confirmez ?" #: src/view/com/util/forms/PostDropdownBtn.tsx:322 msgid "Are you sure? This cannot be undone." -msgstr "Vous confirmez ? Cela ne pourra pas être annulé." +msgstr "Vous confirmez ? Cela ne pourra pas être annulé." #: src/view/com/composer/select-language/SuggestedLanguage.tsx:60 msgid "Are you writing in <0>{0}</0>?" -msgstr "" +msgstr "Écrivez-vous en <0>{0}</0> ?" #: src/screens/Onboarding/index.tsx:26 msgid "Art" -msgstr "" +msgstr "Art" #: src/view/com/modals/SelfLabel.tsx:123 msgid "Artistic or non-erotic nudity." @@ -383,7 +353,7 @@ msgstr "Retour" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:136 msgid "Based on your interest in {interestsText}" -msgstr "" +msgstr "En fonction de votre intérêt pour {interestsText}" #: src/view/screens/Settings/index.tsx:523 msgid "Basics" @@ -396,7 +366,7 @@ msgstr "Date de naissance" #: src/view/screens/Settings/index.tsx:340 msgid "Birthday:" -msgstr "Date de naissance :" +msgstr "Date de naissance :" #: src/view/com/profile/ProfileHeader.tsx:239 #: src/view/com/profile/ProfileHeader.tsx:346 @@ -413,7 +383,7 @@ msgstr "Liste de blocage" #: src/view/screens/ProfileList.tsx:316 msgid "Block these accounts?" -msgstr "Bloquer ces comptes ?" +msgstr "Bloquer ces comptes ?" #: src/view/screens/ProfileList.tsx:320 msgid "Block this List" @@ -462,7 +432,7 @@ msgstr "Bluesky" #: src/view/com/auth/server-input/index.tsx:150 msgid "Bluesky is an open network where you can choose your hosting provider. Custom hosting is now available in beta for developers." -msgstr "" +msgstr "Bluesky est un réseau ouvert où vous pouvez choisir votre hébergeur. L’auto-hébergement est désormais disponible en version bêta pour les développeurs." #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:80 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:80 @@ -479,21 +449,13 @@ msgstr "Bluesky est ouvert." msgid "Bluesky is public." msgstr "Bluesky est public." -#: src/view/com/modals/Waitlist.tsx:70 -#~ msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." -#~ msgstr "Bluesky distribue des invitations pour construire une communauté plus saine. Si personne ne peut vous donner une invitation, vous pouvez vous inscrire sur notre liste d’attente et nous vous en enverrons une bientôt." - #: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." -msgstr "Bluesky n’affichera pas votre profil et vos messages à des personnes non connectées. Il est possible que d’autres applications n’honorent pas cette demande. Cela ne privatise pas votre compte." - -#: src/view/com/modals/ServerInput.tsx:78 -#~ msgid "Bluesky.Social" -#~ msgstr "Bluesky.Social" +msgstr "Bluesky n’affichera pas votre profil et vos posts à des personnes non connectées. Il est possible que d’autres applications n’honorent pas cette demande. Cela ne privatise pas votre compte." #: src/screens/Onboarding/index.tsx:33 msgid "Books" -msgstr "" +msgstr "Livres" #: src/view/screens/Settings/index.tsx:859 msgid "Build version {0} {1}" @@ -504,10 +466,6 @@ msgstr "Version Build {0} {1}" msgid "Business" msgstr "Affaires" -#: src/view/com/modals/ServerInput.tsx:115 -#~ msgid "Button disabled. Input custom domain to proceed." -#~ msgstr "Bouton désactivé. Saisissez un domaine personnalisé pour continuer." - #: src/view/com/profile/ProfileSubpageHeader.tsx:157 msgid "by —" msgstr "par —" @@ -589,10 +547,6 @@ msgstr "Annuler la citation" msgid "Cancel search" msgstr "Annuler la recherche" -#: src/view/com/modals/Waitlist.tsx:136 -#~ msgid "Cancel waitlist signup" -#~ msgstr "Annuler l’inscription sur la liste d’attente" - #: src/view/screens/Settings/index.tsx:334 msgctxt "action" msgid "Change" @@ -613,19 +567,19 @@ msgstr "Modifier mon e-mail" #: src/view/screens/Settings/index.tsx:732 msgid "Change password" -msgstr "" +msgstr "Modifier le mot de passe" #: src/view/screens/Settings/index.tsx:741 msgid "Change Password" -msgstr "" +msgstr "Modifier le mot de passe" #: src/view/com/composer/select-language/SuggestedLanguage.tsx:73 msgid "Change post language to {0}" -msgstr "" +msgstr "Modifier la langue de post en {0}" #: src/view/screens/Settings/index.tsx:733 msgid "Change your Bluesky password" -msgstr "" +msgstr "Changer votre mot de passe pour Bluesky" #: src/view/com/modals/ChangeEmail.tsx:109 msgid "Change Your Email" @@ -634,11 +588,11 @@ msgstr "Modifier votre e-mail" #: src/screens/Deactivated.tsx:72 #: src/screens/Deactivated.tsx:76 msgid "Check my status" -msgstr "" +msgstr "Vérifier mon statut" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:121 msgid "Check out some recommended feeds. Tap + to add them to your list of pinned feeds." -msgstr "Consultez quelques fils d’actu recommandés. Appuyez sur + pour les ajouter à votre liste de fils d’actualité." +msgstr "Consultez quelques fils d’actu recommandés. Appuyez sur + pour les ajouter à votre liste de fils d’actu." #: src/view/com/auth/onboarding/RecommendedFollows.tsx:185 msgid "Check out some recommended users. Follow them to see similar users." @@ -646,11 +600,11 @@ msgstr "Consultez quelques comptes recommandés. Suivez-les pour voir des person #: src/view/com/modals/DeleteAccount.tsx:169 msgid "Check your inbox for an email with the confirmation code to enter below:" -msgstr "Consultez votre boîte de réception, vous avez du recevoir un e-mail contenant un code de confirmation à saisir ci-dessous :" +msgstr "Consultez votre boîte de réception, vous avez du recevoir un e-mail contenant un code de confirmation à saisir ci-dessous :" #: src/view/com/modals/Threadgate.tsx:72 msgid "Choose \"Everybody\" or \"Nobody\"" -msgstr "Choisir « Tout le monde » ou « Personne »" +msgstr "Choisir « Tout le monde » ou « Personne »" #: src/view/screens/Settings/index.tsx:697 msgid "Choose a new Bluesky username or create" @@ -662,20 +616,16 @@ msgstr "Choisir un service" #: src/screens/Onboarding/StepFinished.tsx:135 msgid "Choose the algorithms that power your custom feeds." -msgstr "" +msgstr "Choisissez les algorithmes qui alimentent vos fils d’actu personnalisés." #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:83 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:83 msgid "Choose the algorithms that power your experience with custom feeds." -msgstr "Choisissez les algorithmes qui alimentent votre expérience avec des fils d’actualité personnalisés." - -#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 -#~ msgid "Choose your algorithmic feeds" -#~ msgstr "" +msgstr "Choisissez les algorithmes qui alimentent votre expérience avec des fils d’actu personnalisés." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 msgid "Choose your main feeds" -msgstr "" +msgstr "Choisissez vos principaux fils d’actu" #: src/view/com/auth/create/Step1.tsx:196 msgid "Choose your password" @@ -710,25 +660,25 @@ msgstr "cliquez ici" #: src/components/TagMenu/index.web.tsx:138 msgid "Click here to open tag menu for {tag}" -msgstr "" +msgstr "Cliquez ici pour ouvrir le menu de mot-clé pour {tag}" #: src/components/RichText.tsx:191 msgid "Click here to open tag menu for #{tag}" -msgstr "" +msgstr "Cliquez ici pour ouvrir le menu de mot-clé pour #{tag}" #: src/screens/Onboarding/index.tsx:35 msgid "Climate" -msgstr "" +msgstr "Climat" #: src/view/com/modals/ChangePassword.tsx:265 #: src/view/com/modals/ChangePassword.tsx:268 msgid "Close" -msgstr "" +msgstr "Fermer" #: src/components/Dialog/index.web.tsx:84 #: src/components/Dialog/index.web.tsx:198 msgid "Close active dialog" -msgstr "" +msgstr "Fermer le dialogue actif" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:38 msgid "Close alert" @@ -752,7 +702,7 @@ msgstr "Fermer le pied de page de navigation" #: src/components/TagMenu/index.tsx:262 msgid "Close this dialog" -msgstr "" +msgstr "Fermer ce dialogue" #: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" @@ -776,11 +726,11 @@ msgstr "Réduit la liste des comptes pour une notification donnée" #: src/screens/Onboarding/index.tsx:41 msgid "Comedy" -msgstr "" +msgstr "Comédie" #: src/screens/Onboarding/index.tsx:27 msgid "Comics" -msgstr "" +msgstr "Bandes dessinées" #: src/Navigation.tsx:229 #: src/view/screens/CommunityGuidelines.tsx:32 @@ -789,15 +739,15 @@ msgstr "Directives communautaires" #: src/screens/Onboarding/StepFinished.tsx:148 msgid "Complete onboarding and start using your account" -msgstr "" +msgstr "Terminez le didacticiel et commencez à utiliser votre compte" #: src/view/com/auth/create/Step3.tsx:73 msgid "Complete the challenge" -msgstr "" +msgstr "Compléter le défi" #: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" -msgstr "Permet d’écrire des messages de {MAX_GRAPHEME_LENGTH} caractères maximum" +msgstr "Permet d’écrire des posts de {MAX_GRAPHEME_LENGTH} caractères maximum" #: src/view/com/composer/Prompt.tsx:24 msgid "Compose reply" @@ -805,7 +755,7 @@ msgstr "Rédiger une réponse" #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:67 msgid "Configure content filtering setting for category: {0}" -msgstr "" +msgstr "Configurer les paramètres de filtrage de contenu pour la catégorie : {0}" #: src/components/Prompt.tsx:124 #: src/view/com/modals/AppealLabel.tsx:98 @@ -846,10 +796,6 @@ msgstr "Confirmez votre âge pour activer le contenu pour adultes." msgid "Confirmation code" msgstr "Code de confirmation" -#: src/view/com/modals/Waitlist.tsx:120 -#~ msgid "Confirms signing up {email} to the waitlist" -#~ msgstr "Confirme l’inscription de {email} sur la liste d’attente" - #: src/view/com/auth/create/CreateAccount.tsx:193 #: src/view/com/auth/login/LoginForm.tsx:278 msgid "Connecting..." @@ -857,7 +803,7 @@ msgstr "Connexion…" #: src/view/com/auth/create/CreateAccount.tsx:213 msgid "Contact support" -msgstr "" +msgstr "Contacter le support" #: src/view/screens/Moderation.tsx:83 msgid "Content filtering" @@ -900,19 +846,19 @@ msgstr "Continuer" #: src/screens/Onboarding/StepModeration/index.tsx:115 #: src/screens/Onboarding/StepTopicalFeeds.tsx:111 msgid "Continue to next step" -msgstr "" +msgstr "Passer à l’étape suivante" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:167 msgid "Continue to the next step" -msgstr "" +msgstr "Passer à l’étape suivante" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:191 msgid "Continue to the next step without following any accounts" -msgstr "" +msgstr "Passer à l’étape suivante sans suivre aucun compte" #: src/screens/Onboarding/index.tsx:44 msgid "Cooking" -msgstr "" +msgstr "Cuisine" #: src/view/com/modals/AddAppPasswords.tsx:195 #: src/view/com/modals/InviteCodes.tsx:182 @@ -968,10 +914,6 @@ msgstr "Impossible de charger le fil d’actu" msgid "Could not load list" msgstr "Impossible de charger la liste" -#: src/view/com/auth/create/Step2.tsx:91 -#~ msgid "Country" -#~ msgstr "" - #: src/view/com/auth/HomeLoggedOutCTA.tsx:62 #: src/view/com/auth/SplashScreen.tsx:71 #: src/view/com/auth/SplashScreen.web.tsx:81 @@ -1013,12 +955,12 @@ msgstr "Crée une carte avec une miniature. La carte pointe vers {url}" #: src/screens/Onboarding/index.tsx:29 msgid "Culture" -msgstr "" +msgstr "Culture" #: src/view/com/auth/server-input/index.tsx:95 #: src/view/com/auth/server-input/index.tsx:96 msgid "Custom" -msgstr "" +msgstr "Personnalisé" #: src/view/com/modals/ChangeHandle.tsx:389 msgid "Custom domain" @@ -1027,16 +969,12 @@ msgstr "Domaine personnalisé" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 #: src/view/screens/Feeds.tsx:692 msgid "Custom feeds built by the community bring you new experiences and help you find the content you love." -msgstr "" +msgstr "Les fils d’actu personnalisés élaborés par la communauté vous font vivre de nouvelles expériences et vous aident à trouver le contenu que vous aimez." #: src/view/screens/PreferencesExternalEmbeds.tsx:55 msgid "Customize media from external sites." msgstr "Personnaliser les médias provenant de sites externes." -#: src/view/screens/Settings.tsx:687 -#~ msgid "Danger Zone" -#~ msgstr "Zone de danger" - #: src/view/screens/Settings/index.tsx:485 #: src/view/screens/Settings/index.tsx:511 msgid "Dark" @@ -1048,7 +986,7 @@ msgstr "Mode sombre" #: src/view/screens/Settings/index.tsx:498 msgid "Dark Theme" -msgstr "" +msgstr "Thème sombre" #: src/view/screens/Debug.tsx:83 msgid "Debug panel" @@ -1076,13 +1014,9 @@ msgstr "Supprimer la liste" msgid "Delete my account" msgstr "Supprimer mon compte" -#: src/view/screens/Settings.tsx:706 -#~ msgid "Delete my account…" -#~ msgstr "Supprimer mon compte…" - #: src/view/screens/Settings/index.tsx:784 msgid "Delete My Account…" -msgstr "" +msgstr "Supprimer mon compte…" #: src/view/com/util/forms/PostDropdownBtn.tsx:317 #: src/view/com/util/forms/PostDropdownBtn.tsx:326 @@ -1091,7 +1025,7 @@ msgstr "Supprimer le post" #: src/view/com/util/forms/PostDropdownBtn.tsx:321 msgid "Delete this post?" -msgstr "Supprimer ce post ?" +msgstr "Supprimer ce post ?" #: src/view/com/util/post-embeds/QuoteEmbed.tsx:70 msgid "Deleted" @@ -1108,17 +1042,13 @@ msgstr "Post supprimé." msgid "Description" msgstr "Description" -#: src/view/screens/Settings.tsx:760 -#~ msgid "Developer Tools" -#~ msgstr "Outils de dév" - #: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" -msgstr "Vous vouliez dire quelque chose ?" +msgstr "Vous vouliez dire quelque chose ?" #: src/view/screens/Settings/index.tsx:504 msgid "Dim" -msgstr "" +msgstr "Atténué" #: src/view/com/composer/Composer.tsx:151 msgid "Discard" @@ -1137,13 +1067,9 @@ msgstr "Empêcher les applis de montrer mon compte aux personnes non connectées msgid "Discover new custom feeds" msgstr "Découvrir des fils d’actu personnalisés" -#: src/view/screens/Feeds.tsx:473 -#~ msgid "Discover new feeds" -#~ msgstr "Découvrir de nouveaux fils d’actu" - #: src/view/screens/Feeds.tsx:689 msgid "Discover New Feeds" -msgstr "" +msgstr "Découvrir de nouveaux fils d’actu" #: src/view/com/modals/EditProfile.tsx:192 msgid "Display name" @@ -1155,11 +1081,7 @@ msgstr "Afficher le nom" #: src/view/com/modals/ChangeHandle.tsx:487 msgid "Domain verified!" -msgstr "Domaine vérifié !" - -#: src/view/com/auth/create/Step1.tsx:170 -#~ msgid "Don't have an invite code?" -#~ msgstr "Pas de code d’invitation ?" +msgstr "Domaine vérifié !" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:86 #: src/view/com/modals/EditImage.tsx:333 @@ -1200,20 +1122,20 @@ msgstr "Tapotez deux fois pour vous connecter" #: src/view/screens/Settings/index.tsx:755 msgid "Download Bluesky account data (repository)" -msgstr "" +msgstr "Télécharger les données du compte Bluesky (dépôt)" #: src/view/screens/Settings/ExportCarDialog.tsx:59 #: src/view/screens/Settings/ExportCarDialog.tsx:63 msgid "Download CAR file" -msgstr "" +msgstr "Télécharger le fichier CAR" #: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" -msgstr "" +msgstr "Déposer pour ajouter des images" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:111 msgid "Due to Apple policies, adult content can only be enabled on the web after completing sign up." -msgstr "" +msgstr "En raison des politiques d’Apple, le contenu pour adultes ne peut être activé que via le Web une fois l’inscription terminée." #: src/view/com/modals/EditProfile.tsx:185 msgid "e.g. Alice Roberts" @@ -1298,7 +1220,7 @@ msgstr "Modifier votre description de profil" #: src/screens/Onboarding/index.tsx:34 msgid "Education" -msgstr "" +msgstr "Éducation" #: src/view/com/auth/create/Step1.tsx:176 #: src/view/com/auth/login/ForgotPasswordForm.tsx:156 @@ -1326,7 +1248,7 @@ msgstr "Adresse e-mail vérifiée" #: src/view/screens/Settings/index.tsx:312 msgid "Email:" -msgstr "E-mail :" +msgstr "E-mail :" #: src/view/com/modals/EmbedConsent.tsx:113 msgid "Enable {0} only" @@ -1339,7 +1261,7 @@ msgstr "Activer le contenu pour adultes" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:76 #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:77 msgid "Enable adult content in your feeds" -msgstr "" +msgstr "Activer le contenu pour adultes dans vos fils d’actu" #: src/view/com/modals/EmbedConsent.tsx:97 msgid "Enable External Media" @@ -1364,7 +1286,7 @@ msgstr "Entrer un nom pour ce mot de passe d’application" #: src/components/dialogs/MutedWords.tsx:100 #: src/components/dialogs/MutedWords.tsx:101 msgid "Enter a word or tag" -msgstr "" +msgstr "Saisir un mot ou un mot-clé" #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" @@ -1372,7 +1294,7 @@ msgstr "Entrer un code de confirmation" #: src/view/com/modals/ChangePassword.tsx:151 msgid "Enter the code you received to change your password." -msgstr "" +msgstr "Saisissez le code que vous avez reçu pour modifier votre mot de passe." #: src/view/com/modals/ChangeHandle.tsx:371 msgid "Enter the domain you want to use" @@ -1380,17 +1302,13 @@ msgstr "Entrez le domaine que vous voulez utiliser" #: src/view/com/auth/login/ForgotPasswordForm.tsx:107 msgid "Enter the email you used to create your account. We'll send you a \"reset code\" so you can set a new password." -msgstr "Saisissez l’e-mail que vous avez utilisé pour créer votre compte. Nous vous enverrons un « code de réinitialisation » afin changer votre mot de passe." +msgstr "Saisissez l’e-mail que vous avez utilisé pour créer votre compte. Nous vous enverrons un « code de réinitialisation » afin changer votre mot de passe." #: src/view/com/auth/create/Step1.tsx:228 #: src/view/com/modals/BirthDateSettings.tsx:74 msgid "Enter your birth date" msgstr "Saisissez votre date de naissance" -#: src/view/com/modals/Waitlist.tsx:78 -#~ msgid "Enter your email" -#~ msgstr "Entrez votre e-mail" - #: src/view/com/auth/create/Step1.tsx:172 msgid "Enter your email address" msgstr "Entrez votre e-mail" @@ -1403,21 +1321,17 @@ msgstr "Entrez votre nouvel e-mail ci-dessus" msgid "Enter your new email address below." msgstr "Entrez votre nouvelle e-mail ci-dessous." -#: src/view/com/auth/create/Step2.tsx:188 -#~ msgid "Enter your phone number" -#~ msgstr "" - #: src/view/com/auth/login/Login.tsx:99 msgid "Enter your username and password" msgstr "Entrez votre pseudo et votre mot de passe" #: src/view/com/auth/create/Step3.tsx:67 msgid "Error receiving captcha response." -msgstr "" +msgstr "Erreur de réception de la réponse captcha." #: src/view/screens/Search/Search.tsx:110 msgid "Error:" -msgstr "Erreur :" +msgstr "Erreur :" #: src/view/com/modals/Threadgate.tsx:76 msgid "Everybody" @@ -1436,10 +1350,6 @@ msgstr "Sort de la vue de l’image" msgid "Exits inputting search query" msgstr "Sort de la saisie de la recherche" -#: src/view/com/modals/Waitlist.tsx:138 -#~ msgid "Exits signing up for waitlist with {email}" -#~ msgstr "Sort de l’inscription sur la liste d’attente avec {email}" - #: src/view/com/lightbox/Lightbox.web.tsx:163 msgid "Expand alt text" msgstr "Développer le texte alt" @@ -1451,12 +1361,12 @@ msgstr "Développe ou réduit le post complet auquel vous répondez" #: src/view/screens/Settings/index.tsx:753 msgid "Export my data" -msgstr "" +msgstr "Exporter mes données" #: src/view/screens/Settings/ExportCarDialog.tsx:44 #: src/view/screens/Settings/index.tsx:764 msgid "Export My Data" -msgstr "" +msgstr "Exporter mes données" #: src/view/com/modals/EmbedConsent.tsx:64 msgid "External Media" @@ -1507,10 +1417,6 @@ msgstr "Fil d’actu par {0}" msgid "Feed offline" msgstr "Fil d’actu hors ligne" -#: src/view/com/feeds/FeedPage.tsx:143 -#~ msgid "Feed Preferences" -#~ msgstr "Préférences en matière de fil d’actu" - #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 msgid "Feedback" @@ -1525,15 +1431,7 @@ msgstr "Feedback" #: src/view/shell/Drawer.tsx:476 #: src/view/shell/Drawer.tsx:477 msgid "Feeds" -msgstr "Fil d’actu" - -#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 -#~ msgid "Feeds are created by users and can give you entirely new experiences." -#~ msgstr "" - -#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 -#~ msgid "Feeds are created by users and organizations. They offer you varied experiences and suggest content you may like using algorithms." -#~ msgstr "" +msgstr "Fils d’actu" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:57 msgid "Feeds are created by users to curate content. Choose some feeds that you find interesting." @@ -1545,11 +1443,11 @@ msgstr "Les fils d’actu sont des algorithmes personnalisés qui se construisen #: src/screens/Onboarding/StepTopicalFeeds.tsx:76 msgid "Feeds can be topical as well!" -msgstr "" +msgstr "Les fils d’actu peuvent également être thématiques !" #: src/screens/Onboarding/StepFinished.tsx:151 msgid "Finalizing" -msgstr "" +msgstr "Finalisation" #: src/view/com/posts/CustomFeedEmptyState.tsx:47 #: src/view/com/posts/FollowingEmptyState.tsx:57 @@ -1571,11 +1469,7 @@ msgstr "Recherche de comptes similaires…" #: src/view/screens/PreferencesFollowingFeed.tsx:111 msgid "Fine-tune the content you see on your Following feed." -msgstr "" - -#: src/view/screens/PreferencesHomeFeed.tsx:111 -#~ msgid "Fine-tune the content you see on your home screen." -#~ msgstr "Affine le contenu affiché sur votre écran d’accueil." +msgstr "Affine le contenu affiché sur votre fil d’actu « Following »." #: src/view/screens/PreferencesThreads.tsx:60 msgid "Fine-tune the discussion threads." @@ -1583,11 +1477,11 @@ msgstr "Affine les fils de discussion." #: src/screens/Onboarding/index.tsx:38 msgid "Fitness" -msgstr "" +msgstr "Fitness" #: src/screens/Onboarding/StepFinished.tsx:131 msgid "Flexible" -msgstr "" +msgstr "Flexible" #: src/view/com/modals/EditImage.tsx:115 msgid "Flip horizontal" @@ -1617,11 +1511,11 @@ msgstr "Suivre {0}" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:179 msgid "Follow All" -msgstr "" +msgstr "Suivre tous" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:174 msgid "Follow selected accounts and continue to the next step" -msgstr "" +msgstr "Suivre les comptes sélectionnés et passer à l’étape suivante" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:64 msgid "Follow some users to get started. We can recommend you more users based on who you find interesting." @@ -1663,7 +1557,7 @@ msgstr "Suit {0}" #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 msgid "Following Feed Preferences" -msgstr "" +msgstr "Préférences en matière de fil d’actu « Following »" #: src/view/com/profile/ProfileHeader.tsx:546 msgid "Follows you" @@ -1675,7 +1569,7 @@ msgstr "Vous suit" #: src/screens/Onboarding/index.tsx:43 msgid "Food" -msgstr "" +msgstr "Nourriture" #: src/view/com/modals/DeleteAccount.tsx:111 msgid "For security reasons, we'll need to send a confirmation code to your email address." @@ -1701,7 +1595,7 @@ msgstr "Mot de passe oublié" #: src/screens/Hashtag.tsx:108 #: src/screens/Hashtag.tsx:148 msgid "From @{sanitizedAuthor}" -msgstr "" +msgstr "De @{sanitizedAuthor}" #: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" @@ -1734,12 +1628,12 @@ msgstr "Retour" #: src/screens/Onboarding/Layout.tsx:104 #: src/screens/Onboarding/Layout.tsx:193 msgid "Go back to previous step" -msgstr "" +msgstr "Retour à l’étape précédente" #: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" -msgstr "" +msgstr "Aller à @{queryMaybeHandle}" #: src/view/com/auth/login/ForgotPasswordForm.tsx:189 #: src/view/com/auth/login/ForgotPasswordForm.tsx:218 @@ -1755,19 +1649,15 @@ msgstr "Pseudo" #: src/Navigation.tsx:270 msgid "Hashtag" -msgstr "" - -#: src/components/RichText.tsx:188 -#~ msgid "Hashtag: {tag}" -#~ msgstr "" +msgstr "Mot-clé" #: src/components/RichText.tsx:190 msgid "Hashtag: #{tag}" -msgstr "" +msgstr "Mot-clé : #{tag}" #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" -msgstr "" +msgstr "Un souci ?" #: src/view/shell/desktop/RightNav.tsx:90 #: src/view/shell/Drawer.tsx:321 @@ -1776,15 +1666,15 @@ msgstr "Aide" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:132 msgid "Here are some accounts for you to follow" -msgstr "" +msgstr "Voici quelques comptes à suivre" #: src/screens/Onboarding/StepTopicalFeeds.tsx:85 msgid "Here are some popular topical feeds. You can choose to follow as many as you like." -msgstr "" +msgstr "Voici quelques fils d’actu thématiques populaires. Vous pouvez choisir d’en suivre autant que vous le souhaitez." #: src/screens/Onboarding/StepTopicalFeeds.tsx:80 msgid "Here are some topical feeds based on your interests: {interestsText}. You can choose to follow as many as you like." -msgstr "" +msgstr "Voici quelques fils d’actu thématiques basés sur vos centres d’intérêt : {interestsText}. Vous pouvez choisir d’en suivre autant que vous le souhaitez." #: src/view/com/modals/AddAppPasswords.tsx:153 msgid "Here is your app password." @@ -1815,7 +1705,7 @@ msgstr "Cacher ce contenu" #: src/view/com/util/forms/PostDropdownBtn.tsx:280 msgid "Hide this post?" -msgstr "Cacher ce post ?" +msgstr "Cacher ce post ?" #: src/view/com/notifications/FeedItem.tsx:316 msgid "Hide user list" @@ -1853,13 +1743,6 @@ msgstr "Hmm, nous n’arrivons pas à trouver ce fil d’actu. Il a peut-être msgid "Home" msgstr "Accueil" -#: src/Navigation.tsx:247 -#: src/view/com/pager/FeedsTabBarMobile.tsx:123 -#: src/view/screens/PreferencesHomeFeed.tsx:104 -#: src/view/screens/Settings/index.tsx:543 -#~ msgid "Home Feed Preferences" -#~ msgstr "Préférences de fils d’actu de l’accueil" - #: src/view/com/auth/create/Step1.tsx:75 #: src/view/com/auth/login/ForgotPasswordForm.tsx:120 msgid "Hosting provider" @@ -1867,7 +1750,7 @@ msgstr "Hébergeur" #: src/view/com/modals/InAppBrowserConsent.tsx:44 msgid "How should we open this link?" -msgstr "" +msgstr "Comment ouvrir ce lien ?" #: src/view/com/modals/VerifyEmail.tsx:214 msgid "I have a code" @@ -1891,7 +1774,7 @@ msgstr "Si rien n’est sélectionné, il n’y a pas de restriction d’âge." #: src/view/com/modals/ChangePassword.tsx:146 msgid "If you want to change your password, we will send you a code to verify that this is your account." -msgstr "" +msgstr "Si vous souhaitez modifier votre mot de passe, nous vous enverrons un code pour vérifier qu’il s’agit bien de votre compte." #: src/view/com/util/images/Gallery.tsx:38 msgid "Image" @@ -1916,7 +1799,7 @@ msgstr "Entrez le code de confirmation pour supprimer le compte" #: src/view/com/auth/create/Step1.tsx:177 msgid "Input email for Bluesky account" -msgstr "" +msgstr "Saisir l’email pour le compte Bluesky" #: src/view/com/auth/create/Step1.tsx:151 msgid "Input invite code to proceed" @@ -1934,10 +1817,6 @@ msgstr "Entrez le nouveau mot de passe" msgid "Input password for account deletion" msgstr "Entrez le mot de passe pour la suppression du compte" -#: src/view/com/auth/create/Step2.tsx:196 -#~ msgid "Input phone number for SMS verification" -#~ msgstr "" - #: src/view/com/auth/login/LoginForm.tsx:230 msgid "Input the password tied to {identifier}" msgstr "Entrez le mot de passe associé à {identifier}" @@ -1946,14 +1825,6 @@ msgstr "Entrez le mot de passe associé à {identifier}" msgid "Input the username or email address you used at signup" msgstr "Entrez le pseudo ou l’adresse e-mail que vous avez utilisé lors de l’inscription" -#: src/view/com/auth/create/Step2.tsx:271 -#~ msgid "Input the verification code we have texted to you" -#~ msgstr "" - -#: src/view/com/modals/Waitlist.tsx:90 -#~ msgid "Input your email to get on the Bluesky waitlist" -#~ msgstr "Entrez votre e-mail pour vous inscrire sur la liste d’attente de Bluesky" - #: src/view/com/auth/login/LoginForm.tsx:229 msgid "Input your password" msgstr "Entrez votre mot de passe" @@ -1970,10 +1841,6 @@ msgstr "Enregistrement de post invalide ou non pris en charge" msgid "Invalid username or password" msgstr "Pseudo ou mot de passe incorrect" -#: src/view/screens/Settings.tsx:411 -#~ msgid "Invite" -#~ msgstr "Inviter" - #: src/view/com/modals/InviteCodes.tsx:93 msgid "Invite a Friend" msgstr "Inviter un ami" @@ -1989,41 +1856,24 @@ msgstr "Code d’invitation refusé. Vérifiez que vous l’avez saisi correctem #: src/view/com/modals/InviteCodes.tsx:170 msgid "Invite codes: {0} available" -msgstr "Code d’invitation : {0} disponible" - -#: src/view/shell/Drawer.tsx:645 -#~ msgid "Invite codes: {invitesAvailable} available" -#~ msgstr "Invitations : {invitesAvailable} codes dispo" +msgstr "Code d’invitation : {0} disponible" #: src/view/com/modals/InviteCodes.tsx:169 msgid "Invite codes: 1 available" -msgstr "Invitations : 1 code dispo" +msgstr "Invitations : 1 code dispo" #: src/screens/Onboarding/StepFollowingFeed.tsx:64 msgid "It shows posts from the people you follow as they happen." -msgstr "" +msgstr "Il affiche les posts des personnes que vous suivez au fur et à mesure qu’ils sont publiés." #: src/view/com/auth/HomeLoggedOutCTA.tsx:99 #: src/view/com/auth/SplashScreen.web.tsx:138 msgid "Jobs" msgstr "Emplois" -#: src/view/com/modals/Waitlist.tsx:67 -#~ msgid "Join the waitlist" -#~ msgstr "S’inscrire sur la liste d’attente" - -#: src/view/com/auth/create/Step1.tsx:174 -#: src/view/com/auth/create/Step1.tsx:178 -#~ msgid "Join the waitlist." -#~ msgstr "S’inscrire sur la liste d’attente." - -#: src/view/com/modals/Waitlist.tsx:128 -#~ msgid "Join Waitlist" -#~ msgstr "S’inscrire sur la liste d’attente" - #: src/screens/Onboarding/index.tsx:24 msgid "Journalism" -msgstr "" +msgstr "Journalisme" #: src/view/com/composer/select-language/SelectLangBtn.tsx:104 msgid "Language selection" @@ -2044,7 +1894,7 @@ msgstr "Langues" #: src/view/com/auth/create/StepHeader.tsx:20 msgid "Last step!" -msgstr "Dernière étape !" +msgstr "Dernière étape !" #: src/view/com/util/moderation/ContentHider.tsx:103 msgid "Learn more" @@ -2078,7 +1928,7 @@ msgstr "Quitter Bluesky" #: src/screens/Deactivated.tsx:128 msgid "left to go." -msgstr "" +msgstr "devant vous dans la file." #: src/view/screens/Settings/index.tsx:278 msgid "Legacy storage cleared, you need to restart the app now." @@ -2087,11 +1937,11 @@ msgstr "Stockage ancien effacé, vous devez redémarrer l’application maintena #: src/view/com/auth/login/Login.tsx:128 #: src/view/com/auth/login/Login.tsx:144 msgid "Let's get your password reset!" -msgstr "Réinitialisez votre mot de passe !" +msgstr "Réinitialisez votre mot de passe !" #: src/screens/Onboarding/StepFinished.tsx:151 msgid "Let's go!" -msgstr "" +msgstr "Allons-y !" #: src/view/com/util/UserAvatar.tsx:248 #: src/view/com/util/UserBanner.tsx:62 @@ -2117,7 +1967,7 @@ msgstr "Liké par" #: src/view/screens/PostLikedBy.tsx:27 #: src/view/screens/ProfileFeedLikedBy.tsx:27 msgid "Liked By" -msgstr "" +msgstr "Liké par" #: src/view/com/feeds/FeedSourceCard.tsx:279 msgid "Liked by {0} {1}" @@ -2190,7 +2040,7 @@ msgstr "Listes" #: src/view/com/post-thread/PostThread.tsx:333 #: src/view/com/post-thread/PostThread.tsx:341 msgid "Load more posts" -msgstr "Charger plus d’articles" +msgstr "Charger plus de posts" #: src/view/screens/Notifications.tsx:159 msgid "Load new notifications" @@ -2201,16 +2051,12 @@ msgstr "Charger les nouvelles notifications" #: src/view/screens/ProfileFeed.tsx:495 #: src/view/screens/ProfileList.tsx:681 msgid "Load new posts" -msgstr "Charger les nouveaux messages" +msgstr "Charger les nouveaux posts" #: src/view/com/composer/text-input/mobile/Autocomplete.tsx:95 msgid "Loading..." msgstr "Chargement…" -#: src/view/com/modals/ServerInput.tsx:50 -#~ msgid "Local dev server" -#~ msgstr "Serveur de dév local" - #: src/Navigation.tsx:209 msgid "Log" msgstr "Journaux" @@ -2220,7 +2066,7 @@ msgstr "Journaux" #: src/screens/Deactivated.tsx:178 #: src/screens/Deactivated.tsx:181 msgid "Log out" -msgstr "" +msgstr "Déconnexion" #: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" @@ -2232,19 +2078,19 @@ msgstr "Se connecter à un compte qui n’est pas listé" #: src/view/com/modals/LinkWarning.tsx:65 msgid "Make sure this is where you intend to go!" -msgstr "Assurez-vous que c’est bien là que vous avez l’intention d’aller !" +msgstr "Assurez-vous que c’est bien là que vous avez l’intention d’aller !" #: src/components/dialogs/MutedWords.tsx:83 msgid "Manage your muted words and tags" -msgstr "" +msgstr "Gérer les mots et les mots-clés masqués" #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" -msgstr "" +msgstr "Ne doit pas dépasser 253 caractères" #: src/view/com/auth/create/Step2.tsx:109 msgid "May only contain letters and numbers" -msgstr "" +msgstr "Ne peut contenir que des lettres et des chiffres" #: src/view/screens/Profile.tsx:182 msgid "Media" @@ -2265,7 +2111,7 @@ msgstr "Menu" #: src/view/com/posts/FeedErrorMessage.tsx:197 msgid "Message from server: {0}" -msgstr "Message du serveur : {0}" +msgstr "Message du serveur : {0}" #: src/Navigation.tsx:117 #: src/view/screens/Moderation.tsx:66 @@ -2326,25 +2172,21 @@ msgstr "Plus de fils d’actu" msgid "More options" msgstr "Plus d’options" -#: src/view/com/util/forms/PostDropdownBtn.tsx:315 -#~ msgid "More post options" -#~ msgstr "Plus d’options de post" - #: src/view/screens/PreferencesThreads.tsx:82 msgid "Most-liked replies first" msgstr "Réponses les plus likées en premier" #: src/view/com/auth/create/Step2.tsx:122 msgid "Must be at least 3 characters" -msgstr "" +msgstr "Doit comporter au moins 3 caractères" #: src/components/TagMenu/index.tsx:249 msgid "Mute" -msgstr "" +msgstr "Masquer" #: src/components/TagMenu/index.web.tsx:105 msgid "Mute {truncatedTag}" -msgstr "" +msgstr "Masquer {truncatedTag}" #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" @@ -2356,19 +2198,15 @@ msgstr "Masquer les comptes" #: src/components/TagMenu/index.tsx:209 msgid "Mute all {displayTag} posts" -msgstr "" - -#: src/components/TagMenu/index.tsx:211 -#~ msgid "Mute all {tag} posts" -#~ msgstr "" +msgstr "Masquer tous les posts {displayTag}" #: src/components/dialogs/MutedWords.tsx:149 msgid "Mute in tags only" -msgstr "" +msgstr "Masquer dans les mots-clés uniquement" #: src/components/dialogs/MutedWords.tsx:134 msgid "Mute in text & tags" -msgstr "" +msgstr "Masquer dans le texte et les mots-clés" #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" @@ -2376,7 +2214,7 @@ msgstr "Masquer la liste" #: src/view/screens/ProfileList.tsx:275 msgid "Mute these accounts?" -msgstr "Masquer ces comptes ?" +msgstr "Masquer ces comptes ?" #: src/view/screens/ProfileList.tsx:279 msgid "Mute this List" @@ -2384,11 +2222,11 @@ msgstr "Masquer cette liste" #: src/components/dialogs/MutedWords.tsx:127 msgid "Mute this word in post text and tags" -msgstr "" +msgstr "Masquer ce mot dans le texte du post et les mots-clés" #: src/components/dialogs/MutedWords.tsx:142 msgid "Mute this word in tags only" -msgstr "" +msgstr "Masquer ce mot dans les mots-clés uniquement" #: src/view/com/util/forms/PostDropdownBtn.tsx:251 #: src/view/com/util/forms/PostDropdownBtn.tsx:257 @@ -2398,11 +2236,11 @@ msgstr "Masquer ce fil de discussion" #: src/view/com/util/forms/PostDropdownBtn.tsx:267 #: src/view/com/util/forms/PostDropdownBtn.tsx:269 msgid "Mute words & tags" -msgstr "" +msgstr "Masquer les mots et les mots-clés" #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" -msgstr "" +msgstr "Masqué" #: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" @@ -2415,11 +2253,11 @@ msgstr "Comptes masqués" #: src/view/screens/ModerationMutedAccounts.tsx:115 msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." -msgstr "Les comptes masqués voient leurs posts supprimés de votre fil d’actualité et de vos notifications. Cette option est totalement privée." +msgstr "Les comptes masqués voient leurs posts supprimés de votre fil d’actu et de vos notifications. Cette option est totalement privée." #: src/view/screens/Moderation.tsx:100 msgid "Muted words & tags" -msgstr "" +msgstr "Les mots et les mots-clés masqués" #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." @@ -2443,7 +2281,7 @@ msgstr "Mes fils d’actu enregistrés" #: src/view/com/auth/server-input/index.tsx:118 msgid "my-server.com" -msgstr "" +msgstr "mon-serveur.fr" #: src/view/com/modals/AddAppPasswords.tsx:179 #: src/view/com/modals/CreateOrEditList.tsx:290 @@ -2456,7 +2294,7 @@ msgstr "Le nom est requis" #: src/screens/Onboarding/index.tsx:25 msgid "Nature" -msgstr "" +msgstr "Nature" #: src/view/com/auth/login/ForgotPasswordForm.tsx:190 #: src/view/com/auth/login/ForgotPasswordForm.tsx:219 @@ -2482,11 +2320,11 @@ msgstr "Ne perdez jamais l’accès à vos followers et à vos données." #: src/screens/Onboarding/StepFinished.tsx:119 msgid "Never lose access to your followers or data." -msgstr "" +msgstr "Ne perdez jamais l’accès à vos followers ou à vos données." #: src/components/dialogs/MutedWords.tsx:293 msgid "Nevermind" -msgstr "" +msgstr "Peu importe" #: src/view/screens/Lists.tsx:76 msgctxt "action" @@ -2507,7 +2345,7 @@ msgstr "Nouveau mot de passe" #: src/view/com/modals/ChangePassword.tsx:215 msgid "New Password" -msgstr "" +msgstr "Nouveau mot de passe" #: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" @@ -2539,7 +2377,7 @@ msgstr "Réponses les plus récentes en premier" #: src/screens/Onboarding/index.tsx:23 msgid "News" -msgstr "" +msgstr "Actualités" #: src/view/com/auth/create/CreateAccount.tsx:172 #: src/view/com/auth/login/ForgotPasswordForm.tsx:182 @@ -2582,7 +2420,7 @@ msgstr "Ne suit plus {0}" #: src/view/com/notifications/Feed.tsx:109 msgid "No notifications yet!" -msgstr "Pas encore de notifications !" +msgstr "Pas encore de notifications !" #: src/view/com/composer/text-input/mobile/Autocomplete.tsx:97 #: src/view/com/composer/text-input/web/Autocomplete.tsx:191 @@ -2591,11 +2429,11 @@ msgstr "Aucun résultat" #: src/components/Lists.tsx:192 msgid "No results found" -msgstr "" +msgstr "Aucun résultat trouvé" #: src/view/screens/Feeds.tsx:495 msgid "No results found for \"{query}\"" -msgstr "Aucun résultat trouvé pour « {query} »" +msgstr "Aucun résultat trouvé pour « {query} »" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 #: src/view/screens/Search/Search.tsx:281 @@ -2627,7 +2465,7 @@ msgstr "Pas maintenant" #: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." -msgstr "Remarque : Bluesky est un réseau ouvert et public. Ce paramètre limite uniquement la visibilité de votre contenu sur l’application et le site Web de Bluesky, et d’autres applications peuvent ne pas respecter ce paramètre. Votre contenu peut toujours être montré aux personnes non connectées par d’autres applications et sites Web." +msgstr "Remarque : Bluesky est un réseau ouvert et public. Ce paramètre limite uniquement la visibilité de votre contenu sur l’application et le site Web de Bluesky, et d’autres applications peuvent ne pas respecter ce paramètre. Votre contenu peut toujours être montré aux personnes non connectées par d’autres applications et sites Web." #: src/Navigation.tsx:457 #: src/view/screens/Notifications.tsx:124 @@ -2645,11 +2483,11 @@ msgstr "Nudité" #: src/view/com/util/ErrorBoundary.tsx:35 msgid "Oh no!" -msgstr "Oh non !" +msgstr "Oh non !" #: src/screens/Onboarding/StepInterests/index.tsx:128 msgid "Oh no! Something went wrong." -msgstr "" +msgstr "Oh non ! Il y a eu un problème." #: src/view/com/auth/login/PasswordUpdatedForm.tsx:41 msgid "Okay" @@ -2673,21 +2511,21 @@ msgstr "Seul {0} peut répondre." #: src/components/Lists.tsx:82 msgid "Oops, something went wrong!" -msgstr "" +msgstr "Oups, quelque chose n’a pas marché !" #: src/components/Lists.tsx:188 #: src/view/screens/AppPasswords.tsx:65 #: src/view/screens/Profile.tsx:106 msgid "Oops!" -msgstr "Oups !" +msgstr "Oups !" #: src/screens/Onboarding/StepFinished.tsx:115 msgid "Open" -msgstr "" +msgstr "Ouvrir" #: src/view/screens/Moderation.tsx:75 msgid "Open content filtering settings" -msgstr "" +msgstr "Ouvrir les paramètres de filtrage de contenu" #: src/view/com/composer/Composer.tsx:477 #: src/view/com/composer/Composer.tsx:478 @@ -2696,11 +2534,11 @@ msgstr "Ouvrir le sélecteur d’emoji" #: src/view/screens/Settings/index.tsx:712 msgid "Open links with in-app browser" -msgstr "" +msgstr "Ouvrir des liens avec le navigateur interne à l’appli" #: src/view/screens/Moderation.tsx:92 msgid "Open muted words settings" -msgstr "" +msgstr "Ouvrir les paramètres des mots masqués" #: src/view/com/home/HomeHeaderLayoutMobile.tsx:50 msgid "Open navigation" @@ -2708,7 +2546,7 @@ msgstr "Navigation ouverte" #: src/view/com/util/forms/PostDropdownBtn.tsx:175 msgid "Open post options menu" -msgstr "" +msgstr "Ouvrir le menu d’options du post" #: src/view/screens/Settings/index.tsx:804 msgid "Open storybook page" @@ -2758,10 +2596,6 @@ msgstr "Ouvre la liste des comptes abonnés" msgid "Opens following list" msgstr "Ouvre la liste des abonnements" -#: src/view/screens/Settings.tsx:412 -#~ msgid "Opens invite code list" -#~ msgstr "Ouvre la liste des codes d’invitation" - #: src/view/com/modals/InviteCodes.tsx:172 msgid "Opens list of invite codes" msgstr "Ouvre la liste des codes d’invitation" @@ -2817,16 +2651,12 @@ msgstr "Option {0} sur {numItems}" #: src/view/com/modals/Threadgate.tsx:89 msgid "Or combine these options:" -msgstr "Ou une combinaison de ces options :" +msgstr "Ou une combinaison de ces options :" #: src/view/com/auth/login/ChooseAccountForm.tsx:138 msgid "Other account" msgstr "Autre compte" -#: src/view/com/modals/ServerInput.tsx:88 -#~ msgid "Other service" -#~ msgstr "Autre service" - #: src/view/com/composer/select-language/SelectLangBtn.tsx:91 msgid "Other..." msgstr "Autre…" @@ -2838,7 +2668,7 @@ msgstr "Page introuvable" #: src/view/screens/NotFound.tsx:42 msgid "Page Not Found" -msgstr "" +msgstr "Page introuvable" #: src/view/com/auth/create/Step1.tsx:191 #: src/view/com/auth/create/Step1.tsx:201 @@ -2854,7 +2684,7 @@ msgstr "Mise à jour du mot de passe" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:28 msgid "Password updated!" -msgstr "Mot de passe mis à jour !" +msgstr "Mot de passe mis à jour !" #: src/Navigation.tsx:162 msgid "People followed by @{0}" @@ -2874,11 +2704,7 @@ msgstr "Permission d’accès à la pellicule refusée. Veuillez l’activer dan #: src/screens/Onboarding/index.tsx:31 msgid "Pets" -msgstr "" - -#: src/view/com/auth/create/Step2.tsx:183 -#~ msgid "Phone number" -#~ msgstr "" +msgstr "Animaux domestiques" #: src/view/com/modals/SelfLabel.tsx:121 msgid "Pictures meant for adults." @@ -2916,7 +2742,7 @@ msgstr "Veuillez choisir votre mot de passe." #: src/view/com/auth/create/state.ts:131 msgid "Please complete the verification captcha." -msgstr "" +msgstr "Veuillez compléter le captcha de vérification." #: src/view/com/modals/ChangeEmail.tsx:67 msgid "Please confirm your email before changing it. This is a temporary requirement while email-updating tools are added, and it will soon be removed." @@ -2926,25 +2752,13 @@ msgstr "Veuillez confirmer votre e-mail avant de le modifier. Ceci est temporair msgid "Please enter a name for your app password. All spaces is not allowed." msgstr "Veuillez entrer un nom pour votre mot de passe d’application. Les espaces ne sont pas autorisés." -#: src/view/com/auth/create/Step2.tsx:206 -#~ msgid "Please enter a phone number that can receive SMS text messages." -#~ msgstr "" - #: src/view/com/modals/AddAppPasswords.tsx:145 msgid "Please enter a unique name for this App Password or use our randomly generated one." msgstr "Veuillez saisir un nom unique pour le mot de passe de l’application ou utiliser celui que nous avons généré de manière aléatoire." #: src/components/dialogs/MutedWords.tsx:68 msgid "Please enter a valid word, tag, or phrase to mute" -msgstr "" - -#: src/view/com/auth/create/state.ts:170 -#~ msgid "Please enter the code you received by SMS." -#~ msgstr "" - -#: src/view/com/auth/create/Step2.tsx:282 -#~ msgid "Please enter the verification code sent to {phoneNumberFormatted}." -#~ msgstr "" +msgstr "Veuillez entrer un mot, un mot-clé ou une phrase valide à masquer" #: src/view/com/auth/create/state.ts:103 msgid "Please enter your email." @@ -2952,12 +2766,12 @@ msgstr "Veuillez entrer votre e-mail." #: src/view/com/modals/DeleteAccount.tsx:191 msgid "Please enter your password as well:" -msgstr "Veuillez également entrer votre mot de passe :" +msgstr "Veuillez également entrer votre mot de passe :" #: src/view/com/modals/AppealLabel.tsx:72 #: src/view/com/modals/AppealLabel.tsx:75 msgid "Please tell us why you think this content warning was incorrectly applied!" -msgstr "Dites-nous donc pourquoi vous pensez que cet avertissement de contenu a été appliqué à tort !" +msgstr "Dites-nous donc pourquoi vous pensez que cet avertissement de contenu a été appliqué à tort !" #: src/view/com/modals/VerifyEmail.tsx:101 msgid "Please Verify Your Email" @@ -2969,7 +2783,7 @@ msgstr "Veuillez patienter le temps que votre carte de lien soit chargée" #: src/screens/Onboarding/index.tsx:37 msgid "Politics" -msgstr "" +msgstr "Politique" #: src/view/com/modals/SelfLabel.tsx:111 msgid "Porn" @@ -3018,7 +2832,7 @@ msgstr "Post introuvable" #: src/components/TagMenu/index.tsx:253 msgid "posts" -msgstr "" +msgstr "posts" #: src/view/screens/Profile.tsx:180 msgid "Posts" @@ -3026,7 +2840,7 @@ msgstr "Posts" #: src/components/dialogs/MutedWords.tsx:90 msgid "Posts can be muted based on their text, their tags, or both." -msgstr "" +msgstr "Les posts peuvent être masqués en fonction de leur texte, de leurs mots-clés ou des deux." #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" @@ -3082,7 +2896,7 @@ msgstr "Protégez votre compte en vérifiant votre e-mail." #: src/screens/Onboarding/StepFinished.tsx:101 msgid "Public" -msgstr "" +msgstr "Public" #: src/view/screens/ModerationModlists.tsx:61 msgid "Public, shareable lists of users to mute or block in bulk." @@ -3141,7 +2955,7 @@ msgstr "Supprimer" #: src/view/com/feeds/FeedSourceCard.tsx:108 msgid "Remove {0} from my feeds?" -msgstr "Supprimer {0} de mes fils d’actu ?" +msgstr "Supprimer {0} de mes fils d’actu ?" #: src/view/com/util/AccountDropdownBtn.tsx:22 msgid "Remove account" @@ -3170,7 +2984,7 @@ msgstr "Supprimer l’aperçu d’image" #: src/components/dialogs/MutedWords.tsx:343 msgid "Remove mute word from your list" -msgstr "" +msgstr "Supprimer le mot masqué de votre liste" #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" @@ -3178,11 +2992,11 @@ msgstr "Supprimer le repost" #: src/view/com/feeds/FeedSourceCard.tsx:175 msgid "Remove this feed from my feeds?" -msgstr "Supprimer ce fil d’actu ?" +msgstr "Supprimer ce fil d’actu ?" #: src/view/com/posts/FeedErrorMessage.tsx:132 msgid "Remove this feed from your saved feeds?" -msgstr "Supprimer ce fil d’actu de vos fils d’actu enregistrés ?" +msgstr "Supprimer ce fil d’actu de vos fils d’actu enregistrés ?" #: src/view/com/modals/ListAddRemoveUsers.tsx:199 #: src/view/com/modals/UserAddRemoveLists.tsx:152 @@ -3285,14 +3099,10 @@ msgstr "Reposts de ce post" msgid "Request Change" msgstr "Demande de modification" -#: src/view/com/auth/create/Step2.tsx:219 -#~ msgid "Request code" -#~ msgstr "" - #: src/view/com/modals/ChangePassword.tsx:239 #: src/view/com/modals/ChangePassword.tsx:241 msgid "Request Code" -msgstr "" +msgstr "Demander un code" #: src/view/screens/Settings/index.tsx:456 msgid "Require alt text before posting" @@ -3309,7 +3119,7 @@ msgstr "Réinitialiser le code" #: src/view/com/modals/ChangePassword.tsx:190 msgid "Reset Code" -msgstr "" +msgstr "Code de réinitialisation" #: src/view/screens/Settings/index.tsx:824 msgid "Reset onboarding" @@ -3359,18 +3169,10 @@ msgstr "Réessaye la dernière action, qui a échoué" msgid "Retry" msgstr "Réessayer" -#: src/view/com/auth/create/Step2.tsx:247 -#~ msgid "Retry." -#~ msgstr "" - #: src/view/screens/ProfileList.tsx:903 msgid "Return to previous page" msgstr "Retourne à la page précédente" -#: src/view/shell/desktop/RightNav.tsx:55 -#~ msgid "SANDBOX. Posts and accounts are not permanent." -#~ msgstr "SANDBOX. Les posts et les comptes ne sont pas permanents." - #: src/view/com/lightbox/Lightbox.tsx:132 #: src/view/com/modals/CreateOrEditList.tsx:345 msgctxt "action" @@ -3416,7 +3218,7 @@ msgstr "Enregistre le changement de pseudo en {handle}" #: src/screens/Onboarding/index.tsx:36 msgid "Science" -msgstr "" +msgstr "Science" #: src/view/screens/ProfileList.tsx:859 msgid "Scroll to top" @@ -3442,23 +3244,15 @@ msgstr "Recherche" #: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" -msgstr "" +msgstr "Recherche de « {query} »" #: src/components/TagMenu/index.tsx:145 msgid "Search for all posts by @{authorHandle} with tag {displayTag}" -msgstr "" - -#: src/components/TagMenu/index.tsx:145 -#~ msgid "Search for all posts by @{authorHandle} with tag {tag}" -#~ msgstr "" +msgstr "Rechercher tous les posts de @{authorHandle} avec le mot-clé {displayTag}" #: src/components/TagMenu/index.tsx:94 msgid "Search for all posts with tag {displayTag}" -msgstr "" - -#: src/components/TagMenu/index.tsx:90 -#~ msgid "Search for all posts with tag {tag}" -#~ msgstr "" +msgstr "Rechercher tous les posts avec le mot-clé {displayTag}" #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 @@ -3472,27 +3266,19 @@ msgstr "Étape de sécurité requise" #: src/components/TagMenu/index.web.tsx:66 msgid "See {truncatedTag} posts" -msgstr "" +msgstr "Voir les posts {truncatedTag}" #: src/components/TagMenu/index.web.tsx:83 msgid "See {truncatedTag} posts by user" -msgstr "" +msgstr "Voir les posts {truncatedTag} de ce compte" #: src/components/TagMenu/index.tsx:128 msgid "See <0>{displayTag}</0> posts" -msgstr "" +msgstr "Voir les posts <0>{displayTag}</0>" #: src/components/TagMenu/index.tsx:187 msgid "See <0>{displayTag}</0> posts by this user" -msgstr "" - -#: src/components/TagMenu/index.tsx:128 -#~ msgid "See <0>{tag}</0> posts" -#~ msgstr "" - -#: src/components/TagMenu/index.tsx:189 -#~ msgid "See <0>{tag}</0> posts by this user" -#~ msgstr "" +msgstr "Voir les posts <0>{displayTag}</0> de ce compte" #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" @@ -3506,10 +3292,6 @@ msgstr "Voir la suite" msgid "Select {item}" msgstr "Sélectionner {item}" -#: src/view/com/modals/ServerInput.tsx:75 -#~ msgid "Select Bluesky Social" -#~ msgstr "Sélectionner Bluesky Social" - #: src/view/com/auth/login/Login.tsx:117 msgid "Select from an existing account" msgstr "Sélectionner un compte existant" @@ -3525,23 +3307,19 @@ msgstr "Sélectionner un service" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:52 msgid "Select some accounts below to follow" -msgstr "" +msgstr "Sélectionnez quelques comptes à suivre ci-dessous" #: src/view/com/auth/server-input/index.tsx:82 msgid "Select the service that hosts your data." -msgstr "" - -#: src/screens/Onboarding/StepModeration/index.tsx:49 -#~ msgid "Select the types of content that you want to see (or not see), and we'll handle the rest." -#~ msgstr "" +msgstr "Sélectionnez le service qui héberge vos données." #: src/screens/Onboarding/StepTopicalFeeds.tsx:96 msgid "Select topical feeds to follow from the list below" -msgstr "" +msgstr "Sélectionnez les fils d’actu thématiques à suivre dans la liste ci-dessous" #: src/screens/Onboarding/StepModeration/index.tsx:75 msgid "Select what you want to see (or not see), and we’ll handle the rest." -msgstr "" +msgstr "Sélectionnez ce que vous voulez voir (ou ne pas voir), et nous nous occupons du reste." #: src/view/screens/LanguageSettings.tsx:281 msgid "Select which languages you want your subscribed feeds to include. If none are selected, all languages will be shown." @@ -3553,11 +3331,7 @@ msgstr "Sélectionnez la langue de votre application à afficher par défaut" #: src/screens/Onboarding/StepInterests/index.tsx:196 msgid "Select your interests from the options below" -msgstr "" - -#: src/view/com/auth/create/Step2.tsx:155 -#~ msgid "Select your phone's country" -#~ msgstr "" +msgstr "Sélectionnez vos centres d’intérêt parmi les options ci-dessous" #: src/view/screens/LanguageSettings.tsx:190 msgid "Select your preferred language for translations in your feed." @@ -3565,11 +3339,11 @@ msgstr "Sélectionnez votre langue préférée pour traduire votre fils d’actu #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:116 msgid "Select your primary algorithmic feeds" -msgstr "" +msgstr "Sélectionnez vos principaux fils d’actu algorithmiques" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:142 msgid "Select your secondary algorithmic feeds" -msgstr "" +msgstr "Sélectionnez vos fils d’actu algorithmiques secondaires" #: src/view/com/modals/VerifyEmail.tsx:202 #: src/view/com/modals/VerifyEmail.tsx:204 @@ -3600,7 +3374,7 @@ msgstr "Envoie un e-mail avec le code de confirmation pour la suppression du com #: src/view/com/auth/server-input/index.tsx:110 msgid "Server address" -msgstr "" +msgstr "Adresse du serveur" #: src/view/com/modals/ContentFilteringSettings.tsx:311 msgid "Set {value} for {labelGroup} content moderation policy" @@ -3626,11 +3400,11 @@ msgstr "Change le thème de couleur en fonction du paramètre système" #: src/view/screens/Settings/index.tsx:514 msgid "Set dark theme to the dark theme" -msgstr "" +msgstr "Choisir le thème le plus sombre comme thème sombre" #: src/view/screens/Settings/index.tsx:507 msgid "Set dark theme to the dim theme" -msgstr "" +msgstr "Choisir le thème atténué comme thème sombre" #: src/view/com/auth/login/SetNewPasswordForm.tsx:104 msgid "Set new password" @@ -3642,31 +3416,27 @@ msgstr "Définit le mot de passe" #: src/view/screens/PreferencesFollowingFeed.tsx:225 msgid "Set this setting to \"No\" to hide all quote posts from your feed. Reposts will still be visible." -msgstr "Choisissez « Non » pour cacher toutes les citations sur votre fils d’actu. Les reposts seront toujours visibles." +msgstr "Choisissez « Non » pour cacher toutes les citations sur votre fils d’actu. Les reposts seront toujours visibles." #: src/view/screens/PreferencesFollowingFeed.tsx:122 msgid "Set this setting to \"No\" to hide all replies from your feed." -msgstr "Choisissez « Non » pour cacher toutes les réponses dans votre fils d’actu." +msgstr "Choisissez « Non » pour cacher toutes les réponses dans votre fils d’actu." #: src/view/screens/PreferencesFollowingFeed.tsx:191 msgid "Set this setting to \"No\" to hide all reposts from your feed." -msgstr "Choisissez « Non » pour cacher toutes les reposts de votre fils d’actu." +msgstr "Choisissez « Non » pour cacher toutes les reposts de votre fils d’actu." #: src/view/screens/PreferencesThreads.tsx:122 msgid "Set this setting to \"Yes\" to show replies in a threaded view. This is an experimental feature." -msgstr "Choisissez « Oui » pour afficher les réponses dans un fil de discussion. C’est une fonctionnalité expérimentale." - -#: src/view/screens/PreferencesHomeFeed.tsx:261 -#~ msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your following feed. This is an experimental feature." -#~ msgstr "Choisissez « Oui » pour afficher des échantillons de vos fils d’actu enregistrés dans votre fils d’actu suivant. C’est une fonctionnalité expérimentale." +msgstr "Choisissez « Oui » pour afficher les réponses dans un fil de discussion. C’est une fonctionnalité expérimentale." #: src/view/screens/PreferencesFollowingFeed.tsx:261 msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your Following feed. This is an experimental feature." -msgstr "" +msgstr "Choisissez « Oui » pour afficher des échantillons de vos fils d’actu enregistrés dans votre fil d’actu « Following ». C’est une fonctionnalité expérimentale." #: src/screens/Onboarding/Layout.tsx:50 msgid "Set up your account" -msgstr "" +msgstr "Créez votre compte" #: src/view/com/modals/ChangeHandle.tsx:266 msgid "Sets Bluesky username" @@ -3754,15 +3524,15 @@ msgstr "Afficher les citations" #: src/screens/Onboarding/StepFollowingFeed.tsx:118 msgid "Show quote-posts in Following feed" -msgstr "" +msgstr "Afficher les citations dans le fil d’actu « Following »" #: src/screens/Onboarding/StepFollowingFeed.tsx:134 msgid "Show quotes in Following" -msgstr "" +msgstr "Afficher les citations dans le fil d’actu « Following »" #: src/screens/Onboarding/StepFollowingFeed.tsx:94 msgid "Show re-posts in Following feed" -msgstr "" +msgstr "Afficher les reposts dans le fil d’actu « Following »" #: src/view/screens/PreferencesFollowingFeed.tsx:119 msgid "Show Replies" @@ -3774,11 +3544,11 @@ msgstr "Afficher les réponses des personnes que vous suivez avant toutes les au #: src/screens/Onboarding/StepFollowingFeed.tsx:86 msgid "Show replies in Following" -msgstr "" +msgstr "Afficher les réponses dans le fil d’actu « Following »" #: src/screens/Onboarding/StepFollowingFeed.tsx:70 msgid "Show replies in Following feed" -msgstr "" +msgstr "Afficher les réponses dans le fil d’actu « Following »" #: src/view/screens/PreferencesFollowingFeed.tsx:70 msgid "Show replies with at least {value} {0}" @@ -3790,7 +3560,7 @@ msgstr "Afficher les reposts" #: src/screens/Onboarding/StepFollowingFeed.tsx:110 msgid "Show reposts in Following" -msgstr "" +msgstr "Afficher les reposts dans le fil d’actu « Following »" #: src/view/com/util/moderation/ContentHider.tsx:67 #: src/view/com/util/moderation/PostHider.tsx:61 @@ -3890,31 +3660,19 @@ msgstr "Ignorer" #: src/screens/Onboarding/StepInterests/index.tsx:232 msgid "Skip this flow" -msgstr "" - -#: src/view/com/auth/create/Step2.tsx:82 -#~ msgid "SMS verification" -#~ msgstr "" +msgstr "Passer cette étape" #: src/screens/Onboarding/index.tsx:40 msgid "Software Dev" -msgstr "" - -#: src/view/com/modals/ProfilePreview.tsx:62 -#~ msgid "Something went wrong and we're not sure what." -#~ msgstr "Quelque chose n’a pas marché, mais on ne sait pas trop quoi." +msgstr "Développement de logiciels" #: src/components/Lists.tsx:203 msgid "Something went wrong!" -msgstr "" - -#: src/view/com/modals/Waitlist.tsx:51 -#~ msgid "Something went wrong. Check your email and try again." -#~ msgstr "Quelque chose n’a pas marché. Vérifiez vos e-mails et réessayez." +msgstr "Quelque chose n’a pas marché !" #: src/App.native.tsx:66 msgid "Sorry! Your session expired. Please log in again." -msgstr "Désolé ! Votre session a expiré. Essayez de vous reconnecter." +msgstr "Désolé ! Votre session a expiré. Essayez de vous reconnecter." #: src/view/screens/PreferencesThreads.tsx:69 msgid "Sort Replies" @@ -3922,20 +3680,16 @@ msgstr "Trier les réponses" #: src/view/screens/PreferencesThreads.tsx:72 msgid "Sort replies to the same post by:" -msgstr "Trier les réponses au même post par :" +msgstr "Trier les réponses au même post par :" #: src/screens/Onboarding/index.tsx:30 msgid "Sports" -msgstr "" +msgstr "Sports" #: src/view/com/modals/crop-image/CropImage.web.tsx:122 msgid "Square" msgstr "Carré" -#: src/view/com/modals/ServerInput.tsx:62 -#~ msgid "Staging" -#~ msgstr "Serveur de test" - #: src/view/screens/Settings/index.tsx:871 msgid "Status page" msgstr "État du service" @@ -3964,7 +3718,7 @@ msgstr "S’abonner" #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:173 #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:308 msgid "Subscribe to the {0} feed" -msgstr "" +msgstr "S’abonner au fil d’actu {0}" #: src/view/screens/ProfileList.tsx:604 msgid "Subscribe to this list" @@ -3988,10 +3742,6 @@ msgstr "Suggestif" msgid "Support" msgstr "Soutien" -#: src/view/com/modals/ProfilePreview.tsx:110 -#~ msgid "Swipe up to see more" -#~ msgstr "Glisser vers le haut pour en voir plus" - #: src/view/com/modals/SwitchAccount.tsx:117 msgid "Switch Account" msgstr "Changer de compte" @@ -4016,15 +3766,11 @@ msgstr "Journal système" #: src/components/dialogs/MutedWords.tsx:337 msgid "tag" -msgstr "" +msgstr "mot-clé" #: src/components/TagMenu/index.tsx:78 msgid "Tag menu: {displayTag}" -msgstr "" - -#: src/components/TagMenu/index.tsx:74 -#~ msgid "Tag menu: {tag}" -#~ msgstr "" +msgstr "Menu de mot-clé : {displayTag}" #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" @@ -4036,7 +3782,7 @@ msgstr "Tapper pour voir en entier" #: src/screens/Onboarding/index.tsx:39 msgid "Tech" -msgstr "" +msgstr "Technologie" #: src/view/shell/desktop/RightNav.tsx:81 msgid "Terms" @@ -4051,7 +3797,7 @@ msgstr "Conditions d’utilisation" #: src/components/dialogs/MutedWords.tsx:337 msgid "text" -msgstr "" +msgstr "texte" #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 @@ -4060,7 +3806,7 @@ msgstr "Champ de saisie de texte" #: src/view/com/auth/create/CreateAccount.tsx:94 msgid "That handle is already taken." -msgstr "" +msgstr "Ce pseudo est déjà occupé." #: src/view/com/profile/ProfileHeader.tsx:263 msgid "The account will be able to interact with you after unblocking." @@ -4076,7 +3822,7 @@ msgstr "Notre politique de droits d’auteur a été déplacée vers <0/>" #: src/screens/Onboarding/Layout.tsx:60 msgid "The following steps will help customize your Bluesky experience." -msgstr "" +msgstr "Les étapes suivantes vous aideront à personnaliser votre expérience avec Bluesky." #: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." @@ -4096,7 +3842,7 @@ msgstr "Nos conditions d’utilisation ont été déplacées vers" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:150 msgid "There are many feeds to try:" -msgstr "" +msgstr "Il existe de nombreux fils d’actu à essayer :" #: src/view/screens/ProfileFeed.tsx:550 msgid "There was an an issue contacting the server, please check your internet connection and try again." @@ -4161,7 +3907,7 @@ msgstr "Il y a eu un problème lors de la récupération de vos mots de passe d #: src/view/com/profile/ProfileHeader.tsx:250 #: src/view/com/profile/ProfileHeader.tsx:272 msgid "There was an issue! {0}" -msgstr "Il y a eu un problème ! {0}" +msgstr "Il y a eu un problème ! {0}" #: src/view/screens/ProfileList.tsx:288 #: src/view/screens/ProfileList.tsx:307 @@ -4172,23 +3918,19 @@ msgstr "Il y a eu un problème. Veuillez vérifier votre connexion Internet et r #: src/view/com/util/ErrorBoundary.tsx:36 msgid "There was an unexpected issue in the application. Please let us know if this happened to you!" -msgstr "Un problème inattendu s’est produit dans l’application. N’hésitez pas à nous faire savoir si cela vous est arrivé !" +msgstr "Un problème inattendu s’est produit dans l’application. N’hésitez pas à nous faire savoir si cela vous est arrivé !" #: src/screens/Deactivated.tsx:106 msgid "There's been a rush of new users to Bluesky! We'll activate your account as soon as we can." -msgstr "" - -#: src/view/com/auth/create/Step2.tsx:55 -#~ msgid "There's something wrong with this number. Please choose your country and enter your full phone number!" -#~ msgstr "" +msgstr "Il y a eu un afflux de nouveaux personnes sur Bluesky ! Nous activerons ton compte dès que possible." #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:138 msgid "These are popular accounts you might like:" -msgstr "" +msgstr "Voici des comptes populaires qui pourraient vous intéresser :" #: src/view/com/util/moderation/ScreenHider.tsx:88 msgid "This {screenDescription} has been flagged:" -msgstr "Ce {screenDescription} a été signalé :" +msgstr "Ce {screenDescription} a été signalé :" #: src/view/com/util/moderation/ScreenHider.tsx:83 msgid "This account has requested that users sign in to view their profile." @@ -4196,7 +3938,7 @@ msgstr "Ce compte a demandé aux personnes de se connecter pour voir son profil. #: src/view/com/modals/EmbedConsent.tsx:68 msgid "This content is hosted by {0}. Do you want to enable external media?" -msgstr "Ce contenu est hébergé par {0}. Voulez-vous activer les médias externes ?" +msgstr "Ce contenu est hébergé par {0}. Voulez-vous activer les médias externes ?" #: src/view/com/modals/ModerationDetails.tsx:67 msgid "This content is not available because one of the users involved has blocked the other." @@ -4208,7 +3950,7 @@ msgstr "Ce contenu n’est pas visible sans un compte Bluesky." #: src/view/screens/Settings/ExportCarDialog.tsx:75 msgid "This feature is in beta. You can read more about repository exports in <0>this blogpost.</0>" -msgstr "" +msgstr "Cette fonctionnalité est en version bêta. Vous pouvez en savoir plus sur les exportations de dépôts dans <0>ce blogpost.</0>" #: src/view/com/posts/FeedErrorMessage.tsx:114 msgid "This feed is currently receiving high traffic and is temporarily unavailable. Please try again later." @@ -4218,11 +3960,11 @@ msgstr "Ce fil d’actu reçoit actuellement un trafic important, il est tempora #: src/view/screens/ProfileFeed.tsx:476 #: src/view/screens/ProfileList.tsx:661 msgid "This feed is empty!" -msgstr "Ce fil d’actu est vide !" +msgstr "Ce fil d’actu est vide !" #: src/view/com/posts/CustomFeedEmptyState.tsx:37 msgid "This feed is empty! You may need to follow more users or tune your language settings." -msgstr "Ce fil d’actu est vide ! Vous devriez peut-être suivre plus de comptes ou ajuster vos paramètres de langue." +msgstr "Ce fil d’actu est vide ! Vous devriez peut-être suivre plus de comptes ou ajuster vos paramètres de langue." #: src/view/com/modals/BirthDateSettings.tsx:61 msgid "This information is not shared with other users." @@ -4234,11 +3976,11 @@ msgstr "Ceci est important au cas où vous auriez besoin de changer d’e-mail o #: src/view/com/modals/LinkWarning.tsx:58 msgid "This link is taking you to the following website:" -msgstr "Ce lien vous conduit au site Web suivant :" +msgstr "Ce lien vous conduit au site Web suivant :" #: src/view/screens/ProfileList.tsx:839 msgid "This list is empty!" -msgstr "Cette liste est vide !" +msgstr "Cette liste est vide !" #: src/view/com/modals/AddAppPasswords.tsx:106 msgid "This name is already in use" @@ -4258,19 +4000,15 @@ msgstr "Ce compte est inclus dans la liste <0/> que vous avez bloquée." #: src/view/com/modals/ModerationDetails.tsx:74 msgid "This user is included in the <0/> list which you have muted." -msgstr "" - -#: src/view/com/modals/ModerationDetails.tsx:74 -#~ msgid "This user is included the <0/> list which you have muted." -#~ msgstr "Ce compte est inclus dans la liste <0/> que vous avez masquée." +msgstr "Ce compte est inclus dans la liste <0/> que vous avez masquée." #: src/view/com/modals/SelfLabel.tsx:137 msgid "This warning is only available for posts with media attached." -msgstr "Cet avertissement n’est disponible que pour les messages contenant des médias." +msgstr "Cet avertissement n’est disponible que pour les posts contenant des médias." #: src/components/dialogs/MutedWords.tsx:285 msgid "This will delete {0} from your muted words. You can always add it back later." -msgstr "" +msgstr "Cela supprimera {0} de vos mots masqués. Vous pourrez toujours le réintégrer plus tard." #: src/view/com/util/forms/PostDropdownBtn.tsx:282 msgid "This will hide this post from your feeds." @@ -4291,7 +4029,7 @@ msgstr "Préférences de fils de discussion" #: src/components/dialogs/MutedWords.tsx:113 msgid "Toggle between muted word options." -msgstr "" +msgstr "Basculer entre les options pour les mots masqués." #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" @@ -4375,7 +4113,7 @@ msgstr "Réafficher" #: src/components/TagMenu/index.web.tsx:104 msgid "Unmute {truncatedTag}" -msgstr "" +msgstr "Réafficher {truncatedTag}" #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" @@ -4383,11 +4121,7 @@ msgstr "Réafficher ce compte" #: src/components/TagMenu/index.tsx:208 msgid "Unmute all {displayTag} posts" -msgstr "" - -#: src/components/TagMenu/index.tsx:210 -#~ msgid "Unmute all {tag} posts" -#~ msgstr "" +msgstr "Réafficher tous les posts {displayTag}" #: src/view/com/util/forms/PostDropdownBtn.tsx:251 #: src/view/com/util/forms/PostDropdownBtn.tsx:256 @@ -4421,7 +4155,7 @@ msgstr "Mise à jour…" #: src/view/com/modals/ChangeHandle.tsx:455 msgid "Upload a text file to:" -msgstr "Envoyer un fichier texte vers :" +msgstr "Envoyer un fichier texte vers :" #: src/view/screens/AppPasswords.tsx:195 msgid "Use app passwords to login to other Bluesky clients without giving full access to your account or password." @@ -4434,24 +4168,20 @@ msgstr "Utiliser le fournisseur par défaut" #: src/view/com/modals/InAppBrowserConsent.tsx:56 #: src/view/com/modals/InAppBrowserConsent.tsx:58 msgid "Use in-app browser" -msgstr "" +msgstr "Utiliser le navigateur interne à l’appli" #: src/view/com/modals/InAppBrowserConsent.tsx:66 #: src/view/com/modals/InAppBrowserConsent.tsx:68 msgid "Use my default browser" -msgstr "" +msgstr "Utiliser mon navigateur par défaut" #: src/view/com/modals/AddAppPasswords.tsx:155 msgid "Use this to sign into the other app along with your handle." msgstr "Utilisez-le pour vous connecter à l’autre application avec votre identifiant." -#: src/view/com/modals/ServerInput.tsx:105 -#~ msgid "Use your domain as your Bluesky client service provider" -#~ msgstr "Utilise votre domaine comme votre fournisseur de client Bluesky" - #: src/view/com/modals/InviteCodes.tsx:200 msgid "Used by:" -msgstr "Utilisé par :" +msgstr "Utilisé par :" #: src/view/com/modals/ModerationDetails.tsx:54 msgid "User Blocked" @@ -4511,11 +4241,7 @@ msgstr "comptes suivis par <0/>" #: src/view/com/modals/Threadgate.tsx:106 msgid "Users in \"{0}\"" -msgstr "Comptes dans « {0} »" - -#: src/view/com/auth/create/Step2.tsx:243 -#~ msgid "Verification code" -#~ msgstr "" +msgstr "Comptes dans « {0} »" #: src/view/screens/Settings/index.tsx:910 msgid "Verify email" @@ -4540,7 +4266,7 @@ msgstr "Vérifiez votre e-mail" #: src/screens/Onboarding/index.tsx:42 msgid "Video Games" -msgstr "" +msgstr "Jeux vidéo" #: src/view/com/profile/ProfileHeader.tsx:662 msgid "View {0}'s avatar" @@ -4573,43 +4299,39 @@ msgstr "Avertir" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:134 msgid "We also think you'll like \"For You\" by Skygaze:" -msgstr "" +msgstr "Nous pensons également que vous aimerez « For You » de Skygaze :" #: src/screens/Hashtag.tsx:132 msgid "We couldn't find any results for that hashtag." -msgstr "" +msgstr "Nous n’avons trouvé aucun résultat pour ce mot-clé." #: src/screens/Deactivated.tsx:133 msgid "We estimate {estimatedTime} until your account is ready." -msgstr "" +msgstr "Nous estimons que votre compte sera prêt dans {estimatedTime}." #: src/screens/Onboarding/StepFinished.tsx:93 msgid "We hope you have a wonderful time. Remember, Bluesky is:" -msgstr "" +msgstr "Nous espérons que vous passerez un excellent moment. N’oubliez pas que Bluesky est :" #: src/view/com/posts/DiscoverFallbackHeader.tsx:29 msgid "We ran out of posts from your follows. Here's the latest from <0/>." -msgstr "" - -#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:118 -#~ msgid "We recommend \"For You\" by Skygaze:" -#~ msgstr "" +msgstr "Nous n’avons plus de posts provenant des comptes que vous suivez. Voici le dernier de <0/>." #: src/components/dialogs/MutedWords.tsx:204 msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." -msgstr "" +msgstr "Nous vous recommandons d’éviter les mots communs qui apparaissent dans de nombreux posts, car cela peut avoir pour conséquence qu’aucun post ne s’affiche." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" -msgstr "" +msgstr "Nous vous recommandons notre fil d’actu « Discover » :" #: src/screens/Onboarding/StepInterests/index.tsx:133 msgid "We weren't able to connect. Please try again to continue setting up your account. If it continues to fail, you can skip this flow." -msgstr "" +msgstr "Nous n’avons pas pu nous connecter. Veuillez réessayer pour continuer à configurer votre compte. Si l’échec persiste, vous pouvez sauter cette étape." #: src/screens/Deactivated.tsx:137 msgid "We will let you know when your account is ready." -msgstr "" +msgstr "Nous vous informerons lorsque votre compte sera prêt." #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." @@ -4617,11 +4339,11 @@ msgstr "Nous examinerons votre appel rapidement." #: src/screens/Onboarding/StepInterests/index.tsx:138 msgid "We'll use this to help customize your experience." -msgstr "" +msgstr "Nous utiliserons ces informations pour personnaliser votre expérience." #: src/view/com/auth/create/CreateAccount.tsx:134 msgid "We're so excited to have you join us!" -msgstr "Nous sommes ravis de vous accueillir !" +msgstr "Nous sommes ravis de vous accueillir !" #: src/view/screens/ProfileList.tsx:86 msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." @@ -4629,7 +4351,7 @@ msgstr "Nous sommes désolés, mais nous n’avons pas pu charger cette liste. S #: src/components/dialogs/MutedWords.tsx:230 msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." -msgstr "" +msgstr "Nous sommes désolés, mais nous n’avons pas pu charger vos mots masqués pour le moment. Veuillez réessayer." #: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." @@ -4638,7 +4360,7 @@ msgstr "Nous sommes désolés, mais votre recherche a été annulée. Veuillez r #: src/components/Lists.tsx:211 #: src/view/screens/NotFound.tsx:48 msgid "We're sorry! We can't find the page you were looking for." -msgstr "Nous sommes désolés ! La page que vous recherchez est introuvable." +msgstr "Nous sommes désolés ! La page que vous recherchez est introuvable." #: src/view/com/auth/onboarding/WelcomeMobile.tsx:46 msgid "Welcome to <0>Bluesky</0>" @@ -4646,29 +4368,29 @@ msgstr "Bienvenue sur <0>Bluesky</0>" #: src/screens/Onboarding/StepInterests/index.tsx:130 msgid "What are your interests?" -msgstr "" +msgstr "Quels sont vos centres d’intérêt ?" #: src/view/com/modals/report/Modal.tsx:169 msgid "What is the issue with this {collectionName}?" -msgstr "Quel est le problème avec cette {collectionName} ?" +msgstr "Quel est le problème avec cette {collectionName} ?" #: src/view/com/auth/SplashScreen.tsx:59 #: src/view/com/composer/Composer.tsx:286 msgid "What's up?" -msgstr "Quoi de neuf ?" +msgstr "Quoi de neuf ?" #: src/view/com/modals/lang-settings/PostLanguagesSettings.tsx:78 msgid "Which languages are used in this post?" -msgstr "Quelles sont les langues utilisées dans ce post ?" +msgstr "Quelles sont les langues utilisées dans ce post ?" #: src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx:77 msgid "Which languages would you like to see in your algorithmic feeds?" -msgstr "Quelles langues aimeriez-vous voir apparaître dans vos flux algorithmiques ?" +msgstr "Quelles langues aimeriez-vous voir apparaître dans vos fils d’actu algorithmiques ?" #: src/view/com/composer/threadgate/ThreadgateBtn.tsx:47 #: src/view/com/modals/Threadgate.tsx:66 msgid "Who can reply" -msgstr "Qui peut répondre ?" +msgstr "Qui peut répondre ?" #: src/view/com/modals/crop-image/CropImage.web.tsx:102 msgid "Wide" @@ -4685,11 +4407,7 @@ msgstr "Rédigez votre réponse" #: src/screens/Onboarding/index.tsx:28 msgid "Writers" -msgstr "" - -#: src/view/com/auth/create/Step2.tsx:263 -#~ msgid "XXXXXX" -#~ msgstr "" +msgstr "Écrivain·e·s" #: src/view/com/composer/select-language/SuggestedLanguage.tsx:77 #: src/view/screens/PreferencesFollowingFeed.tsx:129 @@ -4701,26 +4419,18 @@ msgstr "" msgid "Yes" msgstr "Oui" -#: src/screens/Onboarding/StepModeration/index.tsx:46 -#~ msgid "You are in control" -#~ msgstr "" - #: src/screens/Deactivated.tsx:130 msgid "You are in line." -msgstr "" +msgstr "Vous êtes dans la file d’attente." #: src/view/com/posts/FollowingEmptyState.tsx:67 #: src/view/com/posts/FollowingEndOfFeed.tsx:68 msgid "You can also discover new Custom Feeds to follow." msgstr "Vous pouvez aussi découvrir de nouveaux fils d’actu personnalisés à suivre." -#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:123 -#~ msgid "You can also try our \"Discover\" algorithm:" -#~ msgstr "" - #: src/screens/Onboarding/StepFollowingFeed.tsx:142 msgid "You can change these settings later." -msgstr "" +msgstr "Vous pouvez modifier ces paramètres ultérieurement." #: src/view/com/auth/login/Login.tsx:158 #: src/view/com/auth/login/PasswordUpdatedForm.tsx:31 @@ -4729,7 +4439,7 @@ msgstr "Vous pouvez maintenant vous connecter avec votre nouveau mot de passe." #: src/view/com/modals/InviteCodes.tsx:66 msgid "You don't have any invite codes yet! We'll send you some when you've been on Bluesky for a little longer." -msgstr "Vous n’avez encore aucun code d’invitation ! Nous vous en enverrons lorsque vous serez sur Bluesky depuis un peu plus longtemps." +msgstr "Vous n’avez encore aucun code d’invitation ! Nous vous en enverrons lorsque vous serez sur Bluesky depuis un peu plus longtemps." #: src/view/screens/SavedFeeds.tsx:102 msgid "You don't have any pinned feeds." @@ -4737,7 +4447,7 @@ msgstr "Vous n’avez encore aucun fil épinglé." #: src/view/screens/Feeds.tsx:452 msgid "You don't have any saved feeds!" -msgstr "Vous n’avez encore aucun fil enregistré !" +msgstr "Vous n’avez encore aucun fil enregistré !" #: src/view/screens/SavedFeeds.tsx:135 msgid "You don't have any saved feeds." @@ -4756,7 +4466,7 @@ msgstr "Vous avez bloqué ce compte. Vous ne pouvez pas voir son contenu." #: src/view/com/modals/ChangePassword.tsx:87 #: src/view/com/modals/ChangePassword.tsx:121 msgid "You have entered an invalid code. It should look like XXXXX-XXXXX." -msgstr "" +msgstr "Vous avez introduit un code non valide. Il devrait ressembler à XXXXX-XXXXX." #: src/view/com/modals/ModerationDetails.tsx:87 msgid "You have muted this user." @@ -4773,7 +4483,7 @@ msgstr "Vous n’avez aucune liste." #: src/view/screens/ModerationBlockedAccounts.tsx:132 msgid "You have not blocked any accounts yet. To block an account, go to their profile and selected \"Block account\" from the menu on their account." -msgstr "Vous n’avez pas encore bloqué de comptes. Pour bloquer un compte, accédez à son profil et sélectionnez « Bloquer le compte » dans le menu de son compte." +msgstr "Vous n’avez pas encore bloqué de comptes. Pour bloquer un compte, accédez à son profil et sélectionnez « Bloquer le compte » dans le menu de son compte." #: src/view/screens/AppPasswords.tsx:87 msgid "You have not created any app passwords yet. You can create one by pressing the button below." @@ -4781,11 +4491,11 @@ msgstr "Vous n’avez encore créé aucun mot de passe pour l’appli. Vous pouv #: src/view/screens/ModerationMutedAccounts.tsx:131 msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." -msgstr "Vous n’avez encore masqué aucun compte. Pour désactiver un compte, allez sur son profil et sélectionnez « Masquer le compte » dans le menu de son compte." +msgstr "Vous n’avez encore masqué aucun compte. Pour désactiver un compte, allez sur son profil et sélectionnez « Masquer le compte » dans le menu de son compte." #: src/components/dialogs/MutedWords.tsx:250 msgid "You haven't muted any words or tags yet" -msgstr "" +msgstr "Vous n’avez pas encore masqué de mot ou de mot-clé" #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." @@ -4793,7 +4503,7 @@ msgstr "Vous devez avoir 18 ans ou plus pour activer le contenu pour adultes." #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:103 msgid "You must be 18 years or older to enable adult content" -msgstr "" +msgstr "Vous devez avoir 18 ans ou plus pour activer le contenu pour adultes." #: src/view/com/util/forms/PostDropdownBtn.tsx:147 msgid "You will no longer receive notifications for this thread" @@ -4805,25 +4515,25 @@ msgstr "Vous recevrez désormais des notifications pour ce fil de discussion" #: src/view/com/auth/login/SetNewPasswordForm.tsx:107 msgid "You will receive an email with a \"reset code.\" Enter that code here, then enter your new password." -msgstr "Vous recevrez un e-mail contenant un « code de réinitialisation » Saisissez ce code ici, puis votre nouveau mot de passe." +msgstr "Vous recevrez un e-mail contenant un « code de réinitialisation ». Saisissez ce code ici, puis votre nouveau mot de passe." #: src/screens/Onboarding/StepModeration/index.tsx:72 msgid "You're in control" -msgstr "" +msgstr "Vous avez le contrôle" #: src/screens/Deactivated.tsx:87 #: src/screens/Deactivated.tsx:88 #: src/screens/Deactivated.tsx:103 msgid "You're in line" -msgstr "" +msgstr "Vous êtes dans la file d’attente" #: src/screens/Onboarding/StepFinished.tsx:90 msgid "You're ready to go!" -msgstr "" +msgstr "Vous êtes prêt à partir !" #: src/view/com/posts/FollowingEndOfFeed.tsx:48 msgid "You've reached the end of your feed! Find some more accounts to follow." -msgstr "Vous avez atteint la fin de votre fil d’actu ! Trouvez d’autres comptes à suivre." +msgstr "Vous avez atteint la fin de votre fil d’actu ! Trouvez d’autres comptes à suivre." #: src/view/com/auth/create/Step1.tsx:67 msgid "Your account" @@ -4835,7 +4545,7 @@ msgstr "Votre compte a été supprimé" #: src/view/screens/Settings/ExportCarDialog.tsx:47 msgid "Your account repository, containing all public data records, can be downloaded as a \"CAR\" file. This file does not include media embeds, such as images, or your private data, which must be fetched separately." -msgstr "" +msgstr "Le dépôt de votre compte, qui contient toutes les données publiques, peut être téléchargé sous la forme d’un fichier « CAR ». Ce fichier n’inclut pas les éléments multimédias, tels que les images, ni vos données privées, qui doivent être récupérées séparément." #: src/view/com/auth/create/Step1.tsx:215 msgid "Your birth date" @@ -4843,11 +4553,11 @@ msgstr "Votre date de naissance" #: src/view/com/modals/InAppBrowserConsent.tsx:47 msgid "Your choice will be saved, but can be changed later in settings." -msgstr "" +msgstr "Votre choix sera enregistré, mais vous pourrez le modifier ultérieurement dans les paramètres." #: src/screens/Onboarding/StepFollowingFeed.tsx:61 msgid "Your default feed is \"Following\"" -msgstr "" +msgstr "Votre fil d’actu par défaut est « Following »" #: src/view/com/auth/create/state.ts:110 #: src/view/com/auth/login/ForgotPasswordForm.tsx:70 @@ -4855,10 +4565,6 @@ msgstr "" msgid "Your email appears to be invalid." msgstr "Votre e-mail semble être invalide." -#: src/view/com/modals/Waitlist.tsx:109 -#~ msgid "Your email has been saved! We'll be in touch soon." -#~ msgstr "Votre e-mail a été enregistré ! Nous vous contacterons bientôt." - #: src/view/com/modals/ChangeEmail.tsx:125 msgid "Your email has been updated but not verified. As a next step, please verify your new email." msgstr "Votre e-mail a été mis à jour, mais n’a pas été vérifié. L’étape suivante consiste à vérifier votre nouvel e-mail." @@ -4869,7 +4575,7 @@ msgstr "Votre e-mail n’a pas encore été vérifié. Il s’agit d’une mesur #: src/view/com/posts/FollowingEmptyState.tsx:47 msgid "Your following feed is empty! Follow more users to see what's happening." -msgstr "Votre fil d’actu des comptes suivis est vide ! Suivez plus de comptes pour voir ce qui se passe." +msgstr "Votre fil d’actu des comptes suivis est vide ! Suivez plus de comptes pour voir ce qui se passe." #: src/view/com/auth/create/Step2.tsx:83 msgid "Your full handle will be" @@ -4879,19 +4585,13 @@ msgstr "Votre nom complet sera" msgid "Your full handle will be <0>@{0}</0>" msgstr "Votre pseudo complet sera <0>@{0}</0>" -#: src/view/screens/Settings.tsx:430 -#: src/view/shell/desktop/RightNav.tsx:137 -#: src/view/shell/Drawer.tsx:660 -#~ msgid "Your invite codes are hidden when logged in using an App Password" -#~ msgstr "Vos codes d’invitation sont cachés lorsque vous êtes connecté à l’aide d’un mot de passe d’application." - #: src/components/dialogs/MutedWords.tsx:221 msgid "Your muted words" -msgstr "" +msgstr "Vos mots masqués" #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" -msgstr "" +msgstr "Votre mot de passe a été modifié avec succès !" #: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" From 9277282e6c9ea90003a4ee583c862af6e96b5433 Mon Sep 17 00:00:00 2001 From: Hailey <me@haileyok.com> Date: Tue, 19 Mar 2024 11:18:22 -0700 Subject: [PATCH 088/109] add expo-updates github action (#3270) * add expo-updates github action * add two scripts --- .../workflows/bundle-deploy-eas-update.yml | 55 +++++++++ code-signing/certificate.pem | 18 +++ package.json | 4 +- scripts/bundleUpdate.js | 104 ++++++++++++++++++ scripts/bundleUpdate.sh | 26 +++++ 5 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/bundle-deploy-eas-update.yml create mode 100644 code-signing/certificate.pem create mode 100644 scripts/bundleUpdate.js create mode 100644 scripts/bundleUpdate.sh diff --git a/.github/workflows/bundle-deploy-eas-update.yml b/.github/workflows/bundle-deploy-eas-update.yml new file mode 100644 index 0000000000..72a38eaa65 --- /dev/null +++ b/.github/workflows/bundle-deploy-eas-update.yml @@ -0,0 +1,55 @@ +--- +name: Bundle and Deploy EAS Update + +on: + workflow_dispatch: + inputs: + runtimeVersion: + type: string + description: Runtime version (in x.x.x format) that this update is for + required: true + +jobs: + bundleDeploy: + name: Bundle and Deploy EAS Update + runs-on: ubuntu-latest + steps: + - name: 🧐 Validate version + run: | + [[ "${{ github.event.inputs.runtimeVersion }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && echo "Version is valid" || exit 1 + + - name: ⬇️ Checkout + uses: actions/checkout@v4 + + - name: 🔧 Setup Node + uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: yarn + + - name: ⚙️ Install Dependencies + run: yarn install + + - name: 🪛 Install jq + uses: dcarbone/install-jq-action@v2 + + - name: ⛏️ Setup Expo + run: yarn global add eas-cli-local-build-plugin + + - name: 🔤 Compile Translations + run: yarn intl:build + + - name: ✏️ Write environment variables + run: | + export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}' + echo "${{ secrets.ENV_TOKEN }}" > .env + echo "$json" > google-services.json + + - name: 🏗️ Create Bundle + run: yarn export + + - name: 📦 Package Bundle and 🚀 Deploy + run: yarn make-deploy-bundle + env: + DENIS_API_KEY: ${{ secrets.DENIS_API_KEY }} + RUNTIME_VERSION: ${{ github.event.inputs.runtimeVersion }} diff --git a/code-signing/certificate.pem b/code-signing/certificate.pem new file mode 100644 index 0000000000..bfc5cdbde8 --- /dev/null +++ b/code-signing/certificate.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIJcMN2yt5KNDqTMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV +BAMTB0JsdWVza3kwHhcNMjQwMzE0MDA1OTU4WhcNMzQwMzE0MDA1OTU4WjASMRAw +DgYDVQQDEwdCbHVlc2t5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +izSAWEc3wRoa3eTBEh/kE9pH0d6jhEGw9GrYfei60MHT1pSq2cTdyUM1yUZchAeW +gFFtqFxX0pfIZQyMlIZbjkaOxOqzWhB0aCsxngnhbSahFwRxkVwTAuonhqIpaLBL +hrCCCQ2IfZUpy8QeasqlTlmvmijuCC34fXxJlxNcj8SqzIZi+civ7U5PMPfIMMnD +tCDIBy1vxMk57m25X2ikcWUFW64qNVLkFAL36xEnmFTL4Ivqpz23gUcUIe1zbesY +jAgDtlwnAE7mU3oagCUDcSuOveT4POhT35Xp3Y/07I68kmXtrPxwd5k0L0zbisEm +poKZ87E2X29BitihicMpBwIDAQABoyowKDAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0l +AQH/BAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAED1gdMF0yr8Gy87 +RgyaeVpPySwSsO0selmXXrcmOWgiPA05lubyhFEa4P5kdzBEByG2MT+pJkjGYpvK +XRnqXM5VvdS2RhYYFH0cFOIUqBKwCnzViCMuGQeoGUx4oPcKFS0PQ1WjW2d4pS75 +51GBfB6LOepsCHUG0A9XEk7EAyUWc4M2ITCJsTtJh8CVn2pTks2q14ETDs86YQv4 +peDaJv8nhIe8oQkeGn2o/P/ctkwJg/uBydQUsWgjjGTQZTilVjGTW1mwDr9FucAE +d5gKIk4rtR/3Zd/NDdqp8PrkoWeVM7Hwr789/mpUOeqa/j7YNkDYQh7x+M/odd1D +KY0bQEQ= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/package.json b/package.json index b526825fbd..bc2b62ec94 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,9 @@ "intl:extract": "lingui extract", "intl:compile": "lingui compile", "nuke": "rm -rf ./node_modules && rm -rf ./ios && rm -rf ./android", - "update-extensions": "scripts/updateExtensions.sh" + "update-extensions": "bash scripts/updateExtensions.sh", + "export": "npx expo export", + "make-deploy-bundle": "bash scripts/bundleUpdate.sh" }, "dependencies": { "@atproto/api": "^0.12.0", diff --git a/scripts/bundleUpdate.js b/scripts/bundleUpdate.js new file mode 100644 index 0000000000..00217dcd7b --- /dev/null +++ b/scripts/bundleUpdate.js @@ -0,0 +1,104 @@ +const crypto = require('crypto') +const fs = require('fs') +const fsp = fs.promises +const path = require('path') + +const DIST_DIR = './dist' +const BUNDLES_DIR = '/_expo/static/js' +const IOS_BUNDLE_DIR = path.join(DIST_DIR, BUNDLES_DIR, '/ios') +const ANDROID_BUNDLE_DIR = path.join(DIST_DIR, BUNDLES_DIR, '/android') +const METADATA_PATH = path.join(DIST_DIR, '/metadata.json') +const DEST_DIR = './bundleTempDir' + +// Weird, don't feel like figuring out _why_ it wants this +const METADATA = require(`../${METADATA_PATH}`) +const IOS_METADATA_ASSETS = METADATA.fileMetadata.ios.assets +const ANDROID_METADATA_ASSETS = METADATA.fileMetadata.android.assets + +const getMd5 = async path => { + return new Promise(res => { + const hash = crypto.createHash('md5') + const rStream = fs.createReadStream(path) + rStream.on('data', data => { + hash.update(data) + }) + rStream.on('end', () => { + res(hash.digest('hex')) + }) + }) +} + +const moveFiles = async () => { + console.log('Making directory...') + await fsp.mkdir(DEST_DIR) + await fsp.mkdir(path.join(DEST_DIR, '/assets')) + + console.log('Getting ios md5...') + const iosCurrPath = path.join( + IOS_BUNDLE_DIR, + (await fsp.readdir(IOS_BUNDLE_DIR))[0], + ) + const iosMd5 = await getMd5(iosCurrPath) + const iosNewPath = `bundles/${iosMd5}.bundle` + + console.log('Copying ios bundle...') + await fsp.cp(iosCurrPath, path.join(DEST_DIR, iosNewPath)) + + console.log('Getting android md5...') + const androidCurrPath = path.join( + ANDROID_BUNDLE_DIR, + (await fsp.readdir(ANDROID_BUNDLE_DIR))[0], + ) + const androidMd5 = await getMd5(androidCurrPath) + const androidNewPath = `bundles/${androidMd5}.bundle` + + console.log('Copying android bundle...') + await fsp.cp(androidCurrPath, path.join(DEST_DIR, androidNewPath)) + + const iosAssets = [] + const androidAssets = [] + + console.log('Getting ios asset md5s and moving them...') + for (const asset of IOS_METADATA_ASSETS) { + const currPath = path.join(DIST_DIR, asset.path) + const md5 = await getMd5(currPath) + const withExtPath = `assets/${md5}.${asset.ext}` + iosAssets.push(withExtPath) + await fsp.cp(currPath, path.join(DEST_DIR, withExtPath)) + } + + console.log('Getting android asset md5s and moving them...') + for (const asset of ANDROID_METADATA_ASSETS) { + const currPath = path.join(DIST_DIR, asset.path) + const md5 = await getMd5(currPath) + const withExtPath = `assets/${md5}.${asset.ext}` + androidAssets.push(withExtPath) + await fsp.cp(currPath, path.join(DEST_DIR, withExtPath)) + } + + const result = { + version: 0, + bundler: 'metro', + fileMetadata: { + ios: { + bundle: iosNewPath, + assets: iosAssets, + }, + android: { + bundle: androidNewPath, + assets: androidAssets, + }, + }, + } + + console.log('Writing metadata...') + await fsp.writeFile( + path.join(DEST_DIR, 'metadata.json'), + JSON.stringify(result), + ) + + console.log('Finished!') + console.log('Metadata:', result) +} + +moveFiles() diff --git a/scripts/bundleUpdate.sh b/scripts/bundleUpdate.sh new file mode 100644 index 0000000000..18db81a20c --- /dev/null +++ b/scripts/bundleUpdate.sh @@ -0,0 +1,26 @@ +#!/bin/bash +set -o errexit +set -o pipefail +set -o nounset + +rm -rf bundleTempDir +rm -rf bundle.tar.gz + +echo "Creating tarball..." +node scripts/bundleUpdate.js + +cd bundleTempDir || exit + +BUNDLE_VERSION=$(date +%s) +DEPLOYMENT_URL="https://updates.bsky.app/v1/upload?runtime-version=$RUNTIME_VERSION&bundle-version=$BUNDLE_VERSION" + +tar czvf bundle.tar.gz ./* + +echo "Deploying to $DEPLOYMENT_URL..." + +curl -o - --form "bundle=@./bundle.tar.gz" --user "bsky:$DENIS_API_KEY" --basic "$DEPLOYMENT_URL" + +cd .. + +rm -rf bundleTempDir +rm -rf bundle.tar.gz From c9c3bd98b7418845c4e7ee64060a4362eb2e3128 Mon Sep 17 00:00:00 2001 From: Paul Frazee <pfrazee@gmail.com> Date: Tue, 19 Mar 2024 11:38:17 -0700 Subject: [PATCH 089/109] Rework the labeler selection step of the report flow (#3269) * Rework the labeler selection step of the report flow * Fix: use gtMobile * Use primitives, fix avatar * Spacing tweaks * Show handle instead of description --------- Co-authored-by: Eric Bailey <git@esb.lol> --- src/components/LabelingServiceCard/index.tsx | 2 +- .../ReportDialog/SelectLabelerView.tsx | 75 +++++++------------ .../ReportDialog/SelectReportOptionView.tsx | 5 +- src/screens/Moderation/index.tsx | 2 +- 4 files changed, 31 insertions(+), 53 deletions(-) diff --git a/src/components/LabelingServiceCard/index.tsx b/src/components/LabelingServiceCard/index.tsx index 6d06135110..f924f0f594 100644 --- a/src/components/LabelingServiceCard/index.tsx +++ b/src/components/LabelingServiceCard/index.tsx @@ -104,7 +104,7 @@ export function Default({ }: LabelingServiceProps & ViewStyleProp) { return ( <Outer style={style}> - <Avatar /> + <Avatar avatar={labeler.creator.avatar} /> <Content> <Title value={getLabelingServiceTitle({ diff --git a/src/components/ReportDialog/SelectLabelerView.tsx b/src/components/ReportDialog/SelectLabelerView.tsx index 300114fc4f..817426355d 100644 --- a/src/components/ReportDialog/SelectLabelerView.tsx +++ b/src/components/ReportDialog/SelectLabelerView.tsx @@ -5,12 +5,13 @@ import {useLingui} from '@lingui/react' import {AppBskyLabelerDefs} from '@atproto/api' export {useDialogControl as useReportDialogControl} from '#/components/Dialog' +import {getLabelingServiceTitle} from '#/lib/moderation' -import {atoms as a, useTheme} from '#/alf' +import {atoms as a, useTheme, useBreakpoints} from '#/alf' import {Text} from '#/components/Typography' import {Button, useButtonContext} from '#/components/Button' import {Divider} from '#/components/Divider' -import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' +import * as LabelingServiceCard from '#/components/LabelingServiceCard' import {ReportDialogProps} from './types' @@ -22,31 +23,29 @@ export function SelectLabelerView({ }) { const t = useTheme() const {_} = useLingui() + const {gtMobile} = useBreakpoints() return ( <View style={[a.gap_lg]}> - <View style={[a.justify_center, a.gap_sm]}> + <View style={[a.justify_center, gtMobile ? a.gap_sm : a.gap_xs]}> <Text style={[a.text_2xl, a.font_bold]}> - <Trans>Select moderation service</Trans> + <Trans>Select moderator</Trans> </Text> <Text style={[a.text_md, t.atoms.text_contrast_medium]}> - <Trans>Who do you want to send this report to?</Trans> + <Trans>To whom would you like to send this report?</Trans> </Text> </View> <Divider /> - <View style={[a.gap_sm, {marginHorizontal: a.p_md.padding * -1}]}> + <View style={[a.gap_xs, {marginHorizontal: a.p_md.padding * -1}]}> {props.labelers.map(labeler => { return ( <Button key={labeler.creator.did} label={_(msg`Send report to ${labeler.creator.displayName}`)} onPress={() => props.onSelectLabeler(labeler.creator.did)}> - <LabelerButton - title={labeler.creator.displayName || labeler.creator.handle} - description={labeler.creator.description || ''} - /> + <LabelerButton labeler={labeler} /> </Button> ) })} @@ -56,11 +55,9 @@ export function SelectLabelerView({ } function LabelerButton({ - title, - description, + labeler, }: { - title: string - description: string + labeler: AppBskyLabelerDefs.LabelerViewDetailed }) { const t = useTheme() const {hovered, pressed} = useButtonContext() @@ -75,41 +72,21 @@ function LabelerButton({ }, [t]) return ( - <View - style={[ - a.w_full, - a.flex_row, - a.align_center, - a.justify_between, - a.p_md, - a.rounded_md, - {paddingRight: 70}, - interacted && styles.interacted, - ]}> - <View style={[a.flex_1, a.gap_xs]}> - <Text style={[a.text_md, a.font_bold, t.atoms.text_contrast_medium]}> - {title} - </Text> - <Text style={[a.leading_tight, {maxWidth: 400}]} numberOfLines={3}> - {description} - </Text> - </View> - - <View - style={[ - a.absolute, - a.inset_0, - a.justify_center, - a.pr_md, - {left: 'auto'}, - ]}> - <ChevronRight - size="md" - fill={ - hovered ? t.palette.primary_500 : t.atoms.text_contrast_low.color - } + <LabelingServiceCard.Outer + style={[a.p_md, a.rounded_sm, interacted && styles.interacted]}> + <LabelingServiceCard.Avatar avatar={labeler.creator.avatar} /> + <LabelingServiceCard.Content> + <LabelingServiceCard.Title + value={getLabelingServiceTitle({ + displayName: labeler.creator.displayName, + handle: labeler.creator.handle, + })} /> - </View> - </View> + <Text + style={[t.atoms.text_contrast_medium, a.text_sm, a.font_semibold]}> + @{labeler.creator.handle} + </Text> + </LabelingServiceCard.Content> + </LabelingServiceCard.Outer> ) } diff --git a/src/components/ReportDialog/SelectReportOptionView.tsx b/src/components/ReportDialog/SelectReportOptionView.tsx index 037a62fceb..bacf5a8670 100644 --- a/src/components/ReportDialog/SelectReportOptionView.tsx +++ b/src/components/ReportDialog/SelectReportOptionView.tsx @@ -9,7 +9,7 @@ import {DMCA_LINK} from '#/components/ReportDialog/const' import {Link} from '#/components/Link' export {useDialogControl as useReportDialogControl} from '#/components/Dialog' -import {atoms as a, useTheme} from '#/alf' +import {atoms as a, useTheme, useBreakpoints} from '#/alf' import {Text} from '#/components/Typography' import { Button, @@ -35,6 +35,7 @@ export function SelectReportOptionView({ }) { const t = useTheme() const {_} = useLingui() + const {gtMobile} = useBreakpoints() const allReportOptions = useReportOptions() const reportOptions = allReportOptions[props.params.type] @@ -76,7 +77,7 @@ export function SelectReportOptionView({ </Button> ) : null} - <View style={[a.justify_center, a.gap_sm]}> + <View style={[a.justify_center, gtMobile ? a.gap_sm : a.gap_xs]}> <Text style={[a.text_2xl, a.font_bold]}>{i18n.title}</Text> <Text style={[a.text_md, t.atoms.text_contrast_medium]}> {i18n.description} diff --git a/src/screens/Moderation/index.tsx b/src/screens/Moderation/index.tsx index 50e5ee3b9e..d73823fadf 100644 --- a/src/screens/Moderation/index.tsx +++ b/src/screens/Moderation/index.tsx @@ -411,7 +411,7 @@ export function ModerationScreenInner({ t.atoms.bg_contrast_50, ], ]}> - <LabelingService.Avatar /> + <LabelingService.Avatar avatar={labeler.creator.avatar} /> <LabelingService.Content> <LabelingService.Title value={getLabelingServiceTitle({ From 5b4b8e47d9e37d7e6b3c309e877c931f4d61c582 Mon Sep 17 00:00:00 2001 From: Eric Bailey <git@esb.lol> Date: Tue, 19 Mar 2024 13:39:56 -0500 Subject: [PATCH 090/109] Use default label prefs for pwi (#3271) --- src/state/queries/preferences/index.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/state/queries/preferences/index.ts b/src/state/queries/preferences/index.ts index cfc5c5bbe5..f9cd59cda8 100644 --- a/src/state/queries/preferences/index.ts +++ b/src/state/queries/preferences/index.ts @@ -5,6 +5,7 @@ import { BskyFeedViewPreference, ModerationOpts, AppBskyActorDefs, + BSKY_LABELER_DID, } from '@atproto/api' import {track} from '#/lib/analytics/analytics' @@ -19,6 +20,7 @@ import { DEFAULT_THREAD_VIEW_PREFS, DEFAULT_LOGGED_OUT_PREFERENCES, } from '#/state/queries/preferences/const' +import {DEFAULT_LOGGED_OUT_LABEL_PREFERENCES} from '#/state/queries/preferences/moderation' import {STALE} from '#/state/queries' import {useHiddenPosts, useLabelDefinitions} from '#/state/preferences' import {saveLabelers} from '#/state/session/agent-config' @@ -95,7 +97,18 @@ export function useModerationOpts() { } return { userDid: currentAccount?.did, - prefs: {...prefs.data.moderationPrefs, hiddenPosts: hiddenPosts || []}, + prefs: { + ...prefs.data.moderationPrefs, + labelers: prefs.data.moderationPrefs.labelers.length + ? prefs.data.moderationPrefs.labelers + : [ + { + did: BSKY_LABELER_DID, + labels: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES, + }, + ], + hiddenPosts: hiddenPosts || [], + }, labelDefs, } }, [override, currentAccount, labelDefs, prefs.data, hiddenPosts]) From 5e0a6a12ff4f9b3398f3ffeb24fc3b06bab846aa Mon Sep 17 00:00:00 2001 From: Hailey <me@haileyok.com> Date: Tue, 19 Mar 2024 12:01:54 -0700 Subject: [PATCH 091/109] Update trusted hosts, allow `#`, and add more tests (#3232) * Update trusted hosts, allow `#`, and add more tests * update comments --- __tests__/lib/strings/url-helpers.test.ts | 38 +++++++++++++++++++++++ src/lib/strings/url-helpers.ts | 38 ++++++++++++++++------- 2 files changed, 64 insertions(+), 12 deletions(-) diff --git a/__tests__/lib/strings/url-helpers.test.ts b/__tests__/lib/strings/url-helpers.test.ts index 6ac31aeb63..fb4b8f7555 100644 --- a/__tests__/lib/strings/url-helpers.test.ts +++ b/__tests__/lib/strings/url-helpers.test.ts @@ -4,6 +4,7 @@ import { linkRequiresWarning, isPossiblyAUrl, splitApexDomain, + isTrustedUrl, } from '../../../src/lib/strings/url-helpers' describe('linkRequiresWarning', () => { @@ -74,6 +75,10 @@ describe('linkRequiresWarning', () => { // bad uri inputs, default to true ['', '', true], ['example.com', 'example.com', true], + ['/profile', 'Username', false], + ['#', 'Show More', false], + ['https://docs.bsky.app', 'https://docs.bsky.app', false], + ['https://bsky.app/compose/intent?text=test', 'Compose a post', false], ] it.each(cases)( @@ -139,3 +144,36 @@ describe('splitApexDomain', () => { }, ) }) + +describe('isTrustedUrl', () => { + const cases = [ + ['#', true], + ['#profile', true], + ['/', true], + ['/profile', true], + ['/profile/', true], + ['/profile/bob.test', true], + ['https://bsky.app', true], + ['https://bsky.app/', true], + ['https://bsky.app/profile/bob.test', true], + ['https://www.bsky.app', true], + ['https://www.bsky.app/', true], + ['https://docs.bsky.app', true], + ['https://bsky.social', true], + ['https://bsky.social/blog', true], + ['https://blueskyweb.xyz', true], + ['https://blueskyweb.zendesk.com', true], + ['http://bsky.app', true], + ['http://bsky.social', true], + ['http://blueskyweb.xyz', true], + ['http://blueskyweb.zendesk.com', true], + ['https://google.com', false], + ['https://docs.google.com', false], + ['https://google.com/#', false], + ] + + it.each(cases)('given input uri %p, returns %p', (str, expected) => { + const output = isTrustedUrl(str) + expect(output).toEqual(expected) + }) +}) diff --git a/src/lib/strings/url-helpers.ts b/src/lib/strings/url-helpers.ts index 820311e4ee..70a2b70692 100644 --- a/src/lib/strings/url-helpers.ts +++ b/src/lib/strings/url-helpers.ts @@ -4,6 +4,23 @@ import TLDs from 'tlds' import psl from 'psl' export const BSKY_APP_HOST = 'https://bsky.app' +const BSKY_TRUSTED_HOSTS = [ + 'bsky.app', + 'bsky.social', + 'blueskyweb.xyz', + 'blueskyweb.zendesk.com', + ...(__DEV__ ? ['localhost:19006', 'localhost:8100'] : []), +] + +/* + * This will allow any BSKY_TRUSTED_HOSTS value by itself or with a subdomain. + * It will also allow relative paths like /profile as well as #. + */ +const TRUSTED_REGEX = new RegExp( + `^(http(s)?://(([\\w-]+\\.)?${BSKY_TRUSTED_HOSTS.join( + '|([\\w-]+\\.)?', + )})|/|#)`, +) export function isValidDomain(str: string): boolean { return !!TLDs.find(tld => { @@ -86,6 +103,10 @@ export function isExternalUrl(url: string): boolean { return external || rss } +export function isTrustedUrl(url: string): boolean { + return TRUSTED_REGEX.test(url) +} + export function isBskyPostUrl(url: string): boolean { if (isBskyAppUrl(url)) { try { @@ -163,8 +184,8 @@ export function feedUriToHref(url: string): string { export function linkRequiresWarning(uri: string, label: string) { const labelDomain = labelToDomain(label) - // If the uri started with a / we know it is internal. - if (isRelativeUrl(uri)) { + // We should trust any relative URL or a # since we know it links to internal content + if (isRelativeUrl(uri) || uri === '#') { return false } @@ -176,18 +197,11 @@ export function linkRequiresWarning(uri: string, label: string) { } const host = urip.hostname.toLowerCase() - // Hosts that end with bsky.app or bsky.social should be trusted by default. - if ( - host.endsWith('bsky.app') || - host.endsWith('bsky.social') || - host.endsWith('blueskyweb.xyz') - ) { - // if this is a link to internal content, - // warn if it represents itself as a URL to another app + if (isTrustedUrl(uri)) { + // if this is a link to internal content, warn if it represents itself as a URL to another app return !!labelDomain && labelDomain !== host && isPossiblyAUrl(labelDomain) } else { - // if this is a link to external content, - // warn if the label doesnt match the target + // if this is a link to external content, warn if the label doesnt match the target if (!labelDomain) { return true } From 2255d21bda617ff2de8a3ff06f4cde665aa91d15 Mon Sep 17 00:00:00 2001 From: Hailey <me@haileyok.com> Date: Tue, 19 Mar 2024 12:03:16 -0700 Subject: [PATCH 092/109] prevent duplicate pickers from opening on android (#3240) * prevent duplicate pickers from opening on android * revert unnecessary changes * test * one more test --- patches/expo-image-picker+14.7.1.patch | 62 +++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/patches/expo-image-picker+14.7.1.patch b/patches/expo-image-picker+14.7.1.patch index 2d37a182a8..046eb4f4f3 100644 --- a/patches/expo-image-picker+14.7.1.patch +++ b/patches/expo-image-picker+14.7.1.patch @@ -1,8 +1,56 @@ +diff --git a/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/ImagePickerModule.kt b/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/ImagePickerModule.kt +index 3f50f8c..ee47fa1 100644 +--- a/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/ImagePickerModule.kt ++++ b/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/ImagePickerModule.kt +@@ -33,7 +33,9 @@ import kotlin.coroutines.resumeWithException + // TODO(@bbarthec): rename to ExpoImagePicker + private const val moduleName = "ExponentImagePicker" + ++ + class ImagePickerModule : Module() { ++ private var isPickerOpen = false + + override fun definition() = ModuleDefinition { + Name(moduleName) +@@ -129,6 +131,11 @@ class ImagePickerModule : Module() { + options: ImagePickerOptions + ): Any { + return try { ++ if(isPickerOpen) { ++ return ImagePickerResponse(canceled = true) ++ } ++ ++ isPickerOpen = true + var result = launchPicker(pickerLauncher) + if ( + !options.allowsMultipleSelection && +@@ -143,6 +150,8 @@ class ImagePickerModule : Module() { + mediaHandler.readExtras(result.data, options) + } catch (cause: OperationCanceledException) { + return ImagePickerResponse(canceled = true) ++ } finally { ++ isPickerOpen = false + } + } + diff --git a/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/contracts/ImageLibraryContract.kt b/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/contracts/ImageLibraryContract.kt -index ff15c91..41aaf12 100644 +index ff15c91..9763012 100644 --- a/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/contracts/ImageLibraryContract.kt +++ b/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/contracts/ImageLibraryContract.kt -@@ -26,51 +26,26 @@ import java.io.Serializable +@@ -5,12 +5,7 @@ import android.content.ContentResolver + import android.content.Context + import android.content.Intent + import android.net.Uri +-import androidx.activity.result.PickVisualMediaRequest +-import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia +-import androidx.activity.result.contract.ActivityResultContracts.PickMultipleVisualMedia + import expo.modules.imagepicker.ImagePickerOptions +-import expo.modules.imagepicker.MediaTypes +-import expo.modules.imagepicker.UNLIMITED_SELECTION + import expo.modules.imagepicker.getAllDataUris + import expo.modules.imagepicker.toMediaType + import expo.modules.kotlin.activityresult.AppContextActivityResultContract +@@ -26,51 +21,26 @@ import java.io.Serializable * @see [androidx.activity.result.contract.ActivityResultContracts.GetMultipleContents] */ internal class ImageLibraryContract( @@ -12,7 +60,7 @@ index ff15c91..41aaf12 100644 private val contentResolver: ContentResolver get() = appContextProvider.appContext.reactContext?.contentResolver ?: throw Exceptions.ReactContextLost() - + override fun createIntent(context: Context, input: ImageLibraryContractOptions): Intent { - val request = PickVisualMediaRequest.Builder() - .setMediaType( @@ -34,7 +82,7 @@ index ff15c91..41aaf12 100644 + val intent = Intent(Intent.ACTION_GET_CONTENT) + .addCategory(Intent.CATEGORY_OPENABLE) + .setType("image/*") - + if (input.options.allowsMultipleSelection) { - val selectionLimit = input.options.selectionLimit - @@ -45,7 +93,7 @@ index ff15c91..41aaf12 100644 + if(input.options.selectionLimit == 1) { + return intent } - + - if (selectionLimit > 1) { - return PickMultipleVisualMedia(selectionLimit).createIntent(context, request) - } @@ -56,9 +104,9 @@ index ff15c91..41aaf12 100644 - } + intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true) } - + - return PickVisualMedia().createIntent(context, request) + return intent } - + override fun parseResult(input: ImageLibraryContractOptions, resultCode: Int, intent: Intent?) = From 07e6d001a25825bb86ee6e9afcb65abacf9fadc4 Mon Sep 17 00:00:00 2001 From: Hailey <me@haileyok.com> Date: Tue, 19 Mar 2024 12:05:28 -0700 Subject: [PATCH 093/109] patch-fix `RCTRefreshControl` (#3259) --- patches/react-native+0.73.2.patch | 103 ++++----------------------- patches/react-native+0.73.2.patch.md | 8 +-- 2 files changed, 19 insertions(+), 92 deletions(-) diff --git a/patches/react-native+0.73.2.patch b/patches/react-native+0.73.2.patch index 8f100169e5..8db23da0c7 100644 --- a/patches/react-native+0.73.2.patch +++ b/patches/react-native+0.73.2.patch @@ -1,92 +1,19 @@ -diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.mm b/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.mm -index 9dca6a5..090bda5 100644 ---- a/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.mm -+++ b/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.mm -@@ -266,11 +266,10 @@ - (void)textViewDidChange:(__unused UITextView *)textView +diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m +index b09e653..d290dab 100644 +--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m ++++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m +@@ -198,6 +198,14 @@ - (void)refreshControlValueChanged + [self setCurrentRefreshingState:super.refreshing]; + _refreshingProgrammatically = NO; - - (void)textViewDidChangeSelection:(__unused UITextView *)textView - { -- if (_lastStringStateWasUpdatedWith && ![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) { -+ if (![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) { - [self textViewDidChange:_backedTextInputView]; - _ignoreNextTextInputCall = YES; - } -- _lastStringStateWasUpdatedWith = _backedTextInputView.attributedText; - [self textViewProbablyDidChangeSelection]; - } - -diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.mm b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.mm -index 1f06b79..ab458f3 100644 ---- a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.mm -+++ b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.mm -@@ -87,7 +87,7 @@ - (void)invalidateContentSize - return; - } - -- CGSize maximumSize = self.layoutMetrics.frame.size; -+ CGSize maximumSize = self.layoutMetrics.contentFrame.size; - - if (_maximumNumberOfLines == 1) { - maximumSize.width = CGFLOAT_MAX; -@@ -158,6 +158,8 @@ - (void)uiManagerWillPerformMounting - [attributedText insertAttributedString:propertyAttributedText atIndex:0]; - } - -+ [self postprocessAttributedText:attributedText]; -+ - NSAttributedString *newAttributedText; - if (![_previousAttributedText isEqualToAttributedString:attributedText]) { - // We have to follow `set prop` pattern: -@@ -191,6 +193,52 @@ - (void)uiManagerWillPerformMounting - }]; - } - -+- (void)postprocessAttributedText:(NSMutableAttributedString *)attributedText -+{ -+ __block CGFloat maximumLineHeight = 0; -+ -+ [attributedText enumerateAttribute:NSParagraphStyleAttributeName -+ inRange:NSMakeRange(0, attributedText.length) -+ options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired -+ usingBlock:^(NSParagraphStyle *paragraphStyle, __unused NSRange range, __unused BOOL *stop) { -+ if (!paragraphStyle) { -+ return; ++ if (@available(iOS 17.4, *)) { ++ if (_currentRefreshingState) { ++ UIImpactFeedbackGenerator *feedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight]; ++ [feedbackGenerator prepare]; ++ [feedbackGenerator impactOccurred]; + } -+ -+ maximumLineHeight = MAX(paragraphStyle.maximumLineHeight, maximumLineHeight); -+ }]; -+ -+ if (maximumLineHeight == 0) { -+ // `lineHeight` was not specified, nothing to do. -+ return; + } + -+ __block CGFloat maximumFontLineHeight = 0; -+ -+ [attributedText enumerateAttribute:NSFontAttributeName -+ inRange:NSMakeRange(0, attributedText.length) -+ options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired -+ usingBlock:^(UIFont *font, NSRange range, __unused BOOL *stop) { -+ if (!font) { -+ return; -+ } -+ -+ if (maximumFontLineHeight <= font.lineHeight) { -+ maximumFontLineHeight = font.lineHeight; -+ } -+ }]; -+ -+ if (maximumLineHeight < maximumFontLineHeight) { -+ return; -+ } -+ -+ CGFloat baseLineOffset = maximumLineHeight / 2.0 - maximumFontLineHeight / 2.0; -+ -+ [attributedText addAttribute:NSBaselineOffsetAttributeName -+ value:@(baseLineOffset) -+ range:NSMakeRange(0, attributedText.length)]; -+} -+ - #pragma mark - - - - (NSAttributedString *)measurableAttributedText + if (_onRefresh) { + _onRefresh(nil); + } \ No newline at end of file diff --git a/patches/react-native+0.73.2.patch.md b/patches/react-native+0.73.2.patch.md index 3d32751636..7f70baf2fd 100644 --- a/patches/react-native+0.73.2.patch.md +++ b/patches/react-native+0.73.2.patch.md @@ -1,5 +1,5 @@ -# TextInput Patch +# RefreshControl Patch -Patching `RCTBaseTextShadowInput.mm` from https://github.com/facebook/react-native/pull/38359. This fixes some text -getting cut off inside the composer. This was merged in December, so we should be able to remove this patch when RN -ships the next release. +Patching `RCTRefreshControl.mm` temporarily to play an impact haptic on refresh when using iOS 17.4 or higher. Since +17.4, there has been a regression somewhere causing haptics to not play on iOS on refresh. Should monitor for an update +in the RN repo: https://github.com/facebook/react-native/issues/43388 \ No newline at end of file From addd66b37f922fda12a99298a37a0166cf509f89 Mon Sep 17 00:00:00 2001 From: Hailey <me@haileyok.com> Date: Tue, 19 Mar 2024 12:10:10 -0700 Subject: [PATCH 094/109] `PostThread` cleanup (#3183) * cleanup PostThread rm some more unnecessary code cleanup some more pieces fix `isLoading` logic few fixes organize refactor `PostThread` allow chaining of `postThreadQuery` Update `Hashtag` screen with the component changes Make some changes to the List components adjust height and padding of bottom loader to account for bottom bar * rm unnecessary chaining logic * maxReplies logic * adjust error logic * use `<` instead of `<=` * add back warning comment * remove unused prop * adjust order * update prop name * don't show error if `isLoading` --- src/components/Error.tsx | 90 +++++ src/components/Lists.tsx | 177 ++++------ src/screens/Hashtag.tsx | 4 +- src/view/com/post-thread/PostThread.tsx | 439 ++++++++---------------- 4 files changed, 307 insertions(+), 403 deletions(-) create mode 100644 src/components/Error.tsx diff --git a/src/components/Error.tsx b/src/components/Error.tsx new file mode 100644 index 0000000000..1dbf682849 --- /dev/null +++ b/src/components/Error.tsx @@ -0,0 +1,90 @@ +import React from 'react' + +import {CenteredView} from 'view/com/util/Views' +import {atoms as a, useBreakpoints, useTheme} from '#/alf' +import {Text} from '#/components/Typography' +import {View} from 'react-native' +import {Button} from '#/components/Button' +import {useNavigation} from '@react-navigation/core' +import {NavigationProp} from 'lib/routes/types' +import {StackActions} from '@react-navigation/native' +import {router} from '#/routes' + +export function Error({ + title, + message, + onRetry, +}: { + title?: string + message?: string + onRetry?: () => unknown +}) { + const navigation = useNavigation<NavigationProp>() + const t = useTheme() + const {gtMobile} = useBreakpoints() + + const canGoBack = navigation.canGoBack() + const onGoBack = React.useCallback(() => { + if (canGoBack) { + navigation.goBack() + } else { + navigation.navigate('HomeTab') + + // Checking the state for routes ensures that web doesn't encounter errors while going back + if (navigation.getState()?.routes) { + navigation.dispatch(StackActions.push(...router.matchPath('/'))) + } else { + navigation.navigate('HomeTab') + navigation.dispatch(StackActions.popToTop()) + } + } + }, [navigation, canGoBack]) + + return ( + <CenteredView + style={[ + a.flex_1, + a.align_center, + !gtMobile ? a.justify_between : a.gap_5xl, + t.atoms.border_contrast_low, + {paddingTop: 175, paddingBottom: 110}, + ]} + sideBorders> + <View style={[a.w_full, a.align_center, a.gap_lg]}> + <Text style={[a.font_bold, a.text_3xl]}>{title}</Text> + <Text + style={[ + a.text_md, + a.text_center, + t.atoms.text_contrast_high, + {lineHeight: 1.4}, + gtMobile && {width: 450}, + ]}> + {message} + </Text> + </View> + <View style={[a.gap_md, gtMobile ? {width: 350} : [a.w_full, a.px_lg]]}> + {onRetry && ( + <Button + variant="solid" + color="primary" + label="Click here" + onPress={onRetry} + size="large" + style={[a.rounded_sm, a.overflow_hidden, {paddingVertical: 10}]}> + Retry + </Button> + )} + <Button + variant="solid" + color={onRetry ? 'secondary' : 'primary'} + label="Click here" + onPress={onGoBack} + size="large" + style={[a.rounded_sm, a.overflow_hidden, {paddingVertical: 10}]}> + Go Back + </Button> + </View> + </CenteredView> + ) +} diff --git a/src/components/Lists.tsx b/src/components/Lists.tsx index 8a889c15e3..a74484b717 100644 --- a/src/components/Lists.tsx +++ b/src/components/Lists.tsx @@ -1,26 +1,28 @@ import React from 'react' import {atoms as a, useBreakpoints, useTheme} from '#/alf' import {View} from 'react-native' +import {useLingui} from '@lingui/react' + import {CenteredView} from 'view/com/util/Views' import {Loader} from '#/components/Loader' -import {Trans} from '@lingui/macro' +import {msg, Trans} from '@lingui/macro' import {cleanError} from 'lib/strings/errors' import {Button} from '#/components/Button' import {Text} from '#/components/Typography' -import {StackActions} from '@react-navigation/native' -import {router} from '#/routes' -import {useNavigationDeduped} from 'lib/hooks/useNavigationDeduped' +import {Error} from '#/components/Error' export function ListFooter({ isFetching, isError, error, onRetry, + height, }: { - isFetching: boolean - isError: boolean + isFetching?: boolean + isError?: boolean error?: string onRetry?: () => Promise<unknown> + height?: number }) { const t = useTheme() @@ -29,11 +31,10 @@ export function ListFooter({ style={[ a.w_full, a.align_center, - a.justify_center, a.border_t, a.pb_lg, t.atoms.border_contrast_low, - {height: 180}, + {height: height ?? 180, paddingTop: 30}, ]}> {isFetching ? ( <Loader size="xl" /> @@ -53,7 +54,7 @@ function ListFooterMaybeError({ error, onRetry, }: { - isError: boolean + isError?: boolean error?: string onRetry?: () => Promise<unknown> }) { @@ -128,121 +129,71 @@ export function ListMaybePlaceholder({ isLoading, isEmpty, isError, - empty, - error, - notFoundType = 'page', + emptyTitle, + emptyMessage, + errorTitle, + errorMessage, + emptyType = 'page', onRetry, }: { isLoading: boolean - isEmpty: boolean - isError: boolean - empty?: string - error?: string - notFoundType?: 'page' | 'results' + isEmpty?: boolean + isError?: boolean + emptyTitle?: string + emptyMessage?: string + errorTitle?: string + errorMessage?: string + emptyType?: 'page' | 'results' onRetry?: () => Promise<unknown> }) { - const navigation = useNavigationDeduped() const t = useTheme() + const {_} = useLingui() const {gtMobile, gtTablet} = useBreakpoints() - const canGoBack = navigation.canGoBack() - const onGoBack = React.useCallback(() => { - if (canGoBack) { - navigation.goBack() - } else { - navigation.navigate('HomeTab') + if (!isLoading && isError) { + return ( + <Error + title={errorTitle ?? _(msg`Oops!`)} + message={errorMessage ?? _(`Something went wrong!`)} + onRetry={onRetry} + /> + ) + } - // Checking the state for routes ensures that web doesn't encounter errors while going back - if (navigation.getState()?.routes) { - navigation.dispatch(StackActions.push(...router.matchPath('/'))) - } else { - navigation.navigate('HomeTab') - navigation.dispatch(StackActions.popToTop()) - } - } - }, [navigation, canGoBack]) - - if (!isEmpty) return null - - return ( - <CenteredView - style={[ - a.flex_1, - a.align_center, - !gtMobile ? a.justify_between : a.gap_5xl, - t.atoms.border_contrast_low, - {paddingTop: 175, paddingBottom: 110}, - ]} - sideBorders={gtMobile} - topBorder={!gtTablet}> - {isLoading ? ( + if (isLoading) { + return ( + <CenteredView + style={[ + a.flex_1, + a.align_center, + !gtMobile ? a.justify_between : a.gap_5xl, + t.atoms.border_contrast_low, + {paddingTop: 175, paddingBottom: 110}, + ]} + sideBorders={gtMobile} + topBorder={!gtTablet}> <View style={[a.w_full, a.align_center, {top: 100}]}> <Loader size="xl" /> </View> - ) : ( - <> - <View style={[a.w_full, a.align_center, a.gap_lg]}> - <Text style={[a.font_bold, a.text_3xl]}> - {isError ? ( - <Trans>Oops!</Trans> - ) : isEmpty ? ( - <> - {notFoundType === 'results' ? ( - <Trans>No results found</Trans> - ) : ( - <Trans>Page not found</Trans> - )} - </> - ) : undefined} - </Text> + </CenteredView> + ) + } - {isError ? ( - <Text - style={[a.text_md, a.text_center, t.atoms.text_contrast_high]}> - {error ? error : <Trans>Something went wrong!</Trans>} - </Text> - ) : isEmpty ? ( - <Text - style={[a.text_md, a.text_center, t.atoms.text_contrast_high]}> - {empty ? ( - empty - ) : ( - <Trans> - We're sorry! We can't find the page you were looking for. - </Trans> - )} - </Text> - ) : undefined} - </View> - <View - style={[a.gap_md, !gtMobile ? [a.w_full, a.px_lg] : {width: 350}]}> - {isError && onRetry && ( - <Button - variant="solid" - color="primary" - label="Click here" - onPress={onRetry} - size="large" - style={[ - a.rounded_sm, - a.overflow_hidden, - {paddingVertical: 10}, - ]}> - Retry - </Button> - )} - <Button - variant="solid" - color={isError && onRetry ? 'secondary' : 'primary'} - label="Click here" - onPress={onGoBack} - size="large" - style={[a.rounded_sm, a.overflow_hidden, {paddingVertical: 10}]}> - Go Back - </Button> - </View> - </> - )} - </CenteredView> - ) + if (isEmpty) { + return ( + <Error + title={ + emptyTitle ?? + (emptyType === 'results' + ? _(msg`No results found`) + : _(msg`Page not found`)) + } + message={ + emptyMessage ?? + _(msg`We're sorry! We can't find the page you were looking for.`) + } + onRetry={onRetry} + /> + ) + } } diff --git a/src/screens/Hashtag.tsx b/src/screens/Hashtag.tsx index 776cc585e3..46452f087e 100644 --- a/src/screens/Hashtag.tsx +++ b/src/screens/Hashtag.tsx @@ -128,8 +128,8 @@ export default function HashtagScreen({ isError={isError} isEmpty={posts.length < 1} onRetry={refetch} - notFoundType="results" - empty={_(msg`We couldn't find any results for that hashtag.`)} + emptyTitle="results" + emptyMessage={_(msg`We couldn't find any results for that hashtag.`)} /> {!isLoading && posts.length > 0 && ( <List<PostView> diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx index bac7018c34..8042e7bd52 100644 --- a/src/view/com/post-thread/PostThread.tsx +++ b/src/view/com/post-thread/PostThread.tsx @@ -1,25 +1,14 @@ import React, {useEffect, useRef} from 'react' -import { - ActivityIndicator, - Pressable, - StyleSheet, - TouchableOpacity, - View, -} from 'react-native' +import {StyleSheet, useWindowDimensions, View} from 'react-native' import {AppBskyFeedDefs} from '@atproto/api' -import {CenteredView} from '../util/Views' -import {LoadingScreen} from '../util/LoadingScreen' +import {Trans, msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + import {List, ListMethods} from '../util/List' -import { - FontAwesomeIcon, - FontAwesomeIconStyle, -} from '@fortawesome/react-native-fontawesome' import {PostThreadItem} from './PostThreadItem' import {ComposePrompt} from '../composer/Prompt' import {ViewHeader} from '../util/ViewHeader' -import {ErrorMessage} from '../util/error/ErrorMessage' import {Text} from '../util/text/Text' -import {s} from 'lib/styles' import {usePalette} from 'lib/hooks/usePalette' import {useSetTitle} from 'lib/hooks/useSetTitle' import { @@ -30,21 +19,18 @@ import { usePostThreadQuery, sortThread, } from '#/state/queries/post-thread' -import {useNavigation} from '@react-navigation/native' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {NavigationProp} from 'lib/routes/types' import {sanitizeDisplayName} from 'lib/strings/display-names' -import {cleanError} from '#/lib/strings/errors' -import {Trans, msg} from '@lingui/macro' -import {useLingui} from '@lingui/react' import { - UsePreferencesQueryResponse, useModerationOpts, usePreferencesQuery, } from '#/state/queries/preferences' import {useSession} from '#/state/session' import {isAndroid, isNative, isWeb} from '#/platform/detection' import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped' +import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender' +import {ListFooter, ListMaybePlaceholder} from '#/components/Lists' +import {cleanError} from 'lib/strings/errors' // FlatList maintainVisibleContentPosition breaks if too many items // are prepended. This seems to be an optimal number based on *shrug*. @@ -58,9 +44,7 @@ const MAINTAIN_VISIBLE_CONTENT_POSITION = { const TOP_COMPONENT = {_reactKey: '__top_component__'} const REPLY_PROMPT = {_reactKey: '__reply__'} -const CHILD_SPINNER = {_reactKey: '__child_spinner__'} const LOAD_MORE = {_reactKey: '__load_more__'} -const BOTTOM_COMPONENT = {_reactKey: '__bottom_component__'} type YieldedItem = ThreadPost | ThreadBlocked | ThreadNotFound type RowItem = @@ -68,9 +52,7 @@ type RowItem = // TODO: TS doesn't actually enforce it's one of these, it only enforces matching shape. | typeof TOP_COMPONENT | typeof REPLY_PROMPT - | typeof CHILD_SPINNER | typeof LOAD_MORE - | typeof BOTTOM_COMPONENT type ThreadSkeletonParts = { parents: YieldedItem[] @@ -78,6 +60,10 @@ type ThreadSkeletonParts = { replies: YieldedItem[] } +const keyExtractor = (item: RowItem) => { + return item._reactKey +} + export function PostThread({ uri, onCanReply, @@ -85,17 +71,30 @@ export function PostThread({ }: { uri: string | undefined onCanReply: (canReply: boolean) => void - onPressReply: () => void + onPressReply: () => unknown }) { + const {hasSession} = useSession() + const {_} = useLingui() + const pal = usePalette('default') + const {isMobile, isTabletOrMobile} = useWebMediaQueries() + const initialNumToRender = useInitialNumToRender() + const {height: windowHeight} = useWindowDimensions() + + const {data: preferences} = usePreferencesQuery() const { - isLoading, - isError, - error, + isFetching, + isError: isThreadError, + error: threadError, refetch, data: thread, } = usePostThreadQuery(uri) - const {data: preferences} = usePreferencesQuery() + const treeView = React.useMemo( + () => + !!preferences?.threadViewPrefs?.lab_treeViewEnabled && + hasBranchingReplies(thread), + [preferences?.threadViewPrefs, thread], + ) const rootPost = thread?.type === 'post' ? thread.post : undefined const rootPostRecord = thread?.type === 'post' ? thread.record : undefined @@ -105,7 +104,6 @@ export function PostThread({ rootPost && moderationOpts ? moderatePost(rootPost, moderationOpts) : undefined - return !!mod ?.ui('contentList') .blurs.find( @@ -114,6 +112,14 @@ export function PostThread({ ) }, [rootPost, moderationOpts]) + // Values used for proper rendering of parents + const ref = useRef<ListMethods>(null) + const highlightedPostRef = useRef<View | null>(null) + const [maxParents, setMaxParents] = React.useState( + isWeb ? Infinity : PARENTS_CHUNK_SIZE, + ) + const [maxReplies, setMaxReplies] = React.useState(50) + useSetTitle( rootPost && !isNoPwi ? `${sanitizeDisplayName( @@ -121,62 +127,6 @@ export function PostThread({ )}: "${rootPostRecord!.text}"` : '', ) - useEffect(() => { - if (rootPost) { - onCanReply(!rootPost.viewer?.replyDisabled) - } - }, [rootPost, onCanReply]) - - if (isError || AppBskyFeedDefs.isNotFoundPost(thread)) { - return ( - <PostThreadError - error={error} - notFound={AppBskyFeedDefs.isNotFoundPost(thread)} - onRefresh={refetch} - /> - ) - } - if (AppBskyFeedDefs.isBlockedPost(thread)) { - return <PostThreadBlocked /> - } - if (!thread || isLoading || !preferences) { - return <LoadingScreen /> - } - return ( - <PostThreadLoaded - thread={thread} - threadViewPrefs={preferences.threadViewPrefs} - onRefresh={refetch} - onPressReply={onPressReply} - /> - ) -} - -function PostThreadLoaded({ - thread, - threadViewPrefs, - onRefresh, - onPressReply, -}: { - thread: ThreadNode - threadViewPrefs: UsePreferencesQueryResponse['threadViewPrefs'] - onRefresh: () => void - onPressReply: () => void -}) { - const {hasSession} = useSession() - const {_} = useLingui() - const pal = usePalette('default') - const {isMobile, isTabletOrMobile} = useWebMediaQueries() - const ref = useRef<ListMethods>(null) - const highlightedPostRef = useRef<View | null>(null) - const [maxParents, setMaxParents] = React.useState( - isWeb ? Infinity : PARENTS_CHUNK_SIZE, - ) - const [maxReplies, setMaxReplies] = React.useState(100) - const treeView = React.useMemo( - () => !!threadViewPrefs.lab_treeViewEnabled && hasBranchingReplies(thread), - [threadViewPrefs, thread], - ) // On native, this is going to start out `true`. We'll toggle it to `false` after the initial render if flushed. // This ensures that the first render contains no parents--even if they are already available in the cache. @@ -184,18 +134,56 @@ function PostThreadLoaded({ // On the web this is not necessary because we can synchronously adjust the scroll in onContentSizeChange instead. const [deferParents, setDeferParents] = React.useState(isNative) - const skeleton = React.useMemo( - () => - createThreadSkeleton( - sortThread(thread, threadViewPrefs), - hasSession, - treeView, - ), - [thread, threadViewPrefs, hasSession, treeView], - ) + const skeleton = React.useMemo(() => { + const threadViewPrefs = preferences?.threadViewPrefs + if (!threadViewPrefs || !thread) return null + + return createThreadSkeleton( + sortThread(thread, threadViewPrefs), + hasSession, + treeView, + ) + }, [thread, preferences?.threadViewPrefs, hasSession, treeView]) + + const error = React.useMemo(() => { + if (AppBskyFeedDefs.isNotFoundPost(thread)) { + return { + title: _(msg`Post not found`), + message: _(msg`The post may have been deleted.`), + } + } else if (skeleton?.highlightedPost.type === 'blocked') { + return { + title: _(msg`Post hidden`), + message: _( + msg`You have blocked the author or you have been blocked by the author.`, + ), + } + } else if (threadError?.message.startsWith('Post not found')) { + return { + title: _(msg`Post not found`), + message: _(msg`The post may have been deleted.`), + } + } else if (isThreadError) { + return { + message: threadError ? cleanError(threadError) : undefined, + } + } + + return null + }, [thread, skeleton?.highlightedPost, isThreadError, _, threadError]) + + useEffect(() => { + if (error) { + onCanReply(false) + } else if (rootPost) { + onCanReply(!rootPost.viewer?.replyDisabled) + } + }, [rootPost, onCanReply, error]) // construct content const posts = React.useMemo(() => { + if (!skeleton) return [] + const {parents, highlightedPost, replies} = skeleton let arr: RowItem[] = [] if (highlightedPost.type === 'post') { @@ -231,17 +219,11 @@ function PostThreadLoaded({ if (!highlightedPost.post.viewer?.replyDisabled) { arr.push(REPLY_PROMPT) } - if (highlightedPost.ctx.isChildLoading) { - arr.push(CHILD_SPINNER) - } else { - for (let i = 0; i < replies.length; i++) { - arr.push(replies[i]) - if (i === maxReplies) { - arr.push(LOAD_MORE) - break - } + for (let i = 0; i < replies.length; i++) { + arr.push(replies[i]) + if (i === maxReplies) { + break } - arr.push(BOTTOM_COMPONENT) } } return arr @@ -256,7 +238,7 @@ function PostThreadLoaded({ return } // wait for loading to finish - if (thread.type === 'post' && !!thread.parent) { + if (thread?.type === 'post' && !!thread.parent) { function onMeasure(pageY: number) { ref.current?.scrollToOffset({ animated: false, @@ -280,10 +262,10 @@ function PostThreadLoaded({ // To work around this, we prepend rows after scroll bumps against the top and rests. const needsBumpMaxParents = React.useRef(false) const onStartReached = React.useCallback(() => { - if (maxParents < skeleton.parents.length) { + if (skeleton?.parents && maxParents < skeleton.parents.length) { needsBumpMaxParents.current = true } - }, [maxParents, skeleton.parents.length]) + }, [maxParents, skeleton?.parents]) const bumpMaxParentsIfNeeded = React.useCallback(() => { if (!isNative) { return @@ -296,6 +278,11 @@ function PostThreadLoaded({ const onMomentumScrollEnd = bumpMaxParentsIfNeeded const onScrollToTop = bumpMaxParentsIfNeeded + const onEndReached = React.useCallback(() => { + if (isFetching || posts.length < maxReplies) return + setMaxReplies(prev => prev + 50) + }, [isFetching, maxReplies, posts.length]) + const renderItem = React.useCallback( ({item, index}: {item: RowItem; index: number}) => { if (item === TOP_COMPONENT) { @@ -326,46 +313,6 @@ function PostThreadLoaded({ </Text> </View> ) - } else if (item === LOAD_MORE) { - return ( - <Pressable - onPress={() => setMaxReplies(n => n + 50)} - style={[pal.border, pal.view, styles.itemContainer]} - accessibilityLabel={_(msg`Load more posts`)} - accessibilityHint=""> - <View - style={[ - pal.viewLight, - {paddingHorizontal: 18, paddingVertical: 14, borderRadius: 6}, - ]}> - <Text type="lg-medium" style={pal.text}> - <Trans>Load more posts</Trans> - </Text> - </View> - </Pressable> - ) - } else if (item === BOTTOM_COMPONENT) { - // HACK - // due to some complexities with how flatlist works, this is the easiest way - // I could find to get a border positioned directly under the last item - // -prf - return ( - <View - // @ts-ignore web-only - style={{ - // Leave enough space below that the scroll doesn't jump - height: isNative ? 600 : '100vh', - borderTopWidth: 1, - borderColor: pal.colors.border, - }} - /> - ) - } else if (item === CHILD_SPINNER) { - return ( - <View style={[pal.border, styles.childSpinner]}> - <ActivityIndicator /> - </View> - ) } else if (isThreadPost(item)) { const prev = isThreadPost(posts[index - 1]) ? (posts[index - 1] as ThreadPost) @@ -374,7 +321,9 @@ function PostThreadLoaded({ ? (posts[index - 1] as ThreadPost) : undefined const hasUnrevealedParents = - index === 0 && maxParents < skeleton.parents.length + index === 0 && + skeleton?.parents && + maxParents < skeleton.parents.length return ( <View ref={item.ctx.isHighlightedPost ? highlightedPostRef : undefined} @@ -391,9 +340,9 @@ function PostThreadLoaded({ showChildReplyLine={item.ctx.showChildReplyLine} showParentReplyLine={item.ctx.showParentReplyLine} hasPrecedingItem={ - !!prev?.ctx.showChildReplyLine || hasUnrevealedParents + !!prev?.ctx.showChildReplyLine || !!hasUnrevealedParents } - onPostReply={onRefresh} + onPostReply={refetch} /> </View> ) @@ -403,142 +352,62 @@ function PostThreadLoaded({ [ hasSession, isTabletOrMobile, + _, isMobile, onPressReply, pal.border, pal.viewLight, pal.textLight, - pal.view, - pal.text, - pal.colors.border, posts, - onRefresh, + skeleton?.parents, + maxParents, deferParents, treeView, - skeleton.parents.length, - maxParents, - _, + refetch, ], ) return ( - <List - ref={ref} - data={posts} - keyExtractor={item => item._reactKey} - renderItem={renderItem} - onContentSizeChange={isNative ? undefined : onContentSizeChangeWeb} - onStartReached={onStartReached} - onMomentumScrollEnd={onMomentumScrollEnd} - onScrollToTop={onScrollToTop} - maintainVisibleContentPosition={ - isNative ? MAINTAIN_VISIBLE_CONTENT_POSITION : undefined - } - style={s.hContentRegion} - // @ts-ignore our .web version only -prf - desktopFixedHeight - removeClippedSubviews={isAndroid ? false : undefined} - windowSize={11} - /> - ) -} - -function PostThreadBlocked() { - const {_} = useLingui() - const pal = usePalette('default') - const navigation = useNavigation<NavigationProp>() - - const onPressBack = React.useCallback(() => { - if (navigation.canGoBack()) { - navigation.goBack() - } else { - navigation.navigate('Home') - } - }, [navigation]) - - return ( - <CenteredView> - <View style={[pal.view, pal.border, styles.notFoundContainer]}> - <Text type="title-lg" style={[pal.text, s.mb5]}> - <Trans>Post hidden</Trans> - </Text> - <Text type="md" style={[pal.text, s.mb10]}> - <Trans> - You have blocked the author or you have been blocked by the author. - </Trans> - </Text> - <TouchableOpacity - onPress={onPressBack} - accessibilityRole="button" - accessibilityLabel={_(msg`Back`)} - accessibilityHint=""> - <Text type="2xl" style={pal.link}> - <FontAwesomeIcon - icon="angle-left" - style={[pal.link as FontAwesomeIconStyle, s.mr5]} - size={14} + <> + <ListMaybePlaceholder + isLoading={!preferences || !thread} + isError={!!error} + onRetry={refetch} + errorTitle={error?.title} + errorMessage={error?.message} + /> + {!error && thread && ( + <List + ref={ref} + data={posts} + renderItem={renderItem} + keyExtractor={keyExtractor} + onContentSizeChange={isNative ? undefined : onContentSizeChangeWeb} + onStartReached={onStartReached} + onEndReached={onEndReached} + onEndReachedThreshold={2} + onMomentumScrollEnd={onMomentumScrollEnd} + onScrollToTop={onScrollToTop} + maintainVisibleContentPosition={ + isNative ? MAINTAIN_VISIBLE_CONTENT_POSITION : undefined + } + // @ts-ignore our .web version only -prf + desktopFixedHeight + removeClippedSubviews={isAndroid ? false : undefined} + ListFooterComponent={ + <ListFooter + isFetching={isFetching} + onRetry={refetch} + // 300 is based on the minimum height of a post. This is enough extra height for the `maintainVisPos` to + // work without causing weird jumps on web or glitches on native + height={windowHeight - 200} /> - <Trans context="action">Back</Trans> - </Text> - </TouchableOpacity> - </View> - </CenteredView> - ) -} - -function PostThreadError({ - onRefresh, - notFound, - error, -}: { - onRefresh: () => void - notFound: boolean - error: Error | null -}) { - const {_} = useLingui() - const pal = usePalette('default') - const navigation = useNavigation<NavigationProp>() - - const onPressBack = React.useCallback(() => { - if (navigation.canGoBack()) { - navigation.goBack() - } else { - navigation.navigate('Home') - } - }, [navigation]) - - if (notFound) { - return ( - <CenteredView> - <View style={[pal.view, pal.border, styles.notFoundContainer]}> - <Text type="title-lg" style={[pal.text, s.mb5]}> - <Trans>Post not found</Trans> - </Text> - <Text type="md" style={[pal.text, s.mb10]}> - <Trans>The post may have been deleted.</Trans> - </Text> - <TouchableOpacity - onPress={onPressBack} - accessibilityRole="button" - accessibilityLabel={_(msg`Back`)} - accessibilityHint=""> - <Text type="2xl" style={pal.link}> - <FontAwesomeIcon - icon="angle-left" - style={[pal.link as FontAwesomeIconStyle, s.mr5]} - size={14} - /> - <Trans>Back</Trans> - </Text> - </TouchableOpacity> - </View> - </CenteredView> - ) - } - return ( - <CenteredView> - <ErrorMessage message={cleanError(error)} onPressTryAgain={onRefresh} /> - </CenteredView> + } + initialNumToRender={initialNumToRender} + windowSize={11} + /> + )} + </> ) } @@ -558,7 +427,9 @@ function createThreadSkeleton( node: ThreadNode, hasSession: boolean, treeView: boolean, -): ThreadSkeletonParts { +): ThreadSkeletonParts | null { + if (!node) return null + return { parents: Array.from(flattenThreadParents(node, hasSession)), highlightedPost: node, @@ -615,7 +486,10 @@ function hasPwiOptOut(node: ThreadPost) { return !!node.post.author.labels?.find(l => l.val === '!no-unauthenticated') } -function hasBranchingReplies(node: ThreadNode) { +function hasBranchingReplies(node?: ThreadNode) { + if (!node) { + return false + } if (node.type !== 'post') { return false } @@ -629,20 +503,9 @@ function hasBranchingReplies(node: ThreadNode) { } const styles = StyleSheet.create({ - notFoundContainer: { - margin: 10, - paddingHorizontal: 18, - paddingVertical: 14, - borderRadius: 6, - }, itemContainer: { borderTopWidth: 1, paddingHorizontal: 18, paddingVertical: 18, }, - childSpinner: { - borderTopWidth: 1, - paddingTop: 40, - paddingBottom: 200, - }, }) From b9474a5d55be0cf8129db30ff97c6144a3599ad8 Mon Sep 17 00:00:00 2001 From: Hailey <me@haileyok.com> Date: Tue, 19 Mar 2024 12:11:20 -0700 Subject: [PATCH 095/109] ProfileFollows and ProfileFollowers cleanup (#3219) * cleanup PostThread rm some more unnecessary code cleanup some more pieces fix `isLoading` logic few fixes organize refactor `PostThread` allow chaining of `postThreadQuery` Update `Hashtag` screen with the component changes Make some changes to the List components adjust height and padding of bottom loader to account for bottom bar * rm unnecessary chaining logic * maxReplies logic * adjust error logic * use `<` instead of `<=` * add back warning comment * remove unused prop * adjust order * implement list improvements for followers/follows * update prop name * small adjustments fix flex add window size adjust isLoading * remove log * don't show retry for no results * don't show error if `isLoading` --- src/view/com/profile/ProfileFollowers.tsx | 124 ++++++++++++---------- src/view/com/profile/ProfileFollows.tsx | 123 +++++++++++---------- src/view/screens/ProfileFollowers.tsx | 2 +- src/view/screens/ProfileFollows.tsx | 2 +- 4 files changed, 133 insertions(+), 118 deletions(-) diff --git a/src/view/com/profile/ProfileFollowers.tsx b/src/view/com/profile/ProfileFollowers.tsx index 411ae6c176..b11a33f273 100644 --- a/src/view/com/profile/ProfileFollowers.tsx +++ b/src/view/com/profile/ProfileFollowers.tsx @@ -1,39 +1,66 @@ import React from 'react' -import {ActivityIndicator, StyleSheet, View} from 'react-native' import {AppBskyActorDefs as ActorDefs} from '@atproto/api' -import {CenteredView} from '../util/Views' -import {LoadingScreen} from '../util/LoadingScreen' import {List} from '../util/List' -import {ErrorMessage} from '../util/error/ErrorMessage' import {ProfileCardWithFollowBtn} from './ProfileCard' import {useProfileFollowersQuery} from '#/state/queries/profile-followers' import {useResolveDidQuery} from '#/state/queries/resolve-uri' import {logger} from '#/logger' import {cleanError} from '#/lib/strings/errors' +import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender' +import { + ListFooter, + ListHeaderDesktop, + ListMaybePlaceholder, +} from '#/components/Lists' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {useSession} from 'state/session' +import {View} from 'react-native' + +function renderItem({item}: {item: ActorDefs.ProfileViewBasic}) { + return <ProfileCardWithFollowBtn key={item.did} profile={item} /> +} + +function keyExtractor(item: ActorDefs.ProfileViewBasic) { + return item.did +} export function ProfileFollowers({name}: {name: string}) { + const {_} = useLingui() + const initialNumToRender = useInitialNumToRender() + const {currentAccount} = useSession() + const [isPTRing, setIsPTRing] = React.useState(false) const { data: resolvedDid, + isLoading: isDidLoading, error: resolveError, - isFetching: isFetchingDid, } = useResolveDidQuery(name) const { data, + isLoading: isFollowersLoading, isFetching, - isFetched, isFetchingNextPage, hasNextPage, fetchNextPage, - isError, error, refetch, } = useProfileFollowersQuery(resolvedDid) + const isError = React.useMemo( + () => !!resolveError || !!error, + [resolveError, error], + ) + + const isMe = React.useMemo(() => { + return resolvedDid === currentAccount?.did + }, [resolvedDid, currentAccount?.did]) + const followers = React.useMemo(() => { if (data?.pages) { return data.pages.flatMap(page => page.followers) } + return [] }, [data]) const onRefresh = React.useCallback(async () => { @@ -47,7 +74,7 @@ export function ProfileFollowers({name}: {name: string}) { }, [refetch, setIsPTRing]) const onEndReached = async () => { - if (isFetching || !hasNextPage || isError) return + if (isFetching || !hasNextPage || !!error) return try { await fetchNextPage() } catch (err) { @@ -55,57 +82,38 @@ export function ProfileFollowers({name}: {name: string}) { } } - const renderItem = React.useCallback( - ({item}: {item: ActorDefs.ProfileViewBasic}) => ( - <ProfileCardWithFollowBtn key={item.did} profile={item} /> - ), - [], - ) - - if (isFetchingDid || !isFetched) { - return <LoadingScreen /> - } - - // error - // = - if (resolveError || isError) { - return ( - <CenteredView> - <ErrorMessage - message={cleanError(resolveError || error)} - onPressTryAgain={onRefresh} - /> - </CenteredView> - ) - } - - // loaded - // = return ( - <List - data={followers} - keyExtractor={item => item.did} - refreshing={isPTRing} - onRefresh={onRefresh} - onEndReached={onEndReached} - renderItem={renderItem} - initialNumToRender={15} - // FIXME(dan) - // eslint-disable-next-line react/no-unstable-nested-components - ListFooterComponent={() => ( - <View style={styles.footer}> - {(isFetching || isFetchingNextPage) && <ActivityIndicator />} - </View> + <View style={{flex: 1}}> + <ListMaybePlaceholder + isLoading={isDidLoading || isFollowersLoading} + isEmpty={followers.length < 1} + isError={isError} + emptyType="results" + emptyMessage={ + isMe + ? _(msg`You do not have any followers.`) + : _(msg`This user doesn't have any followers.`) + } + errorMessage={cleanError(resolveError || error)} + onRetry={isError ? refetch : undefined} + /> + {followers.length > 0 && ( + <List + data={followers} + renderItem={renderItem} + keyExtractor={keyExtractor} + refreshing={isPTRing} + onRefresh={onRefresh} + onEndReached={onEndReached} + onEndReachedThreshold={4} + ListHeaderComponent={<ListHeaderDesktop title={_(msg`Followers`)} />} + ListFooterComponent={<ListFooter isFetching={isFetchingNextPage} />} + // @ts-ignore our .web version only -prf + desktopFixedHeight + initialNumToRender={initialNumToRender} + windowSize={11} + /> )} - // @ts-ignore our .web version only -prf - desktopFixedHeight - /> + </View> ) } - -const styles = StyleSheet.create({ - footer: { - height: 200, - paddingTop: 20, - }, -}) diff --git a/src/view/com/profile/ProfileFollows.tsx b/src/view/com/profile/ProfileFollows.tsx index bd4af10810..d99e2b840e 100644 --- a/src/view/com/profile/ProfileFollows.tsx +++ b/src/view/com/profile/ProfileFollows.tsx @@ -1,39 +1,65 @@ import React from 'react' -import {ActivityIndicator, StyleSheet, View} from 'react-native' import {AppBskyActorDefs as ActorDefs} from '@atproto/api' -import {CenteredView} from '../util/Views' -import {LoadingScreen} from '../util/LoadingScreen' import {List} from '../util/List' -import {ErrorMessage} from '../util/error/ErrorMessage' import {ProfileCardWithFollowBtn} from './ProfileCard' import {useProfileFollowsQuery} from '#/state/queries/profile-follows' import {useResolveDidQuery} from '#/state/queries/resolve-uri' import {logger} from '#/logger' import {cleanError} from '#/lib/strings/errors' +import { + ListFooter, + ListHeaderDesktop, + ListMaybePlaceholder, +} from '#/components/Lists' +import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender' +import {useSession} from 'state/session' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +function renderItem({item}: {item: ActorDefs.ProfileViewBasic}) { + return <ProfileCardWithFollowBtn key={item.did} profile={item} /> +} + +function keyExtractor(item: ActorDefs.ProfileViewBasic) { + return item.did +} export function ProfileFollows({name}: {name: string}) { + const {_} = useLingui() + const initialNumToRender = useInitialNumToRender() + const {currentAccount} = useSession() + const [isPTRing, setIsPTRing] = React.useState(false) const { data: resolvedDid, + isLoading: isDidLoading, error: resolveError, - isFetching: isFetchingDid, } = useResolveDidQuery(name) const { data, + isLoading: isFollowsLoading, isFetching, - isFetched, isFetchingNextPage, hasNextPage, fetchNextPage, - isError, error, refetch, } = useProfileFollowsQuery(resolvedDid) + const isError = React.useMemo( + () => !!resolveError || !!error, + [resolveError, error], + ) + + const isMe = React.useMemo(() => { + return resolvedDid === currentAccount?.did + }, [resolvedDid, currentAccount?.did]) + const follows = React.useMemo(() => { if (data?.pages) { return data.pages.flatMap(page => page.follows) } + return [] }, [data]) const onRefresh = React.useCallback(async () => { @@ -47,7 +73,7 @@ export function ProfileFollows({name}: {name: string}) { }, [refetch, setIsPTRing]) const onEndReached = async () => { - if (isFetching || !hasNextPage || isError) return + if (isFetching || !hasNextPage || !!error) return try { await fetchNextPage() } catch (err) { @@ -55,57 +81,38 @@ export function ProfileFollows({name}: {name: string}) { } } - const renderItem = React.useCallback( - ({item}: {item: ActorDefs.ProfileViewBasic}) => ( - <ProfileCardWithFollowBtn key={item.did} profile={item} /> - ), - [], - ) - - if (isFetchingDid || !isFetched) { - return <LoadingScreen /> - } - - // error - // = - if (resolveError || isError) { - return ( - <CenteredView> - <ErrorMessage - message={cleanError(resolveError || error)} - onPressTryAgain={onRefresh} - /> - </CenteredView> - ) - } - - // loaded - // = return ( - <List - data={follows} - keyExtractor={item => item.did} - refreshing={isPTRing} - onRefresh={onRefresh} - onEndReached={onEndReached} - renderItem={renderItem} - initialNumToRender={15} - // FIXME(dan) - // eslint-disable-next-line react/no-unstable-nested-components - ListFooterComponent={() => ( - <View style={styles.footer}> - {(isFetching || isFetchingNextPage) && <ActivityIndicator />} - </View> + <> + <ListMaybePlaceholder + isLoading={isDidLoading || isFollowsLoading} + isEmpty={follows.length < 1} + isError={isError} + emptyType="results" + emptyMessage={ + isMe + ? _(msg`You are not following anyone.`) + : _(msg`This user isn't following anyone.`) + } + errorMessage={cleanError(resolveError || error)} + onRetry={isError ? refetch : undefined} + /> + {follows.length > 0 && ( + <List + data={follows} + renderItem={renderItem} + keyExtractor={keyExtractor} + refreshing={isPTRing} + onRefresh={onRefresh} + onEndReached={onEndReached} + onEndReachedThreshold={4} + ListHeaderComponent={<ListHeaderDesktop title={_(msg`Following`)} />} + ListFooterComponent={<ListFooter isFetching={isFetchingNextPage} />} + // @ts-ignore our .web version only -prf + desktopFixedHeight + initialNumToRender={initialNumToRender} + windowSize={11} + /> )} - // @ts-ignore our .web version only -prf - desktopFixedHeight - /> + </> ) } - -const styles = StyleSheet.create({ - footer: { - height: 200, - paddingTop: 20, - }, -}) diff --git a/src/view/screens/ProfileFollowers.tsx b/src/view/screens/ProfileFollowers.tsx index 2cad08cb5d..6f8ecc2e8b 100644 --- a/src/view/screens/ProfileFollowers.tsx +++ b/src/view/screens/ProfileFollowers.tsx @@ -21,7 +21,7 @@ export const ProfileFollowersScreen = ({route}: Props) => { ) return ( - <View> + <View style={{flex: 1}}> <ViewHeader title={_(msg`Followers`)} /> <ProfileFollowersComponent name={name} /> </View> diff --git a/src/view/screens/ProfileFollows.tsx b/src/view/screens/ProfileFollows.tsx index 80502b98bc..bdab201535 100644 --- a/src/view/screens/ProfileFollows.tsx +++ b/src/view/screens/ProfileFollows.tsx @@ -21,7 +21,7 @@ export const ProfileFollowsScreen = ({route}: Props) => { ) return ( - <View> + <View style={{flex: 1}}> <ViewHeader title={_(msg`Following`)} /> <ProfileFollowsComponent name={name} /> </View> From dfe88e165696aeb222aa6d2bd5b7b94ed3eda3f6 Mon Sep 17 00:00:00 2001 From: Eric Bailey <git@esb.lol> Date: Tue, 19 Mar 2024 14:18:57 -0500 Subject: [PATCH 096/109] Use consistent avatar shape/defaults for labelers (#3257) * Add type: labeler to easy spots * Search and ProfileCard * Filter out of suggested follows * ComposeReplyTo * PReviewable avatar in posts * Lists * PostMeta * Notifications * Autocomplete * Straggler * Bump sdk --- package.json | 2 +- src/state/queries/actor-autocomplete.ts | 8 +------- src/state/shell/composer.tsx | 7 ++----- src/view/com/auth/login/ChooseAccountForm.tsx | 6 +++++- src/view/com/composer/Composer.tsx | 6 +++++- src/view/com/composer/ComposerReplyTo.tsx | 1 + src/view/com/composer/Prompt.tsx | 6 +++++- .../com/composer/text-input/mobile/Autocomplete.tsx | 6 +++++- src/view/com/composer/text-input/web/Autocomplete.tsx | 6 +++++- src/view/com/modals/ListAddRemoveUsers.tsx | 6 +++++- src/view/com/modals/SwitchAccount.tsx | 6 +++++- src/view/com/modals/UserAddRemoveLists.tsx | 2 +- src/view/com/notifications/FeedItem.tsx | 7 +++++++ src/view/com/post-thread/PostThreadItem.tsx | 8 +++----- src/view/com/post/Post.tsx | 7 ++----- src/view/com/posts/FeedItem.tsx | 7 ++----- src/view/com/profile/ProfileCard.tsx | 5 ++++- src/view/com/profile/ProfileHeaderSuggestedFollows.tsx | 8 +++++--- src/view/com/util/PostMeta.tsx | 10 +++------- src/view/screens/PostThread.tsx | 6 +----- src/view/screens/Search/Search.tsx | 1 + src/view/screens/Settings/index.tsx | 6 +++++- src/view/shell/Drawer.tsx | 1 + src/view/shell/bottom-bar/BottomBar.tsx | 2 ++ src/view/shell/desktop/LeftNav.tsx | 6 +++++- src/view/shell/desktop/Search.tsx | 1 + yarn.lock | 8 ++++---- 27 files changed, 87 insertions(+), 58 deletions(-) diff --git a/package.json b/package.json index bc2b62ec94..97fd91b03a 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "make-deploy-bundle": "bash scripts/bundleUpdate.sh" }, "dependencies": { - "@atproto/api": "^0.12.0", + "@atproto/api": "^0.12.1", "@bam.tech/react-native-image-resizer": "^3.0.4", "@braintree/sanitize-url": "^6.0.2", "@emoji-mart/react": "^1.1.1", diff --git a/src/state/queries/actor-autocomplete.ts b/src/state/queries/actor-autocomplete.ts index f14b3d65f1..e6bf04ba3d 100644 --- a/src/state/queries/actor-autocomplete.ts +++ b/src/state/queries/actor-autocomplete.ts @@ -101,13 +101,7 @@ function computeSuggestions( } for (const item of searched) { if (!items.find(item2 => item2.handle === item.handle)) { - items.push({ - did: item.did, - handle: item.handle, - displayName: item.displayName, - avatar: item.avatar, - labels: item.labels, - }) + items.push(item) } } return items.filter(profile => { diff --git a/src/state/shell/composer.tsx b/src/state/shell/composer.tsx index a09e8fba9f..5b4e505439 100644 --- a/src/state/shell/composer.tsx +++ b/src/state/shell/composer.tsx @@ -3,6 +3,7 @@ import { AppBskyEmbedRecord, AppBskyRichtextFacet, ModerationDecision, + AppBskyActorDefs, } from '@atproto/api' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' @@ -10,11 +11,7 @@ export interface ComposerOptsPostRef { uri: string cid: string text: string - author: { - handle: string - displayName?: string - avatar?: string - } + author: AppBskyActorDefs.ProfileViewBasic embed?: AppBskyEmbedRecord.ViewRecord['embed'] moderation?: ModerationDecision } diff --git a/src/view/com/auth/login/ChooseAccountForm.tsx b/src/view/com/auth/login/ChooseAccountForm.tsx index 32cd8315d3..d3b075fdb4 100644 --- a/src/view/com/auth/login/ChooseAccountForm.tsx +++ b/src/view/com/auth/login/ChooseAccountForm.tsx @@ -45,7 +45,11 @@ function AccountItem({ accessibilityHint={_(msg`Double tap to sign in`)}> <View style={[pal.borderDark, styles.groupContent, styles.noTopBorder]}> <View style={s.p10}> - <UserAvatar avatar={profile?.avatar} size={30} /> + <UserAvatar + avatar={profile?.avatar} + size={30} + type={profile?.associated?.labeler ? 'labeler' : 'user'} + /> </View> <Text style={styles.accountText}> <Text type="lg-bold" style={pal.text}> diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 0a2692d06c..ab7551b609 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -415,7 +415,11 @@ export const ComposePost = observer(function ComposePost({ styles.textInputLayout, isNative && styles.textInputLayoutMobile, ]}> - <UserAvatar avatar={currentProfile?.avatar} size={50} /> + <UserAvatar + avatar={currentProfile?.avatar} + size={50} + type={currentProfile?.associated?.labeler ? 'labeler' : 'user'} + /> <TextInput ref={textInput} richtext={richtext} diff --git a/src/view/com/composer/ComposerReplyTo.tsx b/src/view/com/composer/ComposerReplyTo.tsx index 4832bca02c..0c1b87d04d 100644 --- a/src/view/com/composer/ComposerReplyTo.tsx +++ b/src/view/com/composer/ComposerReplyTo.tsx @@ -87,6 +87,7 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { avatar={replyTo.author.avatar} size={50} moderation={replyTo.moderation?.ui('avatar')} + type={replyTo.author.associated?.labeler ? 'labeler' : 'user'} /> <View style={styles.replyToPost}> <Text type="xl-medium" style={[pal.text]}> diff --git a/src/view/com/composer/Prompt.tsx b/src/view/com/composer/Prompt.tsx index 632bb2634b..16d1b6fb9e 100644 --- a/src/view/com/composer/Prompt.tsx +++ b/src/view/com/composer/Prompt.tsx @@ -23,7 +23,11 @@ export function ComposePrompt({onPressCompose}: {onPressCompose: () => void}) { accessibilityRole="button" accessibilityLabel={_(msg`Compose reply`)} accessibilityHint={_(msg`Opens composer`)}> - <UserAvatar avatar={profile?.avatar} size={38} /> + <UserAvatar + avatar={profile?.avatar} + size={38} + type={profile?.associated?.labeler ? 'labeler' : 'user'} + /> <Text type="xl" style={[ diff --git a/src/view/com/composer/text-input/mobile/Autocomplete.tsx b/src/view/com/composer/text-input/mobile/Autocomplete.tsx index c400aa48d5..9c8f8f9162 100644 --- a/src/view/com/composer/text-input/mobile/Autocomplete.tsx +++ b/src/view/com/composer/text-input/mobile/Autocomplete.tsx @@ -78,7 +78,11 @@ export function Autocomplete({ accessibilityLabel={`Select ${item.handle}`} accessibilityHint=""> <View style={styles.avatarAndHandle}> - <UserAvatar avatar={item.avatar ?? null} size={24} /> + <UserAvatar + avatar={item.avatar ?? null} + size={24} + type={item.associated?.labeler ? 'labeler' : 'user'} + /> <Text type="md-medium" style={pal.text}> {displayName} </Text> diff --git a/src/view/com/composer/text-input/web/Autocomplete.tsx b/src/view/com/composer/text-input/web/Autocomplete.tsx index 76058fed34..29b8f0bc65 100644 --- a/src/view/com/composer/text-input/web/Autocomplete.tsx +++ b/src/view/com/composer/text-input/web/Autocomplete.tsx @@ -175,7 +175,11 @@ const MentionList = forwardRef<MentionListRef, SuggestionProps>( }} accessibilityRole="button"> <View style={styles.avatarAndDisplayName}> - <UserAvatar avatar={item.avatar ?? null} size={26} /> + <UserAvatar + avatar={item.avatar ?? null} + size={26} + type={item.associated?.labeler ? 'labeler' : 'user'} + /> <Text style={pal.text} numberOfLines={1}> {displayName} </Text> diff --git a/src/view/com/modals/ListAddRemoveUsers.tsx b/src/view/com/modals/ListAddRemoveUsers.tsx index 27c33f806c..4715348dd8 100644 --- a/src/view/com/modals/ListAddRemoveUsers.tsx +++ b/src/view/com/modals/ListAddRemoveUsers.tsx @@ -231,7 +231,11 @@ function UserResult({ width: 54, paddingLeft: 4, }}> - <UserAvatar size={40} avatar={profile.avatar} /> + <UserAvatar + size={40} + avatar={profile.avatar} + type={profile.associated?.labeler ? 'labeler' : 'user'} + /> </View> <View style={{ diff --git a/src/view/com/modals/SwitchAccount.tsx b/src/view/com/modals/SwitchAccount.tsx index c034c4b528..0658805bda 100644 --- a/src/view/com/modals/SwitchAccount.tsx +++ b/src/view/com/modals/SwitchAccount.tsx @@ -45,7 +45,11 @@ function SwitchAccountCard({account}: {account: SessionAccount}) { const contents = ( <View style={[pal.view, styles.linkCard]}> <View style={styles.avi}> - <UserAvatar size={40} avatar={profile?.avatar} /> + <UserAvatar + size={40} + avatar={profile?.avatar} + type={profile?.associated?.labeler ? 'labeler' : 'user'} + /> </View> <View style={[s.flex1]}> <Text type="md-bold" style={pal.text} numberOfLines={1}> diff --git a/src/view/com/modals/UserAddRemoveLists.tsx b/src/view/com/modals/UserAddRemoveLists.tsx index 8452f25133..8a61b1a707 100644 --- a/src/view/com/modals/UserAddRemoveLists.tsx +++ b/src/view/com/modals/UserAddRemoveLists.tsx @@ -180,7 +180,7 @@ function ListItem({ }, ]}> <View style={styles.listItemAvi}> - <UserAvatar size={40} avatar={list.avatar} /> + <UserAvatar size={40} avatar={list.avatar} type="list" /> </View> <View style={styles.listItemContent}> <Text diff --git a/src/view/com/notifications/FeedItem.tsx b/src/view/com/notifications/FeedItem.tsx index b165547904..78b1677c3d 100644 --- a/src/view/com/notifications/FeedItem.tsx +++ b/src/view/com/notifications/FeedItem.tsx @@ -14,6 +14,7 @@ import { ModerationDecision, moderateProfile, AppBskyEmbedRecordWithMedia, + AppBskyActorDefs, } from '@atproto/api' import {AtUri} from '@atproto/api' import { @@ -55,6 +56,7 @@ interface Author { displayName?: string avatar?: string moderation: ModerationDecision + associated?: AppBskyActorDefs.ProfileAssociated } let FeedItem = ({ @@ -100,6 +102,7 @@ let FeedItem = ({ displayName: item.notification.author.displayName, avatar: item.notification.author.avatar, moderation: moderateProfile(item.notification.author, moderationOpts), + associated: item.notification.author.associated, }, ...(item.additional?.map(({author}) => { return { @@ -109,6 +112,7 @@ let FeedItem = ({ displayName: author.displayName, avatar: author.avatar, moderation: moderateProfile(author, moderationOpts), + associated: author.associated, } }) || []), ] @@ -337,6 +341,7 @@ function CondensedAuthorsList({ handle={authors[0].handle} avatar={authors[0].avatar} moderation={authors[0].moderation.ui('avatar')} + type={authors[0].associated?.labeler ? 'labeler' : 'user'} /> </View> ) @@ -355,6 +360,7 @@ function CondensedAuthorsList({ size={35} avatar={author.avatar} moderation={author.moderation.ui('avatar')} + type={author.associated?.labeler ? 'labeler' : 'user'} /> </View> ))} @@ -413,6 +419,7 @@ function ExpandedAuthorsList({ size={35} avatar={author.avatar} moderation={author.moderation.ui('avatar')} + type={author.associated?.labeler ? 'labeler' : 'user'} /> </View> <View style={s.flex1}> diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index c073b55a07..ce4d8d9fa5 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -205,11 +205,7 @@ let PostThreadItemLoaded = ({ uri: post.uri, cid: post.cid, text: record.text, - author: { - handle: post.author.handle, - displayName: post.author.displayName, - avatar: post.author.avatar, - }, + author: post.author, embed: post.embed, moderation, }, @@ -256,6 +252,7 @@ let PostThreadItemLoaded = ({ handle={post.author.handle} avatar={post.author.avatar} moderation={moderation.ui('avatar')} + type={post.author.associated?.labeler ? 'labeler' : 'user'} /> </View> <View style={styles.layoutContent}> @@ -452,6 +449,7 @@ let PostThreadItemLoaded = ({ handle={post.author.handle} avatar={post.author.avatar} moderation={moderation.ui('avatar')} + type={post.author.associated?.labeler ? 'labeler' : 'user'} /> {showChildReplyLine && ( diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx index c7bd4ba2f0..47e46eb0cb 100644 --- a/src/view/com/post/Post.tsx +++ b/src/view/com/post/Post.tsx @@ -118,11 +118,7 @@ function PostInner({ uri: post.uri, cid: post.cid, text: record.text, - author: { - handle: post.author.handle, - displayName: post.author.displayName, - avatar: post.author.avatar, - }, + author: post.author, embed: post.embed, moderation, }, @@ -144,6 +140,7 @@ function PostInner({ handle={post.author.handle} avatar={post.author.avatar} moderation={moderation.ui('avatar')} + type={post.author.associated?.labeler ? 'labeler' : 'user'} /> </View> <View style={styles.layoutContent}> diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx index 0706ddb9b8..0fbcc4a13c 100644 --- a/src/view/com/posts/FeedItem.tsx +++ b/src/view/com/posts/FeedItem.tsx @@ -126,11 +126,7 @@ let FeedItemInner = ({ uri: post.uri, cid: post.cid, text: record.text || '', - author: { - handle: post.author.handle, - displayName: post.author.displayName, - avatar: post.author.avatar, - }, + author: post.author, embed: post.embed, moderation, }, @@ -243,6 +239,7 @@ let FeedItemInner = ({ handle={post.author.handle} avatar={post.author.avatar} moderation={moderation.ui('avatar')} + type={post.author.associated?.labeler ? 'labeler' : 'user'} /> {isThreadParent && ( <View diff --git a/src/view/com/profile/ProfileCard.tsx b/src/view/com/profile/ProfileCard.tsx index d909bda858..235139fff0 100644 --- a/src/view/com/profile/ProfileCard.tsx +++ b/src/view/com/profile/ProfileCard.tsx @@ -49,6 +49,7 @@ export function ProfileCard({ const pal = usePalette('default') const profile = useProfileShadow(profileUnshadowed) const moderationOpts = useModerationOpts() + const isLabeler = profile?.associated?.labeler if (!moderationOpts) { return null } @@ -79,6 +80,7 @@ export function ProfileCard({ size={40} avatar={profile.avatar} moderation={moderation.ui('avatar')} + type={isLabeler ? 'labeler' : 'user'} /> </View> <View style={styles.layoutContent}> @@ -101,7 +103,7 @@ export function ProfileCard({ /> {!!profile.viewer?.followedBy && <View style={s.flexRow} />} </View> - {renderButton ? ( + {renderButton && !isLabeler ? ( <View style={styles.layoutButton}>{renderButton(profile)}</View> ) : undefined} </View> @@ -223,6 +225,7 @@ function FollowersList({ avatar={f.avatar} size={32} moderation={mod.ui('avatar')} + type={f.associated?.labeler ? 'labeler' : 'user'} /> </View> </View> diff --git a/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx b/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx index 947d6e9cc6..a22866b8c9 100644 --- a/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx +++ b/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx @@ -98,9 +98,11 @@ export function ProfileHeaderSuggestedFollows({ <SuggestedFollowSkeleton /> </> ) : data ? ( - data.suggestions.map(profile => ( - <SuggestedFollow key={profile.did} profile={profile} /> - )) + data.suggestions + .filter(s => (s.associated?.labeler ? false : true)) + .map(profile => ( + <SuggestedFollow key={profile.did} profile={profile} /> + )) ) : ( <View /> )} diff --git a/src/view/com/util/PostMeta.tsx b/src/view/com/util/PostMeta.tsx index 53dc20e714..529fc54e01 100644 --- a/src/view/com/util/PostMeta.tsx +++ b/src/view/com/util/PostMeta.tsx @@ -11,16 +11,11 @@ import {sanitizeHandle} from 'lib/strings/handles' import {isAndroid, isWeb} from 'platform/detection' import {TimeElapsed} from './TimeElapsed' import {makeProfileLink} from 'lib/routes/links' -import {ModerationDecision, ModerationUI} from '@atproto/api' +import {AppBskyActorDefs, ModerationDecision, ModerationUI} from '@atproto/api' import {usePrefetchProfileQuery} from '#/state/queries/profile' interface PostMetaOpts { - author: { - avatar?: string - did: string - handle: string - displayName?: string | undefined - } + author: AppBskyActorDefs.ProfileViewBasic moderation: ModerationDecision | undefined authorHasWarning: boolean postHref: string @@ -47,6 +42,7 @@ let PostMeta = (opts: PostMetaOpts): React.ReactNode => { avatar={opts.author.avatar} size={opts.avatarSize || 16} moderation={opts.avatarModeration} + type={opts.author.associated?.labeler ? 'labeler' : 'user'} /> </View> )} diff --git a/src/view/screens/PostThread.tsx b/src/view/screens/PostThread.tsx index aa09ab9ed7..ba1fa130ee 100644 --- a/src/view/screens/PostThread.tsx +++ b/src/view/screens/PostThread.tsx @@ -59,11 +59,7 @@ export function PostThreadScreen({route}: Props) { uri: thread.post.uri, cid: thread.post.cid, text: thread.record.text, - author: { - handle: thread.post.author.handle, - displayName: thread.post.author.displayName, - avatar: thread.post.author.avatar, - }, + author: thread.post.author, embed: thread.post.embed, }, onPost: () => diff --git a/src/view/screens/Search/Search.tsx b/src/view/screens/Search/Search.tsx index 42eec53d31..326e1e5551 100644 --- a/src/view/screens/Search/Search.tsx +++ b/src/view/screens/Search/Search.tsx @@ -141,6 +141,7 @@ function SearchScreenSuggestedFollows() { friends.slice(0, 4).map(friend => getSuggestedFollowsByActor(friend.did).then(foafsRes => { for (const user of foafsRes.suggestions) { + if (user.associated?.labeler) continue friendsOfFriends.set(user.did, user) } }), diff --git a/src/view/screens/Settings/index.tsx b/src/view/screens/Settings/index.tsx index 21225f5813..74fc5d3c97 100644 --- a/src/view/screens/Settings/index.tsx +++ b/src/view/screens/Settings/index.tsx @@ -82,7 +82,11 @@ function SettingsAccountCard({account}: {account: SessionAccount}) { const contents = ( <View style={[pal.view, styles.linkCard]}> <View style={styles.avi}> - <UserAvatar size={40} avatar={profile?.avatar} /> + <UserAvatar + size={40} + avatar={profile?.avatar} + type={profile?.associated?.labeler ? 'labeler' : 'user'} + /> </View> <View style={[s.flex1]}> <Text type="md-bold" style={pal.text}> diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx index 2a37d1fe96..d2dd67dcbc 100644 --- a/src/view/shell/Drawer.tsx +++ b/src/view/shell/Drawer.tsx @@ -75,6 +75,7 @@ let DrawerProfileCard = ({ avatar={profile?.avatar} // See https://github.com/bluesky-social/social-app/pull/1801: usePlainRNImage={true} + type={profile?.associated?.labeler ? 'labeler' : 'user'} /> <Text type="title-lg" diff --git a/src/view/shell/bottom-bar/BottomBar.tsx b/src/view/shell/bottom-bar/BottomBar.tsx index 115faa2965..8a19a0b4fe 100644 --- a/src/view/shell/bottom-bar/BottomBar.tsx +++ b/src/view/shell/bottom-bar/BottomBar.tsx @@ -229,6 +229,7 @@ export function BottomBar({navigation}: BottomTabBarProps) { size={27} // See https://github.com/bluesky-social/social-app/pull/1801: usePlainRNImage={true} + type={profile?.associated?.labeler ? 'labeler' : 'user'} /> </View> ) : ( @@ -238,6 +239,7 @@ export function BottomBar({navigation}: BottomTabBarProps) { size={28} // See https://github.com/bluesky-social/social-app/pull/1801: usePlainRNImage={true} + type={profile?.associated?.labeler ? 'labeler' : 'user'} /> </View> )} diff --git a/src/view/shell/desktop/LeftNav.tsx b/src/view/shell/desktop/LeftNav.tsx index c56ba941ed..097ca2fbfb 100644 --- a/src/view/shell/desktop/LeftNav.tsx +++ b/src/view/shell/desktop/LeftNav.tsx @@ -64,7 +64,11 @@ function ProfileCard() { style={[styles.profileCard, !isDesktop && styles.profileCardTablet]} title={_(msg`My Profile`)} asAnchor> - <UserAvatar avatar={profile.avatar} size={size} /> + <UserAvatar + avatar={profile.avatar} + size={size} + type={profile?.associated?.labeler ? 'labeler' : 'user'} + /> </Link> ) : ( <View style={[styles.profileCard, !isDesktop && styles.profileCardTablet]}> diff --git a/src/view/shell/desktop/Search.tsx b/src/view/shell/desktop/Search.tsx index 8933324eed..0c5bd452fa 100644 --- a/src/view/shell/desktop/Search.tsx +++ b/src/view/shell/desktop/Search.tsx @@ -112,6 +112,7 @@ export function SearchProfileCard({ size={40} avatar={profile.avatar} moderation={moderation.ui('avatar')} + type={profile.associated?.labeler ? 'labeler' : 'user'} /> <View style={{flex: 1}}> <Text diff --git a/yarn.lock b/yarn.lock index 266734cdc1..e9783d786b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,10 +34,10 @@ jsonpointer "^5.0.0" leven "^3.1.0" -"@atproto/api@^0.12.0": - version "0.12.0" - resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.0.tgz#69e52f8761dc7d76c675fa7284bd49240bb0df64" - integrity sha512-nSWiad1Z6IC/oVFSVxD5gZLhkD+J4EW2CFqAqIhklJNc0cjFKdmf8D56Pac6Ktm1sJoM6TVZ8GEeuEG6bJS/aQ== +"@atproto/api@^0.12.1": + version "0.12.1" + resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.1.tgz#3340cbbd6a51a8c2f3248dae55a01415ab71084e" + integrity sha512-Grigs9neuQxytXr2yHq/IfNlgXQVptWDO9KTQr5FDmgMY4Zly2X7Sa99u9c1CW9auwUTbcd+yRFBNEtbA3n3qg== dependencies: "@atproto/common-web" "^0.3.0" "@atproto/lexicon" "^0.4.0" From dac73cbeea3c346c255eec15d08bd9c585263bec Mon Sep 17 00:00:00 2001 From: Minseo Lee <itoupluk427@gmail.com> Date: Wed, 20 Mar 2024 04:24:23 +0900 Subject: [PATCH 097/109] Update Korean localization (#2769) * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update src/locale/locales/ko/messages.po Co-authored-by: Lens0021 / Leslie <lorentz0021@gmail.com> * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update messages.po --------- Co-authored-by: Lens0021 / Leslie <lorentz0021@gmail.com> Co-authored-by: Daniel S. Park <soohan@heartade.dev> --- src/locale/locales/ko/messages.po | 2413 ++++++++++++++++------------- 1 file changed, 1348 insertions(+), 1065 deletions(-) diff --git a/src/locale/locales/ko/messages.po b/src/locale/locales/ko/messages.po index a4c05239fa..28059c3edf 100644 --- a/src/locale/locales/ko/messages.po +++ b/src/locale/locales/ko/messages.po @@ -9,45 +9,27 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: \n" -"Last-Translator: quiple\n" -"Language-Team: quiple, lens0021, HaruChanHeart, hazzzi\n" +"Last-Translator: heartade\n" +"Language-Team: quiple, lens0021, HaruChanHeart, hazzzi, heartade\n" "Plural-Forms: \n" #: src/view/com/modals/VerifyEmail.tsx:142 msgid "(no email)" msgstr "(이메일 없음)" -#: src/view/shell/desktop/RightNav.tsx:168 -#~ msgid "{0, plural, one {# invite code available} other {# invite codes available}}" -#~ msgstr "{0, plural, one {초대 코드 #개 사용 가능} other {초대 코드 #개 사용 가능}}" - -#: src/view/com/profile/ProfileHeader.tsx:593 +#: src/screens/Profile/Header/Metrics.tsx:45 msgid "{following} following" msgstr "{following} 팔로우 중" -#: src/view/shell/desktop/RightNav.tsx:151 -#~ msgid "{invitesAvailable, plural, one {Invite codes: # available} other {Invite codes: # available}}" -#~ msgstr "{invitesAvailable, plural, one {초대 코드: #개 사용 가능} other {초대 코드: #개 사용 가능}}" - -#: src/view/screens/Settings.tsx:435 -#: src/view/shell/Drawer.tsx:664 -#~ msgid "{invitesAvailable} invite code available" -#~ msgstr "초대 코드 {invitesAvailable}개 사용 가능" - -#: src/view/screens/Settings.tsx:437 -#: src/view/shell/Drawer.tsx:666 -#~ msgid "{invitesAvailable} invite codes available" -#~ msgstr "초대 코드 {invitesAvailable}개 사용 가능" - #: src/view/shell/Drawer.tsx:440 msgid "{numUnreadNotifications} unread" msgstr "{numUnreadNotifications}개 읽지 않음" #: src/view/com/threadgate/WhoCanReply.tsx:158 msgid "<0/> members" -msgstr "<0/> 멤버" +msgstr "<0/>의 멤버" -#: src/view/com/profile/ProfileHeader.tsx:595 +#: src/screens/Profile/Header/Metrics.tsx:46 msgid "<0>{following} </0><1>following</1>" msgstr "<0>{following} </0><1>팔로우 중</1>" @@ -63,18 +45,10 @@ msgstr "<1>추천 사용자</1><0>팔로우하기</0>" msgid "<0>Welcome to</0><1>Bluesky</1>" msgstr "<1>Bluesky</1><0>에 오신 것을 환영합니다</0>" -#: src/view/com/profile/ProfileHeader.tsx:558 +#: src/screens/Profile/Header/Handle.tsx:42 msgid "⚠Invalid Handle" msgstr "⚠ 잘못된 핸들" -#: src/view/com/util/moderation/LabelInfo.tsx:45 -msgid "A content warning has been applied to this {0}." -msgstr "이 {0}에 콘텐츠 경고가 적용되었습니다." - -#: src/lib/hooks/useOTAUpdate.ts:16 -msgid "A new version of the app is available. Please update to continue using the app." -msgstr "새 버전의 앱을 사용할 수 있습니다. 앱을 계속 사용하려면 업데이트하세요." - #: src/view/com/util/ViewHeader.tsx:89 #: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" @@ -85,29 +59,38 @@ msgid "Access profile and other navigation links" msgstr "프로필 및 기타 탐색 링크로 이동합니다" #: src/view/com/modals/EditImage.tsx:299 -#: src/view/screens/Settings/index.tsx:451 +#: src/view/screens/Settings/index.tsx:469 msgid "Accessibility" msgstr "접근성" +#: src/components/moderation/LabelsOnMe.tsx:42 +msgid "account" +msgstr "계정" + #: src/view/com/auth/login/LoginForm.tsx:166 -#: src/view/screens/Settings/index.tsx:308 -#: src/view/screens/Settings/index.tsx:721 +#: src/view/screens/Settings/index.tsx:326 +#: src/view/screens/Settings/index.tsx:739 msgid "Account" msgstr "계정" -#: src/view/com/profile/ProfileHeader.tsx:246 +#: src/view/com/profile/ProfileMenu.tsx:139 msgid "Account blocked" msgstr "계정 차단됨" -#: src/view/com/profile/ProfileHeader.tsx:213 +#: src/view/com/profile/ProfileMenu.tsx:153 +msgid "Account followed" +msgstr "계정 팔로우함" + +#: src/view/com/profile/ProfileMenu.tsx:113 msgid "Account muted" msgstr "계정 뮤트됨" -#: src/view/com/modals/ModerationDetails.tsx:86 +#: src/components/moderation/ModerationDetailsDialog.tsx:94 +#: src/lib/moderation/useModerationCauseDescription.ts:91 msgid "Account Muted" msgstr "계정 뮤트됨" -#: src/view/com/modals/ModerationDetails.tsx:72 +#: src/components/moderation/ModerationDetailsDialog.tsx:83 msgid "Account Muted by List" msgstr "리스트로 계정 뮤트됨" @@ -119,11 +102,16 @@ msgstr "계정 옵션" msgid "Account removed from quick access" msgstr "빠른 액세스에서 계정 제거" -#: src/view/com/profile/ProfileHeader.tsx:268 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:130 +#: src/view/com/profile/ProfileMenu.tsx:128 msgid "Account unblocked" msgstr "계정 차단 해제됨" -#: src/view/com/profile/ProfileHeader.tsx:226 +#: src/view/com/profile/ProfileMenu.tsx:166 +msgid "Account unfollowed" +msgstr "계정 언팔로우함" + +#: src/view/com/profile/ProfileMenu.tsx:102 msgid "Account unmuted" msgstr "계정 언뮤트됨" @@ -131,7 +119,7 @@ msgstr "계정 언뮤트됨" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/UserAddRemoveLists.tsx:219 -#: src/view/screens/ProfileList.tsx:813 +#: src/view/screens/ProfileList.tsx:827 msgid "Add" msgstr "추가" @@ -139,12 +127,12 @@ msgstr "추가" msgid "Add a content warning" msgstr "콘텐츠 경고 추가" -#: src/view/screens/ProfileList.tsx:803 +#: src/view/screens/ProfileList.tsx:817 msgid "Add a user to this list" msgstr "이 리스트에 사용자 추가" -#: src/view/screens/Settings/index.tsx:383 -#: src/view/screens/Settings/index.tsx:392 +#: src/view/screens/Settings/index.tsx:401 +#: src/view/screens/Settings/index.tsx:410 msgid "Add account" msgstr "계정 추가" @@ -154,47 +142,38 @@ msgstr "계정 추가" msgid "Add alt text" msgstr "대체 텍스트 추가하기" -#: src/view/screens/AppPasswords.tsx:102 -#: src/view/screens/AppPasswords.tsx:143 -#: src/view/screens/AppPasswords.tsx:156 +#: src/view/screens/AppPasswords.tsx:104 +#: src/view/screens/AppPasswords.tsx:145 +#: src/view/screens/AppPasswords.tsx:158 msgid "Add App Password" msgstr "앱 비밀번호 추가" -#: src/view/com/modals/report/InputIssueDetails.tsx:41 -#: src/view/com/modals/report/Modal.tsx:191 -msgid "Add details" -msgstr "세부 정보 추가" - -#: src/view/com/modals/report/Modal.tsx:194 -msgid "Add details to report" -msgstr "신고 세부 정보 추가" - -#: src/view/com/composer/Composer.tsx:453 +#: src/view/com/composer/Composer.tsx:462 msgid "Add link card" msgstr "링크 카드 추가" -#: src/view/com/composer/Composer.tsx:458 +#: src/view/com/composer/Composer.tsx:467 msgid "Add link card:" msgstr "링크 카드 추가:" #: src/components/dialogs/MutedWords.tsx:158 msgid "Add mute word for configured settings" -msgstr "" +msgstr "구성 설정에 뮤트 단어 추가" #: src/components/dialogs/MutedWords.tsx:87 msgid "Add muted words and tags" -msgstr "" +msgstr "뮤트할 단어 및 태그 추가" #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" msgstr "도메인에 다음 DNS 레코드를 추가하세요:" -#: src/view/com/profile/ProfileHeader.tsx:310 +#: src/view/com/profile/ProfileMenu.tsx:263 +#: src/view/com/profile/ProfileMenu.tsx:266 msgid "Add to Lists" msgstr "리스트에 추가" -#: src/view/com/feeds/FeedSourceCard.tsx:245 -#: src/view/screens/ProfileFeed.tsx:273 +#: src/view/com/feeds/FeedSourceCard.tsx:234 msgid "Add to my feeds" msgstr "내 피드에 추가" @@ -207,34 +186,35 @@ msgstr "추가됨" msgid "Added to list" msgstr "리스트에 추가됨" -#: src/view/com/feeds/FeedSourceCard.tsx:127 +#: src/view/com/feeds/FeedSourceCard.tsx:108 msgid "Added to my feeds" msgstr "내 피드에 추가됨" #: src/view/screens/PreferencesFollowingFeed.tsx:173 msgid "Adjust the number of likes a reply must have to be shown in your feed." -msgstr "답글이 피드에 표시되기 위해 필요한 좋아요 표시 수를 조정합니다." +msgstr "답글이 피드에 표시되기 위해 필요한 좋아요 수를 조정합니다." #: src/view/com/modals/SelfLabel.tsx:75 msgid "Adult Content" msgstr "성인 콘텐츠" -#: src/view/com/modals/ContentFilteringSettings.tsx:141 -msgid "Adult content can only be enabled via the Web at <0/>." -msgstr "성인 콘텐츠는 <0/>에서 웹을 통해서만 활성화할 수 있습니다." +#: src/components/moderation/ModerationLabelPref.tsx:102 +msgid "Adult content is disabled." +msgstr "성인 콘텐츠가 비활성화되어 있습니다." -#: src/view/screens/Settings/index.tsx:664 +#: src/screens/Moderation/index.tsx:383 +#: src/view/screens/Settings/index.tsx:682 msgid "Advanced" msgstr "고급" #: src/view/screens/Feeds.tsx:666 msgid "All the feeds you've saved, right in one place." -msgstr "" +msgstr "저장한 모든 피드를 한 곳에서 확인하세요." #: src/view/com/auth/login/ForgotPasswordForm.tsx:221 #: src/view/com/modals/ChangePassword.tsx:168 msgid "Already have a code?" -msgstr "" +msgstr "이미 코드가 있나요?" #: src/view/com/auth/login/ChooseAccountForm.tsx:98 msgid "Already signed in as @{0}" @@ -260,12 +240,16 @@ msgstr "{0}(으)로 이메일을 보냈습니다. 이 이메일에는 아래에 msgid "An email has been sent to your previous address, {0}. It includes a confirmation code which you can enter below." msgstr "이전 주소인 {0}(으)로 이메일을 보냈습니다. 이 이메일에는 아래에 입력하는 확인 코드가 포함되어 있습니다." -#: src/view/com/profile/FollowButton.tsx:30 -#: src/view/com/profile/FollowButton.tsx:40 +#: src/lib/moderation/useReportOptions.ts:26 +msgid "An issue not included in these options" +msgstr "어떤 옵션에도 포함되지 않는 문제" + +#: src/view/com/profile/FollowButton.tsx:35 +#: src/view/com/profile/FollowButton.tsx:45 msgid "An issue occurred, please try again." msgstr "문제가 발생했습니다. 다시 시도해 주세요." -#: src/view/com/notifications/FeedItem.tsx:237 +#: src/view/com/notifications/FeedItem.tsx:236 #: src/view/com/threadgate/WhoCanReply.tsx:178 msgid "and" msgstr "및" @@ -274,11 +258,15 @@ msgstr "및" msgid "Animals" msgstr "동물" +#: src/lib/moderation/useReportOptions.ts:31 +msgid "Anti-Social Behavior" +msgstr "반사회적 행위" + #: src/view/screens/LanguageSettings.tsx:95 msgid "App Language" msgstr "앱 언어" -#: src/view/screens/AppPasswords.tsx:228 +#: src/view/screens/AppPasswords.tsx:223 msgid "App password deleted" msgstr "앱 비밀번호 삭제됨" @@ -290,58 +278,49 @@ msgstr "앱 비밀번호 이름에는 문자, 숫자, 공백, 대시, 밑줄만 msgid "App Password names must be at least 4 characters long." msgstr "앱 비밀번호 이름은 4자 이상이어야 합니다." -#: src/view/screens/Settings/index.tsx:675 +#: src/view/screens/Settings/index.tsx:693 msgid "App password settings" msgstr "앱 비밀번호 설정" -#: src/view/screens/Settings.tsx:650 -#~ msgid "App passwords" -#~ msgstr "앱 비밀번호" - -#: src/Navigation.tsx:239 -#: src/view/screens/AppPasswords.tsx:187 -#: src/view/screens/Settings/index.tsx:684 +#: src/Navigation.tsx:251 +#: src/view/screens/AppPasswords.tsx:189 +#: src/view/screens/Settings/index.tsx:702 msgid "App Passwords" msgstr "앱 비밀번호" -#: src/view/com/util/forms/PostDropdownBtn.tsx:337 -#: src/view/com/util/forms/PostDropdownBtn.tsx:346 -msgid "Appeal content warning" -msgstr "콘텐츠 경고 이의신청" +#: src/components/moderation/LabelsOnMeDialog.tsx:134 +#: src/components/moderation/LabelsOnMeDialog.tsx:137 +msgid "Appeal" +msgstr "이의신청" -#: src/view/com/modals/AppealLabel.tsx:65 -msgid "Appeal Content Warning" -msgstr "콘텐츠 경고 이의신청" +#: src/components/moderation/LabelsOnMeDialog.tsx:202 +msgid "Appeal \"{0}\" label" +msgstr "\"{0}\" 라벨 이의신청" -#: src/view/com/util/moderation/LabelInfo.tsx:52 -msgid "Appeal this decision" -msgstr "이 결정에 이의신청" +#: src/components/moderation/LabelsOnMeDialog.tsx:193 +msgid "Appeal submitted." +msgstr "이의신청 제출함" -#: src/view/com/util/moderation/LabelInfo.tsx:56 -msgid "Appeal this decision." -msgstr "이 결정에 이의신청합니다." - -#: src/view/screens/Settings/index.tsx:466 +#: src/view/screens/Settings/index.tsx:484 msgid "Appearance" msgstr "모양" -#: src/view/screens/AppPasswords.tsx:224 +#: src/view/screens/AppPasswords.tsx:265 msgid "Are you sure you want to delete the app password \"{name}\"?" msgstr "앱 비밀번호 \"{name}\"을(를) 삭제하시겠습니까?" -#: src/view/com/composer/Composer.tsx:150 +#: src/view/com/feeds/FeedSourceCard.tsx:280 +msgid "Are you sure you want to remove {0} from your feeds?" +msgstr "피드에서 {0}을(를) 제거하시겠습니까?" + +#: src/view/com/composer/Composer.tsx:504 msgid "Are you sure you'd like to discard this draft?" msgstr "이 초안을 삭제하시겠습니까?" #: src/components/dialogs/MutedWords.tsx:282 -#: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" msgstr "정말인가요?" -#: src/view/com/util/forms/PostDropdownBtn.tsx:322 -msgid "Are you sure? This cannot be undone." -msgstr "정말인가요? 되돌릴 수 없습니다." - #: src/view/com/composer/select-language/SuggestedLanguage.tsx:60 msgid "Are you writing in <0>{0}</0>?" msgstr "{0}(으)로 쓰고 있나요?" @@ -354,21 +333,22 @@ msgstr "예술" msgid "Artistic or non-erotic nudity." msgstr "선정적이지 않거나 예술적인 노출." +#: src/components/moderation/LabelsOnMeDialog.tsx:247 +#: src/components/moderation/LabelsOnMeDialog.tsx:248 +#: src/screens/Profile/Header/Shell.tsx:97 #: src/view/com/auth/create/CreateAccount.tsx:158 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 #: src/view/com/auth/login/ForgotPasswordForm.tsx:174 #: src/view/com/auth/login/LoginForm.tsx:259 #: src/view/com/auth/login/SetNewPasswordForm.tsx:179 -#: src/view/com/modals/report/InputIssueDetails.tsx:46 -#: src/view/com/post-thread/PostThread.tsx:472 -#: src/view/com/post-thread/PostThread.tsx:522 -#: src/view/com/post-thread/PostThread.tsx:530 -#: src/view/com/profile/ProfileHeader.tsx:649 +#: src/view/com/post-thread/PostThread.tsx:473 +#: src/view/com/post-thread/PostThread.tsx:523 +#: src/view/com/post-thread/PostThread.tsx:531 #: src/view/com/util/ViewHeader.tsx:87 msgid "Back" msgstr "뒤로" -#: src/view/com/post-thread/PostThread.tsx:480 +#: src/view/com/post-thread/PostThread.tsx:481 msgctxt "action" msgid "Back" msgstr "뒤로" @@ -377,55 +357,61 @@ msgstr "뒤로" msgid "Based on your interest in {interestsText}" msgstr "{interestsText}에 대한 관심사 기반" -#: src/view/screens/Settings/index.tsx:523 +#: src/view/screens/Settings/index.tsx:541 msgid "Basics" msgstr "기본" +#: src/components/dialogs/BirthDateSettings.tsx:101 #: src/view/com/auth/create/Step1.tsx:227 -#: src/view/com/modals/BirthDateSettings.tsx:73 msgid "Birthday" msgstr "생년월일" -#: src/view/screens/Settings/index.tsx:340 +#: src/view/screens/Settings/index.tsx:358 msgid "Birthday:" msgstr "생년월일:" -#: src/view/com/profile/ProfileHeader.tsx:239 -#: src/view/com/profile/ProfileHeader.tsx:346 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:278 +#: src/view/com/profile/ProfileMenu.tsx:361 +msgid "Block" +msgstr "차단" + +#: src/view/com/profile/ProfileMenu.tsx:300 +#: src/view/com/profile/ProfileMenu.tsx:307 msgid "Block Account" msgstr "계정 차단" -#: src/view/screens/ProfileList.tsx:556 +#: src/view/com/profile/ProfileMenu.tsx:344 +msgid "Block Account?" +msgstr "계정을 차단하시겠습니까?" + +#: src/view/screens/ProfileList.tsx:530 msgid "Block accounts" msgstr "계정 차단" -#: src/view/screens/ProfileList.tsx:506 +#: src/view/screens/ProfileList.tsx:478 +#: src/view/screens/ProfileList.tsx:634 msgid "Block list" msgstr "리스트 차단" -#: src/view/screens/ProfileList.tsx:316 +#: src/view/screens/ProfileList.tsx:629 msgid "Block these accounts?" msgstr "이 계정들을 차단하시겠습니까?" -#: src/view/screens/ProfileList.tsx:320 -msgid "Block this List" -msgstr "이 리스트 차단" - #: src/view/com/lists/ListCard.tsx:110 -#: src/view/com/util/post-embeds/QuoteEmbed.tsx:61 +#: src/view/com/util/post-embeds/QuoteEmbed.tsx:55 msgid "Blocked" msgstr "차단됨" -#: src/view/screens/Moderation.tsx:142 +#: src/screens/Moderation/index.tsx:270 msgid "Blocked accounts" msgstr "차단한 계정" -#: src/Navigation.tsx:132 +#: src/Navigation.tsx:134 #: src/view/screens/ModerationBlockedAccounts.tsx:107 msgid "Blocked Accounts" msgstr "차단한 계정" -#: src/view/com/profile/ProfileHeader.tsx:241 +#: src/view/com/profile/ProfileMenu.tsx:356 msgid "Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you." msgstr "차단한 계정은 내 스레드에 답글을 달거나 나를 멘션하거나 기타 다른 방식으로 나와 상호작용할 수 없습니다." @@ -433,14 +419,22 @@ msgstr "차단한 계정은 내 스레드에 답글을 달거나 나를 멘션 msgid "Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you. You will not see their content and they will be prevented from seeing yours." msgstr "차단한 계정은 내 스레드에 답글을 달거나 나를 멘션하거나 기타 다른 방식으로 나와 상호작용할 수 없습니다. 차단한 계정의 콘텐츠를 볼 수 없으며 해당 계정도 내 콘텐츠를 볼 수 없게 됩니다." -#: src/view/com/post-thread/PostThread.tsx:324 +#: src/view/com/post-thread/PostThread.tsx:325 msgid "Blocked post." msgstr "차단된 게시물." -#: src/view/screens/ProfileList.tsx:318 +#: src/screens/Profile/Sections/Labels.tsx:171 +msgid "Blocking does not prevent this labeler from placing labels on your account." +msgstr "차단하더라도 이 라벨러가 내 계정에 라벨을 붙이는 것을 막지는 못합니다." + +#: src/view/screens/ProfileList.tsx:631 msgid "Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you." msgstr "차단 목록은 공개됩니다. 차단한 계정은 내 스레드에 답글을 달거나 나를 멘션하거나 기타 다른 방식으로 나와 상호작용할 수 없습니다." +#: src/view/com/profile/ProfileMenu.tsx:353 +msgid "Blocking will not prevent labels from being applied on your account, but it will stop this account from replying in your threads or interacting with you." +msgstr "차단하더라도 내 계정에 라벨이 붙는 것은 막지 못하지만, 이 계정이 내 스레드에 답글을 달거나 나와 상호작용하는 것은 중지됩니다." + #: src/view/com/auth/HomeLoggedOutCTA.tsx:93 #: src/view/com/auth/SplashScreen.web.tsx:133 msgid "Blog" @@ -454,7 +448,7 @@ msgstr "Bluesky" #: src/view/com/auth/server-input/index.tsx:150 msgid "Bluesky is an open network where you can choose your hosting provider. Custom hosting is now available in beta for developers." -msgstr "" +msgstr "Bluesky는 호스팅 제공자를 선택할 수 있는 개방형 네트워크입니다. 개발자를 위한 사용자 지정 호스팅이 베타 버전으로 제공됩니다." #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:80 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:80 @@ -471,23 +465,23 @@ msgstr "Bluesky는 열려 있습니다." msgid "Bluesky is public." msgstr "Bluesky는 공개적입니다." -#: src/view/com/modals/Waitlist.tsx:70 -#~ msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." -#~ msgstr "Bluesky는 더 건강한 커뮤니티를 구축하기 위해 초대 방식을 사용합니다. 초대해 준 사람이 없는 경우 대기자 명단에 등록하면 곧 초대를 보내겠습니다." - -#: src/view/screens/Moderation.tsx:245 +#: src/screens/Moderation/index.tsx:539 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "로그아웃한 사용자에게 내 프로필과 게시물을 표시하지 않습니다. 다른 앱에서는 이 설정을 따르지 않을 수 있습니다. 내 계정을 비공개로 전환하지는 않습니다." -#: src/view/com/modals/ServerInput.tsx:78 -#~ msgid "Bluesky.Social" -#~ msgstr "Bluesky.Social" +#: src/lib/moderation/useLabelBehaviorDescription.ts:53 +msgid "Blur images" +msgstr "이미지 흐리게" + +#: src/lib/moderation/useLabelBehaviorDescription.ts:51 +msgid "Blur images and filter from feeds" +msgstr "이미지 흐리게 및 피드에서 필터링" #: src/screens/Onboarding/index.tsx:33 msgid "Books" msgstr "책" -#: src/view/screens/Settings/index.tsx:859 +#: src/view/screens/Settings/index.tsx:887 msgid "Build version {0} {1}" msgstr "빌드 버전 {0} {1}" @@ -496,18 +490,18 @@ msgstr "빌드 버전 {0} {1}" msgid "Business" msgstr "비즈니스" -#: src/view/com/modals/ServerInput.tsx:115 -#~ msgid "Button disabled. Input custom domain to proceed." -#~ msgstr "버튼이 비활성화되었습니다. 계속하려면 사용자 지정 도메인을 입력하세요" - #: src/view/com/profile/ProfileSubpageHeader.tsx:157 msgid "by —" -msgstr "—" +msgstr "— 님이 만듦" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:100 msgid "by {0}" msgstr "{0} 님이 만듦" +#: src/components/LabelingServiceCard/index.tsx:57 +msgid "By {0}" +msgstr "{0} 님이 만듦" + #: src/view/com/profile/ProfileSubpageHeader.tsx:161 msgid "by <0/>" msgstr "<0/> 님이 만듦" @@ -516,9 +510,7 @@ msgstr "<0/> 님이 만듦" msgid "by you" msgstr "내가 만듦" -#: src/view/com/composer/photos/OpenCameraBtn.tsx:60 -#: src/view/com/util/UserAvatar.tsx:224 -#: src/view/com/util/UserBanner.tsx:40 +#: src/view/com/composer/photos/OpenCameraBtn.tsx:77 msgid "Camera" msgstr "카메라" @@ -526,9 +518,10 @@ msgstr "카메라" msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must be at least 4 characters long, but no more than 32 characters long." msgstr "글자, 숫자, 공백, 대시, 밑줄만 포함할 수 있습니다. 길이는 4자 이상이어야 하고 32자를 넘지 않아야 합니다." -#: src/components/Prompt.tsx:101 -#: src/view/com/composer/Composer.tsx:307 -#: src/view/com/composer/Composer.tsx:312 +#: src/components/Prompt.tsx:116 +#: src/components/Prompt.tsx:118 +#: src/view/com/composer/Composer.tsx:316 +#: src/view/com/composer/Composer.tsx:321 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 #: src/view/com/modals/ChangePassword.tsx:265 @@ -546,8 +539,6 @@ msgstr "글자, 숫자, 공백, 대시, 밑줄만 포함할 수 있습니다. msgid "Cancel" msgstr "취소" -#: src/view/com/modals/Confirm.tsx:88 -#: src/view/com/modals/Confirm.tsx:91 #: src/view/com/modals/CreateOrEditList.tsx:360 #: src/view/com/modals/DeleteAccount.tsx:156 #: src/view/com/modals/DeleteAccount.tsx:234 @@ -581,21 +572,17 @@ msgstr "게시물 인용 취소" msgid "Cancel search" msgstr "검색 취소" -#: src/view/com/modals/Waitlist.tsx:136 -#~ msgid "Cancel waitlist signup" -#~ msgstr "대기자 명단 등록 취소" - -#: src/view/screens/Settings/index.tsx:334 +#: src/view/screens/Settings/index.tsx:352 msgctxt "action" msgid "Change" msgstr "변경" -#: src/view/screens/Settings/index.tsx:696 +#: src/view/screens/Settings/index.tsx:714 msgid "Change handle" msgstr "핸들 변경" #: src/view/com/modals/ChangeHandle.tsx:161 -#: src/view/screens/Settings/index.tsx:705 +#: src/view/screens/Settings/index.tsx:723 msgid "Change Handle" msgstr "핸들 변경" @@ -603,21 +590,21 @@ msgstr "핸들 변경" msgid "Change my email" msgstr "내 이메일 변경하기" -#: src/view/screens/Settings/index.tsx:732 +#: src/view/screens/Settings/index.tsx:750 msgid "Change password" -msgstr "" +msgstr "비밀번호 변경" -#: src/view/screens/Settings/index.tsx:741 +#: src/view/screens/Settings/index.tsx:759 msgid "Change Password" -msgstr "" +msgstr "비밀번호 변경" #: src/view/com/composer/select-language/SuggestedLanguage.tsx:73 msgid "Change post language to {0}" msgstr "게시물 언어를 {0}(으)로 변경" -#: src/view/screens/Settings/index.tsx:733 +#: src/view/screens/Settings/index.tsx:751 msgid "Change your Bluesky password" -msgstr "" +msgstr "내 Bluesky 비밀번호를 변경합니다" #: src/view/com/modals/ChangeEmail.tsx:109 msgid "Change Your Email" @@ -644,7 +631,7 @@ msgstr "받은 편지함에서 아래에 입력하는 확인 코드가 포함된 msgid "Choose \"Everybody\" or \"Nobody\"" msgstr "\"모두\" 또는 \"없음\"을 선택하세요." -#: src/view/screens/Settings/index.tsx:697 +#: src/view/screens/Settings/index.tsx:715 msgid "Choose a new Bluesky username or create" msgstr "새 Bluesky 사용자 이름을 선택하거나 만듭니다" @@ -659,7 +646,7 @@ msgstr "맞춤 피드를 구동할 알고리즘을 선택하세요." #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:83 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:83 msgid "Choose the algorithms that power your experience with custom feeds." -msgstr "맞춤 피드를 통해 사용자 경험을 강화하는 알고리즘을 선택합니다." +msgstr "맞춤 피드를 통해 사용자 경험을 강화하는 알고리즘을 선택하세요." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 msgid "Choose your main feeds" @@ -669,21 +656,21 @@ msgstr "기본 피드 선택" msgid "Choose your password" msgstr "비밀번호를 입력하세요" -#: src/view/screens/Settings/index.tsx:834 -#: src/view/screens/Settings/index.tsx:835 +#: src/view/screens/Settings/index.tsx:862 +#: src/view/screens/Settings/index.tsx:863 msgid "Clear all legacy storage data" msgstr "모든 레거시 스토리지 데이터 지우기" -#: src/view/screens/Settings/index.tsx:837 +#: src/view/screens/Settings/index.tsx:865 msgid "Clear all legacy storage data (restart after this)" msgstr "모든 레거시 스토리지 데이터 지우기 (이후 다시 시작)" -#: src/view/screens/Settings/index.tsx:846 -#: src/view/screens/Settings/index.tsx:847 +#: src/view/screens/Settings/index.tsx:874 +#: src/view/screens/Settings/index.tsx:875 msgid "Clear all storage data" msgstr "모든 스토리지 데이터 지우기" -#: src/view/screens/Settings/index.tsx:849 +#: src/view/screens/Settings/index.tsx:877 msgid "Clear all storage data (restart after this)" msgstr "모든 스토리지 데이터 지우기 (이후 다시 시작)" @@ -698,11 +685,11 @@ msgstr "이곳을 클릭" #: src/components/TagMenu/index.web.tsx:138 msgid "Click here to open tag menu for {tag}" -msgstr "" +msgstr "이곳을 클릭하여 {tag}의 태그 메뉴 열기" #: src/components/RichText.tsx:191 msgid "Click here to open tag menu for #{tag}" -msgstr "" +msgstr "이곳을 클릭하여 #{tag}의 태그 메뉴 열기" #: src/screens/Onboarding/index.tsx:35 msgid "Climate" @@ -711,22 +698,22 @@ msgstr "기후" #: src/view/com/modals/ChangePassword.tsx:265 #: src/view/com/modals/ChangePassword.tsx:268 msgid "Close" -msgstr "" +msgstr "닫기" #: src/components/Dialog/index.web.tsx:84 #: src/components/Dialog/index.web.tsx:198 msgid "Close active dialog" -msgstr "활성 대화 상자 닫기" +msgstr "열려 있는 대화 상자 닫기" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:38 msgid "Close alert" msgstr "알림 닫기" -#: src/view/com/util/BottomSheetCustomBackdrop.tsx:33 +#: src/view/com/util/BottomSheetCustomBackdrop.tsx:36 msgid "Close bottom drawer" msgstr "하단 서랍 닫기" -#: src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx:26 +#: src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx:30 msgid "Close image" msgstr "이미지 닫기" @@ -734,15 +721,16 @@ msgstr "이미지 닫기" msgid "Close image viewer" msgstr "이미지 뷰어 닫기" -#: src/view/shell/index.web.tsx:51 +#: src/view/shell/index.web.tsx:55 msgid "Close navigation footer" msgstr "탐색 푸터 닫기" +#: src/components/Menu/index.tsx:207 #: src/components/TagMenu/index.tsx:262 msgid "Close this dialog" -msgstr "" +msgstr "이 대화 상자 닫기" -#: src/view/shell/index.web.tsx:52 +#: src/view/shell/index.web.tsx:56 msgid "Closes bottom navigation bar" msgstr "하단 탐색 막대를 닫습니다" @@ -750,15 +738,15 @@ msgstr "하단 탐색 막대를 닫습니다" msgid "Closes password update alert" msgstr "비밀번호 변경 알림을 닫습니다" -#: src/view/com/composer/Composer.tsx:309 +#: src/view/com/composer/Composer.tsx:318 msgid "Closes post composer and discards post draft" msgstr "게시물 작성 상자를 닫고 게시물 초안을 삭제합니다" -#: src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx:27 +#: src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx:31 msgid "Closes viewer for header image" msgstr "헤더 이미지 뷰어를 닫습니다" -#: src/view/com/notifications/FeedItem.tsx:318 +#: src/view/com/notifications/FeedItem.tsx:317 msgid "Collapses list of users for a given notification" msgstr "이 알림에 대한 사용자 목록을 축소합니다" @@ -770,7 +758,7 @@ msgstr "코미디" msgid "Comics" msgstr "만화" -#: src/Navigation.tsx:229 +#: src/Navigation.tsx:241 #: src/view/screens/CommunityGuidelines.tsx:32 msgid "Community Guidelines" msgstr "커뮤니티 가이드라인" @@ -781,9 +769,9 @@ msgstr "온보딩 완료 후 계정 사용 시작" #: src/view/com/auth/create/Step3.tsx:73 msgid "Complete the challenge" -msgstr "" +msgstr "챌린지 완료하기" -#: src/view/com/composer/Composer.tsx:424 +#: src/view/com/composer/Composer.tsx:433 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" msgstr "최대 {MAX_GRAPHEME_LENGTH}자 길이까지 글을 작성할 수 있습니다" @@ -791,12 +779,18 @@ msgstr "최대 {MAX_GRAPHEME_LENGTH}자 길이까지 글을 작성할 수 있습 msgid "Compose reply" msgstr "답글 작성하기" -#: src/screens/Onboarding/StepModeration/ModerationOption.tsx:67 +#: src/components/moderation/GlobalModerationLabelPref.tsx:69 +#: src/components/moderation/ModerationLabelPref.tsx:128 +#: src/screens/Onboarding/StepModeration/ModerationOption.tsx:81 msgid "Configure content filtering setting for category: {0}" msgstr "{0} 카테고리에 대한 콘텐츠 필터링 설정 구성" -#: src/components/Prompt.tsx:124 -#: src/view/com/modals/AppealLabel.tsx:98 +#: src/components/moderation/ModerationLabelPref.tsx:104 +msgid "Configured in <0>moderation settings</0>." +msgstr "<0>검토 설정</0>에서 설정합니다." + +#: src/components/Prompt.tsx:152 +#: src/components/Prompt.tsx:155 #: src/view/com/modals/SelfLabel.tsx:154 #: src/view/com/modals/VerifyEmail.tsx:231 #: src/view/com/modals/VerifyEmail.tsx:233 @@ -805,12 +799,6 @@ msgstr "{0} 카테고리에 대한 콘텐츠 필터링 설정 구성" msgid "Confirm" msgstr "확인" -#: src/view/com/modals/Confirm.tsx:75 -#: src/view/com/modals/Confirm.tsx:78 -msgctxt "action" -msgid "Confirm" -msgstr "확인" - #: src/view/com/modals/ChangeEmail.tsx:193 #: src/view/com/modals/ChangeEmail.tsx:195 msgid "Confirm Change" @@ -824,9 +812,13 @@ msgstr "콘텐츠 언어 설정 확인" msgid "Confirm delete account" msgstr "계정 삭제 확인" -#: src/view/com/modals/ContentFilteringSettings.tsx:156 -msgid "Confirm your age to enable adult content." -msgstr "성인 콘텐츠를 사용하려면 나이를 확인하세요." +#: src/screens/Moderation/index.tsx:304 +msgid "Confirm your age:" +msgstr "나이를 확인하세요:" + +#: src/screens/Moderation/index.tsx:295 +msgid "Confirm your birthdate" +msgstr "생년월일 확인" #: src/view/com/modals/ChangeEmail.tsx:157 #: src/view/com/modals/DeleteAccount.tsx:182 @@ -834,10 +826,6 @@ msgstr "성인 콘텐츠를 사용하려면 나이를 확인하세요." msgid "Confirmation code" msgstr "확인 코드" -#: src/view/com/modals/Waitlist.tsx:120 -#~ msgid "Confirms signing up {email} to the waitlist" -#~ msgstr "{email}을(를) 대기자 명단에 등록합니다" - #: src/view/com/auth/create/CreateAccount.tsx:193 #: src/view/com/auth/login/LoginForm.tsx:278 msgid "Connecting..." @@ -847,25 +835,32 @@ msgstr "연결 중…" msgid "Contact support" msgstr "지원에 연락하기" -#: src/view/screens/Moderation.tsx:83 -msgid "Content filtering" -msgstr "콘텐츠 필터링" +#: src/components/moderation/LabelsOnMe.tsx:42 +msgid "content" +msgstr "콘텐츠" -#: src/view/com/modals/ContentFilteringSettings.tsx:44 -msgid "Content Filtering" -msgstr "콘텐츠 필터링" +#: src/lib/moderation/useGlobalLabelStrings.ts:18 +msgid "Content Blocked" +msgstr "콘텐츠 차단됨" + +#: src/screens/Moderation/index.tsx:288 +msgid "Content filters" +msgstr "콘텐츠 필터" #: src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx:74 #: src/view/screens/LanguageSettings.tsx:278 msgid "Content Languages" msgstr "콘텐츠 언어" -#: src/view/com/modals/ModerationDetails.tsx:65 +#: src/components/moderation/ModerationDetailsDialog.tsx:76 +#: src/lib/moderation/useModerationCauseDescription.ts:75 msgid "Content Not Available" msgstr "콘텐츠를 사용할 수 없음" -#: src/view/com/modals/ModerationDetails.tsx:33 -#: src/view/com/util/moderation/ScreenHider.tsx:78 +#: src/components/moderation/ModerationDetailsDialog.tsx:47 +#: src/components/moderation/ScreenHider.tsx:99 +#: src/lib/moderation/useGlobalLabelStrings.ts:22 +#: src/lib/moderation/useModerationCauseDescription.ts:38 msgid "Content Warning" msgstr "콘텐츠 경고" @@ -873,10 +868,14 @@ msgstr "콘텐츠 경고" msgid "Content warnings" msgstr "콘텐츠 경고" +#: src/components/Menu/index.web.tsx:84 +msgid "Context menu backdrop, click to close the menu." +msgstr "컨텍스트 메뉴 배경을 클릭하여 메뉴를 닫습니다." + #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:170 #: src/screens/Onboarding/StepFollowingFeed.tsx:153 #: src/screens/Onboarding/StepInterests/index.tsx:248 -#: src/screens/Onboarding/StepModeration/index.tsx:118 +#: src/screens/Onboarding/StepModeration/index.tsx:102 #: src/screens/Onboarding/StepTopicalFeeds.tsx:114 #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:148 #: src/view/com/auth/onboarding/RecommendedFollows.tsx:209 @@ -885,7 +884,7 @@ msgstr "계속" #: src/screens/Onboarding/StepFollowingFeed.tsx:150 #: src/screens/Onboarding/StepInterests/index.tsx:245 -#: src/screens/Onboarding/StepModeration/index.tsx:115 +#: src/screens/Onboarding/StepModeration/index.tsx:99 #: src/screens/Onboarding/StepTopicalFeeds.tsx:111 msgid "Continue to next step" msgstr "다음 단계로 계속하기" @@ -907,13 +906,13 @@ msgstr "요리" msgid "Copied" msgstr "복사됨" -#: src/view/screens/Settings/index.tsx:241 +#: src/view/screens/Settings/index.tsx:247 msgid "Copied build version to clipboard" msgstr "빌드 버전 클립보드에 복사됨" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 -#: src/view/com/util/forms/PostDropdownBtn.tsx:161 +#: src/view/com/util/forms/PostDropdownBtn.tsx:158 msgid "Copied to clipboard" msgstr "클립보드에 복사됨" @@ -925,48 +924,40 @@ msgstr "앱 비밀번호를 복사합니다" msgid "Copy" msgstr "복사" -#: src/view/screens/ProfileList.tsx:418 +#: src/view/screens/ProfileList.tsx:388 msgid "Copy link to list" msgstr "리스트 링크 복사" -#: src/view/com/util/forms/PostDropdownBtn.tsx:231 +#: src/view/com/util/forms/PostDropdownBtn.tsx:228 #: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "Copy link to post" msgstr "게시물 링크 복사" -#: src/view/com/profile/ProfileHeader.tsx:295 -msgid "Copy link to profile" -msgstr "프로필 링크 복사" - -#: src/view/com/util/forms/PostDropdownBtn.tsx:223 -#: src/view/com/util/forms/PostDropdownBtn.tsx:225 +#: src/view/com/util/forms/PostDropdownBtn.tsx:220 +#: src/view/com/util/forms/PostDropdownBtn.tsx:222 msgid "Copy post text" msgstr "게시물 텍스트 복사" -#: src/Navigation.tsx:234 +#: src/Navigation.tsx:246 #: src/view/screens/CopyrightPolicy.tsx:29 msgid "Copyright Policy" msgstr "저작권 정책" -#: src/view/screens/ProfileFeed.tsx:97 +#: src/view/screens/ProfileFeed.tsx:102 msgid "Could not load feed" msgstr "피드를 불러올 수 없습니다" -#: src/view/screens/ProfileList.tsx:893 +#: src/view/screens/ProfileList.tsx:907 msgid "Could not load list" msgstr "리스트를 불러올 수 없습니다" -#: src/view/com/auth/create/Step2.tsx:91 -#~ msgid "Country" -#~ msgstr "국가" - #: src/view/com/auth/HomeLoggedOutCTA.tsx:62 #: src/view/com/auth/SplashScreen.tsx:71 #: src/view/com/auth/SplashScreen.web.tsx:81 msgid "Create a new account" msgstr "새 계정 만들기" -#: src/view/screens/Settings/index.tsx:384 +#: src/view/screens/Settings/index.tsx:402 msgid "Create a new Bluesky account" msgstr "새 Bluesky 계정을 만듭니다" @@ -983,19 +974,15 @@ msgstr "앱 비밀번호 만들기" msgid "Create new account" msgstr "새 계정 만들기" -#: src/view/screens/AppPasswords.tsx:249 +#: src/components/ReportDialog/SelectReportOptionView.tsx:93 +msgid "Create report for {0}" +msgstr "{0}에 대한 신고 작성하기" + +#: src/view/screens/AppPasswords.tsx:246 msgid "Created {0}" -msgstr "{0} 생성됨" +msgstr "{0}에 생성됨" -#: src/view/screens/ProfileFeed.tsx:616 -msgid "Created by <0/>" -msgstr "<0/> 님이 만듦" - -#: src/view/screens/ProfileFeed.tsx:614 -msgid "Created by you" -msgstr "내가 만듦" - -#: src/view/com/composer/Composer.tsx:455 +#: src/view/com/composer/Composer.tsx:464 msgid "Creates a card with a thumbnail. The card links to {url}" msgstr "미리보기 이미지가 있는 카드를 만듭니다. 카드가 {url}(으)로 연결됩니다" @@ -1006,7 +993,7 @@ msgstr "문화" #: src/view/com/auth/server-input/index.tsx:95 #: src/view/com/auth/server-input/index.tsx:96 msgid "Custom" -msgstr "" +msgstr "사용자 지정" #: src/view/com/modals/ChangeHandle.tsx:389 msgid "Custom domain" @@ -1021,12 +1008,8 @@ msgstr "커뮤니티에서 구축한 맞춤 피드는 새로운 경험을 제공 msgid "Customize media from external sites." msgstr "외부 사이트 미디어를 사용자 지정합니다." -#: src/view/screens/Settings.tsx:687 -#~ msgid "Danger Zone" -#~ msgstr "위험 구역" - -#: src/view/screens/Settings/index.tsx:485 -#: src/view/screens/Settings/index.tsx:511 +#: src/view/screens/Settings/index.tsx:503 +#: src/view/screens/Settings/index.tsx:529 msgid "Dark" msgstr "어두움" @@ -1034,15 +1017,25 @@ msgstr "어두움" msgid "Dark mode" msgstr "어두운 모드" -#: src/view/screens/Settings/index.tsx:498 +#: src/view/screens/Settings/index.tsx:516 msgid "Dark Theme" -msgstr "" +msgstr "어두운 테마" + +#: src/view/screens/Settings/index.tsx:835 +msgid "Debug Moderation" +msgstr "검토 디버그" #: src/view/screens/Debug.tsx:83 msgid "Debug panel" msgstr "디버그 패널" -#: src/view/screens/Settings/index.tsx:772 +#: src/view/com/util/forms/PostDropdownBtn.tsx:319 +#: src/view/screens/AppPasswords.tsx:268 +#: src/view/screens/ProfileList.tsx:613 +msgid "Delete" +msgstr "삭제" + +#: src/view/screens/Settings/index.tsx:790 msgid "Delete account" msgstr "계정 삭제" @@ -1050,13 +1043,15 @@ msgstr "계정 삭제" msgid "Delete Account" msgstr "계정 삭제" -#: src/view/screens/AppPasswords.tsx:222 -#: src/view/screens/AppPasswords.tsx:242 +#: src/view/screens/AppPasswords.tsx:239 msgid "Delete app password" msgstr "앱 비밀번호 삭제" -#: src/view/screens/ProfileList.tsx:364 -#: src/view/screens/ProfileList.tsx:445 +#: src/view/screens/AppPasswords.tsx:263 +msgid "Delete app password?" +msgstr "앱 비밀번호를 삭제하시겠습니까?" + +#: src/view/screens/ProfileList.tsx:415 msgid "Delete List" msgstr "리스트 삭제" @@ -1064,28 +1059,28 @@ msgstr "리스트 삭제" msgid "Delete my account" msgstr "내 계정 삭제" -#: src/view/screens/Settings.tsx:706 -#~ msgid "Delete my account…" -#~ msgstr "내 계정 삭제…" - -#: src/view/screens/Settings/index.tsx:784 +#: src/view/screens/Settings/index.tsx:802 msgid "Delete My Account…" -msgstr "" +msgstr "내 계정 삭제…" -#: src/view/com/util/forms/PostDropdownBtn.tsx:317 -#: src/view/com/util/forms/PostDropdownBtn.tsx:326 +#: src/view/com/util/forms/PostDropdownBtn.tsx:302 +#: src/view/com/util/forms/PostDropdownBtn.tsx:304 msgid "Delete post" msgstr "게시물 삭제" -#: src/view/com/util/forms/PostDropdownBtn.tsx:321 +#: src/view/screens/ProfileList.tsx:608 +msgid "Delete this list?" +msgstr "이 리스트를 삭제하시겠습니까?" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:314 msgid "Delete this post?" msgstr "이 게시물을 삭제하시겠습니까?" -#: src/view/com/util/post-embeds/QuoteEmbed.tsx:70 +#: src/view/com/util/post-embeds/QuoteEmbed.tsx:64 msgid "Deleted" msgstr "삭제됨" -#: src/view/com/post-thread/PostThread.tsx:316 +#: src/view/com/post-thread/PostThread.tsx:317 msgid "Deleted post." msgstr "삭제된 게시물." @@ -1096,27 +1091,31 @@ msgstr "삭제된 게시물." msgid "Description" msgstr "설명" -#: src/view/screens/Settings.tsx:760 -#~ msgid "Developer Tools" -#~ msgstr "개발자 도구" - -#: src/view/com/composer/Composer.tsx:218 +#: src/view/com/composer/Composer.tsx:217 msgid "Did you want to say anything?" msgstr "하고 싶은 말이 있나요?" -#: src/view/screens/Settings/index.tsx:504 +#: src/view/screens/Settings/index.tsx:522 msgid "Dim" -msgstr "" +msgstr "어둑함" -#: src/view/com/composer/Composer.tsx:151 +#: src/lib/moderation/useLabelBehaviorDescription.ts:32 +#: src/lib/moderation/useLabelBehaviorDescription.ts:42 +#: src/lib/moderation/useLabelBehaviorDescription.ts:68 +#: src/screens/Moderation/index.tsx:347 +msgid "Disabled" +msgstr "비활성화됨" + +#: src/view/com/composer/Composer.tsx:506 msgid "Discard" msgstr "삭제" -#: src/view/com/composer/Composer.tsx:145 -msgid "Discard draft" +#: src/view/com/composer/Composer.tsx:503 +msgid "Discard draft?" msgstr "초안 삭제" -#: src/view/screens/Moderation.tsx:226 +#: src/screens/Moderation/index.tsx:524 +#: src/screens/Moderation/index.tsx:528 msgid "Discourage apps from showing my account to logged-out users" msgstr "앱이 로그아웃한 사용자에게 내 계정을 표시하지 않도록 설정하기" @@ -1125,13 +1124,9 @@ msgstr "앱이 로그아웃한 사용자에게 내 계정을 표시하지 않도 msgid "Discover new custom feeds" msgstr "새로운 맞춤 피드 찾아보기" -#: src/view/screens/Feeds.tsx:473 -#~ msgid "Discover new feeds" -#~ msgstr "새 피드 발견하기" - #: src/view/screens/Feeds.tsx:689 msgid "Discover New Feeds" -msgstr "" +msgstr "새 피드 발견하기" #: src/view/com/modals/EditProfile.tsx:192 msgid "Display name" @@ -1141,13 +1136,29 @@ msgstr "표시 이름" msgid "Display Name" msgstr "표시 이름" +#: src/lib/moderation/useGlobalLabelStrings.ts:39 +msgid "Does not include nudity." +msgstr "노출을 포함하지 않음." + #: src/view/com/modals/ChangeHandle.tsx:487 msgid "Domain verified!" msgstr "도메인을 확인했습니다." -#: src/view/com/auth/create/Step1.tsx:170 -#~ msgid "Don't have an invite code?" -#~ msgstr "초대 코드가 없나요?" +#: src/components/dialogs/BirthDateSettings.tsx:112 +#: src/components/dialogs/BirthDateSettings.tsx:118 +#: src/view/com/auth/server-input/index.tsx:165 +#: src/view/com/auth/server-input/index.tsx:166 +#: src/view/com/modals/AddAppPasswords.tsx:226 +#: src/view/com/modals/AltImage.tsx:139 +#: src/view/com/modals/crop-image/CropImage.web.tsx:152 +#: src/view/com/modals/InviteCodes.tsx:80 +#: src/view/com/modals/InviteCodes.tsx:123 +#: src/view/com/modals/ListAddRemoveUsers.tsx:142 +#: src/view/screens/PreferencesFollowingFeed.tsx:311 +#: src/view/screens/Settings/ExportCarDialog.tsx:93 +#: src/view/screens/Settings/ExportCarDialog.tsx:94 +msgid "Done" +msgstr "완료" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:86 #: src/view/com/modals/EditImage.tsx:333 @@ -1162,22 +1173,6 @@ msgctxt "action" msgid "Done" msgstr "완료" -#: src/view/com/auth/server-input/index.tsx:165 -#: src/view/com/auth/server-input/index.tsx:166 -#: src/view/com/modals/AddAppPasswords.tsx:226 -#: src/view/com/modals/AltImage.tsx:139 -#: src/view/com/modals/ContentFilteringSettings.tsx:88 -#: src/view/com/modals/ContentFilteringSettings.tsx:96 -#: src/view/com/modals/crop-image/CropImage.web.tsx:152 -#: src/view/com/modals/InviteCodes.tsx:80 -#: src/view/com/modals/InviteCodes.tsx:123 -#: src/view/com/modals/ListAddRemoveUsers.tsx:142 -#: src/view/screens/PreferencesFollowingFeed.tsx:311 -#: src/view/screens/Settings/ExportCarDialog.tsx:93 -#: src/view/screens/Settings/ExportCarDialog.tsx:94 -msgid "Done" -msgstr "완료" - #: src/view/com/modals/lang-settings/ConfirmLanguagesButton.tsx:42 msgid "Done{extraText}" msgstr "완료{extraText}" @@ -1186,20 +1181,20 @@ msgstr "완료{extraText}" msgid "Double tap to sign in" msgstr "두 번 탭하여 로그인합니다" -#: src/view/screens/Settings/index.tsx:755 +#: src/view/screens/Settings/index.tsx:773 msgid "Download Bluesky account data (repository)" -msgstr "" +msgstr "Bluesky 계정 데이터를 다운로드합니다 (저장소)" #: src/view/screens/Settings/ExportCarDialog.tsx:59 #: src/view/screens/Settings/ExportCarDialog.tsx:63 msgid "Download CAR file" -msgstr "" +msgstr "CAR 파일 다운로드" #: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" msgstr "드롭하여 이미지 추가" -#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:111 +#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:116 msgid "Due to Apple policies, adult content can only be enabled on the web after completing sign up." msgstr "Apple 정책으로 인해 성인 콘텐츠는 가입을 완료한 후에 웹에서만 사용 설정할 수 있습니다." @@ -1211,6 +1206,10 @@ msgstr "예: 앨리스 로버츠" msgid "e.g. Artist, dog-lover, and avid reader." msgstr "예: 예술가, 개 애호가, 독서광." +#: src/lib/moderation/useGlobalLabelStrings.ts:43 +msgid "E.g. artistic nudes." +msgstr "예: 예술적인 노출." + #: src/view/com/modals/CreateOrEditList.tsx:283 msgid "e.g. Great Posters" msgstr "예: 멋진 포스터" @@ -1236,12 +1235,17 @@ msgctxt "action" msgid "Edit" msgstr "편집" +#: src/view/com/util/UserAvatar.tsx:295 +#: src/view/com/util/UserBanner.tsx:85 +msgid "Edit avatar" +msgstr "아바타 편집" + #: src/view/com/composer/photos/Gallery.tsx:144 #: src/view/com/modals/EditImage.tsx:207 msgid "Edit image" msgstr "이미지 편집" -#: src/view/screens/ProfileList.tsx:433 +#: src/view/screens/ProfileList.tsx:403 msgid "Edit list details" msgstr "리스트 세부 정보 편집" @@ -1249,7 +1253,7 @@ msgstr "리스트 세부 정보 편집" msgid "Edit Moderation List" msgstr "검토 리스트 편집" -#: src/Navigation.tsx:244 +#: src/Navigation.tsx:256 #: src/view/screens/Feeds.tsx:434 #: src/view/screens/SavedFeeds.tsx:84 msgid "Edit My Feeds" @@ -1259,11 +1263,13 @@ msgstr "내 피드 편집" msgid "Edit my profile" msgstr "내 프로필 편집" -#: src/view/com/profile/ProfileHeader.tsx:418 +#: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:172 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:161 msgid "Edit profile" msgstr "프로필 편집" -#: src/view/com/profile/ProfileHeader.tsx:423 +#: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:175 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:164 msgid "Edit Profile" msgstr "프로필 편집" @@ -1312,7 +1318,7 @@ msgstr "이메일 변경됨" msgid "Email verified" msgstr "이메일 확인됨" -#: src/view/screens/Settings/index.tsx:312 +#: src/view/screens/Settings/index.tsx:330 msgid "Email:" msgstr "이메일:" @@ -1320,12 +1326,12 @@ msgstr "이메일:" msgid "Enable {0} only" msgstr "{0}만 사용" -#: src/view/com/modals/ContentFilteringSettings.tsx:167 -msgid "Enable Adult Content" +#: src/screens/Moderation/index.tsx:335 +msgid "Enable adult content" msgstr "성인 콘텐츠 활성화" -#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:76 -#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:77 +#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:78 +#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:79 msgid "Enable adult content in your feeds" msgstr "피드에서 성인 콘텐츠 사용" @@ -1341,7 +1347,11 @@ msgstr "미디어 플레이어를 사용할 외부 사이트" msgid "Enable this setting to only see replies between people you follow." msgstr "내가 팔로우하는 사람들 간의 답글만 표시합니다." -#: src/view/screens/Profile.tsx:455 +#: src/screens/Moderation/index.tsx:345 +msgid "Enabled" +msgstr "활성화됨" + +#: src/screens/Profile/Sections/Feed.tsx:84 msgid "End of feed" msgstr "피드 끝" @@ -1352,7 +1362,7 @@ msgstr "이 앱 비밀번호의 이름을 입력하세요" #: src/components/dialogs/MutedWords.tsx:100 #: src/components/dialogs/MutedWords.tsx:101 msgid "Enter a word or tag" -msgstr "" +msgstr "단어 또는 태그 입력" #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" @@ -1360,7 +1370,7 @@ msgstr "확인 코드 입력" #: src/view/com/modals/ChangePassword.tsx:151 msgid "Enter the code you received to change your password." -msgstr "" +msgstr "비밀번호를 변경하려면 받은 코드를 입력하세요." #: src/view/com/modals/ChangeHandle.tsx:371 msgid "Enter the domain you want to use" @@ -1368,17 +1378,13 @@ msgstr "사용할 도메인 입력" #: src/view/com/auth/login/ForgotPasswordForm.tsx:107 msgid "Enter the email you used to create your account. We'll send you a \"reset code\" so you can set a new password." -msgstr "계정을 만들 때 사용한 이메일을 입력합니다. 새 비밀번호를 설정할 수 있도록 \"재설정 코드\"를 보내드립니다." +msgstr "계정을 만들 때 사용한 이메일을 입력하세요. 새 비밀번호를 설정할 수 있도록 \"재설정 코드\"를 보내드립니다." +#: src/components/dialogs/BirthDateSettings.tsx:102 #: src/view/com/auth/create/Step1.tsx:228 -#: src/view/com/modals/BirthDateSettings.tsx:74 msgid "Enter your birth date" msgstr "생년월일을 입력하세요" -#: src/view/com/modals/Waitlist.tsx:78 -#~ msgid "Enter your email" -#~ msgstr "이메일을 입력하세요" - #: src/view/com/auth/create/Step1.tsx:172 msgid "Enter your email address" msgstr "이메일 주소를 입력하세요" @@ -1391,17 +1397,13 @@ msgstr "새 이메일을 입력하세요" msgid "Enter your new email address below." msgstr "아래에 새 이메일 주소를 입력하세요." -#: src/view/com/auth/create/Step2.tsx:188 -#~ msgid "Enter your phone number" -#~ msgstr "전화번호를 입력하세요" - #: src/view/com/auth/login/Login.tsx:99 msgid "Enter your username and password" msgstr "사용자 이름 및 비밀번호 입력" #: src/view/com/auth/create/Step3.tsx:67 msgid "Error receiving captcha response." -msgstr "" +msgstr "캡차 응답을 수신하는 동안 오류가 발생했습니다." #: src/view/screens/Search/Search.tsx:110 msgid "Error:" @@ -1411,6 +1413,10 @@ msgstr "오류:" msgid "Everybody" msgstr "모두" +#: src/lib/moderation/useReportOptions.ts:66 +msgid "Excessive mentions or replies" +msgstr "과도한 멘션 또는 답글" + #: src/view/com/modals/ChangeHandle.tsx:150 msgid "Exits handle change process" msgstr "핸들 변경 프로세스를 종료합니다" @@ -1424,10 +1430,6 @@ msgstr "이미지 보기를 종료합니다" msgid "Exits inputting search query" msgstr "검색어 입력을 종료합니다" -#: src/view/com/modals/Waitlist.tsx:138 -#~ msgid "Exits signing up for waitlist with {email}" -#~ msgstr "{email}을(를) 대기자 명단에 등록하는 것을 종료합니다" - #: src/view/com/lightbox/Lightbox.web.tsx:163 msgid "Expand alt text" msgstr "대체 텍스트 확장" @@ -1437,14 +1439,22 @@ msgstr "대체 텍스트 확장" msgid "Expand or collapse the full post you are replying to" msgstr "답글을 달고 있는 전체 게시물을 펼치거나 접습니다" -#: src/view/screens/Settings/index.tsx:753 +#: src/lib/moderation/useGlobalLabelStrings.ts:47 +msgid "Explicit or potentially disturbing media." +msgstr "노골적이거나 불쾌감을 줄 수 있는 미디어." + +#: src/lib/moderation/useGlobalLabelStrings.ts:35 +msgid "Explicit sexual images." +msgstr "노골적인 성적 이미지." + +#: src/view/screens/Settings/index.tsx:771 msgid "Export my data" -msgstr "" +msgstr "내 데이터 내보내기" #: src/view/screens/Settings/ExportCarDialog.tsx:44 -#: src/view/screens/Settings/index.tsx:764 +#: src/view/screens/Settings/index.tsx:782 msgid "Export My Data" -msgstr "" +msgstr "내 데이터 내보내기" #: src/view/com/modals/EmbedConsent.tsx:64 msgid "External Media" @@ -1455,13 +1465,13 @@ msgstr "외부 미디어" msgid "External media may allow websites to collect information about you and your device. No information is sent or requested until you press the \"play\" button." msgstr "외부 미디어는 웹사이트가 나와 내 기기에 대한 정보를 수집하도록 할 수 있습니다. \"재생\" 버튼을 누르기 전까지는 어떠한 정보도 전송되거나 요청되지 않습니다." -#: src/Navigation.tsx:263 +#: src/Navigation.tsx:275 #: src/view/screens/PreferencesExternalEmbeds.tsx:52 -#: src/view/screens/Settings/index.tsx:657 +#: src/view/screens/Settings/index.tsx:675 msgid "External Media Preferences" msgstr "외부 미디어 설정" -#: src/view/screens/Settings/index.tsx:648 +#: src/view/screens/Settings/index.tsx:666 msgid "External media settings" msgstr "외부 미디어 설정" @@ -1474,7 +1484,7 @@ msgstr "앱 비밀번호를 만들지 못했습니다." msgid "Failed to create the list. Check your internet connection and try again." msgstr "리스트를 만들지 못했습니다. 인터넷 연결을 확인한 후 다시 시도하세요." -#: src/view/com/util/forms/PostDropdownBtn.tsx:128 +#: src/view/com/util/forms/PostDropdownBtn.tsx:125 msgid "Failed to delete post, please try again" msgstr "게시물을 삭제하지 못했습니다. 다시 시도해 주세요" @@ -1483,11 +1493,11 @@ msgstr "게시물을 삭제하지 못했습니다. 다시 시도해 주세요" msgid "Failed to load recommended feeds" msgstr "추천 피드를 불러오지 못했습니다" -#: src/Navigation.tsx:194 +#: src/Navigation.tsx:196 msgid "Feed" msgstr "피드" -#: src/view/com/feeds/FeedSourceCard.tsx:231 +#: src/view/com/feeds/FeedSourceCard.tsx:218 msgid "Feed by {0}" msgstr "{0} 님의 피드" @@ -1495,20 +1505,16 @@ msgstr "{0} 님의 피드" msgid "Feed offline" msgstr "피드 오프라인" -#: src/view/com/feeds/FeedPage.tsx:143 -#~ msgid "Feed Preferences" -#~ msgstr "피드 설정" - #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 msgid "Feedback" msgstr "피드백" -#: src/Navigation.tsx:452 +#: src/Navigation.tsx:464 #: src/view/screens/Feeds.tsx:419 #: src/view/screens/Feeds.tsx:524 -#: src/view/screens/Profile.tsx:184 -#: src/view/shell/bottom-bar/BottomBar.tsx:181 +#: src/view/screens/Profile.tsx:192 +#: src/view/shell/bottom-bar/BottomBar.tsx:183 #: src/view/shell/desktop/LeftNav.tsx:342 #: src/view/shell/Drawer.tsx:476 #: src/view/shell/Drawer.tsx:477 @@ -1521,11 +1527,15 @@ msgstr "피드는 콘텐츠를 큐레이션하기 위해 사용자에 의해 만 #: src/view/screens/SavedFeeds.tsx:156 msgid "Feeds are custom algorithms that users build with a little coding expertise. <0/> for more information." -msgstr "피드는 사용자가 약간의 코딩 전문 지식으로 구축할 수 있는 맞춤 알고리즘입니다. <0/>에서 자세한 내용을 확인하세요." +msgstr "피드는 사용자가 약간의 코딩 전문 지식만으로 구축할 수 있는 맞춤 알고리즘입니다. <0/>에서 자세한 내용을 확인하세요." #: src/screens/Onboarding/StepTopicalFeeds.tsx:76 msgid "Feeds can be topical as well!" -msgstr "피드도 화제가 될 수 있습니다!" +msgstr "주제 기반 피드도 있습니다!" + +#: src/lib/moderation/useLabelBehaviorDescription.ts:66 +msgid "Filter from feeds" +msgstr "피드에서 필터링" #: src/screens/Onboarding/StepFinished.tsx:151 msgid "Finalizing" @@ -1545,21 +1555,17 @@ msgstr "Bluesky에서 사용자 찾기" msgid "Find users with the search tool on the right" msgstr "오른쪽의 검색 도구로 사용자 찾기" -#: src/view/com/auth/onboarding/RecommendedFollowsItem.tsx:150 +#: src/view/com/auth/onboarding/RecommendedFollowsItem.tsx:153 msgid "Finding similar accounts..." msgstr "유사한 계정을 찾는 중…" #: src/view/screens/PreferencesFollowingFeed.tsx:111 msgid "Fine-tune the content you see on your Following feed." -msgstr "" - -#: src/view/screens/PreferencesHomeFeed.tsx:111 -#~ msgid "Fine-tune the content you see on your home screen." -#~ msgstr "홈 화면에 표시되는 콘텐츠를 미세 조정합니다." +msgstr "팔로우 중 피드에 표시되는 콘텐츠를 미세 조정합니다." #: src/view/screens/PreferencesThreads.tsx:60 msgid "Fine-tune the discussion threads." -msgstr "토론 스레드를 미세 조정합니다." +msgstr "대화 스레드를 미세 조정합니다." #: src/screens/Onboarding/index.tsx:38 msgid "Fitness" @@ -1579,22 +1585,27 @@ msgid "Flip vertically" msgstr "세로로 뒤집기" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:181 -#: src/view/com/post-thread/PostThreadFollowBtn.tsx:136 -#: src/view/com/profile/ProfileHeader.tsx:513 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:229 +#: src/view/com/post-thread/PostThreadFollowBtn.tsx:139 msgid "Follow" msgstr "팔로우" -#: src/view/com/profile/FollowButton.tsx:64 +#: src/view/com/profile/FollowButton.tsx:69 msgctxt "action" msgid "Follow" msgstr "팔로우" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:58 -#: src/view/com/post-thread/PostThreadFollowBtn.tsx:122 -#: src/view/com/profile/ProfileHeader.tsx:504 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:214 +#: src/view/com/post-thread/PostThreadFollowBtn.tsx:125 msgid "Follow {0}" msgstr "{0} 님을 팔로우" +#: src/view/com/profile/ProfileMenu.tsx:242 +#: src/view/com/profile/ProfileMenu.tsx:253 +msgid "Follow Account" +msgstr "계정 팔로우" + #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:179 msgid "Follow All" msgstr "모두 팔로우" @@ -1605,9 +1616,9 @@ msgstr "선택한 계정을 팔로우하고 다음 단계를 계속 진행합니 #: src/view/com/auth/onboarding/RecommendedFollows.tsx:64 msgid "Follow some users to get started. We can recommend you more users based on who you find interesting." -msgstr "일부 사용자를 팔로우하여 시작하세요. 관심 있는 사용자를 기반으로 더 많은 사용자를 추천해 드릴 수 있습니다." +msgstr "시작하려면 사용자 몇 명을 팔로우해 보세요. 누구에게 관심이 있는지를 기반으로 더 많은 사용자를 추천해 드릴 수 있습니다." -#: src/view/com/profile/ProfileCard.tsx:194 +#: src/view/com/profile/ProfileCard.tsx:214 msgid "Followed by {0}" msgstr "{0} 님이 팔로우함" @@ -1627,29 +1638,29 @@ msgstr "님이 나를 팔로우했습니다" msgid "Followers" msgstr "팔로워" -#: src/view/com/post-thread/PostThreadFollowBtn.tsx:136 -#: src/view/com/profile/ProfileHeader.tsx:495 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:227 +#: src/view/com/post-thread/PostThreadFollowBtn.tsx:139 #: src/view/screens/ProfileFollows.tsx:25 msgid "Following" msgstr "팔로우 중" -#: src/view/com/profile/ProfileHeader.tsx:149 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:89 msgid "Following {0}" -msgstr "{0} 팔로우 중" +msgstr "{0} 님을 팔로우했습니다" -#: src/Navigation.tsx:250 +#: src/Navigation.tsx:262 #: src/view/com/home/HomeHeaderLayout.web.tsx:50 #: src/view/com/home/HomeHeaderLayoutMobile.tsx:84 #: src/view/screens/PreferencesFollowingFeed.tsx:104 -#: src/view/screens/Settings/index.tsx:543 +#: src/view/screens/Settings/index.tsx:561 msgid "Following Feed Preferences" -msgstr "" +msgstr "팔로우 중 피드 설정" -#: src/view/com/profile/ProfileHeader.tsx:546 +#: src/screens/Profile/Header/Handle.tsx:24 msgid "Follows you" msgstr "나를 팔로우함" -#: src/view/com/profile/ProfileCard.tsx:141 +#: src/view/com/profile/ProfileCard.tsx:139 msgid "Follows You" msgstr "나를 팔로우함" @@ -1678,12 +1689,16 @@ msgstr "비밀번호 분실" msgid "Forgot Password" msgstr "비밀번호 분실" +#: src/lib/moderation/useReportOptions.ts:52 +msgid "Frequently Posts Unwanted Content" +msgstr "잦은 원치 않는 콘텐츠 게시" + #: src/screens/Hashtag.tsx:108 #: src/screens/Hashtag.tsx:148 msgid "From @{sanitizedAuthor}" -msgstr "" +msgstr "@{sanitizedAuthor} 님의 태그" -#: src/view/com/posts/FeedItem.tsx:189 +#: src/view/com/posts/FeedItem.tsx:183 msgctxt "from-feed" msgid "From <0/>" msgstr "<0/>에서" @@ -1697,20 +1712,29 @@ msgstr "갤러리" msgid "Get Started" msgstr "시작하기" +#: src/lib/moderation/useReportOptions.ts:37 +msgid "Glaring violations of law or terms of service" +msgstr "명백한 법률 또는 서비스 약관 위반 행위" + +#: src/components/moderation/ScreenHider.tsx:143 +#: src/components/moderation/ScreenHider.tsx:152 #: src/view/com/auth/LoggedOut.tsx:81 #: src/view/com/auth/LoggedOut.tsx:82 -#: src/view/com/util/moderation/ScreenHider.tsx:123 #: src/view/shell/desktop/LeftNav.tsx:104 msgid "Go back" msgstr "뒤로" -#: src/view/screens/ProfileFeed.tsx:106 +#: src/screens/Profile/ErrorState.tsx:62 +#: src/screens/Profile/ErrorState.tsx:66 #: src/view/screens/ProfileFeed.tsx:111 -#: src/view/screens/ProfileList.tsx:902 -#: src/view/screens/ProfileList.tsx:907 +#: src/view/screens/ProfileFeed.tsx:116 +#: src/view/screens/ProfileList.tsx:916 +#: src/view/screens/ProfileList.tsx:921 msgid "Go Back" msgstr "뒤로" +#: src/components/ReportDialog/SelectReportOptionView.tsx:73 +#: src/components/ReportDialog/SubmitView.tsx:104 #: src/screens/Onboarding/Layout.tsx:104 #: src/screens/Onboarding/Layout.tsx:193 msgid "Go back to previous step" @@ -1729,21 +1753,25 @@ msgstr "@{queryMaybeHandle}(으)로 이동" msgid "Go to next" msgstr "다음" +#: src/lib/moderation/useGlobalLabelStrings.ts:46 +msgid "Graphic Media" +msgstr "그래픽 미디어" + #: src/view/com/modals/ChangeHandle.tsx:265 msgid "Handle" msgstr "핸들" -#: src/Navigation.tsx:270 -msgid "Hashtag" -msgstr "" +#: src/lib/moderation/useReportOptions.ts:32 +msgid "Harassment, trolling, or intolerance" +msgstr "괴롭힘, 분쟁 유발 또는 차별" -#: src/components/RichText.tsx:188 -#~ msgid "Hashtag: {tag}" -#~ msgstr "" +#: src/Navigation.tsx:282 +msgid "Hashtag" +msgstr "해시태그" #: src/components/RichText.tsx:190 msgid "Hashtag: #{tag}" -msgstr "" +msgstr "해시태그: #{tag}" #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" @@ -1770,41 +1798,42 @@ msgstr "다음은 사용자의 관심사를 기반으로 한 몇 가지 주제 msgid "Here is your app password." msgstr "앱 비밀번호입니다." -#: src/screens/Onboarding/StepModeration/ModerationOption.tsx:41 -#: src/view/com/modals/ContentFilteringSettings.tsx:251 -#: src/view/com/util/moderation/ContentHider.tsx:105 -#: src/view/com/util/moderation/PostHider.tsx:108 +#: src/components/moderation/ContentHider.tsx:115 +#: src/components/moderation/GlobalModerationLabelPref.tsx:43 +#: src/components/moderation/PostHider.tsx:107 +#: src/lib/moderation/useLabelBehaviorDescription.ts:15 +#: src/lib/moderation/useLabelBehaviorDescription.ts:20 +#: src/lib/moderation/useLabelBehaviorDescription.ts:25 +#: src/lib/moderation/useLabelBehaviorDescription.ts:30 +#: src/screens/Onboarding/StepModeration/ModerationOption.tsx:52 +#: src/screens/Onboarding/StepModeration/ModerationOption.tsx:76 +#: src/view/com/util/forms/PostDropdownBtn.tsx:328 msgid "Hide" msgstr "숨기기" -#: src/view/com/modals/ContentFilteringSettings.tsx:224 -#: src/view/com/notifications/FeedItem.tsx:326 +#: src/view/com/notifications/FeedItem.tsx:325 msgctxt "action" msgid "Hide" msgstr "숨기기" #: src/view/com/util/forms/PostDropdownBtn.tsx:276 -#: src/view/com/util/forms/PostDropdownBtn.tsx:287 +#: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Hide post" msgstr "게시물 숨기기" -#: src/view/com/util/moderation/ContentHider.tsx:67 -#: src/view/com/util/moderation/PostHider.tsx:61 +#: src/components/moderation/ContentHider.tsx:67 +#: src/components/moderation/PostHider.tsx:64 msgid "Hide the content" msgstr "콘텐츠 숨기기" -#: src/view/com/util/forms/PostDropdownBtn.tsx:280 +#: src/view/com/util/forms/PostDropdownBtn.tsx:325 msgid "Hide this post?" msgstr "이 게시물을 숨기시겠습니까?" -#: src/view/com/notifications/FeedItem.tsx:316 +#: src/view/com/notifications/FeedItem.tsx:315 msgid "Hide user list" msgstr "사용자 리스트 숨기기" -#: src/view/com/profile/ProfileHeader.tsx:487 -msgid "Hides posts from {0} in your feed" -msgstr "피드에서 {0} 님의 게시물을 숨깁니다" - #: src/view/com/posts/FeedErrorMessage.tsx:111 msgid "Hmm, some kind of issue occurred when contacting the feed server. Please let the feed owner know about this issue." msgstr "피드 서버에 연결하는 중 어떤 문제가 발생했습니다. 피드 소유자에게 이 문제에 대해 알려주세요." @@ -1825,21 +1854,22 @@ msgstr "피드 서버에서 잘못된 응답을 보냈습니다. 피드 소유 msgid "Hmm, we're having trouble finding this feed. It may have been deleted." msgstr "이 피드를 찾는 데 문제가 있습니다. 피드가 삭제되었을 수 있습니다." -#: src/Navigation.tsx:442 -#: src/view/shell/bottom-bar/BottomBar.tsx:137 +#: src/screens/Moderation/index.tsx:61 +msgid "Hmmmm, it seems we're having trouble loading this data. See below for more details. If this issue persists, please contact us." +msgstr "이 데이터를 불러오는 데 문제가 있는 것 같습니다. 자세한 내용은 아래를 참조하세요. 이 문제가 지속되면 문의해 주세요." + +#: src/screens/Profile/ErrorState.tsx:31 +msgid "Hmmmm, we couldn't load that moderation service." +msgstr "검토 서비스를 불러올 수 없습니다." + +#: src/Navigation.tsx:454 +#: src/view/shell/bottom-bar/BottomBar.tsx:139 #: src/view/shell/desktop/LeftNav.tsx:306 #: src/view/shell/Drawer.tsx:398 #: src/view/shell/Drawer.tsx:399 msgid "Home" msgstr "홈" -#: src/Navigation.tsx:247 -#: src/view/com/pager/FeedsTabBarMobile.tsx:123 -#: src/view/screens/PreferencesHomeFeed.tsx:104 -#: src/view/screens/Settings/index.tsx:543 -#~ msgid "Home Feed Preferences" -#~ msgstr "홈 피드 설정" - #: src/view/com/auth/create/Step1.tsx:75 #: src/view/com/auth/login/ForgotPasswordForm.tsx:120 msgid "Hosting provider" @@ -1869,9 +1899,21 @@ msgstr "대체 텍스트가 긴 경우 대체 텍스트 확장 상태를 전환 msgid "If none are selected, suitable for all ages." msgstr "아무것도 선택하지 않으면 모든 연령대에 적합하다는 뜻입니다." +#: src/view/screens/ProfileList.tsx:610 +msgid "If you delete this list, you won't be able to recover it." +msgstr "이 리스트를 삭제하면 다시 복구할 수 없습니다." + +#: src/view/com/util/forms/PostDropdownBtn.tsx:316 +msgid "If you remove this post, you won't be able to recover it." +msgstr "이 게시물을 삭제하면 다시 복구할 수 없습니다." + #: src/view/com/modals/ChangePassword.tsx:146 msgid "If you want to change your password, we will send you a code to verify that this is your account." -msgstr "" +msgstr "비밀번호를 변경하고 싶다면 본인 계정임을 확인할 수 있는 코드를 보내드리겠습니다." + +#: src/lib/moderation/useReportOptions.ts:36 +msgid "Illegal and Urgent" +msgstr "불법 및 긴급 사항" #: src/view/com/util/images/Gallery.tsx:38 msgid "Image" @@ -1881,10 +1923,9 @@ msgstr "이미지" msgid "Image alt text" msgstr "이미지 대체 텍스트" -#: src/view/com/util/UserAvatar.tsx:311 -#: src/view/com/util/UserBanner.tsx:118 -msgid "Image options" -msgstr "이미지 옵션" +#: src/lib/moderation/useReportOptions.ts:47 +msgid "Impersonation or false claims about identity or affiliation" +msgstr "신원 또는 소속에 대한 사칭 또는 허위 주장" #: src/view/com/auth/login/SetNewPasswordForm.tsx:138 msgid "Input code sent to your email for password reset" @@ -1914,10 +1955,6 @@ msgstr "새 비밀번호를 입력합니다" msgid "Input password for account deletion" msgstr "계정을 삭제하기 위해 비밀번호를 입력합니다" -#: src/view/com/auth/create/Step2.tsx:196 -#~ msgid "Input phone number for SMS verification" -#~ msgstr "SMS 인증에 사용할 전화번호를 입력합니다" - #: src/view/com/auth/login/LoginForm.tsx:230 msgid "Input the password tied to {identifier}" msgstr "{identifier}에 연결된 비밀번호를 입력합니다" @@ -1926,14 +1963,6 @@ msgstr "{identifier}에 연결된 비밀번호를 입력합니다" msgid "Input the username or email address you used at signup" msgstr "가입 시 사용한 사용자 이름 또는 이메일 주소를 입력합니다" -#: src/view/com/auth/create/Step2.tsx:271 -#~ msgid "Input the verification code we have texted to you" -#~ msgstr "문자 메시지로 전송된 인증 코드를 입력합니다" - -#: src/view/com/modals/Waitlist.tsx:90 -#~ msgid "Input your email to get on the Bluesky waitlist" -#~ msgstr "Bluesky 대기자 명단에 등록하려면 이메일을 입력합니다" - #: src/view/com/auth/login/LoginForm.tsx:229 msgid "Input your password" msgstr "비밀번호를 입력합니다" @@ -1942,7 +1971,7 @@ msgstr "비밀번호를 입력합니다" msgid "Input your user handle" msgstr "사용자 핸들을 입력합니다" -#: src/view/com/post-thread/PostThreadItem.tsx:226 +#: src/view/com/post-thread/PostThreadItem.tsx:225 msgid "Invalid or unsupported post record" msgstr "유효하지 않거나 지원되지 않는 게시물 기록" @@ -1950,10 +1979,6 @@ msgstr "유효하지 않거나 지원되지 않는 게시물 기록" msgid "Invalid username or password" msgstr "잘못된 사용자 이름 또는 비밀번호" -#: src/view/screens/Settings.tsx:411 -#~ msgid "Invite" -#~ msgstr "초대" - #: src/view/com/modals/InviteCodes.tsx:93 msgid "Invite a Friend" msgstr "친구 초대하기" @@ -1971,10 +1996,6 @@ msgstr "초대 코드가 올바르지 않습니다. 코드를 올바르게 입 msgid "Invite codes: {0} available" msgstr "초대 코드: {0}개 사용 가능" -#: src/view/shell/Drawer.tsx:645 -#~ msgid "Invite codes: {invitesAvailable} available" -#~ msgstr "초대 코드: {invitesAvailable}개 사용 가능" - #: src/view/com/modals/InviteCodes.tsx:169 msgid "Invite codes: 1 available" msgstr "초대 코드: 1개 사용 가능" @@ -1988,37 +2009,56 @@ msgstr "내가 팔로우하는 사람들의 게시물이 올라오는 대로 표 msgid "Jobs" msgstr "채용" -#: src/view/com/modals/Waitlist.tsx:67 -#~ msgid "Join the waitlist" -#~ msgstr "대기자 명단 등록" - -#: src/view/com/auth/create/Step1.tsx:174 -#: src/view/com/auth/create/Step1.tsx:178 -#~ msgid "Join the waitlist." -#~ msgstr "대기자 명단에 등록하세요." - -#: src/view/com/modals/Waitlist.tsx:128 -#~ msgid "Join Waitlist" -#~ msgstr "대기자 명단 등록" - #: src/screens/Onboarding/index.tsx:24 msgid "Journalism" msgstr "저널리즘" +#: src/components/moderation/LabelsOnMe.tsx:59 +msgid "label has been placed on this {labelTarget}" +msgstr "이 {labelTarget}에 라벨이 지정되었습니다" + +#: src/components/moderation/ContentHider.tsx:144 +msgid "Labeled by {0}." +msgstr "{0} 님이 라벨 지정함." + +#: src/components/moderation/ContentHider.tsx:142 +msgid "Labeled by the author." +msgstr "작성자가 라벨 지정함." + +#: src/view/screens/Profile.tsx:186 +msgid "Labels" +msgstr "라벨" + +#: src/screens/Profile/Sections/Labels.tsx:161 +msgid "Labels are annotations on users and content. They can be used to hide, warn, and categorize the network." +msgstr "라벨은 사용자 및 콘텐츠에 대한 주석입니다. 네트워크를 숨기고, 경고하고, 분류하는 데 사용할 수 있습니다." + +#: src/components/moderation/LabelsOnMe.tsx:61 +msgid "labels have been placed on this {labelTarget}" +msgstr "라벨이 {labelTarget}에 지정되었습니다" + +#: src/components/moderation/LabelsOnMeDialog.tsx:63 +msgid "Labels on your account" +msgstr "내 계정의 라벨" + +#: src/components/moderation/LabelsOnMeDialog.tsx:65 +msgid "Labels on your content" +msgstr "내 콘텐츠의 라벨" + #: src/view/com/composer/select-language/SelectLangBtn.tsx:104 msgid "Language selection" msgstr "언어 선택" -#: src/view/screens/Settings/index.tsx:594 +#: src/view/screens/Settings/index.tsx:612 msgid "Language settings" msgstr "언어 설정" -#: src/Navigation.tsx:142 +#: src/Navigation.tsx:144 #: src/view/screens/LanguageSettings.tsx:89 msgid "Language Settings" msgstr "언어 설정" -#: src/view/screens/Settings/index.tsx:603 +#: src/view/screens/Settings/index.tsx:621 msgid "Languages" msgstr "언어" @@ -2026,28 +2066,28 @@ msgstr "언어" msgid "Last step!" msgstr "마지막 단계예요!" -#: src/view/com/util/moderation/ContentHider.tsx:103 -msgid "Learn more" -msgstr "더 알아보기" - -#: src/view/com/util/moderation/PostAlerts.tsx:47 -#: src/view/com/util/moderation/ProfileHeaderAlerts.tsx:65 -#: src/view/com/util/moderation/ScreenHider.tsx:104 +#: src/components/moderation/ScreenHider.tsx:128 msgid "Learn More" msgstr "더 알아보기" -#: src/view/com/util/moderation/ContentHider.tsx:85 -#: src/view/com/util/moderation/PostAlerts.tsx:40 -#: src/view/com/util/moderation/PostHider.tsx:78 -#: src/view/com/util/moderation/ProfileHeaderAlerts.tsx:49 -#: src/view/com/util/moderation/ScreenHider.tsx:101 +#: src/components/moderation/ContentHider.tsx:65 +#: src/components/moderation/ContentHider.tsx:128 +msgid "Learn more about the moderation applied to this content." +msgstr "이 콘텐츠에 적용된 검토 설정에 대해 자세히 알아보세요." + +#: src/components/moderation/PostHider.tsx:85 +#: src/components/moderation/ScreenHider.tsx:125 msgid "Learn more about this warning" msgstr "이 경고에 대해 더 알아보기" -#: src/view/screens/Moderation.tsx:262 +#: src/screens/Moderation/index.tsx:555 msgid "Learn more about what is public on Bluesky." msgstr "Bluesky에서 공개되는 항목에 대해 자세히 알아보세요." +#: src/components/moderation/ContentHider.tsx:152 +msgid "Learn more." +msgstr "더 알아보기" + #: src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx:82 msgid "Leave them all unchecked to see any language." msgstr "모든 언어를 보려면 모두 선택하지 않은 상태로 두세요." @@ -2060,7 +2100,7 @@ msgstr "Bluesky 떠나기" msgid "left to go." msgstr "명 남았습니다." -#: src/view/screens/Settings/index.tsx:278 +#: src/view/screens/Settings/index.tsx:292 msgid "Legacy storage cleared, you need to restart the app now." msgstr "레거시 스토리지가 지워졌으며 지금 앱을 다시 시작해야 합니다." @@ -2073,37 +2113,42 @@ msgstr "비밀번호를 재설정해 봅시다!" msgid "Let's go!" msgstr "출발!" -#: src/view/com/util/UserAvatar.tsx:248 -#: src/view/com/util/UserBanner.tsx:62 -msgid "Library" -msgstr "라이브러리" - -#: src/view/screens/Settings/index.tsx:479 +#: src/view/screens/Settings/index.tsx:497 msgid "Light" msgstr "밝음" -#: src/view/com/util/post-ctrls/PostCtrls.tsx:182 +#: src/view/com/util/post-ctrls/PostCtrls.tsx:185 msgid "Like" msgstr "좋아요" -#: src/view/screens/ProfileFeed.tsx:591 +#: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:257 +#: src/view/screens/ProfileFeed.tsx:572 msgid "Like this feed" msgstr "이 피드에 좋아요 표시" -#: src/Navigation.tsx:199 +#: src/components/LikesDialog.tsx:87 +#: src/Navigation.tsx:201 +#: src/Navigation.tsx:206 msgid "Liked by" msgstr "좋아요 표시한 사용자" +#: src/screens/Profile/ProfileLabelerLikedBy.tsx:42 #: src/view/screens/PostLikedBy.tsx:27 #: src/view/screens/ProfileFeedLikedBy.tsx:27 msgid "Liked By" msgstr "좋아요 표시한 사용자" -#: src/view/com/feeds/FeedSourceCard.tsx:279 +#: src/view/com/feeds/FeedSourceCard.tsx:268 msgid "Liked by {0} {1}" msgstr "{0}명의 사용자가 좋아함" -#: src/view/screens/ProfileFeed.tsx:606 +#: src/components/LabelingServiceCard/index.tsx:72 +msgid "Liked by {count} {0}" +msgstr "{count}명의 사용자가 좋아함" + +#: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:277 +#: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:291 +#: src/view/screens/ProfileFeed.tsx:587 msgid "Liked by {likeCount} {0}" msgstr "{likeCount}명의 사용자가 좋아함" @@ -2115,15 +2160,15 @@ msgstr "님이 내 맞춤 피드를 좋아합니다" msgid "liked your post" msgstr "님이 내 게시물을 좋아합니다" -#: src/view/screens/Profile.tsx:183 +#: src/view/screens/Profile.tsx:191 msgid "Likes" msgstr "좋아요" -#: src/view/com/post-thread/PostThreadItem.tsx:183 +#: src/view/com/post-thread/PostThreadItem.tsx:182 msgid "Likes on this post" msgstr "이 게시물을 좋아요 표시합니다" -#: src/Navigation.tsx:168 +#: src/Navigation.tsx:170 msgid "List" msgstr "리스트" @@ -2131,15 +2176,15 @@ msgstr "리스트" msgid "List Avatar" msgstr "리스트 아바타" -#: src/view/screens/ProfileList.tsx:324 +#: src/view/screens/ProfileList.tsx:311 msgid "List blocked" msgstr "리스트 차단됨" -#: src/view/com/feeds/FeedSourceCard.tsx:233 +#: src/view/com/feeds/FeedSourceCard.tsx:220 msgid "List by {0}" msgstr "{0} 님의 리스트" -#: src/view/screens/ProfileList.tsx:378 +#: src/view/screens/ProfileList.tsx:355 msgid "List deleted" msgstr "리스트 삭제됨" @@ -2151,24 +2196,25 @@ msgstr "리스트 뮤트됨" msgid "List Name" msgstr "리스트 이름" -#: src/view/screens/ProfileList.tsx:343 +#: src/view/screens/ProfileList.tsx:325 msgid "List unblocked" msgstr "리스트 차단 해제됨" -#: src/view/screens/ProfileList.tsx:302 +#: src/view/screens/ProfileList.tsx:297 msgid "List unmuted" msgstr "리스트 언뮤트됨" -#: src/Navigation.tsx:112 -#: src/view/screens/Profile.tsx:185 +#: src/Navigation.tsx:114 +#: src/view/screens/Profile.tsx:187 +#: src/view/screens/Profile.tsx:193 #: src/view/shell/desktop/LeftNav.tsx:379 #: src/view/shell/Drawer.tsx:492 #: src/view/shell/Drawer.tsx:493 msgid "Lists" msgstr "리스트" -#: src/view/com/post-thread/PostThread.tsx:333 -#: src/view/com/post-thread/PostThread.tsx:341 +#: src/view/com/post-thread/PostThread.tsx:334 +#: src/view/com/post-thread/PostThread.tsx:342 msgid "Load more posts" msgstr "더 많은 게시물 불러오기" @@ -2176,10 +2222,10 @@ msgstr "더 많은 게시물 불러오기" msgid "Load new notifications" msgstr "새 알림 불러오기" +#: src/screens/Profile/Sections/Feed.tsx:70 #: src/view/com/feeds/FeedPage.tsx:115 -#: src/view/screens/Profile.tsx:440 #: src/view/screens/ProfileFeed.tsx:495 -#: src/view/screens/ProfileList.tsx:681 +#: src/view/screens/ProfileList.tsx:695 msgid "Load new posts" msgstr "새 게시물 불러오기" @@ -2187,11 +2233,7 @@ msgstr "새 게시물 불러오기" msgid "Loading..." msgstr "불러오는 중…" -#: src/view/com/modals/ServerInput.tsx:50 -#~ msgid "Local dev server" -#~ msgstr "로컬 개발 서버" - -#: src/Navigation.tsx:209 +#: src/Navigation.tsx:221 msgid "Log" msgstr "로그" @@ -2202,7 +2244,7 @@ msgstr "로그" msgid "Log out" msgstr "로그아웃" -#: src/view/screens/Moderation.tsx:155 +#: src/screens/Moderation/index.tsx:448 msgid "Logged-out visibility" msgstr "로그아웃 표시" @@ -2216,17 +2258,17 @@ msgstr "이곳이 당신이 가고자 하는 곳인지 확인하세요!" #: src/components/dialogs/MutedWords.tsx:83 msgid "Manage your muted words and tags" -msgstr "" +msgstr "뮤트한 단어 및 태그 관리" #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" -msgstr "" +msgstr "253자를 넘을 수 없습니다" #: src/view/com/auth/create/Step2.tsx:109 msgid "May only contain letters and numbers" -msgstr "" +msgstr "문자와 숫자만 입력할 수 있습니다" -#: src/view/screens/Profile.tsx:182 +#: src/view/screens/Profile.tsx:190 msgid "Media" msgstr "미디어" @@ -2243,31 +2285,39 @@ msgstr "멘션한 사용자" msgid "Menu" msgstr "메뉴" -#: src/view/com/posts/FeedErrorMessage.tsx:197 +#: src/view/com/posts/FeedErrorMessage.tsx:192 msgid "Message from server: {0}" msgstr "서버에서 보낸 메시지: {0}" -#: src/Navigation.tsx:117 -#: src/view/screens/Moderation.tsx:66 -#: src/view/screens/Settings/index.tsx:625 +#: src/lib/moderation/useReportOptions.ts:45 +msgid "Misleading Account" +msgstr "오해의 소지가 있는 계정" + +#: src/Navigation.tsx:119 +#: src/screens/Moderation/index.tsx:106 +#: src/view/screens/Settings/index.tsx:643 #: src/view/shell/desktop/LeftNav.tsx:397 #: src/view/shell/Drawer.tsx:511 #: src/view/shell/Drawer.tsx:512 msgid "Moderation" msgstr "검토" +#: src/components/moderation/ModerationDetailsDialog.tsx:113 +msgid "Moderation details" +msgstr "검토 세부 정보" + #: src/view/com/lists/ListCard.tsx:93 #: src/view/com/modals/UserAddRemoveLists.tsx:206 msgid "Moderation list by {0}" msgstr "{0} 님의 검토 리스트" -#: src/view/screens/ProfileList.tsx:775 +#: src/view/screens/ProfileList.tsx:789 msgid "Moderation list by <0/>" msgstr "<0/> 님의 검토 리스트" #: src/view/com/lists/ListCard.tsx:91 #: src/view/com/modals/UserAddRemoveLists.tsx:204 -#: src/view/screens/ProfileList.tsx:773 +#: src/view/screens/ProfileList.tsx:787 msgid "Moderation list by you" msgstr "내 검토 리스트" @@ -2279,96 +2329,93 @@ msgstr "검토 리스트 생성됨" msgid "Moderation list updated" msgstr "검토 리스트 업데이트됨" -#: src/view/screens/Moderation.tsx:114 +#: src/screens/Moderation/index.tsx:246 msgid "Moderation lists" msgstr "검토 리스트" -#: src/Navigation.tsx:122 +#: src/Navigation.tsx:124 #: src/view/screens/ModerationModlists.tsx:58 msgid "Moderation Lists" msgstr "검토 리스트" -#: src/view/screens/Settings/index.tsx:619 +#: src/view/screens/Settings/index.tsx:637 msgid "Moderation settings" msgstr "검토 설정" -#: src/view/com/modals/ModerationDetails.tsx:35 +#: src/Navigation.tsx:216 +msgid "Moderation states" +msgstr "검토 상태" + +#: src/screens/Moderation/index.tsx:218 +msgid "Moderation tools" +msgstr "검토 도구" + +#: src/components/moderation/ModerationDetailsDialog.tsx:49 +#: src/lib/moderation/useModerationCauseDescription.ts:40 msgid "Moderator has chosen to set a general warning on the content." -msgstr "중재자가 콘텐츠에 일반 경고를 설정했습니다." +msgstr "관리자가 콘텐츠에 일반 경고를 설정했습니다." #: src/view/shell/desktop/Feeds.tsx:65 msgid "More feeds" msgstr "피드 더 보기" -#: src/view/com/profile/ProfileHeader.tsx:523 -#: src/view/screens/ProfileFeed.tsx:363 -#: src/view/screens/ProfileList.tsx:617 +#: src/view/screens/ProfileList.tsx:599 msgid "More options" msgstr "옵션 더 보기" -#: src/view/com/util/forms/PostDropdownBtn.tsx:315 -#~ msgid "More post options" -#~ msgstr "게시물 옵션 더 보기" - #: src/view/screens/PreferencesThreads.tsx:82 msgid "Most-liked replies first" msgstr "좋아요 많은 순" #: src/view/com/auth/create/Step2.tsx:122 msgid "Must be at least 3 characters" -msgstr "" +msgstr "최소 3자 이상이어야 합니다" #: src/components/TagMenu/index.tsx:249 msgid "Mute" -msgstr "" +msgstr "뮤트" #: src/components/TagMenu/index.web.tsx:105 msgid "Mute {truncatedTag}" -msgstr "" +msgstr "{truncatedTag} 뮤트" -#: src/view/com/profile/ProfileHeader.tsx:327 +#: src/view/com/profile/ProfileMenu.tsx:279 +#: src/view/com/profile/ProfileMenu.tsx:286 msgid "Mute Account" msgstr "계정 뮤트" -#: src/view/screens/ProfileList.tsx:544 +#: src/view/screens/ProfileList.tsx:518 msgid "Mute accounts" msgstr "계정 뮤트" #: src/components/TagMenu/index.tsx:209 msgid "Mute all {displayTag} posts" -msgstr "" - -#: src/components/TagMenu/index.tsx:211 -#~ msgid "Mute all {tag} posts" -#~ msgstr "" +msgstr "모든 {displayTag} 게시물 뮤트" #: src/components/dialogs/MutedWords.tsx:149 msgid "Mute in tags only" -msgstr "" +msgstr "태그에서만 뮤트" #: src/components/dialogs/MutedWords.tsx:134 msgid "Mute in text & tags" -msgstr "" +msgstr "글 및 태그에서 뮤트" -#: src/view/screens/ProfileList.tsx:491 +#: src/view/screens/ProfileList.tsx:461 +#: src/view/screens/ProfileList.tsx:624 msgid "Mute list" msgstr "리스트 뮤트" -#: src/view/screens/ProfileList.tsx:275 +#: src/view/screens/ProfileList.tsx:619 msgid "Mute these accounts?" msgstr "이 계정들을 뮤트하시겠습니까?" -#: src/view/screens/ProfileList.tsx:279 -msgid "Mute this List" -msgstr "이 리스트 뮤트" - #: src/components/dialogs/MutedWords.tsx:127 msgid "Mute this word in post text and tags" -msgstr "" +msgstr "게시물 글 및 태그에서 이 단어 뮤트하기" #: src/components/dialogs/MutedWords.tsx:142 msgid "Mute this word in tags only" -msgstr "" +msgstr "태그에서만 이 단어 뮤트하기" #: src/view/com/util/forms/PostDropdownBtn.tsx:251 #: src/view/com/util/forms/PostDropdownBtn.tsx:257 @@ -2378,17 +2425,17 @@ msgstr "스레드 뮤트" #: src/view/com/util/forms/PostDropdownBtn.tsx:267 #: src/view/com/util/forms/PostDropdownBtn.tsx:269 msgid "Mute words & tags" -msgstr "" +msgstr "단어 및 태그 뮤트" #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" msgstr "뮤트됨" -#: src/view/screens/Moderation.tsx:128 +#: src/screens/Moderation/index.tsx:258 msgid "Muted accounts" msgstr "뮤트한 계정" -#: src/Navigation.tsx:127 +#: src/Navigation.tsx:129 #: src/view/screens/ModerationMutedAccounts.tsx:107 msgid "Muted Accounts" msgstr "뮤트한 계정" @@ -2397,15 +2444,20 @@ msgstr "뮤트한 계정" msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." msgstr "계정을 뮤트하면 피드와 알림에서 해당 계정의 게시물이 사라집니다. 뮤트 목록은 완전히 비공개로 유지됩니다." -#: src/view/screens/Moderation.tsx:100 -msgid "Muted words & tags" -msgstr "" +#: src/lib/moderation/useModerationCauseDescription.ts:85 +msgid "Muted by \"{0}\"" +msgstr "\"{0}\" 님이 뮤트함" -#: src/view/screens/ProfileList.tsx:277 +#: src/screens/Moderation/index.tsx:234 +msgid "Muted words & tags" +msgstr "뮤트한 단어 및 태그" + +#: src/view/screens/ProfileList.tsx:621 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "뮤트 목록은 비공개입니다. 뮤트한 계정은 나와 상호작용할 수 있지만 해당 계정의 게시물을 보거나 해당 계정으로부터 알림을 받을 수 없습니다." -#: src/view/com/modals/BirthDateSettings.tsx:56 +#: src/components/dialogs/BirthDateSettings.tsx:34 +#: src/components/dialogs/BirthDateSettings.tsx:86 msgid "My Birthday" msgstr "내 생년월일" @@ -2417,13 +2469,13 @@ msgstr "내 피드" msgid "My Profile" msgstr "내 프로필" -#: src/view/screens/Settings/index.tsx:582 +#: src/view/screens/Settings/index.tsx:600 msgid "My Saved Feeds" msgstr "내 저장된 피드" #: src/view/com/auth/server-input/index.tsx:118 msgid "my-server.com" -msgstr "" +msgstr "my-server.com" #: src/view/com/modals/AddAppPasswords.tsx:179 #: src/view/com/modals/CreateOrEditList.tsx:290 @@ -2434,6 +2486,12 @@ msgstr "이름" msgid "Name is required" msgstr "이름을 입력하세요" +#: src/lib/moderation/useReportOptions.ts:57 +#: src/lib/moderation/useReportOptions.ts:78 +#: src/lib/moderation/useReportOptions.ts:86 +msgid "Name or Description Violates Community Standards" +msgstr "이름 또는 설명이 커뮤니티 기준을 위반함" + #: src/screens/Onboarding/index.tsx:25 msgid "Nature" msgstr "자연" @@ -2450,6 +2508,10 @@ msgstr "다음 화면으로 이동합니다" msgid "Navigates to your profile" msgstr "내 프로필로 이동합니다" +#: src/components/ReportDialog/SelectReportOptionView.tsx:123 +msgid "Need to report a copyright violation?" +msgstr "저작권 위반을 신고해야 하나요?" + #: src/view/com/modals/EmbedConsent.tsx:107 #: src/view/com/modals/EmbedConsent.tsx:123 msgid "Never load embeds from {0}" @@ -2458,15 +2520,11 @@ msgstr "{0}에서 임베드를 불러오지 않습니다" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:72 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:72 msgid "Never lose access to your followers and data." -msgstr "팔로워와 데이터에 대한 접근 권한을 잃지 않습니다." +msgstr "팔로워와 데이터에 대한 접근 권한을 잃지 마세요." #: src/screens/Onboarding/StepFinished.tsx:119 msgid "Never lose access to your followers or data." -msgstr "팔로워 또는 데이터에 대한 접근 권한을 잃지 않습니다." - -#: src/components/dialogs/MutedWords.tsx:293 -msgid "Nevermind" -msgstr "" +msgstr "팔로워 또는 데이터에 대한 접근 권한을 잃지 마세요." #: src/view/screens/Lists.tsx:76 msgctxt "action" @@ -2487,7 +2545,7 @@ msgstr "새 비밀번호" #: src/view/com/modals/ChangePassword.tsx:215 msgid "New Password" -msgstr "" +msgstr "새 비밀번호" #: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" @@ -2496,10 +2554,10 @@ msgstr "새 게시물" #: src/view/screens/Feeds.tsx:555 #: src/view/screens/Notifications.tsx:168 -#: src/view/screens/Profile.tsx:382 +#: src/view/screens/Profile.tsx:450 #: src/view/screens/ProfileFeed.tsx:433 -#: src/view/screens/ProfileList.tsx:196 -#: src/view/screens/ProfileList.tsx:224 +#: src/view/screens/ProfileList.tsx:199 +#: src/view/screens/ProfileList.tsx:227 #: src/view/shell/desktop/LeftNav.tsx:248 msgid "New post" msgstr "새 게시물" @@ -2551,12 +2609,12 @@ msgstr "다음 이미지" msgid "No" msgstr "아니요" -#: src/view/screens/ProfileFeed.tsx:584 -#: src/view/screens/ProfileList.tsx:755 +#: src/view/screens/ProfileFeed.tsx:561 +#: src/view/screens/ProfileList.tsx:769 msgid "No description" msgstr "설명 없음" -#: src/view/com/profile/ProfileHeader.tsx:170 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:111 msgid "No longer following {0}" msgstr "더 이상 {0} 님을 팔로우하지 않음" @@ -2569,9 +2627,9 @@ msgstr "아직 알림이 없습니다." msgid "No result" msgstr "결과 없음" -#: src/components/Lists.tsx:192 +#: src/components/Lists.tsx:191 msgid "No results found" -msgstr "" +msgstr "결과를 찾을 수 없음" #: src/view/screens/Feeds.tsx:495 msgid "No results found for \"{query}\"" @@ -2591,12 +2649,21 @@ msgstr "괜찮습니다" msgid "Nobody" msgstr "없음" +#: src/components/LikedByList.tsx:102 +#: src/components/LikesDialog.tsx:99 +msgid "Nobody has liked this yet. Maybe you should be the first!" +msgstr "아직 아무도 좋아요를 누르지 않았습니다. 첫 번째가 되어 보세요!" + +#: src/lib/moderation/useGlobalLabelStrings.ts:42 +msgid "Non-sexual Nudity" +msgstr "선정적이지 않은 노출" + #: src/view/com/modals/SelfLabel.tsx:135 msgid "Not Applicable." msgstr "해당 없음." -#: src/Navigation.tsx:107 -#: src/view/screens/Profile.tsx:106 +#: src/Navigation.tsx:109 +#: src/view/screens/Profile.tsx:97 msgid "Not Found" msgstr "찾을 수 없음" @@ -2605,14 +2672,19 @@ msgstr "찾을 수 없음" msgid "Not right now" msgstr "나중에 하기" -#: src/view/screens/Moderation.tsx:252 +#: src/view/com/profile/ProfileMenu.tsx:368 +#: src/view/com/util/forms/PostDropdownBtn.tsx:342 +msgid "Note about sharing" +msgstr "공유 관련 참고 사항" + +#: src/screens/Moderation/index.tsx:546 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "참고: Bluesky는 개방형 공개 네트워크입니다. 이 설정은 Bluesky 앱과 웹사이트에서만 내 콘텐츠가 표시되는 것을 제한하며, 다른 앱에서는 이 설정을 준수하지 않을 수 있습니다. 다른 앱과 웹사이트에서는 로그아웃한 사용자에게 내 콘텐츠가 계속 표시될 수 있습니다." -#: src/Navigation.tsx:457 +#: src/Navigation.tsx:469 #: src/view/screens/Notifications.tsx:124 #: src/view/screens/Notifications.tsx:148 -#: src/view/shell/bottom-bar/BottomBar.tsx:205 +#: src/view/shell/bottom-bar/BottomBar.tsx:207 #: src/view/shell/desktop/LeftNav.tsx:361 #: src/view/shell/Drawer.tsx:435 #: src/view/shell/Drawer.tsx:436 @@ -2623,9 +2695,17 @@ msgstr "알림" msgid "Nudity" msgstr "노출" -#: src/view/com/util/ErrorBoundary.tsx:35 +#: src/lib/moderation/useReportOptions.ts:71 +msgid "Nudity or pornography not labeled as such" +msgstr "누드 또는 음란물로 설정되지 않은 콘텐츠" + +#: src/lib/moderation/useLabelBehaviorDescription.ts:11 +msgid "Off" +msgstr "끄기" + +#: src/view/com/util/ErrorBoundary.tsx:49 msgid "Oh no!" -msgstr "안 돼!" +msgstr "이런!" #: src/screens/Onboarding/StepInterests/index.tsx:128 msgid "Oh no! Something went wrong." @@ -2639,11 +2719,11 @@ msgstr "확인" msgid "Oldest replies first" msgstr "오래된 순" -#: src/view/screens/Settings/index.tsx:234 +#: src/view/screens/Settings/index.tsx:240 msgid "Onboarding reset" msgstr "온보딩 재설정" -#: src/view/com/composer/Composer.tsx:382 +#: src/view/com/composer/Composer.tsx:391 msgid "One or more images is missing alt text." msgstr "하나 이상의 이미지에 대체 텍스트가 누락되었습니다." @@ -2651,13 +2731,13 @@ msgstr "하나 이상의 이미지에 대체 텍스트가 누락되었습니다. msgid "Only {0} can reply." msgstr "{0}만 답글을 달 수 있습니다." -#: src/components/Lists.tsx:82 +#: src/components/Lists.tsx:81 msgid "Oops, something went wrong!" -msgstr "" +msgstr "이런, 뭔가 잘못되었습니다!" -#: src/components/Lists.tsx:188 -#: src/view/screens/AppPasswords.tsx:65 -#: src/view/screens/Profile.tsx:106 +#: src/components/Lists.tsx:187 +#: src/view/screens/AppPasswords.tsx:67 +#: src/view/screens/Profile.tsx:97 msgid "Oops!" msgstr "이런!" @@ -2665,32 +2745,33 @@ msgstr "이런!" msgid "Open" msgstr "공개성" -#: src/view/screens/Moderation.tsx:75 -msgid "Open content filtering settings" -msgstr "" - -#: src/view/com/composer/Composer.tsx:477 -#: src/view/com/composer/Composer.tsx:478 +#: src/view/com/composer/Composer.tsx:486 +#: src/view/com/composer/Composer.tsx:487 msgid "Open emoji picker" msgstr "이모티콘 선택기 열기" -#: src/view/screens/Settings/index.tsx:712 -msgid "Open links with in-app browser" -msgstr "링크를 인앱 브라우저로 엽니다" +#: src/view/screens/ProfileFeed.tsx:299 +msgid "Open feed options menu" +msgstr "피드 옵션 메뉴 열기" -#: src/view/screens/Moderation.tsx:92 -msgid "Open muted words settings" -msgstr "" +#: src/view/screens/Settings/index.tsx:730 +msgid "Open links with in-app browser" +msgstr "링크를 인앱 브라우저로 열기" + +#: src/screens/Moderation/index.tsx:230 +msgid "Open muted words and tags settings" +msgstr "뮤트한 단어 및 태그 설정 열기" #: src/view/com/home/HomeHeaderLayoutMobile.tsx:50 msgid "Open navigation" msgstr "내비게이션 열기" -#: src/view/com/util/forms/PostDropdownBtn.tsx:175 +#: src/view/com/util/forms/PostDropdownBtn.tsx:183 msgid "Open post options menu" -msgstr "" +msgstr "게시물 옵션 메뉴 열기" -#: src/view/screens/Settings/index.tsx:804 +#: src/view/screens/Settings/index.tsx:822 +#: src/view/screens/Settings/index.tsx:832 msgid "Open storybook page" msgstr "스토리북 페이지 열기" @@ -2702,11 +2783,11 @@ msgstr "{numItems}번째 옵션을 엽니다" msgid "Opens additional details for a debug entry" msgstr "디버그 항목에 대한 추가 세부 정보를 엽니다" -#: src/view/com/notifications/FeedItem.tsx:349 +#: src/view/com/notifications/FeedItem.tsx:348 msgid "Opens an expanded list of users in this notification" msgstr "이 알림에서 확장된 사용자 목록을 엽니다" -#: src/view/com/composer/photos/OpenCameraBtn.tsx:61 +#: src/view/com/composer/photos/OpenCameraBtn.tsx:78 msgid "Opens camera on device" msgstr "기기에서 카메라를 엽니다" @@ -2714,7 +2795,7 @@ msgstr "기기에서 카메라를 엽니다" msgid "Opens composer" msgstr "답글 작성 상자를 엽니다" -#: src/view/screens/Settings/index.tsx:595 +#: src/view/screens/Settings/index.tsx:613 msgid "Opens configurable language settings" msgstr "구성 가능한 언어 설정을 엽니다" @@ -2722,31 +2803,15 @@ msgstr "구성 가능한 언어 설정을 엽니다" msgid "Opens device photo gallery" msgstr "기기의 사진 갤러리를 엽니다" -#: src/view/com/profile/ProfileHeader.tsx:420 -msgid "Opens editor for profile display name, avatar, background image, and description" -msgstr "프로필 표시 이름, 아바타, 배경 이미지 및 설명 편집기를 엽니다" - -#: src/view/screens/Settings/index.tsx:649 +#: src/view/screens/Settings/index.tsx:667 msgid "Opens external embeds settings" msgstr "외부 임베드 설정을 엽니다" -#: src/view/com/profile/ProfileHeader.tsx:575 -msgid "Opens followers list" -msgstr "팔로워 목록을 엽니다" - -#: src/view/com/profile/ProfileHeader.tsx:594 -msgid "Opens following list" -msgstr "팔로우 중 목록을 엽니다" - -#: src/view/screens/Settings.tsx:412 -#~ msgid "Opens invite code list" -#~ msgstr "초대 코드 목록을 엽니다" - #: src/view/com/modals/InviteCodes.tsx:172 msgid "Opens list of invite codes" msgstr "초대 코드 목록을 엽니다" -#: src/view/screens/Settings/index.tsx:774 +#: src/view/screens/Settings/index.tsx:792 msgid "Opens modal for account deletion confirmation. Requires email code." msgstr "계정 삭제 확인을 위한 대화 상자를 엽니다. 이메일 코드가 필요합니다" @@ -2754,7 +2819,7 @@ msgstr "계정 삭제 확인을 위한 대화 상자를 엽니다. 이메일 코 msgid "Opens modal for using custom domain" msgstr "사용자 지정 도메인을 사용하기 위한 대화 상자를 엽니다" -#: src/view/screens/Settings/index.tsx:620 +#: src/view/screens/Settings/index.tsx:638 msgid "Opens moderation settings" msgstr "검토 설정을 엽니다" @@ -2767,27 +2832,28 @@ msgstr "비밀번호 재설정 양식을 엽니다" msgid "Opens screen to edit Saved Feeds" msgstr "저장된 피드를 편집할 수 있는 화면을 엽니다" -#: src/view/screens/Settings/index.tsx:576 +#: src/view/screens/Settings/index.tsx:594 msgid "Opens screen with all saved feeds" msgstr "모든 저장된 피드 화면을 엽니다" -#: src/view/screens/Settings/index.tsx:676 +#: src/view/screens/Settings/index.tsx:694 msgid "Opens the app password settings page" msgstr "비밀번호 설정 페이지를 엽니다" -#: src/view/screens/Settings/index.tsx:535 +#: src/view/screens/Settings/index.tsx:553 msgid "Opens the home feed preferences" msgstr "홈 피드 설정을 엽니다" -#: src/view/screens/Settings/index.tsx:805 +#: src/view/screens/Settings/index.tsx:823 +#: src/view/screens/Settings/index.tsx:833 msgid "Opens the storybook page" msgstr "스토리북 페이지를 엽니다" -#: src/view/screens/Settings/index.tsx:793 +#: src/view/screens/Settings/index.tsx:811 msgid "Opens the system log page" msgstr "시스템 로그 페이지를 엽니다" -#: src/view/screens/Settings/index.tsx:556 +#: src/view/screens/Settings/index.tsx:574 msgid "Opens the threads preferences" msgstr "스레드 설정을 엽니다" @@ -2795,23 +2861,27 @@ msgstr "스레드 설정을 엽니다" msgid "Option {0} of {numItems}" msgstr "{numItems}개 중 {0}번째 옵션" +#: src/components/ReportDialog/SubmitView.tsx:162 +msgid "Optionally provide additional information below:" +msgstr "선택 사항으로 아래에 추가 정보를 입력합니다:" + #: src/view/com/modals/Threadgate.tsx:89 msgid "Or combine these options:" msgstr "또는 다음 옵션을 결합하세요:" +#: src/lib/moderation/useReportOptions.ts:25 +msgid "Other" +msgstr "기타" + #: src/view/com/auth/login/ChooseAccountForm.tsx:138 msgid "Other account" msgstr "다른 계정" -#: src/view/com/modals/ServerInput.tsx:88 -#~ msgid "Other service" -#~ msgstr "다른 서비스" - #: src/view/com/composer/select-language/SelectLangBtn.tsx:91 msgid "Other..." msgstr "기타…" -#: src/components/Lists.tsx:194 +#: src/components/Lists.tsx:193 #: src/view/screens/NotFound.tsx:45 msgid "Page not found" msgstr "페이지를 찾을 수 없음" @@ -2836,11 +2906,11 @@ msgstr "비밀번호 변경됨" msgid "Password updated!" msgstr "비밀번호 변경됨" -#: src/Navigation.tsx:162 +#: src/Navigation.tsx:164 msgid "People followed by @{0}" msgstr "@{0} 님이 팔로우한 사람들" -#: src/Navigation.tsx:155 +#: src/Navigation.tsx:157 msgid "People following @{0}" msgstr "@{0} 님을 팔로우하는 사람들" @@ -2856,19 +2926,19 @@ msgstr "앨범에 접근할 수 있는 권한이 거부되었습니다. 시스 msgid "Pets" msgstr "반려동물" -#: src/view/com/auth/create/Step2.tsx:183 -#~ msgid "Phone number" -#~ msgstr "전화번호" - #: src/view/com/modals/SelfLabel.tsx:121 msgid "Pictures meant for adults." msgstr "성인용 사진." -#: src/view/screens/ProfileFeed.tsx:354 -#: src/view/screens/ProfileList.tsx:581 +#: src/view/screens/ProfileFeed.tsx:291 +#: src/view/screens/ProfileList.tsx:563 msgid "Pin to home" msgstr "홈에 고정" +#: src/view/screens/ProfileFeed.tsx:294 +msgid "Pin to Home" +msgstr "홈에 고정" + #: src/view/screens/SavedFeeds.tsx:88 msgid "Pinned Feeds" msgstr "고정된 피드" @@ -2896,7 +2966,7 @@ msgstr "비밀번호를 입력하세요." #: src/view/com/auth/create/state.ts:131 msgid "Please complete the verification captcha." -msgstr "" +msgstr "인증 캡차를 완료해 주세요." #: src/view/com/modals/ChangeEmail.tsx:67 msgid "Please confirm your email before changing it. This is a temporary requirement while email-updating tools are added, and it will soon be removed." @@ -2906,25 +2976,13 @@ msgstr "이메일을 변경하기 전에 이메일을 확인해 주세요. 이 msgid "Please enter a name for your app password. All spaces is not allowed." msgstr "앱 비밀번호의 이름을 입력하세요. 모든 공백 문자는 허용되지 않습니다." -#: src/view/com/auth/create/Step2.tsx:206 -#~ msgid "Please enter a phone number that can receive SMS text messages." -#~ msgstr "SMS 문자 메시지를 받을 수 있는 휴대폰 번호를 입력하세요." - #: src/view/com/modals/AddAppPasswords.tsx:145 msgid "Please enter a unique name for this App Password or use our randomly generated one." msgstr "이 앱 비밀번호에 대해 고유한 이름을 입력하거나 무작위로 생성된 이름을 사용합니다." #: src/components/dialogs/MutedWords.tsx:68 msgid "Please enter a valid word, tag, or phrase to mute" -msgstr "" - -#: src/view/com/auth/create/state.ts:170 -#~ msgid "Please enter the code you received by SMS." -#~ msgstr "SMS로 받은 코드를 입력하세요." - -#: src/view/com/auth/create/Step2.tsx:282 -#~ msgid "Please enter the verification code sent to {phoneNumberFormatted}." -#~ msgstr "{phoneNumberFormatted}(으)로 보내진 인증 코드를 입력하세요." +msgstr "뮤트할 단어나 태그 또는 문구를 입력하세요" #: src/view/com/auth/create/state.ts:103 msgid "Please enter your email." @@ -2934,16 +2992,15 @@ msgstr "이메일을 입력하세요." msgid "Please enter your password as well:" msgstr "비밀번호도 입력해 주세요:" -#: src/view/com/modals/AppealLabel.tsx:72 -#: src/view/com/modals/AppealLabel.tsx:75 -msgid "Please tell us why you think this content warning was incorrectly applied!" -msgstr "이 콘텐츠 경고가 잘못 적용되었다고 생각하는 이유를 알려주세요!" +#: src/components/moderation/LabelsOnMeDialog.tsx:222 +msgid "Please explain why you think this label was incorrectly applied by {0}" +msgstr "{0}이(가) 이 라벨을 잘못 적용했다고 생각하는 이유를 설명해 주세요" #: src/view/com/modals/VerifyEmail.tsx:101 msgid "Please Verify Your Email" msgstr "이메일 인증하기" -#: src/view/com/composer/Composer.tsx:222 +#: src/view/com/composer/Composer.tsx:221 msgid "Please wait for your link card to finish loading" msgstr "링크 카드를 완전히 불러올 때까지 기다려주세요" @@ -2953,15 +3010,19 @@ msgstr "정치" #: src/view/com/modals/SelfLabel.tsx:111 msgid "Porn" -msgstr "포르노" +msgstr "음란물" -#: src/view/com/composer/Composer.tsx:357 -#: src/view/com/composer/Composer.tsx:365 +#: src/lib/moderation/useGlobalLabelStrings.ts:34 +msgid "Pornography" +msgstr "음란물" + +#: src/view/com/composer/Composer.tsx:366 +#: src/view/com/composer/Composer.tsx:374 msgctxt "action" msgid "Post" msgstr "게시하기" -#: src/view/com/post-thread/PostThread.tsx:303 +#: src/view/com/post-thread/PostThread.tsx:304 msgctxt "description" msgid "Post" msgstr "게시물" @@ -2970,20 +3031,30 @@ msgstr "게시물" msgid "Post by {0}" msgstr "{0} 님의 게시물" -#: src/Navigation.tsx:174 -#: src/Navigation.tsx:181 -#: src/Navigation.tsx:188 +#: src/Navigation.tsx:176 +#: src/Navigation.tsx:183 +#: src/Navigation.tsx:190 msgid "Post by @{0}" msgstr "@{0} 님의 게시물" -#: src/view/com/util/forms/PostDropdownBtn.tsx:108 +#: src/view/com/util/forms/PostDropdownBtn.tsx:105 msgid "Post deleted" msgstr "게시물 삭제됨" -#: src/view/com/post-thread/PostThread.tsx:462 +#: src/view/com/post-thread/PostThread.tsx:463 msgid "Post hidden" msgstr "게시물 숨김" +#: src/components/moderation/ModerationDetailsDialog.tsx:98 +#: src/lib/moderation/useModerationCauseDescription.ts:99 +msgid "Post Hidden by Muted Word" +msgstr "뮤트한 단어로 숨겨진 게시물" + +#: src/components/moderation/ModerationDetailsDialog.tsx:101 +#: src/lib/moderation/useModerationCauseDescription.ts:108 +msgid "Post Hidden by You" +msgstr "내가 숨긴 게시물" + #: src/view/com/composer/select-language/SelectLangBtn.tsx:87 msgid "Post language" msgstr "게시물 언어" @@ -2992,21 +3063,21 @@ msgstr "게시물 언어" msgid "Post Languages" msgstr "게시물 언어" -#: src/view/com/post-thread/PostThread.tsx:514 +#: src/view/com/post-thread/PostThread.tsx:515 msgid "Post not found" msgstr "게시물을 찾을 수 없음" #: src/components/TagMenu/index.tsx:253 msgid "posts" -msgstr "" +msgstr "게시물" -#: src/view/screens/Profile.tsx:180 +#: src/view/screens/Profile.tsx:188 msgid "Posts" msgstr "게시물" #: src/components/dialogs/MutedWords.tsx:90 msgid "Posts can be muted based on their text, their tags, or both." -msgstr "" +msgstr "게시물의 글 및 태그에 따라 게시물을 뮤트할 수 있습니다." #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" @@ -3028,14 +3099,14 @@ msgstr "주 언어" msgid "Prioritize Your Follows" msgstr "내 팔로우 먼저 표시" -#: src/view/screens/Settings/index.tsx:632 +#: src/view/screens/Settings/index.tsx:650 #: src/view/shell/desktop/RightNav.tsx:72 msgid "Privacy" msgstr "개인정보" -#: src/Navigation.tsx:219 +#: src/Navigation.tsx:231 #: src/view/screens/PrivacyPolicy.tsx:29 -#: src/view/screens/Settings/index.tsx:891 +#: src/view/screens/Settings/index.tsx:919 #: src/view/shell/Drawer.tsx:262 msgid "Privacy Policy" msgstr "개인정보 처리방침" @@ -3044,7 +3115,12 @@ msgstr "개인정보 처리방침" msgid "Processing..." msgstr "처리 중…" -#: src/view/shell/bottom-bar/BottomBar.tsx:247 +#: src/view/screens/DebugMod.tsx:888 +#: src/view/screens/Profile.tsx:340 +msgid "profile" +msgstr "프로필" + +#: src/view/shell/bottom-bar/BottomBar.tsx:249 #: src/view/shell/desktop/LeftNav.tsx:415 #: src/view/shell/Drawer.tsx:70 #: src/view/shell/Drawer.tsx:546 @@ -3056,7 +3132,7 @@ msgstr "프로필" msgid "Profile updated" msgstr "프로필 업데이트됨" -#: src/view/screens/Settings/index.tsx:949 +#: src/view/screens/Settings/index.tsx:977 msgid "Protect your account by verifying your email." msgstr "이메일을 인증하여 계정을 보호하세요." @@ -3072,11 +3148,11 @@ msgstr "일괄 뮤트하거나 차단할 수 있는 공개적이고 공유 가 msgid "Public, shareable lists which can drive feeds." msgstr "피드를 탐색할 수 있는 공개적이고 공유 가능한 목록입니다." -#: src/view/com/composer/Composer.tsx:342 +#: src/view/com/composer/Composer.tsx:351 msgid "Publish post" msgstr "게시물 게시하기" -#: src/view/com/composer/Composer.tsx:342 +#: src/view/com/composer/Composer.tsx:351 msgid "Publish reply" msgstr "답글 게시하기" @@ -3110,36 +3186,46 @@ msgstr "추천 피드" msgid "Recommended Users" msgstr "추천 사용자" -#: src/components/dialogs/MutedWords.tsx:298 +#: src/components/dialogs/MutedWords.tsx:287 +#: src/view/com/feeds/FeedSourceCard.tsx:283 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:219 -#: src/view/com/util/UserAvatar.tsx:285 -#: src/view/com/util/UserBanner.tsx:91 +#: src/view/com/posts/FeedErrorMessage.tsx:204 msgid "Remove" msgstr "제거" -#: src/view/com/feeds/FeedSourceCard.tsx:108 -msgid "Remove {0} from my feeds?" -msgstr "{0}을(를) 내 피드에서 제거하시겠습니까?" - #: src/view/com/util/AccountDropdownBtn.tsx:22 msgid "Remove account" msgstr "계정 제거" -#: src/view/com/posts/FeedErrorMessage.tsx:131 -#: src/view/com/posts/FeedErrorMessage.tsx:166 +#: src/view/com/util/UserAvatar.tsx:351 +msgid "Remove Avatar" +msgstr "아바타 제거" + +#: src/view/com/util/UserBanner.tsx:145 +msgid "Remove Banner" +msgstr "배너 제거" + +#: src/view/com/posts/FeedErrorMessage.tsx:160 msgid "Remove feed" msgstr "피드 제거" -#: src/view/com/feeds/FeedSourceCard.tsx:107 -#: src/view/com/feeds/FeedSourceCard.tsx:169 -#: src/view/com/feeds/FeedSourceCard.tsx:174 -#: src/view/com/feeds/FeedSourceCard.tsx:245 -#: src/view/screens/ProfileFeed.tsx:273 +#: src/view/com/posts/FeedErrorMessage.tsx:201 +msgid "Remove feed?" +msgstr "피드를 제거하시겠습니까?" + +#: src/view/com/feeds/FeedSourceCard.tsx:173 +#: src/view/com/feeds/FeedSourceCard.tsx:233 +#: src/view/screens/ProfileFeed.tsx:334 +#: src/view/screens/ProfileFeed.tsx:340 msgid "Remove from my feeds" msgstr "내 피드에서 제거" +#: src/view/com/feeds/FeedSourceCard.tsx:278 +msgid "Remove from my feeds?" +msgstr "내 피드에서 제거하시겠습니까?" + #: src/view/com/composer/photos/Gallery.tsx:167 msgid "Remove image" msgstr "이미지 제거" @@ -3148,37 +3234,36 @@ msgstr "이미지 제거" msgid "Remove image preview" msgstr "이미지 미리보기 제거" -#: src/components/dialogs/MutedWords.tsx:343 +#: src/components/dialogs/MutedWords.tsx:330 msgid "Remove mute word from your list" -msgstr "" +msgstr "목록에서 뮤트한 단어 제거" #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" msgstr "재게시를 취소합니다" -#: src/view/com/feeds/FeedSourceCard.tsx:175 -msgid "Remove this feed from my feeds?" -msgstr "이 피드를 내 피드에서 제거하시겠습니까?" - -#: src/view/com/posts/FeedErrorMessage.tsx:132 -msgid "Remove this feed from your saved feeds?" -msgstr "이 피드를 저장된 피드에서 제거하시겠습니까?" +#: src/view/com/posts/FeedErrorMessage.tsx:202 +msgid "Remove this feed from your saved feeds" +msgstr "저장된 피드에서 이 피드를 제거합니다" #: src/view/com/modals/ListAddRemoveUsers.tsx:199 #: src/view/com/modals/UserAddRemoveLists.tsx:152 msgid "Removed from list" msgstr "리스트에서 제거됨" -#: src/view/com/feeds/FeedSourceCard.tsx:113 -#: src/view/com/feeds/FeedSourceCard.tsx:180 +#: src/view/com/feeds/FeedSourceCard.tsx:121 msgid "Removed from my feeds" msgstr "내 피드에서 제거됨" +#: src/view/screens/ProfileFeed.tsx:208 +msgid "Removed from your feeds" +msgstr "내 피드에서 제거됨" + #: src/view/com/composer/ExternalEmbed.tsx:71 msgid "Removes default thumbnail from {0}" msgstr "{0}에서 기본 미리보기 이미지를 제거합니다" -#: src/view/screens/Profile.tsx:181 +#: src/view/screens/Profile.tsx:189 msgid "Replies" msgstr "답글" @@ -3186,7 +3271,7 @@ msgstr "답글" msgid "Replies to this thread are disabled" msgstr "이 스레드에 대한 답글이 비활성화됩니다." -#: src/view/com/composer/Composer.tsx:355 +#: src/view/com/composer/Composer.tsx:364 msgctxt "action" msgid "Reply" msgstr "답글" @@ -3195,34 +3280,51 @@ msgstr "답글" msgid "Reply Filters" msgstr "답글 필터" -#: src/view/com/post/Post.tsx:167 -#: src/view/com/posts/FeedItem.tsx:287 +#: src/view/com/post/Post.tsx:169 +#: src/view/com/posts/FeedItem.tsx:283 msgctxt "description" msgid "Reply to <0/>" msgstr "<0/> 님에게 보내는 답글" -#: src/view/com/modals/report/Modal.tsx:166 -msgid "Report {collectionName}" -msgstr "{collectionName} 신고" - -#: src/view/com/profile/ProfileHeader.tsx:361 +#: src/view/com/profile/ProfileMenu.tsx:319 +#: src/view/com/profile/ProfileMenu.tsx:322 msgid "Report Account" msgstr "계정 신고" -#: src/view/screens/ProfileFeed.tsx:293 +#: src/view/screens/ProfileFeed.tsx:351 +#: src/view/screens/ProfileFeed.tsx:353 msgid "Report feed" msgstr "피드 신고" -#: src/view/screens/ProfileList.tsx:459 +#: src/view/screens/ProfileList.tsx:429 msgid "Report List" msgstr "리스트 신고" -#: src/view/com/modals/report/SendReportButton.tsx:37 -#: src/view/com/util/forms/PostDropdownBtn.tsx:301 -#: src/view/com/util/forms/PostDropdownBtn.tsx:309 +#: src/view/com/util/forms/PostDropdownBtn.tsx:292 +#: src/view/com/util/forms/PostDropdownBtn.tsx:294 msgid "Report post" msgstr "게시물 신고" +#: src/components/ReportDialog/SelectReportOptionView.tsx:42 +msgid "Report this content" +msgstr "이 콘텐츠 신고하기" + +#: src/components/ReportDialog/SelectReportOptionView.tsx:55 +msgid "Report this feed" +msgstr "이 피드 신고하기" + +#: src/components/ReportDialog/SelectReportOptionView.tsx:52 +msgid "Report this list" +msgstr "이 리스트 신고하기" + +#: src/components/ReportDialog/SelectReportOptionView.tsx:49 +msgid "Report this post" +msgstr "이 게시물 신고하기" + +#: src/components/ReportDialog/SelectReportOptionView.tsx:46 +msgid "Report this user" +msgstr "이 사용자 신고하기" + #: src/view/com/modals/Repost.tsx:43 #: src/view/com/modals/Repost.tsx:48 #: src/view/com/modals/Repost.tsx:53 @@ -3244,11 +3346,11 @@ msgstr "재게시 또는 게시물 인용" msgid "Reposted By" msgstr "재게시한 사용자" -#: src/view/com/posts/FeedItem.tsx:207 +#: src/view/com/posts/FeedItem.tsx:201 msgid "Reposted by {0}" msgstr "{0} 님이 재게시함" -#: src/view/com/posts/FeedItem.tsx:224 +#: src/view/com/posts/FeedItem.tsx:218 msgid "Reposted by <0/>" msgstr "<0/> 님이 재게시함" @@ -3256,7 +3358,7 @@ msgstr "<0/> 님이 재게시함" msgid "reposted your post" msgstr "님이 내 게시물을 재게시했습니다" -#: src/view/com/post-thread/PostThreadItem.tsx:188 +#: src/view/com/post-thread/PostThreadItem.tsx:187 msgid "Reposts of this post" msgstr "이 게시물의 재게시" @@ -3265,16 +3367,12 @@ msgstr "이 게시물의 재게시" msgid "Request Change" msgstr "변경 요청" -#: src/view/com/auth/create/Step2.tsx:219 -#~ msgid "Request code" -#~ msgstr "코드 요청" - #: src/view/com/modals/ChangePassword.tsx:239 #: src/view/com/modals/ChangePassword.tsx:241 msgid "Request Code" -msgstr "" +msgstr "코드 요청" -#: src/view/screens/Settings/index.tsx:456 +#: src/view/screens/Settings/index.tsx:474 msgid "Require alt text before posting" msgstr "게시하기 전 대체 텍스트 필수" @@ -3289,13 +3387,13 @@ msgstr "재설정 코드" #: src/view/com/modals/ChangePassword.tsx:190 msgid "Reset Code" -msgstr "" +msgstr "재설정 코드" -#: src/view/screens/Settings/index.tsx:824 +#: src/view/screens/Settings/index.tsx:852 msgid "Reset onboarding" msgstr "온보딩 초기화" -#: src/view/screens/Settings/index.tsx:827 +#: src/view/screens/Settings/index.tsx:855 msgid "Reset onboarding state" msgstr "온보딩 상태 초기화" @@ -3303,19 +3401,19 @@ msgstr "온보딩 상태 초기화" msgid "Reset password" msgstr "비밀번호 재설정" -#: src/view/screens/Settings/index.tsx:814 +#: src/view/screens/Settings/index.tsx:842 msgid "Reset preferences" msgstr "설정 초기화" -#: src/view/screens/Settings/index.tsx:817 +#: src/view/screens/Settings/index.tsx:845 msgid "Reset preferences state" msgstr "설정 상태 초기화" -#: src/view/screens/Settings/index.tsx:825 +#: src/view/screens/Settings/index.tsx:853 msgid "Resets the onboarding state" msgstr "온보딩 상태 초기화" -#: src/view/screens/Settings/index.tsx:815 +#: src/view/screens/Settings/index.tsx:843 msgid "Resets the preferences state" msgstr "설정 상태 초기화" @@ -3339,17 +3437,16 @@ msgstr "오류가 발생한 마지막 작업을 다시 시도합니다" msgid "Retry" msgstr "다시 시도" -#: src/view/com/auth/create/Step2.tsx:247 -#~ msgid "Retry." -#~ msgstr "다시 시도하기" - -#: src/view/screens/ProfileList.tsx:903 +#: src/view/screens/ProfileList.tsx:917 msgid "Return to previous page" msgstr "이전 페이지로 돌아갑니다" -#: src/view/shell/desktop/RightNav.tsx:55 -#~ msgid "SANDBOX. Posts and accounts are not permanent." -#~ msgstr "샌드박스. 글과 계정은 영구적이지 않습니다." +#: src/components/dialogs/BirthDateSettings.tsx:118 +#: src/view/com/modals/ChangeHandle.tsx:173 +#: src/view/com/modals/CreateOrEditList.tsx:337 +#: src/view/com/modals/EditProfile.tsx:224 +msgid "Save" +msgstr "저장" #: src/view/com/lightbox/Lightbox.tsx:132 #: src/view/com/modals/CreateOrEditList.tsx:345 @@ -3357,19 +3454,14 @@ msgctxt "action" msgid "Save" msgstr "저장" -#: src/view/com/modals/BirthDateSettings.tsx:94 -#: src/view/com/modals/BirthDateSettings.tsx:97 -#: src/view/com/modals/ChangeHandle.tsx:173 -#: src/view/com/modals/CreateOrEditList.tsx:337 -#: src/view/com/modals/EditProfile.tsx:224 -#: src/view/screens/ProfileFeed.tsx:346 -msgid "Save" -msgstr "저장" - #: src/view/com/modals/AltImage.tsx:130 msgid "Save alt text" msgstr "대체 텍스트 저장" +#: src/components/dialogs/BirthDateSettings.tsx:112 +msgid "Save birthday" +msgstr "생년월일 저장" + #: src/view/com/modals/EditProfile.tsx:232 msgid "Save Changes" msgstr "변경 사항 저장" @@ -3382,10 +3474,19 @@ msgstr "핸들 변경 저장" msgid "Save image crop" msgstr "이미지 자르기 저장" +#: src/view/screens/ProfileFeed.tsx:335 +#: src/view/screens/ProfileFeed.tsx:341 +msgid "Save to my feeds" +msgstr "내 피드에 저장" + #: src/view/screens/SavedFeeds.tsx:122 msgid "Saved Feeds" msgstr "저장된 피드" +#: src/view/screens/ProfileFeed.tsx:212 +msgid "Saved to your feeds" +msgstr "내 피드에 저장됨" + #: src/view/com/modals/EditProfile.tsx:225 msgid "Saves any changes to your profile" msgstr "프로필에 대한 모든 변경 사항을 저장합니다" @@ -3398,11 +3499,11 @@ msgstr "핸들을 {handle}(으)로 변경합니다" msgid "Science" msgstr "과학" -#: src/view/screens/ProfileList.tsx:859 +#: src/view/screens/ProfileList.tsx:873 msgid "Scroll to top" msgstr "맨 위로 스크롤" -#: src/Navigation.tsx:447 +#: src/Navigation.tsx:459 #: src/view/com/auth/LoggedOut.tsx:122 #: src/view/com/modals/ListAddRemoveUsers.tsx:75 #: src/view/com/util/forms/SearchInput.tsx:67 @@ -3410,7 +3511,7 @@ msgstr "맨 위로 스크롤" #: src/view/screens/Search/Search.tsx:419 #: src/view/screens/Search/Search.tsx:668 #: src/view/screens/Search/Search.tsx:686 -#: src/view/shell/bottom-bar/BottomBar.tsx:159 +#: src/view/shell/bottom-bar/BottomBar.tsx:161 #: src/view/shell/desktop/LeftNav.tsx:324 #: src/view/shell/desktop/Search.tsx:214 #: src/view/shell/desktop/Search.tsx:223 @@ -3426,19 +3527,11 @@ msgstr "\"{query}\"에 대한 검색 결과" #: src/components/TagMenu/index.tsx:145 msgid "Search for all posts by @{authorHandle} with tag {displayTag}" -msgstr "" - -#: src/components/TagMenu/index.tsx:145 -#~ msgid "Search for all posts by @{authorHandle} with tag {tag}" -#~ msgstr "" +msgstr "{displayTag} 태그를 사용한 @{authorHandle} 님의 모든 게시물 검색" #: src/components/TagMenu/index.tsx:94 msgid "Search for all posts with tag {displayTag}" -msgstr "" - -#: src/components/TagMenu/index.tsx:90 -#~ msgid "Search for all posts with tag {tag}" -#~ msgstr "" +msgstr "{displayTag} 태그를 사용한 모든 게시물 검색" #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 @@ -3452,27 +3545,19 @@ msgstr "보안 단계 필요" #: src/components/TagMenu/index.web.tsx:66 msgid "See {truncatedTag} posts" -msgstr "" +msgstr "{truncatedTag} 게시물 보기" #: src/components/TagMenu/index.web.tsx:83 msgid "See {truncatedTag} posts by user" -msgstr "" +msgstr "이 사용자의 {truncatedTag} 게시물 보기" #: src/components/TagMenu/index.tsx:128 msgid "See <0>{displayTag}</0> posts" -msgstr "" +msgstr "<0>{displayTag}</0> 게시물 보기" #: src/components/TagMenu/index.tsx:187 msgid "See <0>{displayTag}</0> posts by this user" -msgstr "" - -#: src/components/TagMenu/index.tsx:128 -#~ msgid "See <0>{tag}</0> posts" -#~ msgstr "" - -#: src/components/TagMenu/index.tsx:189 -#~ msgid "See <0>{tag}</0> posts by this user" -#~ msgstr "" +msgstr "이 사용자의 <0>{displayTag}</0> 게시물 보기" #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" @@ -3486,14 +3571,14 @@ msgstr "See what's next" msgid "Select {item}" msgstr "{item} 선택" -#: src/view/com/modals/ServerInput.tsx:75 -#~ msgid "Select Bluesky Social" -#~ msgstr "Bluesky Social 선택" - #: src/view/com/auth/login/Login.tsx:117 msgid "Select from an existing account" msgstr "기존 계정에서 선택" +#: src/components/ReportDialog/SelectLabelerView.tsx:30 +msgid "Select moderation service" +msgstr "검토 서비스 선택하기" + #: src/view/com/util/Selector.tsx:107 msgid "Select option {i} of {numItems}" msgstr "{numItems}개 중 {i}번째 옵션을 선택합니다" @@ -3507,15 +3592,19 @@ msgstr "서비스 선택" msgid "Select some accounts below to follow" msgstr "아래에서 팔로우할 계정을 선택하세요" +#: src/components/ReportDialog/SubmitView.tsx:135 +msgid "Select the moderation service(s) to report to" +msgstr "신고할 검토 서비스를 선택합니다." + #: src/view/com/auth/server-input/index.tsx:82 msgid "Select the service that hosts your data." -msgstr "" +msgstr "데이터를 호스팅할 서비스를 선택하세요." #: src/screens/Onboarding/StepTopicalFeeds.tsx:96 msgid "Select topical feeds to follow from the list below" msgstr "아래 목록에서 팔로우할 화제 피드를 선택하세요" -#: src/screens/Onboarding/StepModeration/index.tsx:75 +#: src/screens/Onboarding/StepModeration/index.tsx:62 msgid "Select what you want to see (or not see), and we’ll handle the rest." msgstr "보고 싶거나 보고 싶지 않은 항목을 선택하면 나머지는 알아서 처리해 드립니다." @@ -3531,10 +3620,6 @@ msgstr "앱에 표시되는 기본 텍스트 언어를 선택합니다." msgid "Select your interests from the options below" msgstr "아래 옵션에서 관심사를 선택하세요" -#: src/view/com/auth/create/Step2.tsx:155 -#~ msgid "Select your phone's country" -#~ msgstr "전화번호 국가 선택" - #: src/view/screens/LanguageSettings.tsx:190 msgid "Select your preferred language for translations in your feed." msgstr "피드에서 번역을 위해 선호하는 언어를 선택합니다." @@ -3566,47 +3651,46 @@ msgstr "이메일 보내기" msgid "Send feedback" msgstr "피드백 보내기" -#: src/view/com/modals/report/SendReportButton.tsx:45 -msgid "Send Report" +#: src/components/ReportDialog/SubmitView.tsx:214 +#: src/components/ReportDialog/SubmitView.tsx:218 +msgid "Send report" msgstr "신고 보내기" +#: src/components/ReportDialog/SelectLabelerView.tsx:44 +msgid "Send report to {0}" +msgstr "{0} 님에게 신고 보내기" + #: src/view/com/modals/DeleteAccount.tsx:133 msgid "Sends email with confirmation code for account deletion" msgstr "계정 삭제를 위한 확인 코드가 포함된 이메일을 전송합니다" #: src/view/com/auth/server-input/index.tsx:110 msgid "Server address" -msgstr "" +msgstr "서버 주소" -#: src/view/com/modals/ContentFilteringSettings.tsx:311 -msgid "Set {value} for {labelGroup} content moderation policy" -msgstr "{labelGroup} 콘텐츠 관리 정책에 대해 {value}을(를) 설정합니다" +#: src/screens/Moderation/index.tsx:307 +msgid "Set birthdate" +msgstr "생년월일 설정" -#: src/view/com/modals/ContentFilteringSettings.tsx:160 -#: src/view/com/modals/ContentFilteringSettings.tsx:179 -msgctxt "action" -msgid "Set Age" -msgstr "나이 설정" - -#: src/view/screens/Settings/index.tsx:488 +#: src/view/screens/Settings/index.tsx:506 msgid "Set color theme to dark" msgstr "색상 테마를 어두움으로 설정합니다" -#: src/view/screens/Settings/index.tsx:481 +#: src/view/screens/Settings/index.tsx:499 msgid "Set color theme to light" msgstr "색상 테마를 밝음으로 설정합니다" -#: src/view/screens/Settings/index.tsx:475 +#: src/view/screens/Settings/index.tsx:493 msgid "Set color theme to system setting" msgstr "색상 테마를 시스템 설정에 맞춥니다" -#: src/view/screens/Settings/index.tsx:514 +#: src/view/screens/Settings/index.tsx:532 msgid "Set dark theme to the dark theme" -msgstr "" +msgstr "어두운 테마를 완전히 어둡게 설정합니다" -#: src/view/screens/Settings/index.tsx:507 +#: src/view/screens/Settings/index.tsx:525 msgid "Set dark theme to the dim theme" -msgstr "" +msgstr "어두운 테마를 살짝 밝게 설정합니다" #: src/view/com/auth/login/SetNewPasswordForm.tsx:104 msgid "Set new password" @@ -3632,13 +3716,9 @@ msgstr "피드에서 모든 재게시를 숨기려면 이 설정을 \"아니요\ msgid "Set this setting to \"Yes\" to show replies in a threaded view. This is an experimental feature." msgstr "스레드 보기에 답글을 표시하려면 이 설정을 \"예\"로 설정합니다. 이는 실험적인 기능입니다." -#: src/view/screens/PreferencesHomeFeed.tsx:261 -#~ msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your following feed. This is an experimental feature." -#~ msgstr "팔로우한 피드에 저장된 피드 샘플을 표시하려면 이 설정을 \"예\"로 설정합니다. 이는 실험적인 기능입니다." - #: src/view/screens/PreferencesFollowingFeed.tsx:261 msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your Following feed. This is an experimental feature." -msgstr "" +msgstr "팔로우 중 피드에 저장된 피드 샘플을 표시하려면 이 설정을 \"예\"로 설정합니다. 이는 실험적인 기능입니다." #: src/screens/Onboarding/Layout.tsx:50 msgid "Set up your account" @@ -3661,8 +3741,8 @@ msgstr "비밀번호 재설정을 위한 호스팅 제공자를 설정합니다" msgid "Sets server for the Bluesky client" msgstr "Bluesky 클라이언트를 위한 서버를 설정합니다" -#: src/Navigation.tsx:137 -#: src/view/screens/Settings/index.tsx:294 +#: src/Navigation.tsx:139 +#: src/view/screens/Settings/index.tsx:312 #: src/view/shell/desktop/LeftNav.tsx:433 #: src/view/shell/Drawer.tsx:567 #: src/view/shell/Drawer.tsx:568 @@ -3673,28 +3753,39 @@ msgstr "설정" msgid "Sexual activity or erotic nudity." msgstr "성행위 또는 선정적인 노출." +#: src/lib/moderation/useGlobalLabelStrings.ts:38 +msgid "Sexually Suggestive" +msgstr "외설적" + #: src/view/com/lightbox/Lightbox.tsx:141 msgctxt "action" msgid "Share" msgstr "공유" -#: src/view/com/profile/ProfileHeader.tsx:295 -#: src/view/com/util/forms/PostDropdownBtn.tsx:231 +#: src/view/com/profile/ProfileMenu.tsx:215 +#: src/view/com/profile/ProfileMenu.tsx:224 +#: src/view/com/util/forms/PostDropdownBtn.tsx:228 #: src/view/com/util/forms/PostDropdownBtn.tsx:237 -#: src/view/com/util/post-ctrls/PostCtrls.tsx:215 -#: src/view/screens/ProfileList.tsx:418 +#: src/view/com/util/post-ctrls/PostCtrls.tsx:218 +#: src/view/screens/ProfileList.tsx:388 msgid "Share" msgstr "공유" -#: src/view/screens/ProfileFeed.tsx:305 +#: src/view/com/profile/ProfileMenu.tsx:373 +#: src/view/com/util/forms/PostDropdownBtn.tsx:347 +msgid "Share anyway" +msgstr "무시하고 공유" + +#: src/view/screens/ProfileFeed.tsx:361 +#: src/view/screens/ProfileFeed.tsx:363 msgid "Share feed" msgstr "피드 공유" -#: src/screens/Onboarding/StepModeration/ModerationOption.tsx:43 -#: src/view/com/modals/ContentFilteringSettings.tsx:266 -#: src/view/com/util/moderation/ContentHider.tsx:107 -#: src/view/com/util/moderation/PostHider.tsx:108 -#: src/view/screens/Settings/index.tsx:344 +#: src/components/moderation/ContentHider.tsx:115 +#: src/components/moderation/GlobalModerationLabelPref.tsx:45 +#: src/components/moderation/PostHider.tsx:107 +#: src/screens/Onboarding/StepModeration/ModerationOption.tsx:54 +#: src/view/screens/Settings/index.tsx:362 msgid "Show" msgstr "표시" @@ -3702,21 +3793,31 @@ msgstr "표시" msgid "Show all replies" msgstr "모든 답글 표시" -#: src/view/com/util/moderation/ScreenHider.tsx:132 +#: src/components/moderation/ScreenHider.tsx:161 +#: src/components/moderation/ScreenHider.tsx:164 msgid "Show anyway" msgstr "무시하고 표시" +#: src/lib/moderation/useLabelBehaviorDescription.ts:27 +#: src/lib/moderation/useLabelBehaviorDescription.ts:63 +msgid "Show badge" +msgstr "배지 표시" + +#: src/lib/moderation/useLabelBehaviorDescription.ts:61 +msgid "Show badge and filter from feeds" +msgstr "배지 표시 및 피드에서 필터링" + #: src/view/com/modals/EmbedConsent.tsx:87 msgid "Show embeds from {0}" msgstr "{0} 임베드 표시" -#: src/view/com/profile/ProfileHeader.tsx:459 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:193 msgid "Show follows similar to {0}" msgstr "{0} 님과 비슷한 팔로우 표시" -#: src/view/com/post-thread/PostThreadItem.tsx:538 -#: src/view/com/post/Post.tsx:198 -#: src/view/com/posts/FeedItem.tsx:363 +#: src/view/com/post-thread/PostThreadItem.tsx:509 +#: src/view/com/post/Post.tsx:204 +#: src/view/com/posts/FeedItem.tsx:358 msgid "Show More" msgstr "더 보기" @@ -3730,15 +3831,15 @@ msgstr "인용 게시물 표시" #: src/screens/Onboarding/StepFollowingFeed.tsx:118 msgid "Show quote-posts in Following feed" -msgstr "팔로우 중인 피드에 인용 게시물 표시" +msgstr "팔로우 중 피드에 인용 게시물 표시" #: src/screens/Onboarding/StepFollowingFeed.tsx:134 msgid "Show quotes in Following" -msgstr "팔로우 중인 피드에 인용 표시" +msgstr "팔로우 중 피드에 인용 표시" #: src/screens/Onboarding/StepFollowingFeed.tsx:94 msgid "Show re-posts in Following feed" -msgstr "팔로우 중인 피드에 재게시 표시" +msgstr "팔로우 중 피드에 재게시 표시" #: src/view/screens/PreferencesFollowingFeed.tsx:119 msgid "Show Replies" @@ -3750,11 +3851,11 @@ msgstr "내가 팔로우하는 사람들의 답글을 다른 모든 답글보다 #: src/screens/Onboarding/StepFollowingFeed.tsx:86 msgid "Show replies in Following" -msgstr "팔로우 중인 피드에 답글 표시" +msgstr "팔로우 중 피드에 답글 표시" #: src/screens/Onboarding/StepFollowingFeed.tsx:70 msgid "Show replies in Following feed" -msgstr "팔로우 중인 피드에 답글 표시" +msgstr "팔로우 중 피드에 답글 표시" #: src/view/screens/PreferencesFollowingFeed.tsx:70 msgid "Show replies with at least {value} {0}" @@ -3766,32 +3867,35 @@ msgstr "재게시 표시" #: src/screens/Onboarding/StepFollowingFeed.tsx:110 msgid "Show reposts in Following" -msgstr "팔로우 중인 피드에 재게시 표시" +msgstr "팔로우 중 피드에 재게시 표시" -#: src/view/com/util/moderation/ContentHider.tsx:67 -#: src/view/com/util/moderation/PostHider.tsx:61 +#: src/components/moderation/ContentHider.tsx:68 +#: src/components/moderation/PostHider.tsx:64 msgid "Show the content" msgstr "콘텐츠 표시" -#: src/view/com/notifications/FeedItem.tsx:347 +#: src/view/com/notifications/FeedItem.tsx:346 msgid "Show users" msgstr "사용자 표시" -#: src/view/com/profile/ProfileHeader.tsx:462 -msgid "Shows a list of users similar to this user." -msgstr "이 사용자와 유사한 사용자 목록을 표시합니다" +#: src/lib/moderation/useLabelBehaviorDescription.ts:58 +msgid "Show warning" +msgstr "경고 표시" -#: src/view/com/post-thread/PostThreadFollowBtn.tsx:124 -#: src/view/com/profile/ProfileHeader.tsx:506 +#: src/lib/moderation/useLabelBehaviorDescription.ts:56 +msgid "Show warning and filter from feeds" +msgstr "경고 표시 및 피드에서 필터링" + +#: src/view/com/post-thread/PostThreadFollowBtn.tsx:127 msgid "Shows posts from {0} in your feed" msgstr "피드에 {0} 님의 게시물을 표시합니다" #: src/view/com/auth/HomeLoggedOutCTA.tsx:70 #: src/view/com/auth/login/Login.tsx:98 #: src/view/com/auth/SplashScreen.tsx:79 -#: src/view/shell/bottom-bar/BottomBar.tsx:285 -#: src/view/shell/bottom-bar/BottomBar.tsx:286 +#: src/view/shell/bottom-bar/BottomBar.tsx:287 #: src/view/shell/bottom-bar/BottomBar.tsx:288 +#: src/view/shell/bottom-bar/BottomBar.tsx:290 #: src/view/shell/bottom-bar/BottomBarWeb.tsx:178 #: src/view/shell/bottom-bar/BottomBarWeb.tsx:179 #: src/view/shell/bottom-bar/BottomBarWeb.tsx:181 @@ -3821,14 +3925,14 @@ msgstr "로그인" #: src/view/com/modals/SwitchAccount.tsx:64 #: src/view/com/modals/SwitchAccount.tsx:69 -#: src/view/screens/Settings/index.tsx:100 -#: src/view/screens/Settings/index.tsx:103 +#: src/view/screens/Settings/index.tsx:104 +#: src/view/screens/Settings/index.tsx:107 msgid "Sign out" msgstr "로그아웃" -#: src/view/shell/bottom-bar/BottomBar.tsx:275 -#: src/view/shell/bottom-bar/BottomBar.tsx:276 +#: src/view/shell/bottom-bar/BottomBar.tsx:277 #: src/view/shell/bottom-bar/BottomBar.tsx:278 +#: src/view/shell/bottom-bar/BottomBar.tsx:280 #: src/view/shell/bottom-bar/BottomBarWeb.tsx:168 #: src/view/shell/bottom-bar/BottomBarWeb.tsx:169 #: src/view/shell/bottom-bar/BottomBarWeb.tsx:171 @@ -3842,11 +3946,12 @@ msgstr "가입하기" msgid "Sign up or sign in to join the conversation" msgstr "가입 또는 로그인하여 대화에 참여하세요" -#: src/view/com/util/moderation/ScreenHider.tsx:76 +#: src/components/moderation/ScreenHider.tsx:97 +#: src/lib/moderation/useGlobalLabelStrings.ts:28 msgid "Sign-in Required" msgstr "로그인 필요" -#: src/view/screens/Settings/index.tsx:355 +#: src/view/screens/Settings/index.tsx:373 msgid "Signed in as" msgstr "로그인한 계정" @@ -3868,27 +3973,21 @@ msgstr "건너뛰기" msgid "Skip this flow" msgstr "이 단계 건너뛰기" -#: src/view/com/auth/create/Step2.tsx:82 -#~ msgid "SMS verification" -#~ msgstr "SMS 인증" - #: src/screens/Onboarding/index.tsx:40 msgid "Software Dev" msgstr "소프트웨어 개발" -#: src/view/com/modals/ProfilePreview.tsx:62 -#~ msgid "Something went wrong and we're not sure what." -#~ msgstr "문제가 발생했지만 원인을 알 수 없습니다." +#: src/components/ReportDialog/index.tsx:50 +#: src/screens/Moderation/index.tsx:116 +#: src/screens/Profile/Sections/Labels.tsx:88 +msgid "Something went wrong, please try again." +msgstr "뭔가 잘못되었습니다. 다시 시도해 주세요." -#: src/components/Lists.tsx:203 +#: src/components/Lists.tsx:202 msgid "Something went wrong!" -msgstr "" +msgstr "뭔가 잘못되었습니다!" -#: src/view/com/modals/Waitlist.tsx:51 -#~ msgid "Something went wrong. Check your email and try again." -#~ msgstr "문제가 발생했습니다. 이메일을 확인한 후 다시 시도하세요." - -#: src/App.native.tsx:66 +#: src/App.native.tsx:71 msgid "Sorry! Your session expired. Please log in again." msgstr "죄송합니다. 세션이 만료되었습니다. 다시 로그인해 주세요." @@ -3900,6 +3999,18 @@ msgstr "답글 정렬" msgid "Sort replies to the same post by:" msgstr "동일한 게시물에 대한 답글을 정렬하는 기준입니다." +#: src/components/moderation/LabelsOnMeDialog.tsx:147 +msgid "Source:" +msgstr "출처:" + +#: src/lib/moderation/useReportOptions.ts:65 +msgid "Spam" +msgstr "스팸" + +#: src/lib/moderation/useReportOptions.ts:53 +msgid "Spam; excessive mentions or replies" +msgstr "스팸, 과도한 멘션 또는 답글" + #: src/screens/Onboarding/index.tsx:30 msgid "Sports" msgstr "스포츠" @@ -3908,11 +4019,7 @@ msgstr "스포츠" msgid "Square" msgstr "정사각형" -#: src/view/com/modals/ServerInput.tsx:62 -#~ msgid "Staging" -#~ msgstr "스테이징" - -#: src/view/screens/Settings/index.tsx:871 +#: src/view/screens/Settings/index.tsx:899 msgid "Status page" msgstr "상태 페이지" @@ -3920,29 +4027,42 @@ msgstr "상태 페이지" msgid "Step {0} of {numSteps}" msgstr "{numSteps}단계 중 {0}단계" -#: src/view/screens/Settings/index.tsx:274 +#: src/view/screens/Settings/index.tsx:288 msgid "Storage cleared, you need to restart the app now." msgstr "스토리지가 지워졌으며 지금 앱을 다시 시작해야 합니다." -#: src/Navigation.tsx:204 -#: src/view/screens/Settings/index.tsx:807 +#: src/Navigation.tsx:211 +#: src/view/screens/Settings/index.tsx:825 msgid "Storybook" msgstr "스토리북" -#: src/view/com/modals/AppealLabel.tsx:101 +#: src/components/moderation/LabelsOnMeDialog.tsx:256 +#: src/components/moderation/LabelsOnMeDialog.tsx:257 msgid "Submit" msgstr "확인" -#: src/view/screens/ProfileList.tsx:608 +#: src/view/screens/ProfileList.tsx:590 msgid "Subscribe" msgstr "구독" +#: src/screens/Profile/Sections/Labels.tsx:199 +msgid "Subscribe to @{0} to use these labels:" +msgstr "이 라벨을 사용하려면 @{0} 님을 구독하세요:" + +#: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:222 +msgid "Subscribe to Labeler" +msgstr "라벨러 구독" + #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:173 #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:308 msgid "Subscribe to the {0} feed" msgstr "{0} 피드 구독하기" -#: src/view/screens/ProfileList.tsx:604 +#: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:185 +msgid "Subscribe to this labeler" +msgstr "이 라벨러 구독하기" + +#: src/view/screens/ProfileList.tsx:586 msgid "Subscribe to this list" msgstr "이 리스트 구독하기" @@ -3958,49 +4078,41 @@ msgstr "나를 위한 추천" msgid "Suggestive" msgstr "외설적" -#: src/Navigation.tsx:214 +#: src/Navigation.tsx:226 #: src/view/screens/Support.tsx:30 #: src/view/screens/Support.tsx:33 msgid "Support" msgstr "지원" -#: src/view/com/modals/ProfilePreview.tsx:110 -#~ msgid "Swipe up to see more" -#~ msgstr "위로 스와이프하여 더 보기" - #: src/view/com/modals/SwitchAccount.tsx:117 msgid "Switch Account" msgstr "계정 전환" #: src/view/com/modals/SwitchAccount.tsx:97 -#: src/view/screens/Settings/index.tsx:130 +#: src/view/screens/Settings/index.tsx:134 msgid "Switch to {0}" msgstr "{0}(으)로 전환" #: src/view/com/modals/SwitchAccount.tsx:98 -#: src/view/screens/Settings/index.tsx:131 +#: src/view/screens/Settings/index.tsx:135 msgid "Switches the account you are logged in to" msgstr "로그인한 계정을 전환합니다" -#: src/view/screens/Settings/index.tsx:472 +#: src/view/screens/Settings/index.tsx:490 msgid "System" msgstr "시스템" -#: src/view/screens/Settings/index.tsx:795 +#: src/view/screens/Settings/index.tsx:813 msgid "System log" msgstr "시스템 로그" -#: src/components/dialogs/MutedWords.tsx:337 +#: src/components/dialogs/MutedWords.tsx:324 msgid "tag" -msgstr "" +msgstr "태그" #: src/components/TagMenu/index.tsx:78 msgid "Tag menu: {displayTag}" -msgstr "" - -#: src/components/TagMenu/index.tsx:74 -#~ msgid "Tag menu: {tag}" -#~ msgstr "" +msgstr "태그 메뉴: {displayTag}" #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" @@ -4018,29 +4130,43 @@ msgstr "기술" msgid "Terms" msgstr "이용약관" -#: src/Navigation.tsx:224 -#: src/view/screens/Settings/index.tsx:885 +#: src/Navigation.tsx:236 +#: src/view/screens/Settings/index.tsx:913 #: src/view/screens/TermsOfService.tsx:29 #: src/view/shell/Drawer.tsx:256 msgid "Terms of Service" msgstr "서비스 이용약관" -#: src/components/dialogs/MutedWords.tsx:337 -msgid "text" -msgstr "" +#: src/lib/moderation/useReportOptions.ts:58 +#: src/lib/moderation/useReportOptions.ts:79 +#: src/lib/moderation/useReportOptions.ts:87 +msgid "Terms used violate community standards" +msgstr "커뮤니티 기준을 위반하는 용어 사용" -#: src/view/com/modals/AppealLabel.tsx:70 -#: src/view/com/modals/report/InputIssueDetails.tsx:51 +#: src/components/dialogs/MutedWords.tsx:324 +msgid "text" +msgstr "글" + +#: src/components/moderation/LabelsOnMeDialog.tsx:220 msgid "Text input field" msgstr "텍스트 입력 필드" +#: src/components/ReportDialog/SubmitView.tsx:78 +msgid "Thank you. Your report has been sent." +msgstr "감사합니다. 신고를 전송했습니다." + #: src/view/com/auth/create/CreateAccount.tsx:94 msgid "That handle is already taken." -msgstr "" +msgstr "이 핸들은 이미 사용 중입니다." -#: src/view/com/profile/ProfileHeader.tsx:263 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:274 +#: src/view/com/profile/ProfileMenu.tsx:349 msgid "The account will be able to interact with you after unblocking." -msgstr "차단을 해제하면 해당 계정이 나와 상호작용할 수 있게 됩니다." +msgstr "차단을 해제하면 이 계정이 나와 상호작용할 수 있게 됩니다." + +#: src/components/moderation/ModerationDetailsDialog.tsx:128 +msgid "the author" +msgstr "작성자" #: src/view/screens/CommunityGuidelines.tsx:36 msgid "The Community Guidelines have been moved to <0/>" @@ -4050,11 +4176,19 @@ msgstr "커뮤니티 가이드라인을 <0/>(으)로 이동했습니다" msgid "The Copyright Policy has been moved to <0/>" msgstr "저작권 정책을 <0/>(으)로 이동했습니다" +#: src/components/moderation/LabelsOnMeDialog.tsx:49 +msgid "The following labels were applied to your account." +msgstr "내 계정에 다음 라벨이 적용되었습니다." + +#: src/components/moderation/LabelsOnMeDialog.tsx:50 +msgid "The following labels were applied to your content." +msgstr "내 콘텐츠에 다음 라벨이 적용되었습니다." + #: src/screens/Onboarding/Layout.tsx:60 msgid "The following steps will help customize your Bluesky experience." msgstr "다음 단계는 Bluesky 환경을 맞춤 설정하는 데 도움이 됩니다." -#: src/view/com/post-thread/PostThread.tsx:517 +#: src/view/com/post-thread/PostThread.tsx:518 msgid "The post may have been deleted." msgstr "게시물이 삭제되었을 수 있습니다." @@ -4074,20 +4208,21 @@ msgstr "서비스 이용약관을 다음으로 이동했습니다:" msgid "There are many feeds to try:" msgstr "시도해 볼 만한 피드:" -#: src/view/screens/ProfileFeed.tsx:550 +#: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:113 +#: src/view/screens/ProfileFeed.tsx:543 msgid "There was an an issue contacting the server, please check your internet connection and try again." msgstr "서버에 연결하는 동안 문제가 발생했습니다. 인터넷 연결을 확인한 후 다시 시도하세요." -#: src/view/com/posts/FeedErrorMessage.tsx:139 +#: src/view/com/posts/FeedErrorMessage.tsx:138 msgid "There was an an issue removing this feed. Please check your internet connection and try again." msgstr "이 피드를 삭제하는 동안 문제가 발생했습니다. 인터넷 연결을 확인한 후 다시 시도하세요." -#: src/view/screens/ProfileFeed.tsx:210 +#: src/view/screens/ProfileFeed.tsx:217 msgid "There was an an issue updating your feeds, please check your internet connection and try again." msgstr "피드를 업데이트하는 동안 문제가 발생했습니다. 인터넷 연결을 확인한 후 다시 시도하세요." -#: src/view/screens/ProfileFeed.tsx:237 -#: src/view/screens/ProfileList.tsx:267 +#: src/view/screens/ProfileFeed.tsx:244 +#: src/view/screens/ProfileList.tsx:275 #: src/view/screens/SavedFeeds.tsx:209 #: src/view/screens/SavedFeeds.tsx:231 #: src/view/screens/SavedFeeds.tsx:252 @@ -4096,9 +4231,8 @@ msgstr "서버에 연결하는 동안 문제가 발생했습니다" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:57 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:66 -#: src/view/com/feeds/FeedSourceCard.tsx:115 -#: src/view/com/feeds/FeedSourceCard.tsx:129 -#: src/view/com/feeds/FeedSourceCard.tsx:183 +#: src/view/com/feeds/FeedSourceCard.tsx:110 +#: src/view/com/feeds/FeedSourceCard.tsx:123 msgid "There was an issue contacting your server" msgstr "서버에 연결하는 동안 문제가 발생했습니다" @@ -4106,7 +4240,7 @@ msgstr "서버에 연결하는 동안 문제가 발생했습니다" msgid "There was an issue fetching notifications. Tap here to try again." msgstr "알림을 가져오는 동안 문제가 발생했습니다. 이곳을 탭하여 다시 시도하세요." -#: src/view/com/posts/Feed.tsx:265 +#: src/view/com/posts/Feed.tsx:279 msgid "There was an issue fetching posts. Tap here to try again." msgstr "게시물을 가져오는 동안 문제가 발생했습니다. 이곳을 탭하여 다시 시도하세요." @@ -4119,34 +4253,40 @@ msgstr "리스트를 가져오는 동안 문제가 발생했습니다. 이곳을 msgid "There was an issue fetching your lists. Tap here to try again." msgstr "리스트를 가져오는 동안 문제가 발생했습니다. 이곳을 탭하여 다시 시도하세요." -#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:63 -#: src/view/com/modals/ContentFilteringSettings.tsx:126 +#: src/components/ReportDialog/SubmitView.tsx:83 +msgid "There was an issue sending your report. Please check your internet connection." +msgstr "신고를 전송하는 동안 문제가 발생했습니다. 인터넷 연결을 확인해 주세요." + +#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:65 msgid "There was an issue syncing your preferences with the server" msgstr "설정을 서버와 동기화하는 동안 문제가 발생했습니다" -#: src/view/screens/AppPasswords.tsx:66 +#: src/view/screens/AppPasswords.tsx:68 msgid "There was an issue with fetching your app passwords" msgstr "앱 비밀번호를 가져오는 동안 문제가 발생했습니다" -#: src/view/com/post-thread/PostThreadFollowBtn.tsx:93 -#: src/view/com/post-thread/PostThreadFollowBtn.tsx:105 -#: src/view/com/profile/ProfileHeader.tsx:157 -#: src/view/com/profile/ProfileHeader.tsx:178 -#: src/view/com/profile/ProfileHeader.tsx:217 -#: src/view/com/profile/ProfileHeader.tsx:230 -#: src/view/com/profile/ProfileHeader.tsx:250 -#: src/view/com/profile/ProfileHeader.tsx:272 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:98 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:120 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:134 +#: src/view/com/post-thread/PostThreadFollowBtn.tsx:96 +#: src/view/com/post-thread/PostThreadFollowBtn.tsx:108 +#: src/view/com/profile/ProfileMenu.tsx:106 +#: src/view/com/profile/ProfileMenu.tsx:117 +#: src/view/com/profile/ProfileMenu.tsx:132 +#: src/view/com/profile/ProfileMenu.tsx:143 +#: src/view/com/profile/ProfileMenu.tsx:157 +#: src/view/com/profile/ProfileMenu.tsx:170 msgid "There was an issue! {0}" msgstr "문제가 발생했습니다! {0}" #: src/view/screens/ProfileList.tsx:288 -#: src/view/screens/ProfileList.tsx:307 -#: src/view/screens/ProfileList.tsx:329 -#: src/view/screens/ProfileList.tsx:348 +#: src/view/screens/ProfileList.tsx:302 +#: src/view/screens/ProfileList.tsx:316 +#: src/view/screens/ProfileList.tsx:330 msgid "There was an issue. Please check your internet connection and try again." msgstr "문제가 발생했습니다. 인터넷 연결을 확인한 후 다시 시도하세요." -#: src/view/com/util/ErrorBoundary.tsx:36 +#: src/view/com/util/ErrorBoundary.tsx:51 msgid "There was an unexpected issue in the application. Please let us know if this happened to you!" msgstr "애플리케이션에 예기치 않은 문제가 발생했습니다. 이런 일이 발생하면 저희에게 알려주세요!" @@ -4154,27 +4294,36 @@ msgstr "애플리케이션에 예기치 않은 문제가 발생했습니다. 이 msgid "There's been a rush of new users to Bluesky! We'll activate your account as soon as we can." msgstr "Bluesky에 신규 사용자가 몰리고 있습니다! 최대한 빨리 계정을 활성화해 드리겠습니다." -#: src/view/com/auth/create/Step2.tsx:55 -#~ msgid "There's something wrong with this number. Please choose your country and enter your full phone number!" -#~ msgstr "잘못된 번호입니다. 국가를 선택하고 전체 전화번호를 입력하세요." - #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:138 msgid "These are popular accounts you might like:" msgstr "내가 좋아할 만한 인기 계정입니다:" -#: src/view/com/util/moderation/ScreenHider.tsx:88 +#: src/components/moderation/ScreenHider.tsx:116 msgid "This {screenDescription} has been flagged:" -msgstr "이 {screenDescription}에 플래그가 지정되었습니다:" +msgstr "이 {screenDescription}에 다음 플래그가 지정되었습니다:" -#: src/view/com/util/moderation/ScreenHider.tsx:83 +#: src/components/moderation/ScreenHider.tsx:111 msgid "This account has requested that users sign in to view their profile." msgstr "이 계정의 프로필을 보려면 로그인해야 합니다." +#: src/components/moderation/LabelsOnMeDialog.tsx:205 +msgid "This appeal will be sent to <0>{0}</0>." +msgstr "이 이의신청은 <0>{0}</0>에게 보내집니다." + +#: src/lib/moderation/useGlobalLabelStrings.ts:19 +msgid "This content has been hidden by the moderators." +msgstr "이 콘텐츠는 관리자에 의해 숨겨졌습니다." + +#: src/lib/moderation/useGlobalLabelStrings.ts:24 +msgid "This content has received a general warning from moderators." +msgstr "이 콘텐츠는 관리자로부터 일반 경고를 받았습니다." + #: src/view/com/modals/EmbedConsent.tsx:68 msgid "This content is hosted by {0}. Do you want to enable external media?" msgstr "이 콘텐츠는 {0}에서 호스팅됩니다. 외부 미디어를 사용하시겠습니까?" -#: src/view/com/modals/ModerationDetails.tsx:67 +#: src/components/moderation/ModerationDetailsDialog.tsx:78 +#: src/lib/moderation/useModerationCauseDescription.ts:77 msgid "This content is not available because one of the users involved has blocked the other." msgstr "관련 사용자 중 한 명이 다른 사용자를 차단했기 때문에 이 콘텐츠를 사용할 수 없습니다." @@ -4184,15 +4333,15 @@ msgstr "이 콘텐츠는 Bluesky 계정이 없으면 볼 수 없습니다." #: src/view/screens/Settings/ExportCarDialog.tsx:75 msgid "This feature is in beta. You can read more about repository exports in <0>this blogpost.</0>" -msgstr "" +msgstr "이 기능은 베타 버전입니다. 저장소 내보내기에 대한 자세한 내용은 <0>이 블로그 글</0>에서 확인할 수 있습니다." #: src/view/com/posts/FeedErrorMessage.tsx:114 msgid "This feed is currently receiving high traffic and is temporarily unavailable. Please try again later." msgstr "이 피드는 현재 트래픽이 많아 일시적으로 사용할 수 없습니다. 나중에 다시 시도해 주세요." -#: src/view/screens/Profile.tsx:420 +#: src/screens/Profile/Sections/Feed.tsx:50 #: src/view/screens/ProfileFeed.tsx:476 -#: src/view/screens/ProfileList.tsx:661 +#: src/view/screens/ProfileList.tsx:675 msgid "This feed is empty!" msgstr "이 피드는 비어 있습니다." @@ -4200,7 +4349,7 @@ msgstr "이 피드는 비어 있습니다." msgid "This feed is empty! You may need to follow more users or tune your language settings." msgstr "이 피드는 비어 있습니다. 더 많은 사용자를 팔로우하거나 언어 설정을 조정해 보세요." -#: src/view/com/modals/BirthDateSettings.tsx:61 +#: src/components/dialogs/BirthDateSettings.tsx:89 msgid "This information is not shared with other users." msgstr "이 정보는 다른 사용자와 공유되지 않습니다." @@ -4208,14 +4357,26 @@ msgstr "이 정보는 다른 사용자와 공유되지 않습니다." msgid "This is important in case you ever need to change your email or reset your password." msgstr "이는 이메일을 변경하거나 비밀번호를 재설정해야 할 때 중요한 정보입니다." +#: src/components/moderation/ModerationDetailsDialog.tsx:125 +msgid "This label was applied by {0}." +msgstr "이 라벨은 {0}이(가) 적용했습니다." + +#: src/screens/Profile/Sections/Labels.tsx:186 +msgid "This labeler hasn't declared what labels it publishes, and may not be active." +msgstr "이 라벨러는 라벨을 게시하지 않았으며 활성화되어 있지 않을 수 있습니다." + #: src/view/com/modals/LinkWarning.tsx:58 msgid "This link is taking you to the following website:" msgstr "이 링크를 클릭하면 다음 웹사이트로 이동합니다:" -#: src/view/screens/ProfileList.tsx:839 +#: src/view/screens/ProfileList.tsx:853 msgid "This list is empty!" msgstr "이 리스트는 비어 있습니다." +#: src/screens/Profile/ErrorState.tsx:40 +msgid "This moderation service is unavailable. See below for more details. If this issue persists, contact us." +msgstr "이 검토 서비스는 사용할 수 없습니다. 자세한 내용은 아래를 참조하세요. 이 문제가 지속되면 문의해 주세요." + #: src/view/com/modals/AddAppPasswords.tsx:106 msgid "This name is already in use" msgstr "이 이름은 이미 사용 중입니다" @@ -4224,36 +4385,45 @@ msgstr "이 이름은 이미 사용 중입니다" msgid "This post has been deleted." msgstr "이 게시물은 삭제되었습니다." -#: src/view/com/modals/ModerationDetails.tsx:62 +#: src/view/com/util/forms/PostDropdownBtn.tsx:344 +msgid "This post is only visible to logged-in users. It won't be visible to people who aren't logged in." +msgstr "이 게시물은 로그인한 사용자에게만 표시됩니다. 로그인하지 않은 사용자에게는 표시되지 않습니다." + +#: src/view/com/util/forms/PostDropdownBtn.tsx:326 +msgid "This post will be hidden from feeds." +msgstr "이 게시물을 피드에서 숨깁니다." + +#: src/view/com/profile/ProfileMenu.tsx:370 +msgid "This profile is only visible to logged-in users. It won't be visible to people who aren't logged in." +msgstr "이 프로필은 로그인한 사용자에게만 표시됩니다. 로그인하지 않은 사용자에게는 표시되지 않습니다." + +#: src/components/moderation/ModerationDetailsDialog.tsx:73 +#: src/lib/moderation/useModerationCauseDescription.ts:68 msgid "This user has blocked you. You cannot view their content." msgstr "이 사용자는 나를 차단했습니다. 이 사용자의 콘텐츠를 볼 수 없습니다." -#: src/view/com/modals/ModerationDetails.tsx:42 -msgid "This user is included in the <0/> list which you have blocked." -msgstr "이 사용자는 차단한 <0/> 리스트에 포함되어 있습니다." +#: src/lib/moderation/useGlobalLabelStrings.ts:30 +msgid "This user has requested that their content only be shown to signed-in users." +msgstr "이 사용자는 자신의 콘텐츠가 로그인한 사용자에게만 표시되도록 요청했습니다." -#: src/view/com/modals/ModerationDetails.tsx:74 -msgid "This user is included in the <0/> list which you have muted." -msgstr "" +#: src/components/moderation/ModerationDetailsDialog.tsx:56 +msgid "This user is included in the <0>{0}</0> list which you have blocked." +msgstr "이 사용자는 내가 차단한 <0>{0}</0> 리스트에 포함되어 있습니다." -#: src/view/com/modals/ModerationDetails.tsx:74 -#~ msgid "This user is included the <0/> list which you have muted." -#~ msgstr "이 사용자는 뮤트한 <0/> 리스트에 포함되어 있습니다." +#: src/components/moderation/ModerationDetailsDialog.tsx:85 +msgid "This user is included in the <0>{0}</0> list which you have muted." +msgstr "이 사용자는 내가 뮤트한 <0>{0}</0> 리스트에 포함되어 있습니다." #: src/view/com/modals/SelfLabel.tsx:137 msgid "This warning is only available for posts with media attached." msgstr "이 경고는 미디어가 첨부된 게시물에만 사용할 수 있습니다." -#: src/components/dialogs/MutedWords.tsx:285 +#: src/components/dialogs/MutedWords.tsx:284 msgid "This will delete {0} from your muted words. You can always add it back later." -msgstr "" - -#: src/view/com/util/forms/PostDropdownBtn.tsx:282 -msgid "This will hide this post from your feeds." -msgstr "피드에서 이 게시물을 숨깁니다." +msgstr "뮤트한 단어에서 {0}이(가) 삭제됩니다. 나중에 언제든지 다시 추가할 수 있습니다." #: src/view/screens/PreferencesThreads.tsx:53 -#: src/view/screens/Settings/index.tsx:565 +#: src/view/screens/Settings/index.tsx:583 msgid "Thread Preferences" msgstr "스레드 설정" @@ -4261,26 +4431,30 @@ msgstr "스레드 설정" msgid "Threaded Mode" msgstr "스레드 모드" -#: src/Navigation.tsx:257 +#: src/Navigation.tsx:269 msgid "Threads Preferences" msgstr "스레드 설정" #: src/components/dialogs/MutedWords.tsx:113 msgid "Toggle between muted word options." -msgstr "" +msgstr "뮤트한 단어 옵션 사이를 전환합니다." #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" msgstr "드롭다운 열기 및 닫기" +#: src/screens/Moderation/index.tsx:338 +msgid "Toggle to enable or disable adult content" +msgstr "성인 콘텐츠 활성화 또는 비활성화 전환" + #: src/view/com/modals/EditImage.tsx:271 msgid "Transformations" msgstr "변형" -#: src/view/com/post-thread/PostThreadItem.tsx:685 -#: src/view/com/post-thread/PostThreadItem.tsx:687 -#: src/view/com/util/forms/PostDropdownBtn.tsx:215 -#: src/view/com/util/forms/PostDropdownBtn.tsx:217 +#: src/view/com/post-thread/PostThreadItem.tsx:646 +#: src/view/com/post-thread/PostThreadItem.tsx:648 +#: src/view/com/util/forms/PostDropdownBtn.tsx:212 +#: src/view/com/util/forms/PostDropdownBtn.tsx:214 msgid "Translate" msgstr "번역" @@ -4289,11 +4463,11 @@ msgctxt "action" msgid "Try again" msgstr "다시 시도" -#: src/view/screens/ProfileList.tsx:506 +#: src/view/screens/ProfileList.tsx:478 msgid "Un-block list" msgstr "리스트 차단 해제" -#: src/view/screens/ProfileList.tsx:491 +#: src/view/screens/ProfileList.tsx:461 msgid "Un-mute list" msgstr "리스트 언뮤트" @@ -4305,21 +4479,28 @@ msgstr "리스트 언뮤트" msgid "Unable to contact your service. Please check your Internet connection." msgstr "서비스에 연결할 수 없습니다. 인터넷 연결을 확인하세요." -#: src/view/com/profile/ProfileHeader.tsx:433 -#: src/view/screens/ProfileList.tsx:590 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:174 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:278 +#: src/view/com/profile/ProfileMenu.tsx:361 +#: src/view/screens/ProfileList.tsx:572 msgid "Unblock" msgstr "차단 해제" -#: src/view/com/profile/ProfileHeader.tsx:436 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:179 msgctxt "action" msgid "Unblock" msgstr "차단 해제" -#: src/view/com/profile/ProfileHeader.tsx:261 -#: src/view/com/profile/ProfileHeader.tsx:345 +#: src/view/com/profile/ProfileMenu.tsx:299 +#: src/view/com/profile/ProfileMenu.tsx:305 msgid "Unblock Account" msgstr "계정 차단 해제" +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:272 +#: src/view/com/profile/ProfileMenu.tsx:343 +msgid "Unblock Account?" +msgstr "계정을 차단 해제하시겠습니까?" + #: src/view/com/modals/Repost.tsx:42 #: src/view/com/modals/Repost.tsx:55 #: src/view/com/util/post-ctrls/RepostButton.tsx:60 @@ -4327,70 +4508,84 @@ msgstr "계정 차단 해제" msgid "Undo repost" msgstr "재게시 취소" -#: src/view/com/profile/FollowButton.tsx:55 +#: src/view/com/profile/FollowButton.tsx:60 msgctxt "action" msgid "Unfollow" msgstr "언팔로우" -#: src/view/com/profile/ProfileHeader.tsx:485 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:213 msgid "Unfollow {0}" msgstr "{0} 님을 언팔로우" +#: src/view/com/profile/ProfileMenu.tsx:241 +#: src/view/com/profile/ProfileMenu.tsx:251 +msgid "Unfollow Account" +msgstr "계정 언팔로우" + #: src/view/com/auth/create/state.ts:262 msgid "Unfortunately, you do not meet the requirements to create an account." msgstr "아쉽지만 계정을 만들 수 있는 요건을 충족하지 못했습니다." -#: src/view/com/util/post-ctrls/PostCtrls.tsx:182 +#: src/view/com/util/post-ctrls/PostCtrls.tsx:185 msgid "Unlike" msgstr "좋아요 취소" +#: src/view/screens/ProfileFeed.tsx:572 +msgid "Unlike this feed" +msgstr "이 피드 좋아요 취소" + #: src/components/TagMenu/index.tsx:249 -#: src/view/screens/ProfileList.tsx:597 +#: src/view/screens/ProfileList.tsx:579 msgid "Unmute" msgstr "언뮤트" #: src/components/TagMenu/index.web.tsx:104 msgid "Unmute {truncatedTag}" -msgstr "" +msgstr "{truncatedTag} 언뮤트" -#: src/view/com/profile/ProfileHeader.tsx:326 +#: src/view/com/profile/ProfileMenu.tsx:278 +#: src/view/com/profile/ProfileMenu.tsx:284 msgid "Unmute Account" msgstr "계정 언뮤트" #: src/components/TagMenu/index.tsx:208 msgid "Unmute all {displayTag} posts" -msgstr "" - -#: src/components/TagMenu/index.tsx:210 -#~ msgid "Unmute all {tag} posts" -#~ msgstr "" +msgstr "모든 {tag} 게시물 언뮤트" #: src/view/com/util/forms/PostDropdownBtn.tsx:251 #: src/view/com/util/forms/PostDropdownBtn.tsx:256 msgid "Unmute thread" msgstr "스레드 언뮤트" -#: src/view/screens/ProfileFeed.tsx:354 -#: src/view/screens/ProfileList.tsx:581 +#: src/view/screens/ProfileFeed.tsx:294 +#: src/view/screens/ProfileList.tsx:563 msgid "Unpin" msgstr "고정 해제" -#: src/view/screens/ProfileList.tsx:474 +#: src/view/screens/ProfileFeed.tsx:291 +msgid "Unpin from home" +msgstr "홈에서 고정 해제" + +#: src/view/screens/ProfileList.tsx:444 msgid "Unpin moderation list" msgstr "검토 리스트 고정 해제" -#: src/view/screens/ProfileFeed.tsx:346 -msgid "Unsave" -msgstr "저장 해제" +#: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:220 +msgid "Unsubscribe" +msgstr "구독 취소" + +#: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:184 +msgid "Unsubscribe from this labeler" +msgstr "이 라벨러 구독 취소하기" + +#: src/lib/moderation/useReportOptions.ts:70 +msgid "Unwanted Sexual Content" +msgstr "원치 않는 성적 콘텐츠" #: src/view/com/modals/UserAddRemoveLists.tsx:70 msgid "Update {displayName} in Lists" msgstr "리스트에서 {displayName} 업데이트" -#: src/lib/hooks/useOTAUpdate.ts:15 -msgid "Update Available" -msgstr "업데이트 사용 가능" - #: src/view/com/auth/login/SetNewPasswordForm.tsx:204 msgid "Updating..." msgstr "업데이트 중…" @@ -4399,7 +4594,26 @@ msgstr "업데이트 중…" msgid "Upload a text file to:" msgstr "텍스트 파일 업로드 경로:" -#: src/view/screens/AppPasswords.tsx:195 +#: src/view/com/util/UserAvatar.tsx:319 +#: src/view/com/util/UserAvatar.tsx:322 +#: src/view/com/util/UserBanner.tsx:113 +#: src/view/com/util/UserBanner.tsx:116 +msgid "Upload from Camera" +msgstr "카메라에서 업로드" + +#: src/view/com/util/UserAvatar.tsx:336 +#: src/view/com/util/UserBanner.tsx:130 +msgid "Upload from Files" +msgstr "파일에서 업로드" + +#: src/view/com/util/UserAvatar.tsx:330 +#: src/view/com/util/UserAvatar.tsx:334 +#: src/view/com/util/UserBanner.tsx:124 +#: src/view/com/util/UserBanner.tsx:128 +msgid "Upload from Library" +msgstr "라이브러리에서 업로드" + +#: src/view/screens/AppPasswords.tsx:197 msgid "Use app passwords to login to other Bluesky clients without giving full access to your account or password." msgstr "앱 비밀번호를 사용하면 계정이나 비밀번호에 대한 전체 접근 권한을 제공하지 않고도 다른 Bluesky 클라이언트에 로그인할 수 있습니다." @@ -4421,25 +4635,30 @@ msgstr "내 기본 브라우저 사용" msgid "Use this to sign into the other app along with your handle." msgstr "이 비밀번호와 핸들을 사용하여 다른 앱에 로그인하세요." -#: src/view/com/modals/ServerInput.tsx:105 -#~ msgid "Use your domain as your Bluesky client service provider" -#~ msgstr "내 도메인을 Bluesky 클라이언트 서비스 공급자로 사용합니다" - #: src/view/com/modals/InviteCodes.tsx:200 msgid "Used by:" msgstr "사용 계정:" -#: src/view/com/modals/ModerationDetails.tsx:54 +#: src/components/moderation/ModerationDetailsDialog.tsx:65 +#: src/lib/moderation/useModerationCauseDescription.ts:56 msgid "User Blocked" msgstr "사용자 차단됨" -#: src/view/com/modals/ModerationDetails.tsx:40 +#: src/lib/moderation/useModerationCauseDescription.ts:48 +msgid "User Blocked by \"{0}\"" +msgstr " \"{0}\"에서 차단된 사용자" + +#: src/components/moderation/ModerationDetailsDialog.tsx:54 msgid "User Blocked by List" msgstr "리스트로 사용자 차단됨" -#: src/view/com/modals/ModerationDetails.tsx:60 +#: src/lib/moderation/useModerationCauseDescription.ts:66 +msgid "User Blocking You" +msgstr "나를 차단한 사용자" + +#: src/components/moderation/ModerationDetailsDialog.tsx:71 msgid "User Blocks You" -msgstr "사용자가 나를 차단함" +msgstr "나를 차단한 사용자" #: src/view/com/auth/create/Step2.tsx:79 msgid "User handle" @@ -4450,13 +4669,13 @@ msgstr "사용자 핸들" msgid "User list by {0}" msgstr "{0} 님의 사용자 리스트" -#: src/view/screens/ProfileList.tsx:763 +#: src/view/screens/ProfileList.tsx:777 msgid "User list by <0/>" msgstr "<0/> 님의 사용자 리스트" #: src/view/com/lists/ListCard.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:196 -#: src/view/screens/ProfileList.tsx:761 +#: src/view/screens/ProfileList.tsx:775 msgid "User list by you" msgstr "내 사용자 리스트" @@ -4477,7 +4696,7 @@ msgstr "사용자 리스트" msgid "Username or email address" msgstr "사용자 이름 또는 이메일 주소" -#: src/view/screens/ProfileList.tsx:797 +#: src/view/screens/ProfileList.tsx:811 msgid "Users" msgstr "사용자" @@ -4489,19 +4708,19 @@ msgstr "<0/> 님이 팔로우한 사용자" msgid "Users in \"{0}\"" msgstr "\"{0}\"에 있는 사용자" -#: src/view/com/auth/create/Step2.tsx:243 -#~ msgid "Verification code" -#~ msgstr "인증 코드" +#: src/components/LikesDialog.tsx:85 +msgid "Users that have liked this content or profile" +msgstr "이 콘텐츠 또는 프로필을 좋아하는 사용자" -#: src/view/screens/Settings/index.tsx:910 +#: src/view/screens/Settings/index.tsx:938 msgid "Verify email" msgstr "이메일 인증" -#: src/view/screens/Settings/index.tsx:935 +#: src/view/screens/Settings/index.tsx:963 msgid "Verify my email" msgstr "내 이메일 인증하기" -#: src/view/screens/Settings/index.tsx:944 +#: src/view/screens/Settings/index.tsx:972 msgid "Verify My Email" msgstr "내 이메일 인증하기" @@ -4518,7 +4737,7 @@ msgstr "이메일 인증하기" msgid "Video Games" msgstr "비디오 게임" -#: src/view/com/profile/ProfileHeader.tsx:662 +#: src/screens/Profile/Header/Shell.tsx:110 msgid "View {0}'s avatar" msgstr "{0} 님의 아바타를 봅니다" @@ -4526,11 +4745,23 @@ msgstr "{0} 님의 아바타를 봅니다" msgid "View debug entry" msgstr "디버그 항목 보기" -#: src/view/com/posts/FeedSlice.tsx:103 +#: src/components/ReportDialog/SelectReportOptionView.tsx:132 +msgid "View details" +msgstr "세부 정보 보기" + +#: src/components/ReportDialog/SelectReportOptionView.tsx:127 +msgid "View details for reporting a copyright violation" +msgstr "저작권 위반 신고에 대한 세부 정보 보기" + +#: src/view/com/posts/FeedSlice.tsx:99 msgid "View full thread" msgstr "전체 스레드 보기" -#: src/view/com/posts/FeedErrorMessage.tsx:172 +#: src/components/moderation/LabelsOnMe.tsx:51 +msgid "View information about these labels" +msgstr "이 라벨에 대한 정보 보기" + +#: src/view/com/posts/FeedErrorMessage.tsx:166 msgid "View profile" msgstr "프로필 보기" @@ -4538,22 +4769,40 @@ msgstr "프로필 보기" msgid "View the avatar" msgstr "아바타 보기" +#: src/components/LabelingServiceCard/index.tsx:140 +msgid "View the labeling service provided by @{0}" +msgstr "{0} 님이 제공하는 라벨링 서비스 보기" + +#: src/view/screens/ProfileFeed.tsx:584 +msgid "View users who like this feed" +msgstr "이 피드를 좋아하는 사용자 보기" + #: src/view/com/modals/LinkWarning.tsx:75 msgid "Visit Site" msgstr "사이트 방문" -#: src/screens/Onboarding/StepModeration/ModerationOption.tsx:42 -#: src/view/com/modals/ContentFilteringSettings.tsx:259 +#: src/components/moderation/GlobalModerationLabelPref.tsx:44 +#: src/lib/moderation/useLabelBehaviorDescription.ts:17 +#: src/lib/moderation/useLabelBehaviorDescription.ts:22 +#: src/screens/Onboarding/StepModeration/ModerationOption.tsx:53 msgid "Warn" msgstr "경고" +#: src/lib/moderation/useLabelBehaviorDescription.ts:48 +msgid "Warn content" +msgstr "콘텐츠 경고" + +#: src/lib/moderation/useLabelBehaviorDescription.ts:46 +msgid "Warn content and filter from feeds" +msgstr "콘텐츠 경고 및 피드에서 필터링" + #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:134 msgid "We also think you'll like \"For You\" by Skygaze:" msgstr "Skygaze의 \"For You\"를 사용해 볼 수도 있습니다:" #: src/screens/Hashtag.tsx:132 msgid "We couldn't find any results for that hashtag." -msgstr "" +msgstr "해당 해시태그에 대한 결과를 찾을 수 없습니다." #: src/screens/Deactivated.tsx:133 msgid "We estimate {estimatedTime} until your account is ready." @@ -4569,12 +4818,16 @@ msgstr "팔로우한 사용자의 게시물이 부족합니다. 대신 <0/>의 #: src/components/dialogs/MutedWords.tsx:204 msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." -msgstr "" +msgstr "게시물이 표시되지 않을 수 있으므로 많은 게시물에 자주 등장하는 단어는 피하는 것이 좋습니다." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" msgstr "\"Discover\" 피드를 권장합니다:" +#: src/screens/Moderation/index.tsx:391 +msgid "We were unable to load your configured labelers at this time." +msgstr "현재 구성된 라벨러를 불러올 수 없습니다." + #: src/screens/Onboarding/StepInterests/index.tsx:133 msgid "We weren't able to connect. Please try again to continue setting up your account. If it continues to fail, you can skip this flow." msgstr "연결하지 못했습니다. 계정 설정을 계속하려면 다시 시도해 주세요. 계속 실패하면 이 과정을 건너뛸 수 있습니다." @@ -4583,49 +4836,45 @@ msgstr "연결하지 못했습니다. 계정 설정을 계속하려면 다시 msgid "We will let you know when your account is ready." msgstr "계정이 준비되면 알려드리겠습니다." -#: src/view/com/modals/AppealLabel.tsx:48 -msgid "We'll look into your appeal promptly." -msgstr "이의신청을 즉시 검토하겠습니다." - #: src/screens/Onboarding/StepInterests/index.tsx:138 msgid "We'll use this to help customize your experience." msgstr "이를 통해 사용자 환경을 맞춤 설정할 수 있습니다." #: src/view/com/auth/create/CreateAccount.tsx:134 msgid "We're so excited to have you join us!" -msgstr "당신과 함께하게 되어 정말 기쁘네요!" +msgstr "함께하게 되어 정말 기뻐요!" -#: src/view/screens/ProfileList.tsx:86 +#: src/view/screens/ProfileList.tsx:89 msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." msgstr "죄송하지만 이 리스트를 불러올 수 없습니다. 이 문제가 계속되면 리스트 작성자인 @{handleOrDid}에게 문의하세요." #: src/components/dialogs/MutedWords.tsx:230 msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." -msgstr "" +msgstr "죄송하지만 현재 뮤트한 단어를 불러올 수 없습니다. 다시 시도해 주세요." #: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "죄송하지만 검색을 완료할 수 없습니다. 몇 분 후에 다시 시도해 주세요." -#: src/components/Lists.tsx:211 +#: src/components/Lists.tsx:210 #: src/view/screens/NotFound.tsx:48 msgid "We're sorry! We can't find the page you were looking for." msgstr "죄송합니다. 페이지를 찾을 수 없습니다." +#: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:319 +msgid "We're sorry! You can only subscribe to ten labelers, and you've reached your limit of ten." +msgstr "죄송합니다. 라벨러는 10개까지만 구독할 수 있으며 10개에 도달했습니다." + #: src/view/com/auth/onboarding/WelcomeMobile.tsx:46 msgid "Welcome to <0>Bluesky</0>" msgstr "<0>Bluesky</0>에 오신 것을 환영합니다" #: src/screens/Onboarding/StepInterests/index.tsx:130 msgid "What are your interests?" -msgstr "관심사가 어떻게 되나요?" - -#: src/view/com/modals/report/Modal.tsx:169 -msgid "What is the issue with this {collectionName}?" -msgstr "이 {collectionName}에 어떤 문제가 있나요?" +msgstr "어떤 관심사가 있으신가요?" #: src/view/com/auth/SplashScreen.tsx:59 -#: src/view/com/composer/Composer.tsx:286 +#: src/view/com/composer/Composer.tsx:295 msgid "What's up?" msgstr "무슨 일이 일어나고 있나요?" @@ -4642,15 +4891,39 @@ msgstr "알고리즘 피드에 어떤 언어를 표시하시겠습니까?" msgid "Who can reply" msgstr "답글을 달 수 있는 사람" +#: src/components/ReportDialog/SelectLabelerView.tsx:33 +msgid "Who do you want to send this report to?" +msgstr "이 신고를 누구에게 보내시겠습니까?" + +#: src/components/ReportDialog/SelectReportOptionView.tsx:43 +msgid "Why should this content be reviewed?" +msgstr "이 콘텐츠를 검토해야 하는 이유는 무엇인가요?" + +#: src/components/ReportDialog/SelectReportOptionView.tsx:56 +msgid "Why should this feed be reviewed?" +msgstr "이 피드를 검토해야 하는 이유는 무엇인가요?" + +#: src/components/ReportDialog/SelectReportOptionView.tsx:53 +msgid "Why should this list be reviewed?" +msgstr "이 리스트를 검토해야 하는 이유는 무엇인가요?" + +#: src/components/ReportDialog/SelectReportOptionView.tsx:50 +msgid "Why should this post be reviewed?" +msgstr "이 게시물을 검토해야 하는 이유는 무엇인가요?" + +#: src/components/ReportDialog/SelectReportOptionView.tsx:47 +msgid "Why should this user be reviewed?" +msgstr "이 사용자를 검토해야 하는 이유는 무엇인가요?" + #: src/view/com/modals/crop-image/CropImage.web.tsx:102 msgid "Wide" msgstr "가로" -#: src/view/com/composer/Composer.tsx:422 +#: src/view/com/composer/Composer.tsx:431 msgid "Write post" msgstr "게시물 작성" -#: src/view/com/composer/Composer.tsx:285 +#: src/view/com/composer/Composer.tsx:294 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "답글 작성하기" @@ -4659,10 +4932,6 @@ msgstr "답글 작성하기" msgid "Writers" msgstr "작가" -#: src/view/com/auth/create/Step2.tsx:263 -#~ msgid "XXXXXX" -#~ msgstr "XXXXXX" - #: src/view/com/composer/select-language/SuggestedLanguage.tsx:77 #: src/view/screens/PreferencesFollowingFeed.tsx:129 #: src/view/screens/PreferencesFollowingFeed.tsx:201 @@ -4707,11 +4976,13 @@ msgstr "저장된 피드가 없습니다!" msgid "You don't have any saved feeds." msgstr "저장된 피드가 없습니다." -#: src/view/com/post-thread/PostThread.tsx:465 +#: src/view/com/post-thread/PostThread.tsx:466 msgid "You have blocked the author or you have been blocked by the author." msgstr "작성자를 차단했거나 작성자가 나를 차단했습니다." -#: src/view/com/modals/ModerationDetails.tsx:56 +#: src/components/moderation/ModerationDetailsDialog.tsx:67 +#: src/lib/moderation/useModerationCauseDescription.ts:50 +#: src/lib/moderation/useModerationCauseDescription.ts:58 msgid "You have blocked this user. You cannot view their content." msgstr "이 사용자를 차단했습니다. 해당 사용자의 콘텐츠를 볼 수 없습니다." @@ -4720,11 +4991,24 @@ msgstr "이 사용자를 차단했습니다. 해당 사용자의 콘텐츠를 #: src/view/com/modals/ChangePassword.tsx:87 #: src/view/com/modals/ChangePassword.tsx:121 msgid "You have entered an invalid code. It should look like XXXXX-XXXXX." -msgstr "" +msgstr "잘못된 코드를 입력했습니다. XXXXX-XXXXX와 같은 형식이어야 합니다." -#: src/view/com/modals/ModerationDetails.tsx:87 -msgid "You have muted this user." -msgstr "이 사용자를 뮤트했습니다." +#: src/lib/moderation/useModerationCauseDescription.ts:109 +msgid "You have hidden this post" +msgstr "내가 이 게시물을 숨겼습니다" + +#: src/components/moderation/ModerationDetailsDialog.tsx:102 +msgid "You have hidden this post." +msgstr "내가 이 게시물을 숨겼습니다." + +#: src/components/moderation/ModerationDetailsDialog.tsx:95 +#: src/lib/moderation/useModerationCauseDescription.ts:92 +msgid "You have muted this account." +msgstr "내가 이 계정을 뮤트했습니다." + +#: src/lib/moderation/useModerationCauseDescription.ts:86 +msgid "You have muted this user" +msgstr "내가 이 사용자를 뮤트했습니다" #: src/view/com/feeds/ProfileFeedgens.tsx:136 msgid "You have no feeds." @@ -4739,7 +5023,7 @@ msgstr "리스트가 없습니다." msgid "You have not blocked any accounts yet. To block an account, go to their profile and selected \"Block account\" from the menu on their account." msgstr "아직 어떤 계정도 차단하지 않았습니다. 계정을 차단하려면 해당 계정의 프로필로 이동하여 계정 메뉴에서 \"계정 차단\"을 선택하세요." -#: src/view/screens/AppPasswords.tsx:87 +#: src/view/screens/AppPasswords.tsx:89 msgid "You have not created any app passwords yet. You can create one by pressing the button below." msgstr "아직 앱 비밀번호를 생성하지 않았습니다. 아래 버튼을 눌러 생성할 수 있습니다." @@ -4749,21 +5033,25 @@ msgstr "아직 어떤 계정도 뮤트하지 않았습니다. 계정을 뮤트 #: src/components/dialogs/MutedWords.tsx:250 msgid "You haven't muted any words or tags yet" -msgstr "" +msgstr "아직 어떤 단어나 태그도 뮤트하지 않았습니다" -#: src/view/com/modals/ContentFilteringSettings.tsx:175 -msgid "You must be 18 or older to enable adult content." -msgstr "성인 콘텐츠를 활성화하려면 18세 이상이어야 합니다." +#: src/components/moderation/LabelsOnMeDialog.tsx:69 +msgid "You may appeal these labels if you feel they were placed in error." +msgstr "이 라벨이 잘못 지정되었다고 생각되면 이의신청할 수 있습니다." -#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:103 +#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:108 msgid "You must be 18 years or older to enable adult content" msgstr "성인 콘텐츠를 사용하려면 만 18세 이상이어야 합니다." -#: src/view/com/util/forms/PostDropdownBtn.tsx:147 +#: src/components/ReportDialog/SubmitView.tsx:205 +msgid "You must select at least one labeler for a report" +msgstr "신고하려면 하나 이상의 라벨을 선택해야 합니다." + +#: src/view/com/util/forms/PostDropdownBtn.tsx:144 msgid "You will no longer receive notifications for this thread" msgstr "이 스레드에 대한 알림을 더 이상 받지 않습니다" -#: src/view/com/util/forms/PostDropdownBtn.tsx:150 +#: src/view/com/util/forms/PostDropdownBtn.tsx:147 msgid "You will now receive notifications for this thread" msgstr "이제 이 스레드에 대한 알림을 받습니다" @@ -4771,7 +5059,7 @@ msgstr "이제 이 스레드에 대한 알림을 받습니다" msgid "You will receive an email with a \"reset code.\" Enter that code here, then enter your new password." msgstr "\"재설정 코드\"가 포함된 이메일을 받게 되면 여기에 해당 코드를 입력한 다음 새 비밀번호를 입력합니다." -#: src/screens/Onboarding/StepModeration/index.tsx:72 +#: src/screens/Onboarding/StepModeration/index.tsx:59 msgid "You're in control" msgstr "직접 제어하세요" @@ -4785,6 +5073,11 @@ msgstr "대기 중입니다" msgid "You're ready to go!" msgstr "준비가 끝났습니다!" +#: src/components/moderation/ModerationDetailsDialog.tsx:99 +#: src/lib/moderation/useModerationCauseDescription.ts:101 +msgid "You've chosen to hide a word or tag within this post." +msgstr "이 글에서 단어 또는 태그를 숨기도록 설정했습니다." + #: src/view/com/posts/FollowingEndOfFeed.tsx:48 msgid "You've reached the end of your feed! Find some more accounts to follow." msgstr "피드 끝에 도달했습니다! 팔로우할 계정을 더 찾아보세요." @@ -4799,7 +5092,7 @@ msgstr "계정을 삭제했습니다" #: src/view/screens/Settings/ExportCarDialog.tsx:47 msgid "Your account repository, containing all public data records, can be downloaded as a \"CAR\" file. This file does not include media embeds, such as images, or your private data, which must be fetched separately." -msgstr "" +msgstr "모든 공개 데이터 레코드가 포함된 계정 저장소를 \"CAR\" 파일로 다운로드할 수 있습니다. 이 파일에는 이미지와 같은 미디어 임베드나 별도로 가져와야 하는 비공개 데이터는 포함되지 않습니다." #: src/view/com/auth/create/Step1.tsx:215 msgid "Your birth date" @@ -4819,10 +5112,6 @@ msgstr "기본 피드는 \"팔로우 중\"입니다" msgid "Your email appears to be invalid." msgstr "이메일이 잘못된 것 같습니다." -#: src/view/com/modals/Waitlist.tsx:109 -#~ msgid "Your email has been saved! We'll be in touch soon." -#~ msgstr "이메일이 저장되었습니다! 가까운 시일 내에 연락드리겠습니다." - #: src/view/com/modals/ChangeEmail.tsx:125 msgid "Your email has been updated but not verified. As a next step, please verify your new email." msgstr "이메일이 변경되었지만 인증되지 않았습니다. 다음 단계로 새 이메일을 인증해 주세요." @@ -4833,7 +5122,7 @@ msgstr "이메일이 아직 인증되지 않았습니다. 이는 중요한 보 #: src/view/com/posts/FollowingEmptyState.tsx:47 msgid "Your following feed is empty! Follow more users to see what's happening." -msgstr "팔로우 중인 피드가 비어 있습니다! 더 많은 사용자를 팔로우하여 무슨 일이 일어나고 있는지 확인하세요." +msgstr "팔로우 중 피드가 비어 있습니다! 더 많은 사용자를 팔로우하여 무슨 일이 일어나고 있는지 확인하세요." #: src/view/com/auth/create/Step2.tsx:83 msgid "Your full handle will be" @@ -4843,21 +5132,15 @@ msgstr "내 전체 핸들:" msgid "Your full handle will be <0>@{0}</0>" msgstr "내 전체 핸들: <0>@{0}</0>" -#: src/view/screens/Settings.tsx:430 -#: src/view/shell/desktop/RightNav.tsx:137 -#: src/view/shell/Drawer.tsx:660 -#~ msgid "Your invite codes are hidden when logged in using an App Password" -#~ msgstr "앱 비밀번호를 사용하여 로그인하면 초대 코드가 숨겨집니다" - #: src/components/dialogs/MutedWords.tsx:221 msgid "Your muted words" -msgstr "" +msgstr "뮤트한 단어" #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" -msgstr "" +msgstr "비밀번호를 성공적으로 변경했습니다." -#: src/view/com/composer/Composer.tsx:274 +#: src/view/com/composer/Composer.tsx:283 msgid "Your post has been published" msgstr "게시물을 게시했습니다" @@ -4868,11 +5151,11 @@ msgid "Your posts, likes, and blocks are public. Mutes are private." msgstr "게시물, 좋아요, 차단 목록은 공개됩니다. 뮤트 목록은 공개되지 않습니다." #: src/view/com/modals/SwitchAccount.tsx:84 -#: src/view/screens/Settings/index.tsx:118 +#: src/view/screens/Settings/index.tsx:122 msgid "Your profile" msgstr "내 프로필" -#: src/view/com/composer/Composer.tsx:273 +#: src/view/com/composer/Composer.tsx:282 msgid "Your reply has been published" msgstr "내 답글을 게시했습니다" From f685f9c8c01b2406fe72afbdce0a2fc08033bffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gild=C3=A1sio=20Filho?= <gildasiogx@gmail.com> Date: Tue, 19 Mar 2024 16:31:33 -0300 Subject: [PATCH 098/109] Update pt-BR localization to latest version (#2876) * Update messages.po * Update messages.po * Update messages.po * Update messages.po * Update src/locale/locales/pt-BR/messages.po Co-authored-by: Gleydson Rodrigues <gleydsonsr@gmail.com> * Update messages.po --------- Co-authored-by: Gleydson Rodrigues <gleydsonsr@gmail.com> --- src/locale/locales/pt-BR/messages.po | 329 +++++++-------------------- 1 file changed, 81 insertions(+), 248 deletions(-) diff --git a/src/locale/locales/pt-BR/messages.po b/src/locale/locales/pt-BR/messages.po index 5cb145147c..bfd794c551 100644 --- a/src/locale/locales/pt-BR/messages.po +++ b/src/locale/locales/pt-BR/messages.po @@ -8,8 +8,8 @@ msgstr "" "Language: pt-BR\n" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2024-02-08 19:59\n" -"Last-Translator: maisondasilva\n" +"PO-Revision-Date: 2024-03-12 11:36\n" +"Last-Translator: gildaswise\n" "Language-Team: maisondasilva, MightyLoggor, gildaswise, gleydson, faeriarum\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" @@ -17,28 +17,10 @@ msgstr "" msgid "(no email)" msgstr "(sem email)" -#: src/view/shell/desktop/RightNav.tsx:168 -#~ msgid "{0, plural, one {# invite code available} other {# invite codes available}}" -#~ msgstr "{0, plural, one {# convite disponível} other {# convites disponíveis}}" - #: src/view/com/profile/ProfileHeader.tsx:593 msgid "{following} following" msgstr "{following} seguindo" -#: src/view/shell/desktop/RightNav.tsx:151 -#~ msgid "{invitesAvailable, plural, one {Invite codes: # available} other {Invite codes: # available}}" -#~ msgstr "{invitesAvailable, plural, one {Convites: # disponível} other {Convites: # disponíveis}}" - -#: src/view/screens/Settings.tsx:435 -#: src/view/shell/Drawer.tsx:664 -#~ msgid "{invitesAvailable} invite code available" -#~ msgstr "{invitesAvailable} convite disponível" - -#: src/view/screens/Settings.tsx:437 -#: src/view/shell/Drawer.tsx:666 -#~ msgid "{invitesAvailable} invite codes available" -#~ msgstr "{invitesAvailable} convites disponíveis" - #: src/view/shell/Drawer.tsx:440 msgid "{numUnreadNotifications} unread" msgstr "{numUnreadNotifications} não lidas" @@ -179,11 +161,11 @@ msgstr "Adicionar prévia de link:" #: src/components/dialogs/MutedWords.tsx:158 msgid "Add mute word for configured settings" -msgstr "" +msgstr "Adicionar palavra silenciada para as configurações selecionadas" #: src/components/dialogs/MutedWords.tsx:87 msgid "Add muted words and tags" -msgstr "" +msgstr "Adicionar palavras/tags silenciadas" #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" @@ -223,17 +205,13 @@ msgstr "Conteúdo Adulto" msgid "Adult content can only be enabled via the Web at <0/>." msgstr "Conteúdo adulto só pode ser habilitado no site: <0/>." -#: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:78 -#~ msgid "Adult content can only be enabled via the Web at <0>bsky.app</0>." -#~ msgstr "Conteúdo adulto só pode ser habilitado no site: <0>bsky.app</0>." - #: src/view/screens/Settings/index.tsx:664 msgid "Advanced" msgstr "Avançado" #: src/view/screens/Feeds.tsx:666 msgid "All the feeds you've saved, right in one place." -msgstr "" +msgstr "Todos os feeds que você salvou, em um único lugar." #: src/view/com/auth/login/ForgotPasswordForm.tsx:221 #: src/view/com/modals/ChangePassword.tsx:168 @@ -458,7 +436,7 @@ msgstr "Bluesky" #: src/view/com/auth/server-input/index.tsx:150 msgid "Bluesky is an open network where you can choose your hosting provider. Custom hosting is now available in beta for developers." -msgstr "" +msgstr "Bluesky é uma rede aberta que permite a escolha do seu provedor de hospedagem. Desenvolvedores já conseguem utilizar a versão beta de hospedagem própria." #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:80 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:80 @@ -483,10 +461,6 @@ msgstr "Bluesky é público." msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "O Bluesky não mostrará seu perfil e publicações para usuários desconectados. Outros aplicativos podem não honrar esta solicitação. Isso não torna a sua conta privada." -#: src/view/com/modals/ServerInput.tsx:78 -#~ msgid "Bluesky.Social" -#~ msgstr "Bluesky.Social" - #: src/screens/Onboarding/index.tsx:33 msgid "Books" msgstr "Livros" @@ -500,10 +474,6 @@ msgstr "Versão {0} {1}" msgid "Business" msgstr "Empresarial" -#: src/view/com/modals/ServerInput.tsx:115 -#~ msgid "Button disabled. Input custom domain to proceed." -#~ msgstr "Botão desabilitado. Utilize um domínio personalizado para continuar." - #: src/view/com/profile/ProfileSubpageHeader.tsx:157 msgid "by —" msgstr "por -" @@ -665,10 +635,6 @@ msgstr "Escolha os algoritmos que geram seus feeds customizados." msgid "Choose the algorithms that power your experience with custom feeds." msgstr "Escolha os algoritmos que fazem sentido para você com os feeds personalizados." -#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 -#~ msgid "Choose your algorithmic feeds" -#~ msgstr "Escolha seus feeds algoritmicos" - #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 msgid "Choose your main feeds" msgstr "Escolha seus feeds principais" @@ -706,11 +672,11 @@ msgstr "clique aqui" #: src/components/TagMenu/index.web.tsx:138 msgid "Click here to open tag menu for {tag}" -msgstr "" +msgstr "Clique aqui para abrir o menu da tag {tag}" #: src/components/RichText.tsx:191 msgid "Click here to open tag menu for #{tag}" -msgstr "" +msgstr "Clique aqui para abrir o menu da tag #{tag}" #: src/screens/Onboarding/index.tsx:35 msgid "Climate" @@ -748,7 +714,7 @@ msgstr "Fechar o painel de navegação" #: src/components/TagMenu/index.tsx:262 msgid "Close this dialog" -msgstr "" +msgstr "Fechar esta janela" #: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" @@ -789,7 +755,7 @@ msgstr "Completar e começar a usar sua conta" #: src/view/com/auth/create/Step3.tsx:73 msgid "Complete the challenge" -msgstr "" +msgstr "Complete o captcha" #: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" @@ -964,10 +930,6 @@ msgstr "Não foi possível carregar o feed" msgid "Could not load list" msgstr "Não foi possível carregar a lista" -#: src/view/com/auth/create/Step2.tsx:91 -#~ msgid "Country" -#~ msgstr "País" - #: src/view/com/auth/HomeLoggedOutCTA.tsx:62 #: src/view/com/auth/SplashScreen.tsx:71 #: src/view/com/auth/SplashScreen.web.tsx:81 @@ -1014,7 +976,7 @@ msgstr "Cultura" #: src/view/com/auth/server-input/index.tsx:95 #: src/view/com/auth/server-input/index.tsx:96 msgid "Custom" -msgstr "" +msgstr "Customizado" #: src/view/com/modals/ChangeHandle.tsx:389 msgid "Custom domain" @@ -1029,10 +991,6 @@ msgstr "Feeds customizados feitos pela comunidade te proporcionam novas experiê msgid "Customize media from external sites." msgstr "Configurar mídia de sites externos." -#: src/view/screens/Settings.tsx:687 -#~ msgid "Danger Zone" -#~ msgstr "Zona Perigosa" - #: src/view/screens/Settings/index.tsx:485 #: src/view/screens/Settings/index.tsx:511 msgid "Dark" @@ -1072,10 +1030,6 @@ msgstr "Excluir Lista" msgid "Delete my account" msgstr "Excluir minha conta" -#: src/view/screens/Settings.tsx:706 -#~ msgid "Delete my account…" -#~ msgstr "Excluir minha conta…" - #: src/view/screens/Settings/index.tsx:784 msgid "Delete My Account…" msgstr "Excluir minha conta…" @@ -1133,13 +1087,9 @@ msgstr "Desencorajar aplicativos a mostrar minha conta para usuários deslogados msgid "Discover new custom feeds" msgstr "Descubra novos feeds" -#: src/view/screens/Feeds.tsx:473 -#~ msgid "Discover new feeds" -#~ msgstr "Descubra novos feeds" - #: src/view/screens/Feeds.tsx:689 msgid "Discover New Feeds" -msgstr "" +msgstr "Descubra Novos Feeds" #: src/view/com/modals/EditProfile.tsx:192 msgid "Display name" @@ -1196,12 +1146,12 @@ msgstr "Toque duas vezes para logar" #: src/view/screens/Settings/index.tsx:755 msgid "Download Bluesky account data (repository)" -msgstr "" +msgstr "Baixar os dados da minha conta Bluesky (repositório)" #: src/view/screens/Settings/ExportCarDialog.tsx:59 #: src/view/screens/Settings/ExportCarDialog.tsx:63 msgid "Download CAR file" -msgstr "" +msgstr "Baixar arquivo CAR" #: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" @@ -1360,7 +1310,7 @@ msgstr "Insira um nome para esta Senha de Aplicativo" #: src/components/dialogs/MutedWords.tsx:100 #: src/components/dialogs/MutedWords.tsx:101 msgid "Enter a word or tag" -msgstr "" +msgstr "Digite uma palavra ou tag" #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" @@ -1399,17 +1349,13 @@ msgstr "Digite o novo e-mail acima" msgid "Enter your new email address below." msgstr "Digite seu novo endereço de e-mail abaixo." -#: src/view/com/auth/create/Step2.tsx:188 -#~ msgid "Enter your phone number" -#~ msgstr "Digite seu número de telefone" - #: src/view/com/auth/login/Login.tsx:99 msgid "Enter your username and password" msgstr "Digite seu nome de usuário e senha" #: src/view/com/auth/create/Step3.tsx:67 msgid "Error receiving captcha response." -msgstr "" +msgstr "Não foi possível processar o captcha." #: src/view/screens/Search/Search.tsx:110 msgid "Error:" @@ -1447,12 +1393,12 @@ msgstr "Mostrar ou esconder o post a que você está respondendo" #: src/view/screens/Settings/index.tsx:753 msgid "Export my data" -msgstr "" +msgstr "Exportar meus dados" #: src/view/screens/Settings/ExportCarDialog.tsx:44 #: src/view/screens/Settings/index.tsx:764 msgid "Export My Data" -msgstr "" +msgstr "Exportar Meus Dados" #: src/view/com/modals/EmbedConsent.tsx:64 msgid "External Media" @@ -1523,14 +1469,6 @@ msgstr "Comentários" msgid "Feeds" msgstr "Feeds" -#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 -#~ msgid "Feeds are created by users and can give you entirely new experiences." -#~ msgstr "Feeds são criados por usuários e podem te dar experiências completamente únicas." - -#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 -#~ msgid "Feeds are created by users and organizations. They offer you varied experiences and suggest content you may like using algorithms." -#~ msgstr "Feeds são criados por usuários ou organizações. Eles oferecem experiências únicas e podem te sugerir conteúdo usando algoritmos próprios." - #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:57 msgid "Feeds are created by users to curate content. Choose some feeds that you find interesting." msgstr "Os feeds são criados por usuários para curadoria de conteúdo. Escolha alguns feeds que você acha interessantes." @@ -1567,11 +1505,7 @@ msgstr "Procurando contas semelhantes..." #: src/view/screens/PreferencesFollowingFeed.tsx:111 msgid "Fine-tune the content you see on your Following feed." -msgstr "" - -#: src/view/screens/PreferencesHomeFeed.tsx:111 -#~ msgid "Fine-tune the content you see on your home screen." -#~ msgstr "Ajuste o conteúdo que você vê na sua tela inicial." +msgstr "Ajuste o conteúdo que você vê na sua tela inicial." #: src/view/screens/PreferencesThreads.tsx:60 msgid "Fine-tune the discussion threads." @@ -1659,7 +1593,7 @@ msgstr "Seguindo {0}" #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 msgid "Following Feed Preferences" -msgstr "" +msgstr "Configurações do feed principal" #: src/view/com/profile/ProfileHeader.tsx:546 msgid "Follows you" @@ -1697,7 +1631,7 @@ msgstr "Esqueci a Senha" #: src/screens/Hashtag.tsx:108 #: src/screens/Hashtag.tsx:148 msgid "From @{sanitizedAuthor}" -msgstr "" +msgstr "De @{sanitizedAuthor}" #: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" @@ -1751,15 +1685,15 @@ msgstr "Usuário" #: src/Navigation.tsx:270 msgid "Hashtag" -msgstr "" +msgstr "Hashtag" #: src/components/RichText.tsx:188 #~ msgid "Hashtag: {tag}" -#~ msgstr "" +#~ msgstr "Hashtag: {tag}" #: src/components/RichText.tsx:190 msgid "Hashtag: #{tag}" -msgstr "" +msgstr "Hashtag: #{tag}" #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" @@ -1930,10 +1864,6 @@ msgstr "Insira a nova senha" msgid "Input password for account deletion" msgstr "Insira a senha para excluir a conta" -#: src/view/com/auth/create/Step2.tsx:196 -#~ msgid "Input phone number for SMS verification" -#~ msgstr "Insira o número de telefone para verificação via SMS" - #: src/view/com/auth/login/LoginForm.tsx:230 msgid "Input the password tied to {identifier}" msgstr "Insira a senha da conta {identifier}" @@ -1942,10 +1872,6 @@ msgstr "Insira a senha da conta {identifier}" msgid "Input the username or email address you used at signup" msgstr "Insira o usuário ou e-mail que você cadastrou" -#: src/view/com/auth/create/Step2.tsx:271 -#~ msgid "Input the verification code we have texted to you" -#~ msgstr "Insira o código de verificação que enviamos para você" - #: src/view/com/modals/Waitlist.tsx:90 #~ msgid "Input your email to get on the Bluesky waitlist" #~ msgstr "Insira seu e-mail para entrar na lista de espera do Bluesky" @@ -1966,10 +1892,6 @@ msgstr "Post inválido" msgid "Invalid username or password" msgstr "Credenciais inválidas" -#: src/view/screens/Settings.tsx:411 -#~ msgid "Invite" -#~ msgstr "Convidar" - #: src/view/com/modals/InviteCodes.tsx:93 msgid "Invite a Friend" msgstr "Convide um Amigo" @@ -1987,10 +1909,6 @@ msgstr "Convite inválido. Verifique se você o inseriu corretamente e tente nov msgid "Invite codes: {0} available" msgstr "Convites: {0} disponíveis" -#: src/view/shell/Drawer.tsx:645 -#~ msgid "Invite codes: {invitesAvailable} available" -#~ msgstr "Convites: {invitesAvailable} disponível" - #: src/view/com/modals/InviteCodes.tsx:169 msgid "Invite codes: 1 available" msgstr "Convites: 1 disponível" @@ -2232,15 +2150,15 @@ msgstr "Certifique-se de onde está indo!" #: src/components/dialogs/MutedWords.tsx:83 msgid "Manage your muted words and tags" -msgstr "" +msgstr "Gerencie suas palavras/tags silenciadas" #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" -msgstr "" +msgstr "Não pode ter mais que 253 caracteres" #: src/view/com/auth/create/Step2.tsx:109 msgid "May only contain letters and numbers" -msgstr "" +msgstr "Só pode conter letras e números" #: src/view/screens/Profile.tsx:182 msgid "Media" @@ -2332,15 +2250,15 @@ msgstr "Respostas mais curtidas primeiro" #: src/view/com/auth/create/Step2.tsx:122 msgid "Must be at least 3 characters" -msgstr "" +msgstr "Deve ter no mínimo 3 caracteres" #: src/components/TagMenu/index.tsx:249 msgid "Mute" -msgstr "" +msgstr "Silenciar" #: src/components/TagMenu/index.web.tsx:105 msgid "Mute {truncatedTag}" -msgstr "" +msgstr "Silenciar {truncatedTag}" #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" @@ -2352,19 +2270,19 @@ msgstr "Silenciar contas" #: src/components/TagMenu/index.tsx:209 msgid "Mute all {displayTag} posts" -msgstr "" +msgstr "Silenciar posts com {displayTag}" #: src/components/TagMenu/index.tsx:211 #~ msgid "Mute all {tag} posts" -#~ msgstr "" +#~ msgstr "Silenciar posts com {tag}" #: src/components/dialogs/MutedWords.tsx:149 msgid "Mute in tags only" -msgstr "" +msgstr "Silenciar apenas as tags" #: src/components/dialogs/MutedWords.tsx:134 msgid "Mute in text & tags" -msgstr "" +msgstr "Silenciar texto e tags" #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" @@ -2380,11 +2298,11 @@ msgstr "Silenciar esta lista" #: src/components/dialogs/MutedWords.tsx:127 msgid "Mute this word in post text and tags" -msgstr "" +msgstr "Silenciar esta palavra no conteúdo de um post e tags" #: src/components/dialogs/MutedWords.tsx:142 msgid "Mute this word in tags only" -msgstr "" +msgstr "Silenciar esta palavra apenas nas tags de um post" #: src/view/com/util/forms/PostDropdownBtn.tsx:251 #: src/view/com/util/forms/PostDropdownBtn.tsx:257 @@ -2394,7 +2312,7 @@ msgstr "Silenciar thread" #: src/view/com/util/forms/PostDropdownBtn.tsx:267 #: src/view/com/util/forms/PostDropdownBtn.tsx:269 msgid "Mute words & tags" -msgstr "" +msgstr "Silenciar palavras/tags" #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" @@ -2415,7 +2333,7 @@ msgstr "Contas silenciadas não aparecem no seu feed ou nas suas notificações. #: src/view/screens/Moderation.tsx:100 msgid "Muted words & tags" -msgstr "" +msgstr "Palavras/tags silenciadas" #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." @@ -2439,7 +2357,7 @@ msgstr "Meus Feeds Salvos" #: src/view/com/auth/server-input/index.tsx:118 msgid "my-server.com" -msgstr "" +msgstr "meu-servidor.com.br" #: src/view/com/modals/AddAppPasswords.tsx:179 #: src/view/com/modals/CreateOrEditList.tsx:290 @@ -2482,7 +2400,7 @@ msgstr "Nunca perca o acesso aos seus seguidores ou dados." #: src/components/dialogs/MutedWords.tsx:293 msgid "Nevermind" -msgstr "" +msgstr "Deixa pra lá" #: src/view/screens/Lists.tsx:76 msgctxt "action" @@ -2587,7 +2505,7 @@ msgstr "Nenhum resultado" #: src/components/Lists.tsx:192 msgid "No results found" -msgstr "" +msgstr "Nenhum resultado encontrado" #: src/view/screens/Feeds.tsx:495 msgid "No results found for \"{query}\"" @@ -2669,7 +2587,7 @@ msgstr "Apenas {0} pode responder." #: src/components/Lists.tsx:82 msgid "Oops, something went wrong!" -msgstr "" +msgstr "Opa, algo deu errado!" #: src/components/Lists.tsx:188 #: src/view/screens/AppPasswords.tsx:65 @@ -2683,7 +2601,7 @@ msgstr "Abrir" #: src/view/screens/Moderation.tsx:75 msgid "Open content filtering settings" -msgstr "" +msgstr "Abrir configurações de filtro" #: src/view/com/composer/Composer.tsx:477 #: src/view/com/composer/Composer.tsx:478 @@ -2696,7 +2614,7 @@ msgstr "Abrir links no navegador interno" #: src/view/screens/Moderation.tsx:92 msgid "Open muted words settings" -msgstr "" +msgstr "Abrir configurações das palavras silenciadas" #: src/view/com/home/HomeHeaderLayoutMobile.tsx:50 msgid "Open navigation" @@ -2704,7 +2622,7 @@ msgstr "Abrir navegação" #: src/view/com/util/forms/PostDropdownBtn.tsx:175 msgid "Open post options menu" -msgstr "" +msgstr "Abrir opções do post" #: src/view/screens/Settings/index.tsx:804 msgid "Open storybook page" @@ -2754,10 +2672,6 @@ msgstr "Abre lista de seguidores" msgid "Opens following list" msgstr "Abre lista de seguidos" -#: src/view/screens/Settings.tsx:412 -#~ msgid "Opens invite code list" -#~ msgstr "Abre lista de convites" - #: src/view/com/modals/InviteCodes.tsx:172 msgid "Opens list of invite codes" msgstr "Abre a lista de códigos de convite" @@ -2819,10 +2733,6 @@ msgstr "Ou combine estas opções:" msgid "Other account" msgstr "Outra conta" -#: src/view/com/modals/ServerInput.tsx:88 -#~ msgid "Other service" -#~ msgstr "Outro serviço" - #: src/view/com/composer/select-language/SelectLangBtn.tsx:91 msgid "Other..." msgstr "Outro..." @@ -2872,10 +2782,6 @@ msgstr "A permissão de galeria foi recusada. Por favor, habilite-a nas configur msgid "Pets" msgstr "Pets" -#: src/view/com/auth/create/Step2.tsx:183 -#~ msgid "Phone number" -#~ msgstr "Número de telefone" - #: src/view/com/modals/SelfLabel.tsx:121 msgid "Pictures meant for adults." msgstr "Imagens destinadas a adultos." @@ -2912,7 +2818,7 @@ msgstr "Por favor, escolha sua senha." #: src/view/com/auth/create/state.ts:131 msgid "Please complete the verification captcha." -msgstr "" +msgstr "Por favor, complete o captcha de verificação." #: src/view/com/modals/ChangeEmail.tsx:67 msgid "Please confirm your email before changing it. This is a temporary requirement while email-updating tools are added, and it will soon be removed." @@ -2922,17 +2828,13 @@ msgstr "Por favor, confirme seu e-mail antes de alterá-lo. Este é um requisito msgid "Please enter a name for your app password. All spaces is not allowed." msgstr "Por favor, insira um nome para a sua Senha de Aplicativo." -#: src/view/com/auth/create/Step2.tsx:206 -#~ msgid "Please enter a phone number that can receive SMS text messages." -#~ msgstr "Por favor, insira um número de telefone que possa receber mensagens SMS." - #: src/view/com/modals/AddAppPasswords.tsx:145 msgid "Please enter a unique name for this App Password or use our randomly generated one." msgstr "Por favor, insira um nome único para esta Senha de Aplicativo ou use nosso nome gerado automaticamente." #: src/components/dialogs/MutedWords.tsx:68 msgid "Please enter a valid word, tag, or phrase to mute" -msgstr "" +msgstr "Por favor, insira uma palavra, tag ou frase para silenciar" #: src/view/com/auth/create/state.ts:170 #~ msgid "Please enter the code you received by SMS." @@ -2955,11 +2857,6 @@ msgstr "Por favor, digite sua senha também:" msgid "Please tell us why you think this content warning was incorrectly applied!" msgstr "Por favor, diga-nos por que você acha que este aviso de conteúdo foi aplicado incorretamente!" -#: src/view/com/modals/AppealLabel.tsx:72 -#: src/view/com/modals/AppealLabel.tsx:75 -#~ msgid "Please tell us why you think this decision was incorrect." -#~ msgstr "Por favor, conte-nos por que achou que esta decisão está incorreta." - #: src/view/com/modals/VerifyEmail.tsx:101 msgid "Please Verify Your Email" msgstr "Por favor, verifique seu e-mail" @@ -3019,7 +2916,7 @@ msgstr "Post não encontrado" #: src/components/TagMenu/index.tsx:253 msgid "posts" -msgstr "" +msgstr "posts" #: src/view/screens/Profile.tsx:180 msgid "Posts" @@ -3027,7 +2924,7 @@ msgstr "Posts" #: src/components/dialogs/MutedWords.tsx:90 msgid "Posts can be muted based on their text, their tags, or both." -msgstr "" +msgstr "Posts podem ser silenciados baseados no seu conteúdo, tags ou ambos." #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" @@ -3171,7 +3068,7 @@ msgstr "Remover visualização da imagem" #: src/components/dialogs/MutedWords.tsx:343 msgid "Remove mute word from your list" -msgstr "" +msgstr "Remover palavra silenciada da lista" #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" @@ -3286,10 +3183,6 @@ msgstr "Reposts" msgid "Request Change" msgstr "Solicitar Alteração" -#: src/view/com/auth/create/Step2.tsx:219 -#~ msgid "Request code" -#~ msgstr "Solicitar código" - #: src/view/com/modals/ChangePassword.tsx:239 #: src/view/com/modals/ChangePassword.tsx:241 msgid "Request Code" @@ -3368,10 +3261,6 @@ msgstr "Tente novamente" msgid "Return to previous page" msgstr "Voltar para página anterior" -#: src/view/shell/desktop/RightNav.tsx:55 -#~ msgid "SANDBOX. Posts and accounts are not permanent." -#~ msgstr "SANDBOX. Posts e contas não são permanentes." - #: src/view/com/lightbox/Lightbox.tsx:132 #: src/view/com/modals/CreateOrEditList.tsx:345 msgctxt "action" @@ -3447,19 +3336,19 @@ msgstr "Pesquisar por \"{query}\"" #: src/components/TagMenu/index.tsx:145 msgid "Search for all posts by @{authorHandle} with tag {displayTag}" -msgstr "" +msgstr "Pesquisar por posts de @{authorHandle} com a tag {displayTag}" #: src/components/TagMenu/index.tsx:145 #~ msgid "Search for all posts by @{authorHandle} with tag {tag}" -#~ msgstr "" +#~ msgstr "Pesquisar por posts de @{authorHandle} com a tag {tag}" #: src/components/TagMenu/index.tsx:94 msgid "Search for all posts with tag {displayTag}" -msgstr "" +msgstr "Pesquisar por posts com a tag {displayTag}" #: src/components/TagMenu/index.tsx:90 #~ msgid "Search for all posts with tag {tag}" -#~ msgstr "" +#~ msgstr "Pesquisar por posts com a tag {tag}" #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 @@ -3473,27 +3362,27 @@ msgstr "Passo de Segurança Necessário" #: src/components/TagMenu/index.web.tsx:66 msgid "See {truncatedTag} posts" -msgstr "" +msgstr "Ver posts com {truncatedTag}" #: src/components/TagMenu/index.web.tsx:83 msgid "See {truncatedTag} posts by user" -msgstr "" +msgstr "Ver posts com {truncatedTag} deste usuário" #: src/components/TagMenu/index.tsx:128 msgid "See <0>{displayTag}</0> posts" -msgstr "" +msgstr "Ver posts com <0>{displayTag}</0>" #: src/components/TagMenu/index.tsx:187 msgid "See <0>{displayTag}</0> posts by this user" -msgstr "" +msgstr "Ver posts com <0>{displayTag}</0> deste usuário" #: src/components/TagMenu/index.tsx:128 #~ msgid "See <0>{tag}</0> posts" -#~ msgstr "" +#~ msgstr "Ver posts com <0>{tag}</0>" #: src/components/TagMenu/index.tsx:189 #~ msgid "See <0>{tag}</0> posts by this user" -#~ msgstr "" +#~ msgstr "Ver posts com <0>{tag}</0> deste usuário" #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" @@ -3507,10 +3396,6 @@ msgstr "Veja o que vem por aí" msgid "Select {item}" msgstr "Selecionar {item}" -#: src/view/com/modals/ServerInput.tsx:75 -#~ msgid "Select Bluesky Social" -#~ msgstr "Selecionar Bluesky Social" - #: src/view/com/auth/login/Login.tsx:117 msgid "Select from an existing account" msgstr "Selecionar de uma conta existente" @@ -3530,11 +3415,7 @@ msgstr "Selecione algumas contas para seguir" #: src/view/com/auth/server-input/index.tsx:82 msgid "Select the service that hosts your data." -msgstr "" - -#: src/screens/Onboarding/StepModeration/index.tsx:49 -#~ msgid "Select the types of content that you want to see (or not see), and we'll handle the rest." -#~ msgstr "Selecione os tipos de conteúdo que você quer (ou não) ver, e cuidaremos do resto." +msgstr "Selecione o serviço que hospeda seus dados." #: src/screens/Onboarding/StepTopicalFeeds.tsx:96 msgid "Select topical feeds to follow from the list below" @@ -3556,10 +3437,6 @@ msgstr "Selecione o idioma do seu aplicativo" msgid "Select your interests from the options below" msgstr "Selecione seus interesses" -#: src/view/com/auth/create/Step2.tsx:155 -#~ msgid "Select your phone's country" -#~ msgstr "Selecione o país do número de telefone" - #: src/view/screens/LanguageSettings.tsx:190 msgid "Select your preferred language for translations in your feed." msgstr "Selecione seu idioma preferido para as traduções no seu feed." @@ -3601,7 +3478,7 @@ msgstr "Envia o e-mail com o código de confirmação para excluir a conta" #: src/view/com/auth/server-input/index.tsx:110 msgid "Server address" -msgstr "" +msgstr "URL do servidor" #: src/view/com/modals/ContentFilteringSettings.tsx:311 msgid "Set {value} for {labelGroup} content moderation policy" @@ -3657,13 +3534,9 @@ msgstr "Defina esta configuração como \"Não\" para ocultar todos os reposts d msgid "Set this setting to \"Yes\" to show replies in a threaded view. This is an experimental feature." msgstr "Defina esta configuração como \"Sim\" para mostrar respostas em uma visualização de thread. Este é um recurso experimental." -#: src/view/screens/PreferencesHomeFeed.tsx:261 -#~ msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your following feed. This is an experimental feature." -#~ msgstr "Defina esta configuração como \"Sim\" para mostrar amostras de seus feeds salvos na sua página inicial. Este é um recurso experimental." - #: src/view/screens/PreferencesFollowingFeed.tsx:261 msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your Following feed. This is an experimental feature." -msgstr "" +msgstr "Defina esta configuração como \"Sim\" para exibir amostras de seus feeds salvos no seu feed inicial. Este é um recurso experimental." #: src/screens/Onboarding/Layout.tsx:50 msgid "Set up your account" @@ -3893,10 +3766,6 @@ msgstr "Pular" msgid "Skip this flow" msgstr "Pular" -#: src/view/com/auth/create/Step2.tsx:82 -#~ msgid "SMS verification" -#~ msgstr "Verificação por SMS" - #: src/screens/Onboarding/index.tsx:40 msgid "Software Dev" msgstr "Desenvolvimento de software" @@ -3907,7 +3776,7 @@ msgstr "Desenvolvimento de software" #: src/components/Lists.tsx:203 msgid "Something went wrong!" -msgstr "" +msgstr "Algo deu errado!" #: src/view/com/modals/Waitlist.tsx:51 #~ msgid "Something went wrong. Check your email and try again." @@ -3933,10 +3802,6 @@ msgstr "Esportes" msgid "Square" msgstr "Quadrado" -#: src/view/com/modals/ServerInput.tsx:62 -#~ msgid "Staging" -#~ msgstr "Staging" - #: src/view/screens/Settings/index.tsx:871 msgid "Status page" msgstr "Página de status" @@ -3989,10 +3854,6 @@ msgstr "Sugestivo" msgid "Support" msgstr "Suporte" -#: src/view/com/modals/ProfilePreview.tsx:110 -#~ msgid "Swipe up to see more" -#~ msgstr "Deslize para cima para ver mais" - #: src/view/com/modals/SwitchAccount.tsx:117 msgid "Switch Account" msgstr "Alterar Conta" @@ -4017,15 +3878,15 @@ msgstr "Log do sistema" #: src/components/dialogs/MutedWords.tsx:337 msgid "tag" -msgstr "" +msgstr "tag" #: src/components/TagMenu/index.tsx:78 msgid "Tag menu: {displayTag}" -msgstr "" +msgstr "Menu da tag: {displayTag}" #: src/components/TagMenu/index.tsx:74 #~ msgid "Tag menu: {tag}" -#~ msgstr "" +#~ msgstr "Menu da tag: {tag}" #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" @@ -4052,7 +3913,7 @@ msgstr "Termos de Serviço" #: src/components/dialogs/MutedWords.tsx:337 msgid "text" -msgstr "" +msgstr "texto" #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 @@ -4061,7 +3922,7 @@ msgstr "Campo de entrada de texto" #: src/view/com/auth/create/CreateAccount.tsx:94 msgid "That handle is already taken." -msgstr "" +msgstr "Este identificador de usuário já está sendo usado." #: src/view/com/profile/ProfileHeader.tsx:263 msgid "The account will be able to interact with you after unblocking." @@ -4179,10 +4040,6 @@ msgstr "Houve um problema inesperado no aplicativo. Por favor, deixe-nos saber s msgid "There's been a rush of new users to Bluesky! We'll activate your account as soon as we can." msgstr "Muitos usuários estão tentando acessar o Bluesky! Ativaremos sua conta assim que possível." -#: src/view/com/auth/create/Step2.tsx:55 -#~ msgid "There's something wrong with this number. Please choose your country and enter your full phone number!" -#~ msgstr "Houve um problema com este número. Por favor, escolha um país e digite seu número de telefone completo!" - #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:138 msgid "These are popular accounts you might like:" msgstr "Estas são contas populares que talvez você goste:" @@ -4209,7 +4066,7 @@ msgstr "Este conteúdo não é visível sem uma conta do Bluesky." #: src/view/screens/Settings/ExportCarDialog.tsx:75 msgid "This feature is in beta. You can read more about repository exports in <0>this blogpost.</0>" -msgstr "" +msgstr "Esta funcionalidade está em beta. Você pode ler mais sobre exportação de repositórios <0>neste post</0> do nosso blog." #: src/view/com/posts/FeedErrorMessage.tsx:114 msgid "This feed is currently receiving high traffic and is temporarily unavailable. Please try again later." @@ -4261,17 +4118,13 @@ msgstr "Este usuário está incluído na lista <0/>, que você bloqueou." msgid "This user is included in the <0/> list which you have muted." msgstr "Este usuário está incluído na lista <0/>, que você silenciou." -#: src/view/com/modals/ModerationDetails.tsx:74 -#~ msgid "This user is included the <0/> list which you have muted." -#~ msgstr "Este usuário está incluído na lista <0/>, que você silenciou." - #: src/view/com/modals/SelfLabel.tsx:137 msgid "This warning is only available for posts with media attached." msgstr "Este aviso só está disponível para publicações com mídia anexada." #: src/components/dialogs/MutedWords.tsx:285 msgid "This will delete {0} from your muted words. You can always add it back later." -msgstr "" +msgstr "Isso removerá {0} das suas palavras silenciadas. Você pode adicioná-la novamente depois." #: src/view/com/util/forms/PostDropdownBtn.tsx:282 msgid "This will hide this post from your feeds." @@ -4292,7 +4145,7 @@ msgstr "Preferências das Threads" #: src/components/dialogs/MutedWords.tsx:113 msgid "Toggle between muted word options." -msgstr "" +msgstr "Alternar entre opções de uma palavra silenciada" #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" @@ -4376,7 +4229,7 @@ msgstr "Dessilenciar" #: src/components/TagMenu/index.web.tsx:104 msgid "Unmute {truncatedTag}" -msgstr "" +msgstr "Dessilenciar {truncatedTag}" #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" @@ -4384,11 +4237,11 @@ msgstr "Dessilenciar conta" #: src/components/TagMenu/index.tsx:208 msgid "Unmute all {displayTag} posts" -msgstr "" +msgstr "Dessilenciar posts com {displayTag}" #: src/components/TagMenu/index.tsx:210 #~ msgid "Unmute all {tag} posts" -#~ msgstr "" +#~ msgstr "Dessilenciar posts com {tag}" #: src/view/com/util/forms/PostDropdownBtn.tsx:251 #: src/view/com/util/forms/PostDropdownBtn.tsx:256 @@ -4446,10 +4299,6 @@ msgstr "Usar o meu navegador padrão" msgid "Use this to sign into the other app along with your handle." msgstr "Use esta senha para entrar no outro aplicativo juntamente com seu identificador." -#: src/view/com/modals/ServerInput.tsx:105 -#~ msgid "Use your domain as your Bluesky client service provider" -#~ msgstr "Use seu domínio como o provedor de serviço do Bluesky" - #: src/view/com/modals/InviteCodes.tsx:200 msgid "Used by:" msgstr "Usado por:" @@ -4514,10 +4363,6 @@ msgstr "usuários seguidos por <0/>" msgid "Users in \"{0}\"" msgstr "Usuários em \"{0}\"" -#: src/view/com/auth/create/Step2.tsx:243 -#~ msgid "Verification code" -#~ msgstr "Código de verificação" - #: src/view/screens/Settings/index.tsx:910 msgid "Verify email" msgstr "Verificar e-mail" @@ -4578,7 +4423,7 @@ msgstr "Também recomendamos o \"For You\", do Skygaze:" #: src/screens/Hashtag.tsx:132 msgid "We couldn't find any results for that hashtag." -msgstr "" +msgstr "Não encontramos nenhum post com esta hashtag." #: src/screens/Deactivated.tsx:133 msgid "We estimate {estimatedTime} until your account is ready." @@ -4598,7 +4443,7 @@ msgstr "Não temos mais posts de quem você segue. Aqui estão os mais novos de #: src/components/dialogs/MutedWords.tsx:204 msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." -msgstr "" +msgstr "Não recomendamos utilizar palavras comuns que aparecem em muitos posts, já que isso pode resultar em filtrar todos eles." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" @@ -4630,7 +4475,7 @@ msgstr "Tivemos um problema ao exibir esta lista. Se continuar acontecendo, cont #: src/components/dialogs/MutedWords.tsx:230 msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." -msgstr "" +msgstr "Não foi possível carregar sua lista de palavras silenciadas. Por favor, tente novamente." #: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." @@ -4688,10 +4533,6 @@ msgstr "Escreva sua resposta" msgid "Writers" msgstr "Escritores" -#: src/view/com/auth/create/Step2.tsx:263 -#~ msgid "XXXXXX" -#~ msgstr "XXXXXX" - #: src/view/com/composer/select-language/SuggestedLanguage.tsx:77 #: src/view/screens/PreferencesFollowingFeed.tsx:129 #: src/view/screens/PreferencesFollowingFeed.tsx:201 @@ -4702,10 +4543,6 @@ msgstr "Escritores" msgid "Yes" msgstr "Sim" -#: src/screens/Onboarding/StepModeration/index.tsx:46 -#~ msgid "You are in control" -#~ msgstr "Você está no controle" - #: src/screens/Deactivated.tsx:130 msgid "You are in line." msgstr "Você está na fila." @@ -4715,10 +4552,6 @@ msgstr "Você está na fila." msgid "You can also discover new Custom Feeds to follow." msgstr "Você também pode descobrir novos feeds para seguir." -#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:123 -#~ msgid "You can also try our \"Discover\" algorithm:" -#~ msgstr "Você também pode tentar nosso algoritmo \"Discover\":" - #: src/screens/Onboarding/StepFollowingFeed.tsx:142 msgid "You can change these settings later." msgstr "Você pode mudar estas configurações depois." @@ -4786,7 +4619,7 @@ msgstr "Você ainda não silenciou nenhuma conta. Para silenciar uma conta, aces #: src/components/dialogs/MutedWords.tsx:250 msgid "You haven't muted any words or tags yet" -msgstr "" +msgstr "Você não silenciou nenhuma palavra ou tag ainda" #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." @@ -4836,7 +4669,7 @@ msgstr "Sua conta foi excluída" #: src/view/screens/Settings/ExportCarDialog.tsx:47 msgid "Your account repository, containing all public data records, can be downloaded as a \"CAR\" file. This file does not include media embeds, such as images, or your private data, which must be fetched separately." -msgstr "" +msgstr "O repositório da sua conta, contendo todos os seus dados públicos, pode ser baixado como um arquivo \"CAR\". Este arquivo não inclui imagens ou dados privados, estes devem ser exportados separadamente." #: src/view/com/auth/create/Step1.tsx:215 msgid "Your birth date" @@ -4888,7 +4721,7 @@ msgstr "Seu usuário completo será <0>@{0}</0>" #: src/components/dialogs/MutedWords.tsx:221 msgid "Your muted words" -msgstr "" +msgstr "Suas palavras silenciadas" #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" From 0e2619f7d50379453138234d448899cedf026dd8 Mon Sep 17 00:00:00 2001 From: Leonid <kasumi@bangdream.moe> Date: Wed, 20 Mar 2024 03:43:41 +0800 Subject: [PATCH 099/109] Update zh-CN translation to latest version (#2901) * Update Chinese translation for "followed you" message * Update translations for zh-CN locale * Update messages.po * Delete empty line * Add translations in messages.po * fix some issue * Apply suggestions from code review * Update src/locale/locales/zh-CN/messages.po * Update src/locale/locales/zh-CN/messages.po * Update src/locale/locales/zh-CN/messages.po * accept suggestions * unify translations * Update Chinese translations for Navigation and PreferencesHomeFeed * Update translations * merge latest translations --------- Co-authored-by: Frudrax Cheng <i@cynosura.one> --- src/locale/locales/zh-CN/messages.po | 518 +++++++++++++-------------- 1 file changed, 259 insertions(+), 259 deletions(-) diff --git a/src/locale/locales/zh-CN/messages.po b/src/locale/locales/zh-CN/messages.po index eac822f055..d7fb15b036 100644 --- a/src/locale/locales/zh-CN/messages.po +++ b/src/locale/locales/zh-CN/messages.po @@ -1,6 +1,6 @@ msgid "" msgstr "" -"POT-Creation-Date: 2024-02-07 19:20+0800\n" +"POT-Creation-Date: 2024-02-17 21:00+0800\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -23,7 +23,7 @@ msgstr "(没有邮件)" #: src/view/com/profile/ProfileHeader.tsx:593 msgid "{following} following" -msgstr "{following} 正在关注" +msgstr "{following} 个正在关注" #: src/view/shell/desktop/RightNav.tsx:151 #~ msgid "{invitesAvailable, plural, one {Invite codes: # available} other {Invite codes: # available}}" @@ -41,15 +41,15 @@ msgstr "{following} 正在关注" #: src/view/shell/Drawer.tsx:440 msgid "{numUnreadNotifications} unread" -msgstr "{numUnreadNotifications} 未读" +msgstr "{numUnreadNotifications} 个未读" #: src/view/com/threadgate/WhoCanReply.tsx:158 msgid "<0/> members" -msgstr "<0/> 成员" +msgstr "<0/> 个成员" #: src/view/com/profile/ProfileHeader.tsx:595 msgid "<0>{following} </0><1>following</1>" -msgstr "<0>{following} </0><1>正在关注</1>" +msgstr "<0>{following} </0><1>个正在关注</1>" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:30 msgid "<0>Choose your</0><1>Recommended</1><2>Feeds</2>" @@ -69,11 +69,11 @@ msgstr "⚠无效的用户识别符" #: src/view/com/util/moderation/LabelInfo.tsx:45 msgid "A content warning has been applied to this {0}." -msgstr "此处已启用内容警告 {0}." +msgstr "内容警告已套用到这个{0}." #: src/lib/hooks/useOTAUpdate.ts:16 msgid "A new version of the app is available. Please update to continue using the app." -msgstr "App 新版本已发布,请更新以继续使用。" +msgstr "应用新版本已发布,请更新以继续使用。" #: src/view/com/util/ViewHeader.tsx:89 #: src/view/screens/Search/Search.tsx:647 @@ -137,7 +137,7 @@ msgstr "添加" #: src/view/com/modals/SelfLabel.tsx:56 msgid "Add a content warning" -msgstr "添加内容警告" +msgstr "新增内容警告" #: src/view/screens/ProfileList.tsx:803 msgid "Add a user to this list" @@ -152,18 +152,18 @@ msgstr "添加账户" #: src/view/com/composer/photos/Gallery.tsx:180 #: src/view/com/modals/AltImage.tsx:116 msgid "Add alt text" -msgstr "添加替代文字" +msgstr "新增替代文字" #: src/view/screens/AppPasswords.tsx:102 #: src/view/screens/AppPasswords.tsx:143 #: src/view/screens/AppPasswords.tsx:156 msgid "Add App Password" -msgstr "添加 App 专用密码" +msgstr "新增应用专用密码" #: src/view/com/modals/report/InputIssueDetails.tsx:41 #: src/view/com/modals/report/Modal.tsx:191 msgid "Add details" -msgstr "添加细节" +msgstr "新增细节" #: src/view/com/modals/report/Modal.tsx:194 msgid "Add details to report" @@ -179,15 +179,15 @@ msgstr "添加链接卡片:" #: src/components/dialogs/MutedWords.tsx:158 msgid "Add mute word for configured settings" -msgstr "" +msgstr "为配置的设置添加隐藏词" #: src/components/dialogs/MutedWords.tsx:87 msgid "Add muted words and tags" -msgstr "" +msgstr "添加隐藏词和话题标签" #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" -msgstr "将以下DNS记录添加到你的域名:" +msgstr "将以下 DNS 记录新增到你的域名:" #: src/view/com/profile/ProfileHeader.tsx:310 msgid "Add to Lists" @@ -205,15 +205,15 @@ msgstr "已添加" #: src/view/com/modals/ListAddRemoveUsers.tsx:191 #: src/view/com/modals/UserAddRemoveLists.tsx:144 msgid "Added to list" -msgstr "添加至列表" +msgstr "已添加至列表" #: src/view/com/feeds/FeedSourceCard.tsx:127 msgid "Added to my feeds" -msgstr "添加至自定义信息流" +msgstr "已添加至自定义信息流" #: src/view/screens/PreferencesFollowingFeed.tsx:173 msgid "Adjust the number of likes a reply must have to be shown in your feed." -msgstr "调整回复中需要具有的点赞数才会在你的信息流中显示。" +msgstr "调整回复中需要具有的喜欢数才会在你的信息流中显示。" #: src/view/com/modals/SelfLabel.tsx:75 msgid "Adult Content" @@ -221,7 +221,7 @@ msgstr "成人内容" #: src/view/com/modals/ContentFilteringSettings.tsx:141 msgid "Adult content can only be enabled via the Web at <0/>." -msgstr "要显示成人内容,你必须访问网页端上的<0/>。" +msgstr "要显示成人内容,你必须访问网页端<0/>来启用。" #: src/view/screens/Settings/index.tsx:664 msgid "Advanced" @@ -229,12 +229,12 @@ msgstr "详细设置" #: src/view/screens/Feeds.tsx:666 msgid "All the feeds you've saved, right in one place." -msgstr "" +msgstr "你保存的所有信息流都集中在一处。" #: src/view/com/auth/login/ForgotPasswordForm.tsx:221 #: src/view/com/modals/ChangePassword.tsx:168 msgid "Already have a code?" -msgstr "已经有确认码了?" +msgstr "已经有验证码了?" #: src/view/com/auth/login/ChooseAccountForm.tsx:98 msgid "Already signed in as @{0}" @@ -250,7 +250,7 @@ msgstr "替代文字" #: src/view/com/composer/photos/Gallery.tsx:209 msgid "Alt text describes images for blind and low-vision users, and helps give context to everyone." -msgstr "为图片添加替代文字,以帮助盲人及视障群体了解图片内容。" +msgstr "为图片新增替代文字,以帮助盲人及视障群体了解图片内容。" #: src/view/com/modals/VerifyEmail.tsx:124 msgid "An email has been sent to {0}. It includes a confirmation code which you can enter below." @@ -280,29 +280,29 @@ msgstr "应用语言" #: src/view/screens/AppPasswords.tsx:228 msgid "App password deleted" -msgstr "App 专用密码已删除" +msgstr "应用专用密码已删除" #: src/view/com/modals/AddAppPasswords.tsx:134 msgid "App Password names can only contain letters, numbers, spaces, dashes, and underscores." -msgstr "App 专用密码只能包含字母、数字、空格、破折号及下划线。" +msgstr "应用专用密码只能包含字母、数字、空格、破折号及下划线。" #: src/view/com/modals/AddAppPasswords.tsx:99 msgid "App Password names must be at least 4 characters long." -msgstr "App 专用密码必须至少为 4 个字符。" +msgstr "应用专用密码必须至少为 4 个字符。" #: src/view/screens/Settings/index.tsx:675 msgid "App password settings" -msgstr "App 专用密码设置" +msgstr "应用专用密码设置" #: src/view/screens/Settings.tsx:650 #~ msgid "App passwords" -#~ msgstr "App 专用密码" +#~ msgstr "应用专用密码" #: src/Navigation.tsx:239 #: src/view/screens/AppPasswords.tsx:187 #: src/view/screens/Settings/index.tsx:684 msgid "App Passwords" -msgstr "App 专用密码" +msgstr "应用专用密码" #: src/view/com/util/forms/PostDropdownBtn.tsx:337 #: src/view/com/util/forms/PostDropdownBtn.tsx:346 @@ -327,7 +327,7 @@ msgstr "外观" #: src/view/screens/AppPasswords.tsx:224 msgid "Are you sure you want to delete the app password \"{name}\"?" -msgstr "你确定要删除这条 App 专用密码 \"{name}\"?" +msgstr "你确定要删除这条应用专用密码 \"{name}\"?" #: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" @@ -388,7 +388,7 @@ msgstr "生日" #: src/view/screens/Settings/index.tsx:340 msgid "Birthday:" -msgstr "生日:" +msgstr "生日:" #: src/view/com/profile/ProfileHeader.tsx:239 #: src/view/com/profile/ProfileHeader.tsx:346 @@ -439,7 +439,7 @@ msgstr "已屏蔽帖子。" #: src/view/screens/ProfileList.tsx:318 msgid "Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you." -msgstr "屏蔽是公共性的。被屏蔽的账户无法在你的帖子中回复、提及你或以其他方式与你互动。" +msgstr "屏蔽是公开的。被屏蔽的账户无法在你的帖子中回复、提及你或以其他方式与你互动。" #: src/view/com/auth/HomeLoggedOutCTA.tsx:93 #: src/view/com/auth/SplashScreen.web.tsx:133 @@ -454,7 +454,7 @@ msgstr "Bluesky" #: src/view/com/auth/server-input/index.tsx:150 msgid "Bluesky is an open network where you can choose your hosting provider. Custom hosting is now available in beta for developers." -msgstr "" +msgstr "Bluesky 是一个开放的公共网络,你可以选择自己的托管提供商。现在,自定义托管现在已经进入开发者测试阶段。" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:80 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:80 @@ -558,32 +558,32 @@ msgstr "取消" #: src/view/com/modals/DeleteAccount.tsx:152 #: src/view/com/modals/DeleteAccount.tsx:230 msgid "Cancel account deletion" -msgstr "撤销账户删除申请" +msgstr "取消账户删除申请" #: src/view/com/modals/ChangeHandle.tsx:149 msgid "Cancel change handle" -msgstr "撤销修改用户识别符" +msgstr "取消修改用户识别符" #: src/view/com/modals/crop-image/CropImage.web.tsx:134 msgid "Cancel image crop" -msgstr "撤销图片裁剪" +msgstr "取消裁剪图片" #: src/view/com/modals/EditProfile.tsx:244 msgid "Cancel profile editing" -msgstr "撤销个人资料编辑" +msgstr "取消编辑个人资料" #: src/view/com/modals/Repost.tsx:78 msgid "Cancel quote post" -msgstr "撤销引用帖子" +msgstr "取消引用帖子" #: src/view/com/modals/ListAddRemoveUsers.tsx:87 #: src/view/shell/desktop/Search.tsx:234 msgid "Cancel search" -msgstr "撤销搜索" +msgstr "取消搜索" #: src/view/com/modals/Waitlist.tsx:136 -#~ msgid "Cancel waitlist signup" -#~ msgstr "撤销候补列表申请" +msgid "Cancel waitlist signup" +msgstr "取消候补列表申请" #: src/view/screens/Settings/index.tsx:334 msgctxt "action" @@ -630,7 +630,7 @@ msgstr "检查我的状态" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:121 msgid "Check out some recommended feeds. Tap + to add them to your list of pinned feeds." -msgstr "查看一些推荐的信息流。点击 + 去将他们添加到你的固定信息流列表中。" +msgstr "查看一些推荐的信息流。点击 + 去将他们新增到你的固定信息流列表中。" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:185 msgid "Check out some recommended users. Follow them to see similar users." @@ -663,7 +663,7 @@ msgstr "选择可改进你自定义信息流的算法。" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 msgid "Choose your main feeds" -msgstr "选择你的首选信息流" +msgstr "选择你的主要信息流" #: src/view/com/auth/create/Step1.tsx:196 msgid "Choose your password" @@ -724,7 +724,7 @@ msgstr "关闭警告" #: src/view/com/util/BottomSheetCustomBackdrop.tsx:33 msgid "Close bottom drawer" -msgstr "关闭底栏抽屉" +msgstr "关闭底部抽屉" #: src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx:26 msgid "Close image" @@ -740,11 +740,11 @@ msgstr "关闭导航页脚" #: src/components/TagMenu/index.tsx:262 msgid "Close this dialog" -msgstr "" +msgstr "关闭该窗口" #: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" -msgstr "关闭底栏" +msgstr "关闭底部导航栏" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:39 msgid "Closes password update alert" @@ -781,7 +781,7 @@ msgstr "完成引导并开始使用你的账户" #: src/view/com/auth/create/Step3.tsx:73 msgid "Complete the challenge" -msgstr "" +msgstr "完成验证" #: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" @@ -896,7 +896,7 @@ msgstr "继续下一步" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:191 msgid "Continue to the next step without following any accounts" -msgstr "不关注任何账户,继续下一步" +msgstr "继续下一步,不关注任何账户" #: src/screens/Onboarding/index.tsx:44 msgid "Cooking" @@ -919,7 +919,7 @@ msgstr "已复制至剪贴板" #: src/view/com/modals/AddAppPasswords.tsx:189 msgid "Copies app password" -msgstr "已复制 App 专用密码" +msgstr "已复制应用专用密码" #: src/view/com/modals/AddAppPasswords.tsx:188 msgid "Copy" @@ -976,7 +976,7 @@ msgstr "创建账户" #: src/view/com/modals/AddAppPasswords.tsx:226 msgid "Create App Password" -msgstr "创建 App 专用密码" +msgstr "创建应用专用密码" #: src/view/com/auth/HomeLoggedOutCTA.tsx:54 #: src/view/com/auth/SplashScreen.tsx:68 @@ -1006,7 +1006,7 @@ msgstr "文化" #: src/view/com/auth/server-input/index.tsx:95 #: src/view/com/auth/server-input/index.tsx:96 msgid "Custom" -msgstr "" +msgstr "自定义" #: src/view/com/modals/ChangeHandle.tsx:389 msgid "Custom domain" @@ -1015,7 +1015,7 @@ msgstr "自定义域名" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 #: src/view/screens/Feeds.tsx:692 msgid "Custom feeds built by the community bring you new experiences and help you find the content you love." -msgstr "由社区构建的自定义信息流能为你带来新的体验,并帮助你找到你喜欢的内容。" +msgstr "由社群构建的自定义信息流能为你带来新的体验,并帮助你找到你喜欢的内容。" #: src/view/screens/PreferencesExternalEmbeds.tsx:55 msgid "Customize media from external sites." @@ -1053,7 +1053,7 @@ msgstr "删除账号" #: src/view/screens/AppPasswords.tsx:222 #: src/view/screens/AppPasswords.tsx:242 msgid "Delete app password" -msgstr "删除 App 专用密码" +msgstr "删除应用专用密码" #: src/view/screens/ProfileList.tsx:364 #: src/view/screens/ProfileList.tsx:445 @@ -1131,7 +1131,7 @@ msgstr "探索新的自定义信息流" #: src/view/screens/Feeds.tsx:689 msgid "Discover New Feeds" -msgstr "" +msgstr "探索新的信息流" #: src/view/com/modals/EditProfile.tsx:192 msgid "Display name" @@ -1188,44 +1188,44 @@ msgstr "双击以登录" #: src/view/screens/Settings/index.tsx:755 msgid "Download Bluesky account data (repository)" -msgstr "" +msgstr "下载你的 Bluesky 账户数据(数据库)" #: src/view/screens/Settings/ExportCarDialog.tsx:59 #: src/view/screens/Settings/ExportCarDialog.tsx:63 msgid "Download CAR file" -msgstr "" +msgstr "下载 CAR 文件" #: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" -msgstr "拖放即可添加图片" +msgstr "拖放即可新增图片" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:111 msgid "Due to Apple policies, adult content can only be enabled on the web after completing sign up." -msgstr "受 Apple 政策限制,成人内容只能在完成注册后在网页端启用显示。" +msgstr "受 Apple 政策限制,显示成人内容只能在完成注册后在网页端设置中启用。" #: src/view/com/modals/EditProfile.tsx:185 msgid "e.g. Alice Roberts" -msgstr "例:张蓝天" +msgstr "例如:张蓝天" #: src/view/com/modals/EditProfile.tsx:203 msgid "e.g. Artist, dog-lover, and avid reader." -msgstr "例:普通艺术家一枚,喜欢撸猫。" +msgstr "例如:艺术家、爱狗人士和狂热读者。" #: src/view/com/modals/CreateOrEditList.tsx:283 msgid "e.g. Great Posters" -msgstr "例:发布重要帖子的用户" +msgstr "例如:优秀的发帖者" #: src/view/com/modals/CreateOrEditList.tsx:284 msgid "e.g. Spammers" -msgstr "例:垃圾内容制造者" +msgstr "例如:垃圾内容制造者" #: src/view/com/modals/CreateOrEditList.tsx:312 msgid "e.g. The posters who never miss." -msgstr "例:你绝不能错过其发布帖子的用户。" +msgstr "例如:绝不容错过的发帖者。" #: src/view/com/modals/CreateOrEditList.tsx:313 msgid "e.g. Users that repeatedly reply with ads." -msgstr "例:散布广告内容的用户。" +msgstr "例如:散布广告内容的用户。" #: src/view/com/modals/InviteCodes.tsx:96 msgid "Each code works once. You'll receive more invite codes periodically." @@ -1261,11 +1261,11 @@ msgstr "编辑个人资料" #: src/view/com/profile/ProfileHeader.tsx:418 msgid "Edit profile" -msgstr "编辑资料" +msgstr "编辑个人资料" #: src/view/com/profile/ProfileHeader.tsx:423 msgid "Edit Profile" -msgstr "编辑资料" +msgstr "编辑个人资料" #: src/view/com/home/HomeHeaderLayout.web.tsx:62 #: src/view/screens/Feeds.tsx:355 @@ -1343,16 +1343,16 @@ msgstr "启用此设置以仅查看你关注的人之间的回复。" #: src/view/screens/Profile.tsx:455 msgid "End of feed" -msgstr "结束信息流" +msgstr "信息流的末尾" #: src/view/com/modals/AddAppPasswords.tsx:166 msgid "Enter a name for this App Password" -msgstr "为此 App 专用密码命名" +msgstr "为此应用专用密码命名" #: src/components/dialogs/MutedWords.tsx:100 #: src/components/dialogs/MutedWords.tsx:101 msgid "Enter a word or tag" -msgstr "" +msgstr "输入一个词或标签" #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" @@ -1368,7 +1368,7 @@ msgstr "输入你想使用的域名" #: src/view/com/auth/login/ForgotPasswordForm.tsx:107 msgid "Enter the email you used to create your account. We'll send you a \"reset code\" so you can set a new password." -msgstr "输入你用于创建账户的电子邮箱。我们将向你发送重置码,以便你重新设置密码。" +msgstr "输入你用于创建账户的电子邮箱。我们将向你发送用于密码重设的确认码。" #: src/view/com/auth/create/Step1.tsx:228 #: src/view/com/modals/BirthDateSettings.tsx:74 @@ -1401,7 +1401,7 @@ msgstr "输入你的用户名和密码" #: src/view/com/auth/create/Step3.tsx:67 msgid "Error receiving captcha response." -msgstr "" +msgstr "Captcha 响应错误" #: src/view/screens/Search/Search.tsx:110 msgid "Error:" @@ -1422,7 +1422,7 @@ msgstr "退出图片查看器" #: src/view/com/modals/ListAddRemoveUsers.tsx:88 #: src/view/shell/desktop/Search.tsx:235 msgid "Exits inputting search query" -msgstr "退出搜索查询" +msgstr "退出搜索查询输入" #: src/view/com/modals/Waitlist.tsx:138 #~ msgid "Exits signing up for waitlist with {email}" @@ -1439,12 +1439,12 @@ msgstr "展开或折叠你要回复的完整帖子" #: src/view/screens/Settings/index.tsx:753 msgid "Export my data" -msgstr "" +msgstr "导出账号数据" #: src/view/screens/Settings/ExportCarDialog.tsx:44 #: src/view/screens/Settings/index.tsx:764 msgid "Export My Data" -msgstr "" +msgstr "导出账号数据" #: src/view/com/modals/EmbedConsent.tsx:64 msgid "External Media" @@ -1468,7 +1468,7 @@ msgstr "外部媒体设置" #: src/view/com/modals/AddAppPasswords.tsx:115 #: src/view/com/modals/AddAppPasswords.tsx:119 msgid "Failed to create app password." -msgstr "创建 App 专用密码失败。" +msgstr "创建应用专用密码失败。" #: src/view/com/modals/CreateOrEditList.tsx:206 msgid "Failed to create the list. Check your internet connection and try again." @@ -1489,7 +1489,7 @@ msgstr "信息流" #: src/view/com/feeds/FeedSourceCard.tsx:231 msgid "Feed by {0}" -msgstr "信息流由 {0} 创建" +msgstr "由 {0} 创建的信息流" #: src/view/screens/Feeds.tsx:605 msgid "Feed offline" @@ -1529,7 +1529,7 @@ msgstr "创建信息流要求一些编程基础。查看 <0/> 以获取详情。 #: src/screens/Onboarding/StepTopicalFeeds.tsx:76 msgid "Feeds can be topical as well!" -msgstr "信息流也可以是话题性的!" +msgstr "信息流也可以围绕某些话题!" #: src/screens/Onboarding/StepFinished.tsx:151 msgid "Finalizing" @@ -1547,23 +1547,23 @@ msgstr "寻找一些正在使用 Bluesky 的用户" #: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" -msgstr "使用右侧的工具来搜索用户" +msgstr "使用右侧的搜索工具来查找用户" #: src/view/com/auth/onboarding/RecommendedFollowsItem.tsx:150 msgid "Finding similar accounts..." -msgstr "寻找类似的账户..." +msgstr "正在寻找类似的账户..." #: src/view/screens/PreferencesFollowingFeed.tsx:111 msgid "Fine-tune the content you see on your Following feed." -msgstr "" +msgstr "调整你在关注信息流上所看到的内容。" #: src/view/screens/PreferencesHomeFeed.tsx:111 #~ msgid "Fine-tune the content you see on your home screen." -#~ msgstr "微调你在主页上所看到的内容。" +#~ msgstr "调整你在主页上所看到的内容。" #: src/view/screens/PreferencesThreads.tsx:60 msgid "Fine-tune the discussion threads." -msgstr "微调讨论主题。" +msgstr "调整讨论主题。" #: src/screens/Onboarding/index.tsx:38 msgid "Fitness" @@ -1625,7 +1625,7 @@ msgstr "仅限已关注的用户" #: src/view/com/notifications/FeedItem.tsx:166 msgid "followed you" -msgstr "已关注" +msgstr "关注了你" #: src/view/screens/ProfileFollowers.tsx:25 msgid "Followers" @@ -1647,15 +1647,15 @@ msgstr "正在关注 {0}" #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 msgid "Following Feed Preferences" -msgstr "" +msgstr "关注信息流首选项" #: src/view/com/profile/ProfileHeader.tsx:546 msgid "Follows you" -msgstr "已关注" +msgstr "关注了你" #: src/view/com/profile/ProfileCard.tsx:141 msgid "Follows You" -msgstr "已关注" +msgstr "关注了你" #: src/screens/Onboarding/index.tsx:43 msgid "Food" @@ -1685,7 +1685,7 @@ msgstr "忘记密码" #: src/screens/Hashtag.tsx:108 #: src/screens/Hashtag.tsx:148 msgid "From @{sanitizedAuthor}" -msgstr "" +msgstr "来自 @{sanitizedAuthor}" #: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" @@ -1723,7 +1723,7 @@ msgstr "返回上一步" #: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" -msgstr "转到 @{queryMaybeHandle}" +msgstr "前往 @{queryMaybeHandle}" #: src/view/com/auth/login/ForgotPasswordForm.tsx:189 #: src/view/com/auth/login/ForgotPasswordForm.tsx:218 @@ -1731,7 +1731,7 @@ msgstr "转到 @{queryMaybeHandle}" #: src/view/com/auth/login/SetNewPasswordForm.tsx:195 #: src/view/com/modals/ChangePassword.tsx:165 msgid "Go to next" -msgstr "转到下一个" +msgstr "前往下一步" #: src/view/com/modals/ChangeHandle.tsx:265 msgid "Handle" @@ -1739,15 +1739,15 @@ msgstr "用户识别符" #: src/Navigation.tsx:270 msgid "Hashtag" -msgstr "" +msgstr "话题标签" #: src/components/RichText.tsx:188 #~ msgid "Hashtag: {tag}" -#~ msgstr "" +#~ msgstr "话题标签:{tag}" #: src/components/RichText.tsx:190 msgid "Hashtag: #{tag}" -msgstr "" +msgstr "话题标签:#{tag}" #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" @@ -1760,19 +1760,19 @@ msgstr "帮助" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:132 msgid "Here are some accounts for you to follow" -msgstr "这里是一些推荐关注的用户" +msgstr "这里有一些推荐关注的用户" #: src/screens/Onboarding/StepTopicalFeeds.tsx:85 msgid "Here are some popular topical feeds. You can choose to follow as many as you like." -msgstr "这里是一些流行的信息流供你挑选。" +msgstr "这里有一些流行的信息流供你挑选。" #: src/screens/Onboarding/StepTopicalFeeds.tsx:80 msgid "Here are some topical feeds based on your interests: {interestsText}. You can choose to follow as many as you like." -msgstr "这里是一些基于你兴趣所推荐的信息流供你挑选:{interestsText}。" +msgstr "这里有一些基于你兴趣所推荐的信息流供你挑选:{interestsText}。关注的信息流数量没有限制。" #: src/view/com/modals/AddAppPasswords.tsx:153 msgid "Here is your app password." -msgstr "这里是你的 App 专用密码。" +msgstr "这里是你的应用专用密码。" #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:41 #: src/view/com/modals/ContentFilteringSettings.tsx:251 @@ -1875,7 +1875,7 @@ msgstr "若不勾选,则默认为全年龄向。" #: src/view/com/modals/ChangePassword.tsx:146 msgid "If you want to change your password, we will send you a code to verify that this is your account." -msgstr "如果你想要更改密码,我们将向你发送一个确认码以验证这是你的账户。" +msgstr "如果你想要更改密码,我们将向你发送一个验证码以验证这是你的账户。" #: src/view/com/util/images/Gallery.tsx:38 msgid "Image" @@ -1908,7 +1908,7 @@ msgstr "输入邀请码以继续" #: src/view/com/modals/AddAppPasswords.tsx:180 msgid "Input name for app password" -msgstr "输入 App 专用密码名称" +msgstr "输入应用专用密码名称" #: src/view/com/auth/login/SetNewPasswordForm.tsx:162 msgid "Input new password" @@ -1932,7 +1932,7 @@ msgstr "输入注册时使用的用户名或电子邮箱" #: src/view/com/auth/create/Step2.tsx:271 #~ msgid "Input the verification code we have texted to you" -#~ msgstr "输入收到的短信验证码" +#~ msgstr "输入我们发送到你手机的短信验证码" #: src/view/com/modals/Waitlist.tsx:90 #~ msgid "Input your email to get on the Bluesky waitlist" @@ -1973,7 +1973,7 @@ msgstr "邀请码无效,请检查你输入的邀请码并重试。" #: src/view/com/modals/InviteCodes.tsx:170 msgid "Invite codes: {0} available" -msgstr "邀请码:{0} 可用" +msgstr "邀请码:{0} 个可用" #: src/view/shell/Drawer.tsx:645 #~ msgid "Invite codes: {invitesAvailable} available" @@ -1981,7 +1981,7 @@ msgstr "邀请码:{0} 可用" #: src/view/com/modals/InviteCodes.tsx:169 msgid "Invite codes: 1 available" -msgstr "邀请码:1 可用" +msgstr "邀请码:1 个可用" #: src/screens/Onboarding/StepFollowingFeed.tsx:64 msgid "It shows posts from the people you follow as they happen." @@ -2054,7 +2054,7 @@ msgstr "了解有关 Bluesky 公开内容的更多详情。" #: src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx:82 msgid "Leave them all unchecked to see any language." -msgstr "全部不选中以查看任何语言。" +msgstr "全部留空以查看所有语言的帖子。" #: src/view/com/modals/LinkWarning.tsx:51 msgid "Leaving Bluesky" @@ -2088,44 +2088,44 @@ msgstr "亮色" #: src/view/com/util/post-ctrls/PostCtrls.tsx:182 msgid "Like" -msgstr "点赞" +msgstr "喜欢" #: src/view/screens/ProfileFeed.tsx:591 msgid "Like this feed" -msgstr "点赞这个信息流" +msgstr "喜欢这个信息流" #: src/Navigation.tsx:199 msgid "Liked by" -msgstr "点赞" +msgstr "喜欢" #: src/view/screens/PostLikedBy.tsx:27 #: src/view/screens/ProfileFeedLikedBy.tsx:27 msgid "Liked By" -msgstr "点赞" +msgstr "喜欢" #: src/view/com/feeds/FeedSourceCard.tsx:279 msgid "Liked by {0} {1}" -msgstr "{0} {1} 点赞" +msgstr "{0} 个 {1} 喜欢" #: src/view/screens/ProfileFeed.tsx:606 msgid "Liked by {likeCount} {0}" -msgstr "{likeCount} {0} 点赞" +msgstr "{likeCount} 个 {0} 喜欢" #: src/view/com/notifications/FeedItem.tsx:170 msgid "liked your custom feed" -msgstr "点赞你的自定义信息流" +msgstr "赞了你的自定义信息流" #: src/view/com/notifications/FeedItem.tsx:155 msgid "liked your post" -msgstr "点赞你的帖子" +msgstr "赞了你的帖子" #: src/view/screens/Profile.tsx:183 msgid "Likes" -msgstr "点赞" +msgstr "喜欢" #: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" -msgstr "点赞这条帖子" +msgstr "这条帖子的喜欢数" #: src/Navigation.tsx:168 msgid "List" @@ -2157,11 +2157,11 @@ msgstr "列表名称" #: src/view/screens/ProfileList.tsx:343 msgid "List unblocked" -msgstr "取消屏蔽列表" +msgstr "解除对列表的屏蔽" #: src/view/screens/ProfileList.tsx:302 msgid "List unmuted" -msgstr "取消隐藏列表" +msgstr "解除对列表的隐藏" #: src/Navigation.tsx:112 #: src/view/screens/Profile.tsx:185 @@ -2216,19 +2216,19 @@ msgstr "登录未列出的账户" #: src/view/com/modals/LinkWarning.tsx:65 msgid "Make sure this is where you intend to go!" -msgstr "请确认!" +msgstr "请确认目标页面地址是否正确!" #: src/components/dialogs/MutedWords.tsx:83 msgid "Manage your muted words and tags" -msgstr "" +msgstr "管理你的隐藏词和话题标签" #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" -msgstr "" +msgstr "不能长于 253 个字符" #: src/view/com/auth/create/Step2.tsx:109 msgid "May only contain letters and numbers" -msgstr "" +msgstr "只能包含字母和数字" #: src/view/screens/Profile.tsx:182 msgid "Media" @@ -2263,17 +2263,17 @@ msgstr "限制" #: src/view/com/lists/ListCard.tsx:93 #: src/view/com/modals/UserAddRemoveLists.tsx:206 msgid "Moderation list by {0}" -msgstr "限制列表由 {0} 创建" +msgstr "由 {0} 创建的限制列表" #: src/view/screens/ProfileList.tsx:775 msgid "Moderation list by <0/>" -msgstr "限制列表由 </0> 创建" +msgstr "由 </0> 创建的限制列表" #: src/view/com/lists/ListCard.tsx:91 #: src/view/com/modals/UserAddRemoveLists.tsx:204 #: src/view/screens/ProfileList.tsx:773 msgid "Moderation list by you" -msgstr "限制列表由你创建" +msgstr "你创建的限制列表" #: src/view/com/modals/CreateOrEditList.tsx:197 msgid "Moderation list created" @@ -2316,19 +2316,19 @@ msgstr "更多选项" #: src/view/screens/PreferencesThreads.tsx:82 msgid "Most-liked replies first" -msgstr "最多点赞优先" +msgstr "优先显示最多喜欢" #: src/view/com/auth/create/Step2.tsx:122 msgid "Must be at least 3 characters" -msgstr "" +msgstr "需要至少 3 个字符" #: src/components/TagMenu/index.tsx:249 msgid "Mute" -msgstr "" +msgstr "隐藏" #: src/components/TagMenu/index.web.tsx:105 msgid "Mute {truncatedTag}" -msgstr "" +msgstr "隐藏 {truncatedTag}" #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" @@ -2340,19 +2340,19 @@ msgstr "隐藏账户" #: src/components/TagMenu/index.tsx:209 msgid "Mute all {displayTag} posts" -msgstr "" +msgstr "隐藏所有 {displayTag} 的帖子" #: src/components/TagMenu/index.tsx:211 #~ msgid "Mute all {tag} posts" -#~ msgstr "" +#~ msgstr "隐藏所有 {tag} 的帖子" #: src/components/dialogs/MutedWords.tsx:149 msgid "Mute in tags only" -msgstr "" +msgstr "仅隐藏话题标签" #: src/components/dialogs/MutedWords.tsx:134 msgid "Mute in text & tags" -msgstr "" +msgstr "隐藏文本和话题标签" #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" @@ -2368,11 +2368,11 @@ msgstr "隐藏这个列表" #: src/components/dialogs/MutedWords.tsx:127 msgid "Mute this word in post text and tags" -msgstr "" +msgstr "在帖子文本和话题标签中隐藏该词" #: src/components/dialogs/MutedWords.tsx:142 msgid "Mute this word in tags only" -msgstr "" +msgstr "仅在话题标签中隐藏该词" #: src/view/com/util/forms/PostDropdownBtn.tsx:251 #: src/view/com/util/forms/PostDropdownBtn.tsx:257 @@ -2382,7 +2382,7 @@ msgstr "隐藏讨论串" #: src/view/com/util/forms/PostDropdownBtn.tsx:267 #: src/view/com/util/forms/PostDropdownBtn.tsx:269 msgid "Mute words & tags" -msgstr "" +msgstr "隐藏词和话题标签" #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" @@ -2403,7 +2403,7 @@ msgstr "已隐藏的账户将不会在你的通知或时间线中显示,被隐 #: src/view/screens/Moderation.tsx:100 msgid "Muted words & tags" -msgstr "" +msgstr "已隐藏词和话题标签" #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." @@ -2419,7 +2419,7 @@ msgstr "自定义信息流" #: src/view/shell/desktop/LeftNav.tsx:65 msgid "My Profile" -msgstr "个人资料" +msgstr "我的个人资料" #: src/view/screens/Settings/index.tsx:582 msgid "My Saved Feeds" @@ -2427,7 +2427,7 @@ msgstr "我保存的信息流" #: src/view/com/auth/server-input/index.tsx:118 msgid "my-server.com" -msgstr "" +msgstr "my-server.com" #: src/view/com/modals/AddAppPasswords.tsx:179 #: src/view/com/modals/CreateOrEditList.tsx:290 @@ -2470,7 +2470,7 @@ msgstr "永远不会失去对你的关注者或数据的访问。" #: src/components/dialogs/MutedWords.tsx:293 msgid "Nevermind" -msgstr "" +msgstr "放弃" #: src/view/screens/Lists.tsx:76 msgctxt "action" @@ -2519,7 +2519,7 @@ msgstr "新的用户列表" #: src/view/screens/PreferencesThreads.tsx:79 msgid "Newest replies first" -msgstr "最新回复优先" +msgstr "优先显示最新回复" #: src/screens/Onboarding/index.tsx:23 msgid "News" @@ -2535,12 +2535,12 @@ msgstr "新闻" #: src/view/com/modals/ChangePassword.tsx:251 #: src/view/com/modals/ChangePassword.tsx:253 msgid "Next" -msgstr "下一个" +msgstr "下一步" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 msgctxt "action" msgid "Next" -msgstr "下一个" +msgstr "下一步" #: src/view/com/lightbox/Lightbox.web.tsx:149 msgid "Next image" @@ -2566,7 +2566,7 @@ msgstr "不再关注 {0}" #: src/view/com/notifications/Feed.tsx:109 msgid "No notifications yet!" -msgstr "没有通知!" +msgstr "还没有通知!" #: src/view/com/composer/text-input/mobile/Autocomplete.tsx:97 #: src/view/com/composer/text-input/web/Autocomplete.tsx:191 @@ -2575,7 +2575,7 @@ msgstr "没有结果" #: src/components/Lists.tsx:192 msgid "No results found" -msgstr "" +msgstr "未找到结果" #: src/view/screens/Feeds.tsx:495 msgid "No results found for \"{query}\"" @@ -2607,7 +2607,7 @@ msgstr "未找到" #: src/view/com/modals/VerifyEmail.tsx:246 #: src/view/com/modals/VerifyEmail.tsx:252 msgid "Not right now" -msgstr "不是现在" +msgstr "暂时不需要" #: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." @@ -2641,7 +2641,7 @@ msgstr "好的" #: src/view/screens/PreferencesThreads.tsx:78 msgid "Oldest replies first" -msgstr "最旧的回复优先" +msgstr "优先显示最旧的回复" #: src/view/screens/Settings/index.tsx:234 msgid "Onboarding reset" @@ -2657,7 +2657,7 @@ msgstr "只有 {0} 可以回复。" #: src/components/Lists.tsx:82 msgid "Oops, something went wrong!" -msgstr "" +msgstr "糟糕,发生了一些错误!" #: src/components/Lists.tsx:188 #: src/view/screens/AppPasswords.tsx:65 @@ -2667,16 +2667,16 @@ msgstr "Oops!" #: src/screens/Onboarding/StepFinished.tsx:115 msgid "Open" -msgstr "打开" +msgstr "开启" #: src/view/screens/Moderation.tsx:75 msgid "Open content filtering settings" -msgstr "" +msgstr "打开内容过滤设置" #: src/view/com/composer/Composer.tsx:477 #: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" -msgstr "打开 emoji 选择器" +msgstr "打开表情符号选择器" #: src/view/screens/Settings/index.tsx:712 msgid "Open links with in-app browser" @@ -2684,116 +2684,116 @@ msgstr "在内置浏览器中打开链接" #: src/view/screens/Moderation.tsx:92 msgid "Open muted words settings" -msgstr "" +msgstr "打开隐藏词设置" #: src/view/com/home/HomeHeaderLayoutMobile.tsx:50 msgid "Open navigation" -msgstr "打开导航" +msgstr "开启导航" #: src/view/com/util/forms/PostDropdownBtn.tsx:175 msgid "Open post options menu" -msgstr "" +msgstr "打开帖子选项菜单" #: src/view/screens/Settings/index.tsx:804 msgid "Open storybook page" -msgstr "打开故事书界面" +msgstr "开启 Storybook 界面" #: src/view/com/util/forms/DropdownButton.tsx:154 msgid "Opens {numItems} options" -msgstr "打开 {numItems} 个选项" +msgstr "开启 {numItems} 个选项" #: src/view/screens/Log.tsx:54 msgid "Opens additional details for a debug entry" -msgstr "打开调试记录的附加详细信息" +msgstr "开启调试记录的额外详细信息" #: src/view/com/notifications/FeedItem.tsx:349 msgid "Opens an expanded list of users in this notification" -msgstr "打开此通知中的扩展用户列表" +msgstr "展开此通知中的扩展用户列表" #: src/view/com/composer/photos/OpenCameraBtn.tsx:61 msgid "Opens camera on device" -msgstr "打开设备相机" +msgstr "开启设备相机" #: src/view/com/composer/Prompt.tsx:25 msgid "Opens composer" -msgstr "打开编辑器" +msgstr "开启编辑器" #: src/view/screens/Settings/index.tsx:595 msgid "Opens configurable language settings" -msgstr "打开可配置的语言设置" +msgstr "开启可配置的语言设置" #: src/view/com/composer/photos/SelectPhotoBtn.tsx:44 msgid "Opens device photo gallery" -msgstr "打开设备相册" +msgstr "开启设备相册" #: src/view/com/profile/ProfileHeader.tsx:420 msgid "Opens editor for profile display name, avatar, background image, and description" -msgstr "打开个人资料(如名称、头像、背景图片、描述等)编辑器" +msgstr "开启个人资料(如名称、头像、背景图片、描述等)编辑器" #: src/view/screens/Settings/index.tsx:649 msgid "Opens external embeds settings" -msgstr "打开外部嵌入设置" +msgstr "开启外部嵌入设置" #: src/view/com/profile/ProfileHeader.tsx:575 msgid "Opens followers list" -msgstr "打开关注者列表" +msgstr "开启关注者列表" #: src/view/com/profile/ProfileHeader.tsx:594 msgid "Opens following list" -msgstr "打开正在关注列表" +msgstr "开启正在关注列表" #: src/view/screens/Settings.tsx:412 #~ msgid "Opens invite code list" -#~ msgstr "打开邀请码列表" +#~ msgstr "开启邀请码列表" #: src/view/com/modals/InviteCodes.tsx:172 msgid "Opens list of invite codes" -msgstr "打开邀请码列表" +msgstr "开启邀请码列表" #: src/view/screens/Settings/index.tsx:774 msgid "Opens modal for account deletion confirmation. Requires email code." -msgstr "打开用户删除确认界面,需要电子邮箱接收验证码。" +msgstr "开启用户删除确认界面,需要电子邮箱接收验证码。" #: src/view/com/modals/ChangeHandle.tsx:281 msgid "Opens modal for using custom domain" -msgstr "打开使用自定义域名的模式" +msgstr "开启使用自定义域名的模式" #: src/view/screens/Settings/index.tsx:620 msgid "Opens moderation settings" -msgstr "打开限制设置" +msgstr "开启限制设置" #: src/view/com/auth/login/LoginForm.tsx:239 msgid "Opens password reset form" -msgstr "打开密码重置申请" +msgstr "开启密码重置申请" #: src/view/com/home/HomeHeaderLayout.web.tsx:63 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" -msgstr "打开用于编辑已保存信息流的界面" +msgstr "开启用于编辑已保存信息流的界面" #: src/view/screens/Settings/index.tsx:576 msgid "Opens screen with all saved feeds" -msgstr "打开包含所有已保存信息流的界面" +msgstr "开启包含所有已保存信息流的界面" #: src/view/screens/Settings/index.tsx:676 msgid "Opens the app password settings page" -msgstr "打开 App 专用密码设置页" +msgstr "开启应用专用密码设置页" #: src/view/screens/Settings/index.tsx:535 msgid "Opens the home feed preferences" -msgstr "打开主页信息流首选项" +msgstr "开启主页信息流首选项" #: src/view/screens/Settings/index.tsx:805 msgid "Opens the storybook page" -msgstr "打开故事书界面" +msgstr "开启 Storybook 界面" #: src/view/screens/Settings/index.tsx:793 msgid "Opens the system log page" -msgstr "打开系统日志界面" +msgstr "开启系统日志界面" #: src/view/screens/Settings/index.tsx:556 msgid "Opens the threads preferences" -msgstr "打开讨论串首选项" +msgstr "开启讨论串首选项" #: src/view/com/util/forms/DropdownButton.tsx:280 msgid "Option {0} of {numItems}" @@ -2842,11 +2842,11 @@ msgstr "密码已更新!" #: src/Navigation.tsx:162 msgid "People followed by @{0}" -msgstr "被这些人所关注 @{0}" +msgstr "@{0} 关注的人" #: src/Navigation.tsx:155 msgid "People following @{0}" -msgstr "正在关注 @{0}" +msgstr "关注 @{0} 的人" #: src/view/com/lightbox/Lightbox.tsx:66 msgid "Permission to access camera roll is required." @@ -2900,15 +2900,15 @@ msgstr "请设置你的密码。" #: src/view/com/auth/create/state.ts:131 msgid "Please complete the verification captcha." -msgstr "" +msgstr "请完成 Captcha 验证" #: src/view/com/modals/ChangeEmail.tsx:67 msgid "Please confirm your email before changing it. This is a temporary requirement while email-updating tools are added, and it will soon be removed." -msgstr "更改前请先确认你的电子邮箱。这是添加电子邮箱更新工具的临时要求,此限制将很快被移除。" +msgstr "更改前请先确认你的电子邮箱。这是新增电子邮箱更新工具的临时要求,此限制将很快被移除。" #: src/view/com/modals/AddAppPasswords.tsx:90 msgid "Please enter a name for your app password. All spaces is not allowed." -msgstr "请输入 App 专用密码的名称,不允许使用空格。" +msgstr "请输入应用专用密码的名称,不允许使用空格。" #: src/view/com/auth/create/Step2.tsx:206 #~ msgid "Please enter a phone number that can receive SMS text messages." @@ -2916,11 +2916,11 @@ msgstr "请输入 App 专用密码的名称,不允许使用空格。" #: src/view/com/modals/AddAppPasswords.tsx:145 msgid "Please enter a unique name for this App Password or use our randomly generated one." -msgstr "请输入此 App 专用密码的唯一名称,或使用我们提供的随机生成名称。" +msgstr "请输入此应用专用密码的唯一名称,或使用我们提供的随机生成名称。" #: src/components/dialogs/MutedWords.tsx:68 msgid "Please enter a valid word, tag, or phrase to mute" -msgstr "" +msgstr "请输入一个有效的词、话题标签或短语" #: src/view/com/auth/create/state.ts:170 #~ msgid "Please enter the code you received by SMS." @@ -2949,7 +2949,7 @@ msgstr "请验证你的电子邮箱" #: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" -msgstr "请等待你的链接卡片加载完成" +msgstr "请等待你的链接卡片加载完毕" #: src/screens/Onboarding/index.tsx:37 msgid "Politics" @@ -2972,13 +2972,13 @@ msgstr "发布" #: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" -msgstr "发布者 {0}" +msgstr "{0} 的帖子" #: src/Navigation.tsx:174 #: src/Navigation.tsx:181 #: src/Navigation.tsx:188 msgid "Post by @{0}" -msgstr "发布者 @{0}" +msgstr "@{0} 的帖子" #: src/view/com/util/forms/PostDropdownBtn.tsx:108 msgid "Post deleted" @@ -3002,7 +3002,7 @@ msgstr "无法找到帖子" #: src/components/TagMenu/index.tsx:253 msgid "posts" -msgstr "" +msgstr "帖子" #: src/view/screens/Profile.tsx:180 msgid "Posts" @@ -3010,11 +3010,11 @@ msgstr "帖子" #: src/components/dialogs/MutedWords.tsx:90 msgid "Posts can be muted based on their text, their tags, or both." -msgstr "" +msgstr "帖子可以根据其文本、话题标签或两者来隐藏。" #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" -msgstr "已隐藏帖子" +msgstr "帖子已隐藏" #: src/view/com/modals/LinkWarning.tsx:46 msgid "Potentially Misleading Link" @@ -3030,7 +3030,7 @@ msgstr "首选语言" #: src/view/screens/PreferencesThreads.tsx:97 msgid "Prioritize Your Follows" -msgstr "关注者优先" +msgstr "优先显示关注者" #: src/view/screens/Settings/index.tsx:632 #: src/view/shell/desktop/RightNav.tsx:72 @@ -3054,11 +3054,11 @@ msgstr "处理中..." #: src/view/shell/Drawer.tsx:546 #: src/view/shell/Drawer.tsx:547 msgid "Profile" -msgstr "资料" +msgstr "个人资料" #: src/view/com/modals/EditProfile.tsx:128 msgid "Profile updated" -msgstr "资料已更新" +msgstr "个人资料已更新" #: src/view/screens/Settings/index.tsx:949 msgid "Protect your account by verifying your email." @@ -3100,7 +3100,7 @@ msgstr "引用帖子" #: src/view/screens/PreferencesThreads.tsx:86 msgid "Random (aka \"Poster's Roulette\")" -msgstr "以随机顺序显示 (又名试试手气)" +msgstr "随机显示 (手气不错)" #: src/view/com/modals/EditImage.tsx:236 msgid "Ratios" @@ -3121,7 +3121,7 @@ msgstr "推荐的用户" #: src/view/com/util/UserAvatar.tsx:285 #: src/view/com/util/UserBanner.tsx:91 msgid "Remove" -msgstr "删除" +msgstr "移除" #: src/view/com/feeds/FeedSourceCard.tsx:108 msgid "Remove {0} from my feeds?" @@ -3154,7 +3154,7 @@ msgstr "删除图片预览" #: src/components/dialogs/MutedWords.tsx:343 msgid "Remove mute word from your list" -msgstr "" +msgstr "从你的隐藏词列表中删除" #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" @@ -3280,20 +3280,20 @@ msgstr "确认码" #: src/view/screens/Settings/index.tsx:456 msgid "Require alt text before posting" -msgstr "要求发布前提供替代文本" +msgstr "发布时检查媒体是否存在替代文本" #: src/view/com/auth/create/Step1.tsx:146 msgid "Required for this provider" -msgstr "应提供商要求" +msgstr "服务提供者要求" #: src/view/com/auth/login/SetNewPasswordForm.tsx:124 #: src/view/com/auth/login/SetNewPasswordForm.tsx:136 msgid "Reset code" -msgstr "重置码" +msgstr "确认码" #: src/view/com/modals/ChangePassword.tsx:190 msgid "Reset Code" -msgstr "重置代码" +msgstr "确认码" #: src/view/screens/Settings/index.tsx:824 msgid "Reset onboarding" @@ -3380,7 +3380,7 @@ msgstr "保存更改" #: src/view/com/modals/ChangeHandle.tsx:170 msgid "Save handle change" -msgstr "保存新的用户识别符" +msgstr "保存用户识别符更改" #: src/view/com/modals/crop-image/CropImage.web.tsx:144 msgid "Save image crop" @@ -3430,19 +3430,19 @@ msgstr "搜索 \"{query}\"" #: src/components/TagMenu/index.tsx:145 msgid "Search for all posts by @{authorHandle} with tag {displayTag}" -msgstr "" +msgstr "搜索 @{authorHandle} 带有 {displayTag} 的所有帖子" #: src/components/TagMenu/index.tsx:145 #~ msgid "Search for all posts by @{authorHandle} with tag {tag}" -#~ msgstr "" +#~ msgstr "搜索 @{authorHandle} 带有 {tag} 的所有帖子" #: src/components/TagMenu/index.tsx:94 msgid "Search for all posts with tag {displayTag}" -msgstr "" +msgstr "搜索所有带有 {displayTag} 的帖子" #: src/components/TagMenu/index.tsx:90 #~ msgid "Search for all posts with tag {tag}" -#~ msgstr "" +#~ msgstr "搜索所有带有 {tag} 的帖子" #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 @@ -3456,27 +3456,27 @@ msgstr "所需的安全步骤" #: src/components/TagMenu/index.web.tsx:66 msgid "See {truncatedTag} posts" -msgstr "" +msgstr "查看 {truncatedTag} 的帖子" #: src/components/TagMenu/index.web.tsx:83 msgid "See {truncatedTag} posts by user" -msgstr "" +msgstr "按用户查看 {truncatedTag} 的帖子" #: src/components/TagMenu/index.tsx:128 msgid "See <0>{displayTag}</0> posts" -msgstr "" +msgstr "查看 <0>{displayTag}</0> 的帖子" #: src/components/TagMenu/index.tsx:187 msgid "See <0>{displayTag}</0> posts by this user" -msgstr "" +msgstr "查看该用户 <0>{displayTag}</0> 的帖子" #: src/components/TagMenu/index.tsx:128 #~ msgid "See <0>{tag}</0> posts" -#~ msgstr "" +#~ msgstr "查看 <0>{tag}</0> 的帖子" #: src/components/TagMenu/index.tsx:189 #~ msgid "See <0>{tag}</0> posts by this user" -#~ msgstr "" +#~ msgstr "查看该用户 <0>{tag}</0> 的帖子" #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" @@ -3496,11 +3496,11 @@ msgstr "选择 {item}" #: src/view/com/auth/login/Login.tsx:117 msgid "Select from an existing account" -msgstr "选择已存在的账户" +msgstr "从现有账户中选择" #: src/view/com/util/Selector.tsx:107 msgid "Select option {i} of {numItems}" -msgstr "从 {i} 项中选择 {numItems} 项" +msgstr "选择 {numItems} 项中的第 {i} 项" #: src/view/com/auth/create/Step1.tsx:96 #: src/view/com/auth/login/LoginForm.tsx:150 @@ -3513,7 +3513,7 @@ msgstr "选择以下一些账户进行关注" #: src/view/com/auth/server-input/index.tsx:82 msgid "Select the service that hosts your data." -msgstr "" +msgstr "选择托管你数据的服务器。" #: src/screens/Onboarding/StepTopicalFeeds.tsx:96 msgid "Select topical feeds to follow from the list below" @@ -3576,11 +3576,11 @@ msgstr "提交举报" #: src/view/com/modals/DeleteAccount.tsx:133 msgid "Sends email with confirmation code for account deletion" -msgstr "发送包含账户删除确认码的电子邮件" +msgstr "发送包含账户删除验证码的电子邮件" #: src/view/com/auth/server-input/index.tsx:110 msgid "Server address" -msgstr "" +msgstr "服务器地址" #: src/view/com/modals/ContentFilteringSettings.tsx:311 msgid "Set {value} for {labelGroup} content moderation policy" @@ -3642,7 +3642,7 @@ msgstr "启用此设置项以在分层视图中显示回复。这是一个实验 #: src/view/screens/PreferencesFollowingFeed.tsx:261 msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your Following feed. This is an experimental feature." -msgstr "" +msgstr "启用此设置项以在关注信息流中显示已保存信息流的样例。这是一个实验性功能。" #: src/screens/Onboarding/Layout.tsx:50 msgid "Set up your account" @@ -3762,7 +3762,7 @@ msgstr "在关注信息流中显示回复" #: src/view/screens/PreferencesFollowingFeed.tsx:70 msgid "Show replies with at least {value} {0}" -msgstr "显示至少包含 {value} {0} 的回复" +msgstr "显示至少包含 {value} 个 {0} 的回复" #: src/view/screens/PreferencesFollowingFeed.tsx:188 msgid "Show Reposts" @@ -3886,7 +3886,7 @@ msgstr "程序开发" #: src/components/Lists.tsx:203 msgid "Something went wrong!" -msgstr "" +msgstr "出了点问题!" #: src/view/com/modals/Waitlist.tsx:51 #~ msgid "Something went wrong. Check your email and try again." @@ -3894,7 +3894,7 @@ msgstr "" #: src/App.native.tsx:66 msgid "Sorry! Your session expired. Please log in again." -msgstr "很抱歉,你的会话已过期,请重新登录。" +msgstr "很抱歉,你的登录会话已过期,请重新登录。" #: src/view/screens/PreferencesThreads.tsx:69 msgid "Sort Replies" @@ -3926,12 +3926,12 @@ msgstr "第 {0} 步,共 {numSteps} 步" #: src/view/screens/Settings/index.tsx:274 msgid "Storage cleared, you need to restart the app now." -msgstr "已清除存储,请立即重启 App。" +msgstr "已清除存储,请立即重启应用。" #: src/Navigation.tsx:204 #: src/view/screens/Settings/index.tsx:807 msgid "Storybook" -msgstr "故事书" +msgstr "Storybook" #: src/view/com/modals/AppealLabel.tsx:101 msgid "Submit" @@ -3996,15 +3996,15 @@ msgstr "系统日志" #: src/components/dialogs/MutedWords.tsx:337 msgid "tag" -msgstr "" +msgstr "话题标签" #: src/components/TagMenu/index.tsx:78 msgid "Tag menu: {displayTag}" -msgstr "" +msgstr "话题标签菜单:{displayTag}" #: src/components/TagMenu/index.tsx:74 #~ msgid "Tag menu: {tag}" -#~ msgstr "" +#~ msgstr "话题标签菜单:{tag}" #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" @@ -4031,16 +4031,16 @@ msgstr "服务条款" #: src/components/dialogs/MutedWords.tsx:337 msgid "text" -msgstr "" +msgstr "文本" #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" -msgstr "文本输入字段" +msgstr "文本输入框" #: src/view/com/auth/create/CreateAccount.tsx:94 msgid "That handle is already taken." -msgstr "" +msgstr "该用户识别符已被占用" #: src/view/com/profile/ProfileHeader.tsx:263 msgid "The account will be able to interact with you after unblocking." @@ -4060,7 +4060,7 @@ msgstr "以下步骤将帮助定制你的 Bluesky 体验。" #: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." -msgstr "此帖子似乎已被删除。" +msgstr "此帖子可能已被删除。" #: src/view/screens/PrivacyPolicy.tsx:33 msgid "The Privacy Policy has been moved to <0/>" @@ -4068,7 +4068,7 @@ msgstr "隐私政策已迁移至 <0/>" #: src/view/screens/Support.tsx:36 msgid "The support form has been moved. If you need help, please <0/> or visit {HELP_DESK_URL} to get in touch with us." -msgstr "支持表单已移动位置。如果你需要帮助,请点击<0/>或访问{HELP_DESK_URL}与我们联系。" +msgstr "支持表单已被移除。如果你需要帮助,请点击<0/>或访问{HELP_DESK_URL}与我们联系。" #: src/view/screens/TermsOfService.tsx:33 msgid "The Terms of Service have been moved to" @@ -4130,7 +4130,7 @@ msgstr "与服务器同步首选项时出现问题" #: src/view/screens/AppPasswords.tsx:66 msgid "There was an issue with fetching your app passwords" -msgstr "获取 App 专用密码时出现问题" +msgstr "获取应用专用密码时出现问题" #: src/view/com/post-thread/PostThreadFollowBtn.tsx:93 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:105 @@ -4168,7 +4168,7 @@ msgstr "这里是一些受欢迎的账号,你可能会喜欢:" #: src/view/com/util/moderation/ScreenHider.tsx:88 msgid "This {screenDescription} has been flagged:" -msgstr "这个 {screenDescription} 已被标记:" +msgstr "{screenDescription} 已被标记:" #: src/view/com/util/moderation/ScreenHider.tsx:83 msgid "This account has requested that users sign in to view their profile." @@ -4188,7 +4188,7 @@ msgstr "没有 Bluesky 账户,无法查看此内容。" #: src/view/screens/Settings/ExportCarDialog.tsx:75 msgid "This feature is in beta. You can read more about repository exports in <0>this blogpost.</0>" -msgstr "" +msgstr "该功能正在测试。你可以在<0>这篇博客文章</0>中获得关于导出数据的更多信息。" #: src/view/com/posts/FeedErrorMessage.tsx:114 msgid "This feed is currently receiving high traffic and is temporarily unavailable. Please try again later." @@ -4206,7 +4206,7 @@ msgstr "该信息流为空!你或许需要先关注更多的人或检查你的 #: src/view/com/modals/BirthDateSettings.tsx:61 msgid "This information is not shared with other users." -msgstr "此信息不与其他用户共享。" +msgstr "此信息不会分享给其他用户。" #: src/view/com/modals/VerifyEmail.tsx:119 msgid "This is important in case you ever need to change your email or reset your password." @@ -4226,7 +4226,7 @@ msgstr "该名称已被使用" #: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." -msgstr "此帖已被删除。" +msgstr "此帖子已被删除。" #: src/view/com/modals/ModerationDetails.tsx:62 msgid "This user has blocked you. You cannot view their content." @@ -4250,7 +4250,7 @@ msgstr "此警告仅适用于附带媒体的帖子。" #: src/components/dialogs/MutedWords.tsx:285 msgid "This will delete {0} from your muted words. You can always add it back later." -msgstr "" +msgstr "这将从你的隐藏词中删除 {0}。你随时可以重新添加。" #: src/view/com/util/forms/PostDropdownBtn.tsx:282 msgid "This will hide this post from your feeds." @@ -4263,7 +4263,7 @@ msgstr "讨论串首选项" #: src/view/screens/PreferencesThreads.tsx:119 msgid "Threaded Mode" -msgstr "分层模式" +msgstr "讨论串模式" #: src/Navigation.tsx:257 msgid "Threads Preferences" @@ -4271,11 +4271,11 @@ msgstr "讨论串首选项" #: src/components/dialogs/MutedWords.tsx:113 msgid "Toggle between muted word options." -msgstr "" +msgstr "在隐藏词选项之间切换。" #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" -msgstr "切换下拉菜单" +msgstr "切换下拉式菜单" #: src/view/com/modals/EditImage.tsx:271 msgid "Transformations" @@ -4329,16 +4329,16 @@ msgstr "取消屏蔽" #: src/view/com/util/post-ctrls/RepostButton.tsx:60 #: src/view/com/util/post-ctrls/RepostButton.web.tsx:48 msgid "Undo repost" -msgstr "撤销转发" +msgstr "取消转发" #: src/view/com/profile/FollowButton.tsx:55 msgctxt "action" msgid "Unfollow" -msgstr "取关" +msgstr "取消关注" #: src/view/com/profile/ProfileHeader.tsx:485 msgid "Unfollow {0}" -msgstr "取关 {0}" +msgstr "取消关注 {0}" #: src/view/com/auth/create/state.ts:262 msgid "Unfortunately, you do not meet the requirements to create an account." @@ -4355,7 +4355,7 @@ msgstr "取消隐藏" #: src/components/TagMenu/index.web.tsx:104 msgid "Unmute {truncatedTag}" -msgstr "" +msgstr "取消隐藏 {truncatedTag}" #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" @@ -4363,7 +4363,7 @@ msgstr "取消隐藏账户" #: src/components/TagMenu/index.tsx:208 msgid "Unmute all {displayTag} posts" -msgstr "" +msgstr "取消隐藏所有 {displayTag} 帖子" #: src/components/TagMenu/index.tsx:210 #~ msgid "Unmute all {tag} posts" @@ -4405,7 +4405,7 @@ msgstr "将文本文件上传至:" #: src/view/screens/AppPasswords.tsx:195 msgid "Use app passwords to login to other Bluesky clients without giving full access to your account or password." -msgstr "使用应用程序密码登录到其他 Bluesky 客户端,而无需对其授予你账户或密码的完全访问权限。" +msgstr "使用应用专用密码登录到其他 Bluesky 客户端,而无需对其授予你账户或密码的完全访问权限。" #: src/view/com/modals/ChangeHandle.tsx:515 msgid "Use default provider" @@ -4520,7 +4520,7 @@ msgstr "验证你的邮箱" #: src/screens/Onboarding/index.tsx:42 msgid "Video Games" -msgstr "视频游戏" +msgstr "电子游戏" #: src/view/com/profile/ProfileHeader.tsx:662 msgid "View {0}'s avatar" @@ -4536,7 +4536,7 @@ msgstr "查看整个讨论串" #: src/view/com/posts/FeedErrorMessage.tsx:172 msgid "View profile" -msgstr "查看资料" +msgstr "查看个人资料" #: src/view/com/profile/ProfileSubpageHeader.tsx:128 msgid "View the avatar" @@ -4557,7 +4557,7 @@ msgstr "我们认为还你会喜欢 Skygaze 所维护的 \"For You\":" #: src/screens/Hashtag.tsx:132 msgid "We couldn't find any results for that hashtag." -msgstr "" +msgstr "找不到任何与该话题标签相关的结果。" #: src/screens/Deactivated.tsx:133 msgid "We estimate {estimatedTime} until your account is ready." @@ -4573,7 +4573,7 @@ msgstr "我们已经看完了你关注的帖子。这是来自 <0/> 的最新消 #: src/components/dialogs/MutedWords.tsx:204 msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." -msgstr "" +msgstr "不建议您使用会出现在许多帖子中的常见词汇,这可能导致你的时间线上没有帖子可显示。" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" @@ -4605,7 +4605,7 @@ msgstr "很抱歉,我们无法解析此列表。如果问题持续发生,请 #: src/components/dialogs/MutedWords.tsx:230 msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." -msgstr "" +msgstr "很抱歉,我们无法加载你的隐藏词列表。请重试。" #: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." @@ -4713,7 +4713,7 @@ msgstr "你目前还没有任何保存的信息流。" #: src/view/com/post-thread/PostThread.tsx:465 msgid "You have blocked the author or you have been blocked by the author." -msgstr "你已屏蔽该作者,或你已被该作者屏蔽。" +msgstr "你已屏蔽该帖子作者,或你已被该作者屏蔽。" #: src/view/com/modals/ModerationDetails.tsx:56 msgid "You have blocked this user. You cannot view their content." @@ -4724,7 +4724,7 @@ msgstr "你已屏蔽了此用户,你将无法查看他们发布的内容。" #: src/view/com/modals/ChangePassword.tsx:87 #: src/view/com/modals/ChangePassword.tsx:121 msgid "You have entered an invalid code. It should look like XXXXX-XXXXX." -msgstr "你输入的邀请码无效。它应该长得像这样 XXXXX-XXXXX。" +msgstr "你输入的确认码无效。它应该长得像这样 XXXXX-XXXXX。" #: src/view/com/modals/ModerationDetails.tsx:87 msgid "You have muted this user." @@ -4745,7 +4745,7 @@ msgstr "你还没有屏蔽任何账号。要屏蔽账号,请转到其个人资 #: src/view/screens/AppPasswords.tsx:87 msgid "You have not created any app passwords yet. You can create one by pressing the button below." -msgstr "你尚未创建任何 App 专用密码,可以通过点击下面的按钮来创建一个。" +msgstr "你尚未创建任何应用专用密码,可以通过点击下面的按钮来创建一个。" #: src/view/screens/ModerationMutedAccounts.tsx:131 msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." @@ -4753,7 +4753,7 @@ msgstr "你还没有隐藏任何账号。要隐藏账号,请转到其个人资 #: src/components/dialogs/MutedWords.tsx:250 msgid "You haven't muted any words or tags yet" -msgstr "" +msgstr "你还没有隐藏任何词或话题标签" #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." @@ -4773,7 +4773,7 @@ msgstr "你将收到这条讨论串的通知" #: src/view/com/auth/login/SetNewPasswordForm.tsx:107 msgid "You will receive an email with a \"reset code.\" Enter that code here, then enter your new password." -msgstr "你将收到一封带有重置代码的电子邮件。请在此输入该重置代码,然后输入你的新密码。" +msgstr "你将收到一封带有确认码的电子邮件。请在此输入该确认码,然后输入你的新密码。" #: src/screens/Onboarding/StepModeration/index.tsx:72 msgid "You're in control" @@ -4803,7 +4803,7 @@ msgstr "你的账户已删除" #: src/view/screens/Settings/ExportCarDialog.tsx:47 msgid "Your account repository, containing all public data records, can be downloaded as a \"CAR\" file. This file does not include media embeds, such as images, or your private data, which must be fetched separately." -msgstr "" +msgstr "您的帐户数据库包含所有公共数据记录,它们将被导出为“CAR”文件。此文件不包括帖子中的媒体,例如图像或您的隐私数据,这些数据需要另外获取。" #: src/view/com/auth/create/Step1.tsx:215 msgid "Your birth date" @@ -4837,7 +4837,7 @@ msgstr "你的电子邮箱尚未验证。这是一个重要的安全步骤,我 #: src/view/com/posts/FollowingEmptyState.tsx:47 msgid "Your following feed is empty! Follow more users to see what's happening." -msgstr "你的关注信息流为空!关注更多用户去看看他们发了什么什么。" +msgstr "你的关注信息流为空!关注更多用户去看看他们发了什么。" #: src/view/com/auth/create/Step2.tsx:83 msgid "Your full handle will be" @@ -4851,25 +4851,25 @@ msgstr "你的完整用户识别符将修改为 <0>@{0}</0>" #: src/view/shell/desktop/RightNav.tsx:137 #: src/view/shell/Drawer.tsx:660 #~ msgid "Your invite codes are hidden when logged in using an App Password" -#~ msgstr "在使用 App 专用密码登录时,你的邀请码将被隐藏" +#~ msgstr "在使用应用专用密码登录时,你的邀请码将被隐藏" #: src/components/dialogs/MutedWords.tsx:221 msgid "Your muted words" -msgstr "" +msgstr "你的隐藏词" #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" -msgstr "你的密码已更改成功!" +msgstr "你的密码已成功更改!" #: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" -msgstr "你的帖子已发送" +msgstr "你的帖子已发布" #: src/screens/Onboarding/StepFinished.tsx:105 #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:59 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:59 msgid "Your posts, likes, and blocks are public. Mutes are private." -msgstr "你的帖子、点赞和屏蔽是公开可见的,而隐藏不可见。" +msgstr "你的帖子、喜欢和屏蔽是公开可见的,而隐藏不可见。" #: src/view/com/modals/SwitchAccount.tsx:84 #: src/view/screens/Settings/index.tsx:118 @@ -4878,7 +4878,7 @@ msgstr "你的个人资料" #: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" -msgstr "你的回复已发送" +msgstr "你的回复已发布" #: src/view/com/auth/create/Step2.tsx:65 msgid "Your user handle" From 5621c8042510c86f6c4fa63b5c5ce9fc02b0bf8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Be=C3=A0?= <bea.ivan@gmail.com> Date: Tue, 19 Mar 2024 20:44:22 +0100 Subject: [PATCH 100/109] Update catalan localization messages.po (#2904) * Update catalan localization messages.po Localization of new lines * Update messages.po * Update messages.po Corrections applied --- src/locale/locales/ca/messages.po | 248 +++++++++++++++--------------- 1 file changed, 124 insertions(+), 124 deletions(-) diff --git a/src/locale/locales/ca/messages.po b/src/locale/locales/ca/messages.po index b52bb7613a..0fd11dab60 100644 --- a/src/locale/locales/ca/messages.po +++ b/src/locale/locales/ca/messages.po @@ -244,12 +244,12 @@ msgstr "Avançat" #: src/view/screens/Feeds.tsx:666 msgid "All the feeds you've saved, right in one place." -msgstr "" +msgstr "Tots els canals que has desat, en un sol lloc." #: src/view/com/auth/login/ForgotPasswordForm.tsx:221 #: src/view/com/modals/ChangePassword.tsx:168 msgid "Already have a code?" -msgstr "" +msgstr "Ja tens un codi?" #: src/view/com/auth/login/ChooseAccountForm.tsx:98 msgid "Already signed in as @{0}" @@ -287,7 +287,7 @@ msgstr "i" #: src/screens/Onboarding/index.tsx:32 msgid "Animals" -msgstr "" +msgstr "Animals" #: src/view/screens/LanguageSettings.tsx:95 msgid "App Language" @@ -366,7 +366,7 @@ msgstr "Estàs escrivint en <0>{0}</0>?" #: src/screens/Onboarding/index.tsx:26 msgid "Art" -msgstr "" +msgstr "Art" #: src/view/com/modals/SelfLabel.tsx:123 msgid "Artistic or non-erotic nudity." @@ -393,7 +393,7 @@ msgstr "Endarrere" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:136 msgid "Based on your interest in {interestsText}" -msgstr "" +msgstr "Segons els teus interessos en {interestsText}" #: src/view/screens/Settings/index.tsx:523 msgid "Basics" @@ -472,7 +472,7 @@ msgstr "Bluesky" #: src/view/com/auth/server-input/index.tsx:150 msgid "Bluesky is an open network where you can choose your hosting provider. Custom hosting is now available in beta for developers." -msgstr "" +msgstr "Bluesky és una xarxa oberta on pots escollir el teu proveïdor d'allotjament. L'allotjament personalitzat està disponible en beta per a desenvolupadors" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:80 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:80 @@ -503,7 +503,7 @@ msgstr "Bluesky no mostrarà el teu perfil ni les publicacions als usuaris que n #: src/screens/Onboarding/index.tsx:33 msgid "Books" -msgstr "" +msgstr "Llibres" #: src/view/screens/Settings/index.tsx:859 msgid "Build version {0} {1}" @@ -631,11 +631,11 @@ msgstr "Canvia el meu correu" #: src/view/screens/Settings/index.tsx:732 msgid "Change password" -msgstr "" +msgstr "Canvia la contrasenya" #: src/view/screens/Settings/index.tsx:741 msgid "Change Password" -msgstr "" +msgstr "Canvia la contrasenya" #: src/view/com/composer/select-language/SuggestedLanguage.tsx:73 msgid "Change post language to {0}" @@ -643,7 +643,7 @@ msgstr "Canvia l'idioma de la publicació a {0}" #: src/view/screens/Settings/index.tsx:733 msgid "Change your Bluesky password" -msgstr "" +msgstr "Canvia la teva contrasenya de Bluesky" #: src/view/com/modals/ChangeEmail.tsx:109 msgid "Change Your Email" @@ -652,7 +652,7 @@ msgstr "Canvia el teu correu" #: src/screens/Deactivated.tsx:72 #: src/screens/Deactivated.tsx:76 msgid "Check my status" -msgstr "" +msgstr "Comprova el meu estat" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:121 msgid "Check out some recommended feeds. Tap + to add them to your list of pinned feeds." @@ -680,7 +680,7 @@ msgstr "Tria un servei" #: src/screens/Onboarding/StepFinished.tsx:135 msgid "Choose the algorithms that power your custom feeds." -msgstr "" +msgstr "Tria els algoritmes que alimentaran els teus canals personalitzats." #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:83 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:83 @@ -689,7 +689,7 @@ msgstr "Tria els algoritmes que potenciaran la teva experiència amb els canals #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 msgid "Choose your main feeds" -msgstr "" +msgstr "Tria els teus canals principals" #: src/view/com/auth/create/Step1.tsx:196 msgid "Choose your password" @@ -732,12 +732,12 @@ msgstr "" #: src/screens/Onboarding/index.tsx:35 msgid "Climate" -msgstr "" +msgstr "Clima" #: src/view/com/modals/ChangePassword.tsx:265 #: src/view/com/modals/ChangePassword.tsx:268 msgid "Close" -msgstr "" +msgstr "Tanca" #: src/components/Dialog/index.web.tsx:84 #: src/components/Dialog/index.web.tsx:198 @@ -790,11 +790,11 @@ msgstr "Plega la llista d'usuaris per una notificació concreta" #: src/screens/Onboarding/index.tsx:41 msgid "Comedy" -msgstr "" +msgstr "Comèdia" #: src/screens/Onboarding/index.tsx:27 msgid "Comics" -msgstr "" +msgstr "Còmics" #: src/Navigation.tsx:229 #: src/view/screens/CommunityGuidelines.tsx:32 @@ -803,7 +803,7 @@ msgstr "Directrius de la comunitat" #: src/screens/Onboarding/StepFinished.tsx:148 msgid "Complete onboarding and start using your account" -msgstr "" +msgstr "Finalitza el registre i comença a utilitzar el teu compte" #: src/view/com/auth/create/Step3.tsx:73 msgid "Complete the challenge" @@ -819,7 +819,7 @@ msgstr "Redacta una resposta" #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:67 msgid "Configure content filtering setting for category: {0}" -msgstr "" +msgstr "Configura els filtres de continguts per la categoria: {0}" #: src/components/Prompt.tsx:124 #: src/view/com/modals/AppealLabel.tsx:98 @@ -914,19 +914,19 @@ msgstr "Continua" #: src/screens/Onboarding/StepModeration/index.tsx:115 #: src/screens/Onboarding/StepTopicalFeeds.tsx:111 msgid "Continue to next step" -msgstr "" +msgstr "Continua" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:167 msgid "Continue to the next step" -msgstr "" +msgstr "Continua" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:191 msgid "Continue to the next step without following any accounts" -msgstr "" +msgstr "Continua sense seguir cap compte" #: src/screens/Onboarding/index.tsx:44 msgid "Cooking" -msgstr "" +msgstr "Cuina" #: src/view/com/modals/AddAppPasswords.tsx:195 #: src/view/com/modals/InviteCodes.tsx:182 @@ -1027,12 +1027,12 @@ msgstr "Crea una targeta amb una minuatura. La targeta enllaça a {url}" #: src/screens/Onboarding/index.tsx:29 msgid "Culture" -msgstr "" +msgstr "Cultura" #: src/view/com/auth/server-input/index.tsx:95 #: src/view/com/auth/server-input/index.tsx:96 msgid "Custom" -msgstr "" +msgstr "Personalitzat" #: src/view/com/modals/ChangeHandle.tsx:389 msgid "Custom domain" @@ -1041,7 +1041,7 @@ msgstr "Domini personalitzat" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 #: src/view/screens/Feeds.tsx:692 msgid "Custom feeds built by the community bring you new experiences and help you find the content you love." -msgstr "" +msgstr "Els canals personalitzats fets per la comunitat et porten noves experiències i t'ajuden a trobar contingut que t'agradarà." #: src/view/screens/PreferencesExternalEmbeds.tsx:55 msgid "Customize media from external sites." @@ -1062,7 +1062,7 @@ msgstr "Mode fosc" #: src/view/screens/Settings/index.tsx:498 msgid "Dark Theme" -msgstr "" +msgstr "Tema fosc" #: src/view/screens/Debug.tsx:83 msgid "Debug panel" @@ -1096,7 +1096,7 @@ msgstr "Elimina el meu compte" #: src/view/screens/Settings/index.tsx:784 msgid "Delete My Account…" -msgstr "" +msgstr "Elimina el meu compte…" #: src/view/com/util/forms/PostDropdownBtn.tsx:317 #: src/view/com/util/forms/PostDropdownBtn.tsx:326 @@ -1136,7 +1136,7 @@ msgstr "Vols dir alguna cosa?" #: src/view/screens/Settings/index.tsx:504 msgid "Dim" -msgstr "" +msgstr "Tènue" #: src/view/com/composer/Composer.tsx:151 msgid "Discard" @@ -1161,7 +1161,7 @@ msgstr "Descobreix nous canals personalitzats" #: src/view/screens/Feeds.tsx:689 msgid "Discover New Feeds" -msgstr "" +msgstr "Descobreix nous canals" #: src/view/com/modals/EditProfile.tsx:192 msgid "Display name" @@ -1218,20 +1218,20 @@ msgstr "Fes doble toc per iniciar la sessió" #: src/view/screens/Settings/index.tsx:755 msgid "Download Bluesky account data (repository)" -msgstr "" +msgstr "Descarrega les dades del compte de Bluesky (repositori)" #: src/view/screens/Settings/ExportCarDialog.tsx:59 #: src/view/screens/Settings/ExportCarDialog.tsx:63 msgid "Download CAR file" -msgstr "" +msgstr "Descarrega el fitxer CAR" #: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" -msgstr "" +msgstr "Deixa anar per afegir imatges" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:111 msgid "Due to Apple policies, adult content can only be enabled on the web after completing sign up." -msgstr "" +msgstr "Degut a les polítiques d'Apple, el contingut per a adults només es pot habilitar a la web després de registrar-se" #: src/view/com/modals/EditProfile.tsx:185 msgid "e.g. Alice Roberts" @@ -1316,7 +1316,7 @@ msgstr "Edita la descripció del teu perfil" #: src/screens/Onboarding/index.tsx:34 msgid "Education" -msgstr "" +msgstr "Ensenyament" #: src/view/com/auth/create/Step1.tsx:176 #: src/view/com/auth/login/ForgotPasswordForm.tsx:156 @@ -1357,7 +1357,7 @@ msgstr "Habilita el contingut per a adults" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:76 #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:77 msgid "Enable adult content in your feeds" -msgstr "" +msgstr "Habilita veure el contingut per adults als teus canals" #: src/view/com/modals/EmbedConsent.tsx:97 msgid "Enable External Media" @@ -1394,7 +1394,7 @@ msgstr "Entra el codi de confirmació" #: src/view/com/modals/ChangePassword.tsx:151 msgid "Enter the code you received to change your password." -msgstr "" +msgstr "Introdueix el codi que has rebut per canviar la teva contrasenya." #: src/view/com/modals/ChangeHandle.tsx:371 msgid "Enter the domain you want to use" @@ -1473,12 +1473,12 @@ msgstr "Expandeix o replega la publicació completa a la qual estàs responent" #: src/view/screens/Settings/index.tsx:753 msgid "Export my data" -msgstr "" +msgstr "Exporta les meves dades" #: src/view/screens/Settings/ExportCarDialog.tsx:44 #: src/view/screens/Settings/index.tsx:764 msgid "Export My Data" -msgstr "" +msgstr "Exporta les meves dades" #: src/view/com/modals/EmbedConsent.tsx:64 msgid "External Media" @@ -1559,11 +1559,11 @@ msgstr "Els canals són algoritmes personalitzats creats per usuaris que coneixe #: src/screens/Onboarding/StepTopicalFeeds.tsx:76 msgid "Feeds can be topical as well!" -msgstr "" +msgstr "Els canals també poden ser d'actualitat!" #: src/screens/Onboarding/StepFinished.tsx:151 msgid "Finalizing" -msgstr "" +msgstr "Finalitzant" #: src/view/com/posts/CustomFeedEmptyState.tsx:47 #: src/view/com/posts/FollowingEmptyState.tsx:57 @@ -1597,11 +1597,11 @@ msgstr "Ajusta els fils de debat." #: src/screens/Onboarding/index.tsx:38 msgid "Fitness" -msgstr "" +msgstr "Exercici" #: src/screens/Onboarding/StepFinished.tsx:131 msgid "Flexible" -msgstr "" +msgstr "Flexible" #: src/view/com/modals/EditImage.tsx:115 msgid "Flip horizontal" @@ -1631,11 +1631,11 @@ msgstr "Segueix {0}" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:179 msgid "Follow All" -msgstr "" +msgstr "Segueix-los a tots" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:174 msgid "Follow selected accounts and continue to the next step" -msgstr "" +msgstr "Segueix els comptes seleccionats i continua" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:64 msgid "Follow some users to get started. We can recommend you more users based on who you find interesting." @@ -1693,7 +1693,7 @@ msgstr "Et segueix" #: src/screens/Onboarding/index.tsx:43 msgid "Food" -msgstr "" +msgstr "Menjar" #: src/view/com/modals/DeleteAccount.tsx:111 msgid "For security reasons, we'll need to send a confirmation code to your email address." @@ -1752,7 +1752,7 @@ msgstr "Ves enrere" #: src/screens/Onboarding/Layout.tsx:104 #: src/screens/Onboarding/Layout.tsx:193 msgid "Go back to previous step" -msgstr "" +msgstr "Ves al pas anterior" #: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 @@ -1794,15 +1794,15 @@ msgstr "Ajuda" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:132 msgid "Here are some accounts for you to follow" -msgstr "" +msgstr "Aquí tens uns quants comptes que pots seguir" #: src/screens/Onboarding/StepTopicalFeeds.tsx:85 msgid "Here are some popular topical feeds. You can choose to follow as many as you like." -msgstr "" +msgstr "Aquí tens alguns canals d'actualitat populars. Pots seguir-ne tants com vulguis." #: src/screens/Onboarding/StepTopicalFeeds.tsx:80 msgid "Here are some topical feeds based on your interests: {interestsText}. You can choose to follow as many as you like." -msgstr "" +msgstr "Aquí tens uns quants canals d'actualitat basats en els teus interesos: {interestsText}. Pots seguir-ne tants com vulguis." #: src/view/com/modals/AddAppPasswords.tsx:153 msgid "Here is your app password." @@ -1914,7 +1914,7 @@ msgstr "Si no en selecciones cap, és apropiat per a totes les edats." #: src/view/com/modals/ChangePassword.tsx:146 msgid "If you want to change your password, we will send you a code to verify that this is your account." -msgstr "" +msgstr "Si vols canviar la contrasenya t'enviarem un codi per verificar que aquest compte és teu." #: src/view/com/util/images/Gallery.tsx:38 msgid "Image" @@ -2024,7 +2024,7 @@ msgstr "Codis d'invitació: 1 disponible" #: src/screens/Onboarding/StepFollowingFeed.tsx:64 msgid "It shows posts from the people you follow as they happen." -msgstr "" +msgstr "Mostra les publicacions de les persones que segueixes cronològicament." #: src/view/com/auth/HomeLoggedOutCTA.tsx:99 #: src/view/com/auth/SplashScreen.web.tsx:138 @@ -2046,7 +2046,7 @@ msgstr "Feines" #: src/screens/Onboarding/index.tsx:24 msgid "Journalism" -msgstr "" +msgstr "Periodisme" #: src/view/com/composer/select-language/SelectLangBtn.tsx:104 msgid "Language selection" @@ -2101,7 +2101,7 @@ msgstr "Sortint de Bluesky" #: src/screens/Deactivated.tsx:128 msgid "left to go." -msgstr "" +msgstr "queda." #: src/view/screens/Settings/index.tsx:278 msgid "Legacy storage cleared, you need to restart the app now." @@ -2114,7 +2114,7 @@ msgstr "Restablirem la teva contrasenya!" #: src/screens/Onboarding/StepFinished.tsx:151 msgid "Let's go!" -msgstr "" +msgstr "Som-hi!" #: src/view/com/util/UserAvatar.tsx:248 #: src/view/com/util/UserBanner.tsx:62 @@ -2140,7 +2140,7 @@ msgstr "Li ha agradat a" #: src/view/screens/PostLikedBy.tsx:27 #: src/view/screens/ProfileFeedLikedBy.tsx:27 msgid "Liked By" -msgstr "" +msgstr "Li ha agradat a" #: src/view/com/feeds/FeedSourceCard.tsx:279 msgid "Liked by {0} {1}" @@ -2152,7 +2152,7 @@ msgstr "Li ha agradat a {likeCount} {0}" #: src/view/com/notifications/FeedItem.tsx:170 msgid "liked your custom feed" -msgstr "" +msgstr "els hi ha agradat el teu canal personalitzat" #: src/view/com/notifications/FeedItem.tsx:171 #~ msgid "liked your custom feed{0}" @@ -2247,7 +2247,7 @@ msgstr "Registre" #: src/screens/Deactivated.tsx:178 #: src/screens/Deactivated.tsx:181 msgid "Log out" -msgstr "" +msgstr "Desconnecta" #: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" @@ -2477,7 +2477,7 @@ msgstr "Els meus canals desats" #: src/view/com/auth/server-input/index.tsx:118 msgid "my-server.com" -msgstr "" +msgstr "el-meu-servidor.com" #: src/view/com/modals/AddAppPasswords.tsx:179 #: src/view/com/modals/CreateOrEditList.tsx:290 @@ -2490,7 +2490,7 @@ msgstr "Es requereix un nom" #: src/screens/Onboarding/index.tsx:25 msgid "Nature" -msgstr "" +msgstr "Natura" #: src/view/com/auth/login/ForgotPasswordForm.tsx:190 #: src/view/com/auth/login/ForgotPasswordForm.tsx:219 @@ -2516,7 +2516,7 @@ msgstr "No perdis mai accés als teus seguidors ni a les teves dades." #: src/screens/Onboarding/StepFinished.tsx:119 msgid "Never lose access to your followers or data." -msgstr "" +msgstr "No perdis mai accés als teus seguidors i les teves dades." #: src/components/dialogs/MutedWords.tsx:293 msgid "Nevermind" @@ -2541,7 +2541,7 @@ msgstr "Nova contrasenya" #: src/view/com/modals/ChangePassword.tsx:215 msgid "New Password" -msgstr "" +msgstr "Nova contrasenya" #: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" @@ -2577,7 +2577,7 @@ msgstr "Les respostes més noves primer" #: src/screens/Onboarding/index.tsx:23 msgid "News" -msgstr "" +msgstr "Notícies" #: src/view/com/auth/create/CreateAccount.tsx:172 #: src/view/com/auth/login/ForgotPasswordForm.tsx:182 @@ -2687,7 +2687,7 @@ msgstr "Ostres!" #: src/screens/Onboarding/StepInterests/index.tsx:128 msgid "Oh no! Something went wrong." -msgstr "" +msgstr "Ostres! Alguna cosa ha fallat." #: src/view/com/auth/login/PasswordUpdatedForm.tsx:41 msgid "Okay" @@ -2721,7 +2721,7 @@ msgstr "Ostres!" #: src/screens/Onboarding/StepFinished.tsx:115 msgid "Open" -msgstr "" +msgstr "Obre" #: src/view/screens/Moderation.tsx:75 msgid "Open content filtering settings" @@ -2750,7 +2750,7 @@ msgstr "" #: src/view/screens/Settings/index.tsx:804 msgid "Open storybook page" -msgstr "" +msgstr "Obre la pàgina d'historial" #: src/view/com/util/forms/DropdownButton.tsx:154 msgid "Opens {numItems} options" @@ -2876,7 +2876,7 @@ msgstr "Pàgina no trobada" #: src/view/screens/NotFound.tsx:42 msgid "Page Not Found" -msgstr "" +msgstr "Pàgina no trobada" #: src/view/com/auth/create/Step1.tsx:191 #: src/view/com/auth/create/Step1.tsx:201 @@ -2912,7 +2912,7 @@ msgstr "S'ha denegat el permís per accedir a la càmera. Activa'l a la configur #: src/screens/Onboarding/index.tsx:31 msgid "Pets" -msgstr "" +msgstr "Mascotes" #: src/view/com/auth/create/Step2.tsx:183 #~ msgid "Phone number" @@ -3010,7 +3010,7 @@ msgstr "Espera que es generi la targeta de l'enllaç" #: src/screens/Onboarding/index.tsx:37 msgid "Politics" -msgstr "" +msgstr "Política" #: src/view/com/modals/SelfLabel.tsx:111 msgid "Porn" @@ -3129,7 +3129,7 @@ msgstr "Protegeix el teu compte verificant el teu correu." #: src/screens/Onboarding/StepFinished.tsx:101 msgid "Public" -msgstr "" +msgstr "Públic" #: src/view/screens/ModerationModlists.tsx:61 msgid "Public, shareable lists of users to mute or block in bulk." @@ -3300,7 +3300,7 @@ msgstr "Informa de la publicació" #: src/view/com/util/post-ctrls/RepostButton.tsx:61 msgctxt "action" msgid "Repost" -msgstr "Respon" +msgstr "Republica" #: src/view/com/util/post-ctrls/RepostButton.web.tsx:48 msgid "Repost" @@ -3317,11 +3317,11 @@ msgstr "Republica o cita la publicació" #: src/view/screens/PostRepostedBy.tsx:27 msgid "Reposted By" -msgstr "" +msgstr "Republicat per" #: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" -msgstr "" +msgstr "Republicat per {0}" #: src/view/com/posts/FeedItem.tsx:206 #~ msgid "Reposted by {0})" @@ -3351,7 +3351,7 @@ msgstr "Demana un canvi" #: src/view/com/modals/ChangePassword.tsx:239 #: src/view/com/modals/ChangePassword.tsx:241 msgid "Request Code" -msgstr "" +msgstr "Demana un codi" #: src/view/screens/Settings/index.tsx:456 msgid "Require alt text before posting" @@ -3368,7 +3368,7 @@ msgstr "Codi de restabliment" #: src/view/com/modals/ChangePassword.tsx:190 msgid "Reset Code" -msgstr "" +msgstr "Codi de restabliment" #: src/view/screens/Settings/index.tsx:824 msgid "Reset onboarding" @@ -3475,7 +3475,7 @@ msgstr "Desa el canvi d'identificador a {handle}" #: src/screens/Onboarding/index.tsx:36 msgid "Science" -msgstr "" +msgstr "Ciència" #: src/view/screens/ProfileList.tsx:859 msgid "Scroll to top" @@ -3584,19 +3584,19 @@ msgstr "Selecciona el servei" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:52 msgid "Select some accounts below to follow" -msgstr "" +msgstr "Selecciona alguns d'aquests comptes per seguir-los" #: src/view/com/auth/server-input/index.tsx:82 msgid "Select the service that hosts your data." -msgstr "" +msgstr "Selecciona el servei que allotja les teves dades." #: src/screens/Onboarding/StepTopicalFeeds.tsx:96 msgid "Select topical feeds to follow from the list below" -msgstr "" +msgstr "Selecciona els canals d'actualitat per seguir d'aquesta llista" #: src/screens/Onboarding/StepModeration/index.tsx:75 msgid "Select what you want to see (or not see), and we’ll handle the rest." -msgstr "" +msgstr "Selecciona què vols veure (o què no vols veure) i nosaltres farem la resta." #: src/view/screens/LanguageSettings.tsx:281 msgid "Select which languages you want your subscribed feeds to include. If none are selected, all languages will be shown." @@ -3608,7 +3608,7 @@ msgstr "Selecciona l'idioma de l'aplicació perquè el text predeterminat es mos #: src/screens/Onboarding/StepInterests/index.tsx:196 msgid "Select your interests from the options below" -msgstr "" +msgstr "Selecciona els teus interesos d'entre aquestes opcions" #: src/view/com/auth/create/Step2.tsx:155 #~ msgid "Select your phone's country" @@ -3620,11 +3620,11 @@ msgstr "Selecciona el teu idioma preferit per a les traduccions al teu canal." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:116 msgid "Select your primary algorithmic feeds" -msgstr "" +msgstr "Selecciona els teus canals algorítmics primaris" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:142 msgid "Select your secondary algorithmic feeds" -msgstr "" +msgstr "Selecciona els teus canals algorítmics secundaris" #: src/view/com/modals/VerifyEmail.tsx:202 #: src/view/com/modals/VerifyEmail.tsx:204 @@ -3659,7 +3659,7 @@ msgstr "Envia un correu amb el codi de confirmació per l'eliminació del compte #: src/view/com/auth/server-input/index.tsx:110 msgid "Server address" -msgstr "" +msgstr "Adreça del servidor" #: src/view/com/modals/ContentFilteringSettings.tsx:311 msgid "Set {value} for {labelGroup} content moderation policy" @@ -3685,11 +3685,11 @@ msgstr "Estableix el tema de colors a la configuració del sistema" #: src/view/screens/Settings/index.tsx:514 msgid "Set dark theme to the dark theme" -msgstr "" +msgstr "Posa el tema fosc" #: src/view/screens/Settings/index.tsx:507 msgid "Set dark theme to the dim theme" -msgstr "" +msgstr "Posa el tema fosc al tema atenuat" #: src/view/com/auth/login/SetNewPasswordForm.tsx:104 msgid "Set new password" @@ -3725,7 +3725,7 @@ msgstr "" #: src/screens/Onboarding/Layout.tsx:50 msgid "Set up your account" -msgstr "" +msgstr "Configura el teu compte" #: src/view/com/modals/ChangeHandle.tsx:266 msgid "Sets Bluesky username" @@ -3813,15 +3813,15 @@ msgstr "Mostra les publicacions citades" #: src/screens/Onboarding/StepFollowingFeed.tsx:118 msgid "Show quote-posts in Following feed" -msgstr "" +msgstr "Mostra les publicacions citades en el canal Seguint" #: src/screens/Onboarding/StepFollowingFeed.tsx:134 msgid "Show quotes in Following" -msgstr "" +msgstr "Mostra els citats a Seguint" #: src/screens/Onboarding/StepFollowingFeed.tsx:94 msgid "Show re-posts in Following feed" -msgstr "" +msgstr "Mostra les republicacions al canal Seguint" #: src/view/screens/PreferencesFollowingFeed.tsx:119 msgid "Show Replies" @@ -3833,11 +3833,11 @@ msgstr "Mostra les respostes dels comptes que segueixes abans que les altres." #: src/screens/Onboarding/StepFollowingFeed.tsx:86 msgid "Show replies in Following" -msgstr "" +msgstr "Mostra les respostes a Seguint" #: src/screens/Onboarding/StepFollowingFeed.tsx:70 msgid "Show replies in Following feed" -msgstr "" +msgstr "Mostrea les respostes al canal Seguint" #: src/view/screens/PreferencesFollowingFeed.tsx:70 msgid "Show replies with at least {value} {0}" @@ -3849,7 +3849,7 @@ msgstr "Mostra republicacions" #: src/screens/Onboarding/StepFollowingFeed.tsx:110 msgid "Show reposts in Following" -msgstr "" +msgstr "Mostra les republicacions al canal Seguint" #: src/view/com/util/moderation/ContentHider.tsx:67 #: src/view/com/util/moderation/PostHider.tsx:61 @@ -3949,7 +3949,7 @@ msgstr "Salta aquest pas" #: src/screens/Onboarding/StepInterests/index.tsx:232 msgid "Skip this flow" -msgstr "" +msgstr "Salta aquest flux" #: src/view/com/auth/create/Step2.tsx:82 #~ msgid "SMS verification" @@ -3957,7 +3957,7 @@ msgstr "" #: src/screens/Onboarding/index.tsx:40 msgid "Software Dev" -msgstr "" +msgstr "Desenvolupament de programari" #: src/view/com/modals/ProfilePreview.tsx:62 #~ msgid "Something went wrong and we're not sure what." @@ -3985,7 +3985,7 @@ msgstr "Ordena les respostes a la mateixa publicació per:" #: src/screens/Onboarding/index.tsx:30 msgid "Sports" -msgstr "" +msgstr "Esports" #: src/view/com/modals/crop-image/CropImage.web.tsx:122 msgid "Square" @@ -4023,7 +4023,7 @@ msgstr "Subscriure's" #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:173 #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:308 msgid "Subscribe to the {0} feed" -msgstr "" +msgstr "Subscriu-te al canal {0}" #: src/view/screens/ProfileList.tsx:604 msgid "Subscribe to this list" @@ -4095,7 +4095,7 @@ msgstr "Toca per veure-ho completament" #: src/screens/Onboarding/index.tsx:39 msgid "Tech" -msgstr "" +msgstr "Tecnologia" #: src/view/shell/desktop/RightNav.tsx:81 msgid "Terms" @@ -4135,7 +4135,7 @@ msgstr "La política de drets d'autoria ha estat traslladada a <0/>" #: src/screens/Onboarding/Layout.tsx:60 msgid "The following steps will help customize your Bluesky experience." -msgstr "" +msgstr "Els següents passos t'ajudaran a personalitzar la teva experiència a Bluesky." #: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." @@ -4159,7 +4159,7 @@ msgstr "Les condicions del servei han estat traslladades a " #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:150 msgid "There are many feeds to try:" -msgstr "" +msgstr "Hi ha molts canals per provar:" #: src/view/screens/ProfileFeed.tsx:550 msgid "There was an an issue contacting the server, please check your internet connection and try again." @@ -4239,7 +4239,7 @@ msgstr "S'ha produït un problema inesperat a l'aplicació. Fes-nos saber si aix #: src/screens/Deactivated.tsx:106 msgid "There's been a rush of new users to Bluesky! We'll activate your account as soon as we can." -msgstr "" +msgstr "Hi ha hagut una gran quantitat d'usuaris nous a Bluesky! Activarem el teu compte tan aviat com puguem." #: src/view/com/auth/create/Step2.tsx:55 #~ msgid "There's something wrong with this number. Please choose your country and enter your full phone number!" @@ -4247,7 +4247,7 @@ msgstr "" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:138 msgid "These are popular accounts you might like:" -msgstr "" +msgstr "Aquests són alguns comptes populars que et poden agradar:" #~ msgid "This {0} has been labeled." #~ msgstr "Aquest {0} ha estat etiquetat." @@ -4274,7 +4274,7 @@ msgstr "Aquest contingut no es pot veure sense un compte de Bluesky." #: src/view/screens/Settings/ExportCarDialog.tsx:75 msgid "This feature is in beta. You can read more about repository exports in <0>this blogpost.</0>" -msgstr "" +msgstr "Aquesta funcionalitat està en beta. En <0>aquesta entrada al blog</0> tens més informació." #: src/view/com/posts/FeedErrorMessage.tsx:114 msgid "This feed is currently receiving high traffic and is temporarily unavailable. Please try again later." @@ -4328,7 +4328,7 @@ msgstr "Aquest usuari està inclós a la llista <0/> que tens bloquejada" #: src/view/com/modals/ModerationDetails.tsx:74 msgid "This user is included in the <0/> list which you have muted." -msgstr "" +msgstr "Aquest usuari està inclòs a la llista <0/> que has silenciat." #: src/view/com/modals/ModerationDetails.tsx:74 #~ msgid "This user is included the <0/> list which you have muted." @@ -4614,7 +4614,7 @@ msgstr "Verifica el teu correu" #: src/screens/Onboarding/index.tsx:42 msgid "Video Games" -msgstr "" +msgstr "Videojocs" #: src/view/com/profile/ProfileHeader.tsx:662 msgid "View {0}'s avatar" @@ -4647,7 +4647,7 @@ msgstr "Adverteix" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:134 msgid "We also think you'll like \"For You\" by Skygaze:" -msgstr "" +msgstr "També creiem que t'agradarà el canal \"For You\" d'Skygaze:" #: src/screens/Hashtag.tsx:132 msgid "We couldn't find any results for that hashtag." @@ -4655,11 +4655,11 @@ msgstr "" #: src/screens/Deactivated.tsx:133 msgid "We estimate {estimatedTime} until your account is ready." -msgstr "" +msgstr "Calculem {estimatedTime} fins que el teu compte estigui llest." #: src/screens/Onboarding/StepFinished.tsx:93 msgid "We hope you have a wonderful time. Remember, Bluesky is:" -msgstr "" +msgstr "Esperem que t'ho passis pipa. Recorda que Bluesky és:" #: src/view/com/posts/DiscoverFallbackHeader.tsx:29 msgid "We ran out of posts from your follows. Here's the latest from <0/>." @@ -4671,15 +4671,15 @@ msgstr "" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" -msgstr "" +msgstr "Et reomanem el nostre canal \"Discover\":" #: src/screens/Onboarding/StepInterests/index.tsx:133 msgid "We weren't able to connect. Please try again to continue setting up your account. If it continues to fail, you can skip this flow." -msgstr "" +msgstr "No ens hem pogut connectar. Torna-ho a provar per continuar configurant el teu compte. Si continua fallant, pots ometre aquest flux." #: src/screens/Deactivated.tsx:137 msgid "We will let you know when your account is ready." -msgstr "" +msgstr "T'informarem quan el teu compte estigui llest." #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." @@ -4687,7 +4687,7 @@ msgstr "Analitzarem la teva apel·lació ràpidament." #: src/screens/Onboarding/StepInterests/index.tsx:138 msgid "We'll use this to help customize your experience." -msgstr "" +msgstr "Ho farem servir per personalitzar la teva experiència." #: src/view/com/auth/create/CreateAccount.tsx:134 msgid "We're so excited to have you join us!" @@ -4716,7 +4716,7 @@ msgstr "Benvingut a <0>Bluesky</0>" #: src/screens/Onboarding/StepInterests/index.tsx:130 msgid "What are your interests?" -msgstr "" +msgstr "Quins són els teus interesos?" #: src/view/com/modals/report/Modal.tsx:169 msgid "What is the issue with this {collectionName}?" @@ -4758,7 +4758,7 @@ msgstr "Escriu la teva resposta" #: src/screens/Onboarding/index.tsx:28 msgid "Writers" -msgstr "" +msgstr "Escriptors" #: src/view/com/auth/create/Step2.tsx:263 #~ msgid "XXXXXX" @@ -4776,7 +4776,7 @@ msgstr "Sí" #: src/screens/Deactivated.tsx:130 msgid "You are in line." -msgstr "" +msgstr "Estàs a la cua." #: src/view/com/posts/FollowingEmptyState.tsx:67 #: src/view/com/posts/FollowingEndOfFeed.tsx:68 @@ -4789,7 +4789,7 @@ msgstr "També pots descobrir nous canals personalitzats per seguir." #: src/screens/Onboarding/StepFollowingFeed.tsx:142 msgid "You can change these settings later." -msgstr "" +msgstr "Pots canviar aquests paràmetres més endavant." #: src/view/com/auth/login/Login.tsx:158 #: src/view/com/auth/login/PasswordUpdatedForm.tsx:31 @@ -4825,7 +4825,7 @@ msgstr "Has bloquejat aquest usuari. No pots veure el seu contingut." #: src/view/com/modals/ChangePassword.tsx:87 #: src/view/com/modals/ChangePassword.tsx:121 msgid "You have entered an invalid code. It should look like XXXXX-XXXXX." -msgstr "" +msgstr "Has entrat un codi invàlid. Hauria de ser tipus XXXXX-XXXXX." #: src/view/com/modals/ModerationDetails.tsx:87 msgid "You have muted this user." @@ -4862,7 +4862,7 @@ msgstr "Has de tenir 18 anys o més per habilitar el contingut per a adults." #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:103 msgid "You must be 18 years or older to enable adult content" -msgstr "" +msgstr "Has de tenir 18 anys o més per habilitar el contingut per a adults" #: src/view/com/util/forms/PostDropdownBtn.tsx:147 msgid "You will no longer receive notifications for this thread" @@ -4878,17 +4878,17 @@ msgstr "Rebràs un correu amb un \"codi de restabliment\". Introdueix aquí el c #: src/screens/Onboarding/StepModeration/index.tsx:72 msgid "You're in control" -msgstr "" +msgstr "Tu tens el control" #: src/screens/Deactivated.tsx:87 #: src/screens/Deactivated.tsx:88 #: src/screens/Deactivated.tsx:103 msgid "You're in line" -msgstr "" +msgstr "Estàs a la cua" #: src/screens/Onboarding/StepFinished.tsx:90 msgid "You're ready to go!" -msgstr "" +msgstr "Ja està tot llest!" #: src/view/com/posts/FollowingEndOfFeed.tsx:48 msgid "You've reached the end of your feed! Find some more accounts to follow." @@ -4904,7 +4904,7 @@ msgstr "El teu compte s'ha eliminat" #: src/view/screens/Settings/ExportCarDialog.tsx:47 msgid "Your account repository, containing all public data records, can be downloaded as a \"CAR\" file. This file does not include media embeds, such as images, or your private data, which must be fetched separately." -msgstr "" +msgstr "El repositori del teu compte, que conté tots els registres de dades públiques, es pot baixar com a fitxer \"CAR\". Aquest fitxer no inclou incrustacions multimèdia, com ara imatges, ni les teves dades privades, que s'han d'obtenir per separat." #: src/view/com/auth/create/Step1.tsx:215 msgid "Your birth date" @@ -4916,7 +4916,7 @@ msgstr "La teva elecció es desarà, però es pot canviar més endavant a la con #: src/screens/Onboarding/StepFollowingFeed.tsx:61 msgid "Your default feed is \"Following\"" -msgstr "" +msgstr "El teu canal per defecte és \"Seguint\"" #: src/view/com/auth/create/state.ts:110 #: src/view/com/auth/login/ForgotPasswordForm.tsx:70 @@ -4964,7 +4964,7 @@ msgstr "" #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" -msgstr "" +msgstr "S'ha canviat la teva contrasenya!" #: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" From d966b3e425440d45f9b2dae41a3ec26e23b39110 Mon Sep 17 00:00:00 2001 From: Paul Frazee <pfrazee@gmail.com> Date: Tue, 19 Mar 2024 12:56:29 -0700 Subject: [PATCH 101/109] Fix merge error --- src/components/Lists.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Lists.tsx b/src/components/Lists.tsx index 8e4a58007c..d3e0720286 100644 --- a/src/components/Lists.tsx +++ b/src/components/Lists.tsx @@ -150,7 +150,6 @@ export function ListMaybePlaceholder({ const t = useTheme() const {_} = useLingui() const {gtMobile, gtTablet} = useBreakpoints() - const {_} = useLingui() if (!isLoading && isError) { return ( From 40908e9ce79dbb54dcd5368038fedc0323d68134 Mon Sep 17 00:00:00 2001 From: Paul Frazee <pfrazee@gmail.com> Date: Tue, 19 Mar 2024 13:04:45 -0700 Subject: [PATCH 102/109] Fix formatting --- src/locale/i18n.ts | 4 ++-- src/locale/i18n.web.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/locale/i18n.ts b/src/locale/i18n.ts index 045fa0addb..a1e950947b 100644 --- a/src/locale/i18n.ts +++ b/src/locale/i18n.ts @@ -33,10 +33,10 @@ export async function dynamicActivate(locale: AppLanguage) { i18n.loadAndActivate({locale, messages: messagesEs}) break } - case AppLanguage.fi: { + case AppLanguage.fi: { i18n.loadAndActivate({locale, messages: messagesFi}) break - } + } case AppLanguage.fr: { i18n.loadAndActivate({locale, messages: messagesFr}) break diff --git a/src/locale/i18n.web.ts b/src/locale/i18n.web.ts index 1c5112f067..334b2586e5 100644 --- a/src/locale/i18n.web.ts +++ b/src/locale/i18n.web.ts @@ -20,7 +20,7 @@ export async function dynamicActivate(locale: AppLanguage) { mod = await import(`./locales/es/messages`) break } - case AppLanguage.fi: { + case AppLanguage.fi: { mod = await import(`./locales/fi/messages`) break } From 5bec5877172ac0f18c3c1bebec7ad6c46ca0ae39 Mon Sep 17 00:00:00 2001 From: dan <dan.abramov@gmail.com> Date: Tue, 19 Mar 2024 20:11:26 +0000 Subject: [PATCH 103/109] [Statsig] Include OS and track app state changes (#3273) * Include platform in identify * Track back/foregrounding --- src/lib/statsig/events.ts | 2 ++ src/lib/statsig/statsig.tsx | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/lib/statsig/events.ts b/src/lib/statsig/events.ts index fa7e597fbc..cb9f3fe924 100644 --- a/src/lib/statsig/events.ts +++ b/src/lib/statsig/events.ts @@ -2,6 +2,8 @@ export type LogEvents = { init: { initMs: number } + 'state:background': {} + 'state:foreground': {} 'feed:endReached': { feedType: string itemCount: number diff --git a/src/lib/statsig/statsig.tsx b/src/lib/statsig/statsig.tsx index 5745d204ad..3abec5c4f9 100644 --- a/src/lib/statsig/statsig.tsx +++ b/src/lib/statsig/statsig.tsx @@ -1,9 +1,11 @@ import React from 'react' +import {Platform} from 'react-native' import { Statsig, StatsigProvider, useGate as useStatsigGate, } from 'statsig-react-native-expo' +import {AppState, AppStateStatus} from 'react-native' import {useSession} from '../../state/session' import {sha256} from 'js-sha256' import {LogEvents} from './events' @@ -58,9 +60,25 @@ function toStatsigUser(did: string | undefined) { if (did) { userID = sha256(did) } - return {userID} + return { + userID, + platform: Platform.OS, + } } +let lastState: AppStateStatus = AppState.currentState +AppState.addEventListener('change', (state: AppStateStatus) => { + if (state === lastState) { + return + } + lastState = state + if (state === 'active') { + logEvent('state:foreground', {}) + } else { + logEvent('state:background', {}) + } +}) + export function Provider({children}: {children: React.ReactNode}) { const {currentAccount} = useSession() const currentStatsigUser = React.useMemo( From 69f8ea80f82a1d93914f8c2f04b99bc0e4ec932e Mon Sep 17 00:00:00 2001 From: surfdude29 <149612116+surfdude29@users.noreply.github.com> Date: Tue, 19 Mar 2024 20:11:48 +0000 Subject: [PATCH 104/109] Fix typos and clarify two `accessibilityHint`s (#2923) * Clarify accessibilityHint in Settings * Fix typo in ModerationMutedAccounts.tsx * Fix typo in ModerationBlockedAccounts.tsx * fix lint error in ModerationMutedAccounts.tsx * try again * fix lint error in index.tsx * try again * Update index.tsx * Update index.tsx --------- Co-authored-by: Paul Frazee <pfrazee@gmail.com> --- src/view/screens/ModerationBlockedAccounts.tsx | 2 +- src/view/screens/ModerationMutedAccounts.tsx | 4 ++-- src/view/screens/Settings/index.tsx | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/view/screens/ModerationBlockedAccounts.tsx b/src/view/screens/ModerationBlockedAccounts.tsx index 09d77987f9..eb3b270488 100644 --- a/src/view/screens/ModerationBlockedAccounts.tsx +++ b/src/view/screens/ModerationBlockedAccounts.tsx @@ -131,7 +131,7 @@ export function ModerationBlockedAccounts({}: Props) { <Text type="lg" style={[pal.text, styles.emptyText]}> <Trans> You have not blocked any accounts yet. To block an account, go - to their profile and selected "Block account" from the menu on + to their profile and select "Block account" from the menu on their account. </Trans> </Text> diff --git a/src/view/screens/ModerationMutedAccounts.tsx b/src/view/screens/ModerationMutedAccounts.tsx index 1aff19dd3b..911ace7782 100644 --- a/src/view/screens/ModerationMutedAccounts.tsx +++ b/src/view/screens/ModerationMutedAccounts.tsx @@ -130,8 +130,8 @@ export function ModerationMutedAccounts({}: Props) { <Text type="lg" style={[pal.text, styles.emptyText]}> <Trans> You have not muted any accounts yet. To mute an account, go to - their profile and selected "Mute account" from the menu on - their account. + their profile and select "Mute account" from the menu on their + account. </Trans> </Text> </View> diff --git a/src/view/screens/Settings/index.tsx b/src/view/screens/Settings/index.tsx index 4650077770..7e808f9100 100644 --- a/src/view/screens/Settings/index.tsx +++ b/src/view/screens/Settings/index.tsx @@ -711,7 +711,7 @@ export function SettingsScreen({}: Props) { accessibilityRole="button" accessibilityLabel={_(msg`Change handle`)} accessibilityHint={_( - msg`Opens modal for choosing or creating a new Bluesky username`, + msg`Opens modal for choosing a new Bluesky handle`, )}> <View style={[styles.iconContainer, pal.btn]}> <FontAwesomeIcon @@ -772,7 +772,7 @@ export function SettingsScreen({}: Props) { accessibilityRole="button" accessibilityLabel={_(msg`Export my data`)} accessibilityHint={_( - msg`Opens modal for downloading Bluesky account data (repository)`, + msg`Opens modal for downloading your Bluesky account data (repository)`, )}> <View style={[styles.iconContainer, pal.btn]}> <FontAwesomeIcon From 0cac671e8a09057a457c912534eb9d65240f2f56 Mon Sep 17 00:00:00 2001 From: Dovgonosyk <159719660+Dovgonosyk@users.noreply.github.com> Date: Tue, 19 Mar 2024 22:13:27 +0200 Subject: [PATCH 105/109] Update Ukrainian translation (#2951) Co-authored-by: Ukrainians <github-actions@github.com> --- src/locale/locales/uk/messages.po | 1416 ++++++++++++----------------- 1 file changed, 563 insertions(+), 853 deletions(-) diff --git a/src/locale/locales/uk/messages.po b/src/locale/locales/uk/messages.po index 41782f776d..2af731a4bb 100644 --- a/src/locale/locales/uk/messages.po +++ b/src/locale/locales/uk/messages.po @@ -8,7 +8,7 @@ msgstr "" "Language: uk\n" "Project-Id-Version: bsky-app-ua\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2024-01-09 23:26\n" +"PO-Revision-Date: 2024-03-13 11:56\n" "Last-Translator: \n" "Language-Team: Ukrainian\n" "Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" @@ -18,60 +18,35 @@ msgstr "" "X-Crowdin-File: /main/src/locale/locales/en/messages.po\n" "X-Crowdin-File-ID: 14\n" -#: src/view/screens/Profile.tsx:214 -#~ msgid "- end of feed -" -#~ msgstr "" - -#: src/view/com/modals/SelfLabel.tsx:138 -#~ msgid ". This warning is only available for posts with media attached." -#~ msgstr "" - #: src/view/com/modals/VerifyEmail.tsx:142 msgid "(no email)" -msgstr "" +msgstr "(немає ел. адреси)" #: src/view/shell/desktop/RightNav.tsx:168 #~ msgid "{0, plural, one {# invite code available} other {# invite codes available}}" -#~ msgstr "{0, plural, one {Доступний # код запрошення} few {Доступно # коди запрошення} other {Доступно # кодів запрошення}}" - -#: src/view/com/modals/CreateOrEditList.tsx:185 -#: src/view/screens/Settings.tsx:294 -#~ msgid "{0}" -#~ msgstr "{0}" - -#: src/view/com/modals/CreateOrEditList.tsx:176 -#~ msgid "{0} {purposeLabel} List" -#~ msgstr "{0} Список {purposeLabel}" +#~ msgstr "" #: src/view/com/profile/ProfileHeader.tsx:593 msgid "{following} following" -msgstr "" +msgstr "{following} підписок" #: src/view/shell/desktop/RightNav.tsx:151 #~ msgid "{invitesAvailable, plural, one {Invite codes: # available} other {Invite codes: # available}}" -#~ msgstr "{invitesAvailable, plural, one {Коди запрошень: доступно #} other {Коди запрошень: доступно #}}" +#~ msgstr "" #: src/view/screens/Settings.tsx:435 #: src/view/shell/Drawer.tsx:664 #~ msgid "{invitesAvailable} invite code available" -#~ msgstr "Доступний код запрошення" +#~ msgstr "" #: src/view/screens/Settings.tsx:437 #: src/view/shell/Drawer.tsx:666 #~ msgid "{invitesAvailable} invite codes available" -#~ msgstr "Доступно {invitesAvailable} кодів запрошення" - -#: src/view/screens/Search/Search.tsx:87 -#~ msgid "{message}" -#~ msgstr "{message}" +#~ msgstr "" #: src/view/shell/Drawer.tsx:440 msgid "{numUnreadNotifications} unread" -msgstr "" - -#: src/Navigation.tsx:147 -#~ msgid "@{0}" -#~ msgstr "" +msgstr "{numUnreadNotifications} непрочитаних" #: src/view/com/threadgate/WhoCanReply.tsx:158 msgid "<0/> members" @@ -79,7 +54,7 @@ msgstr "<0/> учасників" #: src/view/com/profile/ProfileHeader.tsx:595 msgid "<0>{following} </0><1>following</1>" -msgstr "" +msgstr "<0>{following} </0><1>підписок</1>" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:30 msgid "<0>Choose your</0><1>Recommended</1><2>Feeds</2>" @@ -89,25 +64,13 @@ msgstr "<0>Оберіть свої</0><1>рекомендовані</1><2>стр msgid "<0>Follow some</0><1>Recommended</1><2>Users</2>" msgstr "<0>Підпишіться на деяких </0><1>рекомендованих </1><2>користувачів</2>" -#: src/view/com/modals/AddAppPasswords.tsx:132 -#~ msgid "<0>Here is your app password.</0> Use this to sign into the other app along with your handle." -#~ msgstr "" - -#: src/view/screens/Moderation.tsx:212 -#~ msgid "<0>Note: This setting may not be respected by third-party apps that display Bluesky content.</0>" -#~ msgstr "" - -#: src/view/screens/Moderation.tsx:212 -#~ msgid "<0>Note: Your profile and posts will remain publicly available. Third-party apps that display Bluesky content may not respect this setting.</0>" -#~ msgstr "" - #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:21 msgid "<0>Welcome to</0><1>Bluesky</1>" -msgstr "" +msgstr "<0>Ласкаво просимо до</0><1>Bluesky</1>" #: src/view/com/profile/ProfileHeader.tsx:558 msgid "⚠Invalid Handle" -msgstr "" +msgstr "⚠Недопустимий псевдонім" #: src/view/com/util/moderation/LabelInfo.tsx:45 msgid "A content warning has been applied to this {0}." @@ -120,11 +83,11 @@ msgstr "Доступна нова версія. Будь ласка, онові #: src/view/com/util/ViewHeader.tsx:89 #: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" -msgstr "" +msgstr "Відкрити навігацію й налаштування" #: src/view/com/home/HomeHeaderLayoutMobile.tsx:52 msgid "Access profile and other navigation links" -msgstr "" +msgstr "Відкрити профіль та іншу навігацію" #: src/view/com/modals/EditImage.tsx:299 #: src/view/screens/Settings/index.tsx:451 @@ -139,19 +102,19 @@ msgstr "Обліковий запис" #: src/view/com/profile/ProfileHeader.tsx:246 msgid "Account blocked" -msgstr "" +msgstr "Обліковий запис заблоковано" #: src/view/com/profile/ProfileHeader.tsx:213 msgid "Account muted" -msgstr "" +msgstr "Обліковий запис ігнорується" #: src/view/com/modals/ModerationDetails.tsx:86 msgid "Account Muted" -msgstr "" +msgstr "Обліковий запис ігнорується" #: src/view/com/modals/ModerationDetails.tsx:72 msgid "Account Muted by List" -msgstr "" +msgstr "Обліковий запис ігнорується списком" #: src/view/com/util/AccountDropdownBtn.tsx:41 msgid "Account options" @@ -159,15 +122,15 @@ msgstr "Параметри облікового запису" #: src/view/com/util/AccountDropdownBtn.tsx:25 msgid "Account removed from quick access" -msgstr "" +msgstr "Обліковий запис вилучено зі швидкого доступу" #: src/view/com/profile/ProfileHeader.tsx:268 msgid "Account unblocked" -msgstr "" +msgstr "Обліковий запис розблоковано" #: src/view/com/profile/ProfileHeader.tsx:226 msgid "Account unmuted" -msgstr "" +msgstr "Обліковий запис більше не ігнорується" #: src/components/dialogs/MutedWords.tsx:165 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 @@ -200,7 +163,7 @@ msgstr "Додати альтернативний текст" #: src/view/screens/AppPasswords.tsx:143 #: src/view/screens/AppPasswords.tsx:156 msgid "Add App Password" -msgstr "" +msgstr "Додати пароль застосунку" #: src/view/com/modals/report/InputIssueDetails.tsx:41 #: src/view/com/modals/report/Modal.tsx:191 @@ -221,11 +184,11 @@ msgstr "Додати попередній перегляд:" #: src/components/dialogs/MutedWords.tsx:158 msgid "Add mute word for configured settings" -msgstr "" +msgstr "Додати слово до ігнорування з обраними налаштуваннями" #: src/components/dialogs/MutedWords.tsx:87 msgid "Add muted words and tags" -msgstr "" +msgstr "Додати ігноровані слова та теги" #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" @@ -242,7 +205,7 @@ msgstr "Додати до моїх стрічок" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:139 msgid "Added" -msgstr "" +msgstr "Додано" #: src/view/com/modals/ListAddRemoveUsers.tsx:191 #: src/view/com/modals/UserAddRemoveLists.tsx:144 @@ -251,7 +214,7 @@ msgstr "Додано до списку" #: src/view/com/feeds/FeedSourceCard.tsx:127 msgid "Added to my feeds" -msgstr "" +msgstr "Додано до моїх стрічок" #: src/view/screens/PreferencesFollowingFeed.tsx:173 msgid "Adjust the number of likes a reply must have to be shown in your feed." @@ -263,7 +226,7 @@ msgstr "Вміст для дорослих" #: src/view/com/modals/ContentFilteringSettings.tsx:141 msgid "Adult content can only be enabled via the Web at <0/>." -msgstr "" +msgstr "Вміст для дорослих можна увімкнути лише у вебверсії на <0/>." #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:78 #~ msgid "Adult content can only be enabled via the Web at <0>bsky.app</0>." @@ -275,16 +238,16 @@ msgstr "Розширені" #: src/view/screens/Feeds.tsx:666 msgid "All the feeds you've saved, right in one place." -msgstr "" +msgstr "Усі збережені стрічки в одному місці." #: src/view/com/auth/login/ForgotPasswordForm.tsx:221 #: src/view/com/modals/ChangePassword.tsx:168 msgid "Already have a code?" -msgstr "" +msgstr "Вже маєте код?" #: src/view/com/auth/login/ChooseAccountForm.tsx:98 msgid "Already signed in as @{0}" -msgstr "" +msgstr "Вже увійшли як @{0}" #: src/view/com/composer/photos/Gallery.tsx:130 msgid "ALT" @@ -309,7 +272,7 @@ msgstr "Було надіслано лист на вашу попередню а #: src/view/com/profile/FollowButton.tsx:30 #: src/view/com/profile/FollowButton.tsx:40 msgid "An issue occurred, please try again." -msgstr "" +msgstr "Виникла проблема, будь ласка, спробуйте ще раз." #: src/view/com/notifications/FeedItem.tsx:237 #: src/view/com/threadgate/WhoCanReply.tsx:178 @@ -318,7 +281,7 @@ msgstr "та" #: src/screens/Onboarding/index.tsx:32 msgid "Animals" -msgstr "" +msgstr "Тварини" #: src/view/screens/LanguageSettings.tsx:95 msgid "App Language" @@ -326,23 +289,23 @@ msgstr "Мова застосунку" #: src/view/screens/AppPasswords.tsx:228 msgid "App password deleted" -msgstr "" +msgstr "Пароль застосунку видалено" #: src/view/com/modals/AddAppPasswords.tsx:134 msgid "App Password names can only contain letters, numbers, spaces, dashes, and underscores." -msgstr "" +msgstr "Назва пароля може містити лише латинські літери, цифри, пробіли, мінуси та нижні підкреслення." #: src/view/com/modals/AddAppPasswords.tsx:99 msgid "App Password names must be at least 4 characters long." -msgstr "" +msgstr "Назва пароля застосунку мусить бути хоча б 4 символи в довжину." #: src/view/screens/Settings/index.tsx:675 msgid "App password settings" -msgstr "" +msgstr "Налаштування пароля застосунків" #: src/view/screens/Settings.tsx:650 #~ msgid "App passwords" -#~ msgstr "Паролі для застосунків" +#~ msgstr "" #: src/Navigation.tsx:239 #: src/view/screens/AppPasswords.tsx:187 @@ -359,10 +322,6 @@ msgstr "Оскаржити попередження про вміст" msgid "Appeal Content Warning" msgstr "Оскаржити попередження про вміст" -#: src/view/com/modals/AppealLabel.tsx:65 -#~ msgid "Appeal Decision" -#~ msgstr "" - #: src/view/com/util/moderation/LabelInfo.tsx:52 msgid "Appeal this decision" msgstr "Оскаржити це рішення" @@ -375,10 +334,6 @@ msgstr "Оскаржити це рішення" msgid "Appearance" msgstr "Оформлення" -#: src/view/screens/Moderation.tsx:206 -#~ msgid "Apps that respect this setting, including the official Bluesky app and bsky.app website, won't show your content to logged out users." -#~ msgstr "" - #: src/view/screens/AppPasswords.tsx:224 msgid "Are you sure you want to delete the app password \"{name}\"?" msgstr "Ви дійсно хочете видалити пароль для застосунку \"{name}\"?" @@ -398,20 +353,16 @@ msgstr "Ви впевнені? Це не можна буде скасувати. #: src/view/com/composer/select-language/SuggestedLanguage.tsx:60 msgid "Are you writing in <0>{0}</0>?" -msgstr "" +msgstr "Ви пишете <0>{0}</0>?" #: src/screens/Onboarding/index.tsx:26 msgid "Art" -msgstr "" +msgstr "Мистецтво" #: src/view/com/modals/SelfLabel.tsx:123 msgid "Artistic or non-erotic nudity." msgstr "Художня або нееротична оголеність." -#: src/view/screens/Moderation.tsx:189 -#~ msgid "Ask apps to limit the visibility of my account" -#~ msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:158 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 #: src/view/com/auth/login/ForgotPasswordForm.tsx:174 @@ -429,11 +380,11 @@ msgstr "Назад" #: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" -msgstr "" +msgstr "Назад" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:136 msgid "Based on your interest in {interestsText}" -msgstr "" +msgstr "Ґрунтуючись на вашому інтересі до {interestsText}" #: src/view/screens/Settings/index.tsx:523 msgid "Basics" @@ -467,12 +418,12 @@ msgstr "Заблокувати ці облікові записи?" #: src/view/screens/ProfileList.tsx:320 msgid "Block this List" -msgstr "" +msgstr "Заблокувати список" #: src/view/com/lists/ListCard.tsx:110 #: src/view/com/util/post-embeds/QuoteEmbed.tsx:61 msgid "Blocked" -msgstr "" +msgstr "Заблоковано" #: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" @@ -512,7 +463,7 @@ msgstr "Bluesky" #: src/view/com/auth/server-input/index.tsx:150 msgid "Bluesky is an open network where you can choose your hosting provider. Custom hosting is now available in beta for developers." -msgstr "" +msgstr "Bluesky є відкритою мережею, де ви можете обрати свого хостинг-провайдера. Власний хостинг тепер доступний в бета-версії для розробників." #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:80 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:80 @@ -531,7 +482,7 @@ msgstr "Bluesky публічний." #: src/view/com/modals/Waitlist.tsx:70 #~ msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." -#~ msgstr "Bluesky використовує систему запрошень для створення здоровішої спільноти. Якщо Ви не знаєте когось хто має запрошення, ви можете записатися до черги очікування і ми скоро надішлемо вам код запрошення." +#~ msgstr "" #: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." @@ -539,11 +490,11 @@ msgstr "Bluesky не буде показувати ваш профіль і по #: src/view/com/modals/ServerInput.tsx:78 #~ msgid "Bluesky.Social" -#~ msgstr "Bluesky.Social" +#~ msgstr "" #: src/screens/Onboarding/index.tsx:33 msgid "Books" -msgstr "" +msgstr "Книги" #: src/view/screens/Settings/index.tsx:859 msgid "Build version {0} {1}" @@ -560,19 +511,19 @@ msgstr "Організація" #: src/view/com/profile/ProfileSubpageHeader.tsx:157 msgid "by —" -msgstr "" +msgstr "від —" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:100 msgid "by {0}" -msgstr "" +msgstr "від {0}" #: src/view/com/profile/ProfileSubpageHeader.tsx:161 msgid "by <0/>" -msgstr "" +msgstr "від <0/>" #: src/view/com/profile/ProfileSubpageHeader.tsx:159 msgid "by you" -msgstr "" +msgstr "створено вами" #: src/view/com/composer/photos/OpenCameraBtn.tsx:60 #: src/view/com/util/UserAvatar.tsx:224 @@ -611,20 +562,16 @@ msgstr "Скасувати" #: src/view/com/modals/DeleteAccount.tsx:234 msgctxt "action" msgid "Cancel" -msgstr "" +msgstr "Скасувати" #: src/view/com/modals/DeleteAccount.tsx:152 #: src/view/com/modals/DeleteAccount.tsx:230 msgid "Cancel account deletion" msgstr "Скасувати видалення облікового запису" -#: src/view/com/modals/AltImage.tsx:123 -#~ msgid "Cancel add image alt text" -#~ msgstr "" - #: src/view/com/modals/ChangeHandle.tsx:149 msgid "Cancel change handle" -msgstr "Скасувати зміну псевдоніму" +msgstr "Скасувати зміну псевдоніма" #: src/view/com/modals/crop-image/CropImage.web.tsx:134 msgid "Cancel image crop" @@ -632,11 +579,11 @@ msgstr "Скасувати обрізання зображення" #: src/view/com/modals/EditProfile.tsx:244 msgid "Cancel profile editing" -msgstr "Скасувати редагування профілю" +msgstr "Скасувати зміни профілю" #: src/view/com/modals/Repost.tsx:78 msgid "Cancel quote post" -msgstr "Скасувати цитування повідомлення" +msgstr "Скасувати цитування посту" #: src/view/com/modals/ListAddRemoveUsers.tsx:87 #: src/view/shell/desktop/Search.tsx:234 @@ -645,16 +592,12 @@ msgstr "Скасувати пошук" #: src/view/com/modals/Waitlist.tsx:136 #~ msgid "Cancel waitlist signup" -#~ msgstr "Скасувати запис у чергу очікування" +#~ msgstr "" #: src/view/screens/Settings/index.tsx:334 msgctxt "action" msgid "Change" -msgstr "" - -#: src/view/screens/Settings.tsx:306 -#~ msgid "Change" -#~ msgstr "Змінити" +msgstr "Змінити" #: src/view/screens/Settings/index.tsx:696 msgid "Change handle" @@ -671,19 +614,19 @@ msgstr "Змінити адресу електронної пошти" #: src/view/screens/Settings/index.tsx:732 msgid "Change password" -msgstr "" +msgstr "Змінити пароль" #: src/view/screens/Settings/index.tsx:741 msgid "Change Password" -msgstr "" +msgstr "Зміна пароля" #: src/view/com/composer/select-language/SuggestedLanguage.tsx:73 msgid "Change post language to {0}" -msgstr "" +msgstr "Змінити мову поста на {0}" #: src/view/screens/Settings/index.tsx:733 msgid "Change your Bluesky password" -msgstr "" +msgstr "Змінити ваш пароль Bluesky" #: src/view/com/modals/ChangeEmail.tsx:109 msgid "Change Your Email" @@ -692,7 +635,7 @@ msgstr "Змінити адресу електронної пошти" #: src/screens/Deactivated.tsx:72 #: src/screens/Deactivated.tsx:76 msgid "Check my status" -msgstr "" +msgstr "Перевірити мій статус" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:121 msgid "Check out some recommended feeds. Tap + to add them to your list of pinned feeds." @@ -700,11 +643,11 @@ msgstr "Подивіться на деякі з рекомендованих с #: src/view/com/auth/onboarding/RecommendedFollows.tsx:185 msgid "Check out some recommended users. Follow them to see similar users." -msgstr "Подивіться на деяких рекомендованих користувачів. Підпишіться на них щоб бачити схожих користувачів." +msgstr "Ознайомтеся з деякими рекомендованими користувачами. Слідкуйте за ними, щоб побачити дописи від подібних користувачів." #: src/view/com/modals/DeleteAccount.tsx:169 msgid "Check your inbox for an email with the confirmation code to enter below:" -msgstr "Пошукайте у вашій поштовій скриньці лист із кодом, щоб ввести нижче:" +msgstr "Перевірте свою поштову скриньку на наявність електронного листа з кодом підтвердження та введіть його нижче:" #: src/view/com/modals/Threadgate.tsx:72 msgid "Choose \"Everybody\" or \"Nobody\"" @@ -712,7 +655,7 @@ msgstr "Виберіть \"Усі\" або \"Ніхто\"" #: src/view/screens/Settings/index.tsx:697 msgid "Choose a new Bluesky username or create" -msgstr "" +msgstr "Оберіть або створіть своє ім'я користувача" #: src/view/com/auth/server-input/index.tsx:79 msgid "Choose Service" @@ -720,24 +663,20 @@ msgstr "Оберіть хостинг-провайдера" #: src/screens/Onboarding/StepFinished.tsx:135 msgid "Choose the algorithms that power your custom feeds." -msgstr "" +msgstr "Оберіть алгоритми, що наповнюватимуть ваші стрічки." #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:83 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:83 msgid "Choose the algorithms that power your experience with custom feeds." msgstr "Автори стрічок можуть обирати будь-які алгоритми для формування стрічки саме для вас." -#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:65 -#~ msgid "Choose your" -#~ msgstr "" - #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 #~ msgid "Choose your algorithmic feeds" #~ msgstr "" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:103 msgid "Choose your main feeds" -msgstr "" +msgstr "Виберіть ваші основні стрічки" #: src/view/com/auth/create/Step1.tsx:196 msgid "Choose your password" @@ -768,29 +707,29 @@ msgstr "Очистити пошуковий запит" #: src/view/screens/Support.tsx:40 msgid "click here" -msgstr "" +msgstr "натисніть тут" #: src/components/TagMenu/index.web.tsx:138 msgid "Click here to open tag menu for {tag}" -msgstr "" +msgstr "Натисніть тут, щоб відкрити меню тегів для {tag}" #: src/components/RichText.tsx:191 msgid "Click here to open tag menu for #{tag}" -msgstr "" +msgstr "Натисніть тут, щоб відкрити меню тегів для #{tag}" #: src/screens/Onboarding/index.tsx:35 msgid "Climate" -msgstr "" +msgstr "Клімат" #: src/view/com/modals/ChangePassword.tsx:265 #: src/view/com/modals/ChangePassword.tsx:268 msgid "Close" -msgstr "" +msgstr "Закрити" #: src/components/Dialog/index.web.tsx:84 #: src/components/Dialog/index.web.tsx:198 msgid "Close active dialog" -msgstr "" +msgstr "Закрити діалогове вікно" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:38 msgid "Close alert" @@ -814,35 +753,35 @@ msgstr "Закрити панель навігації" #: src/components/TagMenu/index.tsx:262 msgid "Close this dialog" -msgstr "" +msgstr "Закрити діалогове вікно" #: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" -msgstr "" +msgstr "Закриває нижню панель навігації" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:39 msgid "Closes password update alert" -msgstr "" +msgstr "Закриває сповіщення про оновлення пароля" #: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" -msgstr "" +msgstr "Закриває редактор постів і видаляє чернетку" #: src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx:27 msgid "Closes viewer for header image" -msgstr "" +msgstr "Закриває перегляд зображення" #: src/view/com/notifications/FeedItem.tsx:318 msgid "Collapses list of users for a given notification" -msgstr "" +msgstr "Згортає список користувачів для даного сповіщення" #: src/screens/Onboarding/index.tsx:41 msgid "Comedy" -msgstr "" +msgstr "Комедія" #: src/screens/Onboarding/index.tsx:27 msgid "Comics" -msgstr "" +msgstr "Комікси" #: src/Navigation.tsx:229 #: src/view/screens/CommunityGuidelines.tsx:32 @@ -851,15 +790,15 @@ msgstr "Правила спільноти" #: src/screens/Onboarding/StepFinished.tsx:148 msgid "Complete onboarding and start using your account" -msgstr "" +msgstr "Завершіть ознайомлення та розпочніть користуватися вашим обліковим записом" #: src/view/com/auth/create/Step3.tsx:73 msgid "Complete the challenge" -msgstr "" +msgstr "Виконайте завдання" #: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" -msgstr "" +msgstr "Створюйте пости до {MAX_GRAPHEME_LENGTH} символів у довжину" #: src/view/com/composer/Prompt.tsx:24 msgid "Compose reply" @@ -867,7 +806,7 @@ msgstr "Відповісти" #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:67 msgid "Configure content filtering setting for category: {0}" -msgstr "" +msgstr "Налаштувати фільтрування вмісту для категорій: {0}" #: src/components/Prompt.tsx:124 #: src/view/com/modals/AppealLabel.tsx:98 @@ -883,7 +822,7 @@ msgstr "Підтвердити" #: src/view/com/modals/Confirm.tsx:78 msgctxt "action" msgid "Confirm" -msgstr "" +msgstr "Підтвердити" #: src/view/com/modals/ChangeEmail.tsx:193 #: src/view/com/modals/ChangeEmail.tsx:195 @@ -892,7 +831,7 @@ msgstr "Підтвердити" #: src/view/com/modals/lang-settings/ConfirmLanguagesButton.tsx:34 msgid "Confirm content language settings" -msgstr "Підтвердити перелік мов" +msgstr "Підтвердити налаштування мови вмісту" #: src/view/com/modals/DeleteAccount.tsx:220 msgid "Confirm delete account" @@ -900,7 +839,7 @@ msgstr "Підтвердити видалення облікового запи #: src/view/com/modals/ContentFilteringSettings.tsx:156 msgid "Confirm your age to enable adult content." -msgstr "" +msgstr "Підтвердьте свій вік, щоб дозволити вміст для дорослих." #: src/view/com/modals/ChangeEmail.tsx:157 #: src/view/com/modals/DeleteAccount.tsx:182 @@ -919,7 +858,7 @@ msgstr "З’єднання..." #: src/view/com/auth/create/CreateAccount.tsx:213 msgid "Contact support" -msgstr "" +msgstr "Служба підтримки" #: src/view/screens/Moderation.tsx:83 msgid "Content filtering" @@ -936,7 +875,7 @@ msgstr "Мови" #: src/view/com/modals/ModerationDetails.tsx:65 msgid "Content Not Available" -msgstr "" +msgstr "Вміст недоступний" #: src/view/com/modals/ModerationDetails.tsx:33 #: src/view/com/util/moderation/ScreenHider.tsx:78 @@ -955,26 +894,26 @@ msgstr "Попередження про вміст" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:148 #: src/view/com/auth/onboarding/RecommendedFollows.tsx:209 msgid "Continue" -msgstr "Продовжити" +msgstr "Далі" #: src/screens/Onboarding/StepFollowingFeed.tsx:150 #: src/screens/Onboarding/StepInterests/index.tsx:245 #: src/screens/Onboarding/StepModeration/index.tsx:115 #: src/screens/Onboarding/StepTopicalFeeds.tsx:111 msgid "Continue to next step" -msgstr "" +msgstr "Перейти до наступного кроку" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:167 msgid "Continue to the next step" -msgstr "" +msgstr "Перейти до наступного кроку" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:191 msgid "Continue to the next step without following any accounts" -msgstr "" +msgstr "Перейдіть до наступного кроку, ні на кого не підписуючись" #: src/screens/Onboarding/index.tsx:44 msgid "Cooking" -msgstr "" +msgstr "Кухарство" #: src/view/com/modals/AddAppPasswords.tsx:195 #: src/view/com/modals/InviteCodes.tsx:182 @@ -983,17 +922,17 @@ msgstr "Скопійовано" #: src/view/screens/Settings/index.tsx:241 msgid "Copied build version to clipboard" -msgstr "" +msgstr "Версію збірки скопійовано до буфера обміну" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 #: src/view/com/util/forms/PostDropdownBtn.tsx:161 msgid "Copied to clipboard" -msgstr "" +msgstr "Скопійовано" #: src/view/com/modals/AddAppPasswords.tsx:189 msgid "Copies app password" -msgstr "" +msgstr "Копіює пароль застосунку" #: src/view/com/modals/AddAppPasswords.tsx:188 msgid "Copy" @@ -1001,21 +940,21 @@ msgstr "Скопіювати" #: src/view/screens/ProfileList.tsx:418 msgid "Copy link to list" -msgstr "Скопіювати посилання" +msgstr "Копіювати посилання на список" #: src/view/com/util/forms/PostDropdownBtn.tsx:231 #: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "Copy link to post" -msgstr "Скопіювати посилання" +msgstr "Копіювати посилання на пост" #: src/view/com/profile/ProfileHeader.tsx:295 msgid "Copy link to profile" -msgstr "Скопіювати посилання" +msgstr "Копіювати посилання на профіль" #: src/view/com/util/forms/PostDropdownBtn.tsx:223 #: src/view/com/util/forms/PostDropdownBtn.tsx:225 msgid "Copy post text" -msgstr "Скопіювати текст" +msgstr "Копіювати текст повідомлення" #: src/Navigation.tsx:234 #: src/view/screens/CopyrightPolicy.tsx:29 @@ -1042,7 +981,7 @@ msgstr "Створити новий обліковий запис" #: src/view/screens/Settings/index.tsx:384 msgid "Create a new Bluesky account" -msgstr "" +msgstr "Створити новий обліковий запис Bluesky" #: src/view/com/auth/create/CreateAccount.tsx:133 msgid "Create Account" @@ -1050,7 +989,7 @@ msgstr "Створити обліковий запис" #: src/view/com/modals/AddAppPasswords.tsx:226 msgid "Create App Password" -msgstr "" +msgstr "Створити пароль застосунку" #: src/view/com/auth/HomeLoggedOutCTA.tsx:54 #: src/view/com/auth/SplashScreen.tsx:68 @@ -1063,24 +1002,24 @@ msgstr "Створено: {0}" #: src/view/screens/ProfileFeed.tsx:616 msgid "Created by <0/>" -msgstr "" +msgstr "Створено <0/>" #: src/view/screens/ProfileFeed.tsx:614 msgid "Created by you" -msgstr "" +msgstr "Створено вами" #: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" -msgstr "" +msgstr "Створює картку з мініатюрою. Посилання картки: {url}" #: src/screens/Onboarding/index.tsx:29 msgid "Culture" -msgstr "" +msgstr "Культура" #: src/view/com/auth/server-input/index.tsx:95 #: src/view/com/auth/server-input/index.tsx:96 msgid "Custom" -msgstr "" +msgstr "Користувацький" #: src/view/com/modals/ChangeHandle.tsx:389 msgid "Custom domain" @@ -1089,7 +1028,7 @@ msgstr "Власний домен" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:106 #: src/view/screens/Feeds.tsx:692 msgid "Custom feeds built by the community bring you new experiences and help you find the content you love." -msgstr "" +msgstr "Кастомні стрічки, створені спільнотою, подарують вам нові враження та допоможуть знайти контент, який ви любите." #: src/view/screens/PreferencesExternalEmbeds.tsx:55 msgid "Customize media from external sites." @@ -1097,28 +1036,24 @@ msgstr "Налаштування медіа зі сторонніх вебсай #: src/view/screens/Settings.tsx:687 #~ msgid "Danger Zone" -#~ msgstr "Небезпечна зона" +#~ msgstr "" #: src/view/screens/Settings/index.tsx:485 #: src/view/screens/Settings/index.tsx:511 msgid "Dark" -msgstr "" +msgstr "Темна" #: src/view/screens/Debug.tsx:63 msgid "Dark mode" -msgstr "" +msgstr "Темний режим" #: src/view/screens/Settings/index.tsx:498 msgid "Dark Theme" -msgstr "" - -#: src/Navigation.tsx:204 -#~ msgid "Debug" -#~ msgstr "" +msgstr "Темна тема" #: src/view/screens/Debug.tsx:83 msgid "Debug panel" -msgstr "" +msgstr "Панель налагодження" #: src/view/screens/Settings/index.tsx:772 msgid "Delete account" @@ -1144,11 +1079,11 @@ msgstr "Видалити мій обліковий запис" #: src/view/screens/Settings.tsx:706 #~ msgid "Delete my account…" -#~ msgstr "Видалити мій обліковий запис…" +#~ msgstr "" #: src/view/screens/Settings/index.tsx:784 msgid "Delete My Account…" -msgstr "" +msgstr "Видалити мій обліковий запис..." #: src/view/com/util/forms/PostDropdownBtn.tsx:317 #: src/view/com/util/forms/PostDropdownBtn.tsx:326 @@ -1161,7 +1096,7 @@ msgstr "Видалити цей пост?" #: src/view/com/util/post-embeds/QuoteEmbed.tsx:70 msgid "Deleted" -msgstr "" +msgstr "Видалено" #: src/view/com/post-thread/PostThread.tsx:316 msgid "Deleted post." @@ -1174,13 +1109,9 @@ msgstr "Видалений пост." msgid "Description" msgstr "Опис" -#: src/view/com/auth/create/Step1.tsx:96 -#~ msgid "Dev Server" -#~ msgstr "" - #: src/view/screens/Settings.tsx:760 #~ msgid "Developer Tools" -#~ msgstr "Інструменти розробника" +#~ msgstr "" #: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" @@ -1188,7 +1119,7 @@ msgstr "Порожній пост. Ви хотіли щось написати?" #: src/view/screens/Settings/index.tsx:504 msgid "Dim" -msgstr "" +msgstr "Тьмяний" #: src/view/com/composer/Composer.tsx:151 msgid "Discard" @@ -1205,15 +1136,15 @@ msgstr "Попросити застосунки не показувати мій #: src/view/com/posts/FollowingEmptyState.tsx:74 #: src/view/com/posts/FollowingEndOfFeed.tsx:75 msgid "Discover new custom feeds" -msgstr "" +msgstr "Відкрийте для себе нові стрічки" #: src/view/screens/Feeds.tsx:473 #~ msgid "Discover new feeds" -#~ msgstr "Відкрийте для себе нові стрічки" +#~ msgstr "" #: src/view/screens/Feeds.tsx:689 msgid "Discover New Feeds" -msgstr "" +msgstr "Відкрийте для себе нові стрічки" #: src/view/com/modals/EditProfile.tsx:192 msgid "Display name" @@ -1242,7 +1173,7 @@ msgstr "Домен перевірено!" #: src/view/screens/PreferencesThreads.tsx:162 msgctxt "action" msgid "Done" -msgstr "" +msgstr "Готово" #: src/view/com/auth/server-input/index.tsx:165 #: src/view/com/auth/server-input/index.tsx:166 @@ -1266,48 +1197,48 @@ msgstr "Готово{extraText}" #: src/view/com/auth/login/ChooseAccountForm.tsx:45 msgid "Double tap to sign in" -msgstr "" +msgstr "Двічі натисніть, щоб увійти" #: src/view/screens/Settings/index.tsx:755 msgid "Download Bluesky account data (repository)" -msgstr "" +msgstr "Завантажити дані облікового запису в Bluesky (репозиторій)" #: src/view/screens/Settings/ExportCarDialog.tsx:59 #: src/view/screens/Settings/ExportCarDialog.tsx:63 msgid "Download CAR file" -msgstr "" +msgstr "Завантажити CAR файл" #: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" -msgstr "" +msgstr "Перетягніть і відпустіть, щоб додати зображення" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:111 msgid "Due to Apple policies, adult content can only be enabled on the web after completing sign up." -msgstr "" +msgstr "Через політику компанії Apple, перегляд вмісту для дорослих можна ввімкнути лише в інтернеті після реєстрації." #: src/view/com/modals/EditProfile.tsx:185 msgid "e.g. Alice Roberts" -msgstr "" +msgstr "напр. Тарас Шевченко" #: src/view/com/modals/EditProfile.tsx:203 msgid "e.g. Artist, dog-lover, and avid reader." -msgstr "" +msgstr "напр. Художниця, собачниця та завзята читачка." #: src/view/com/modals/CreateOrEditList.tsx:283 msgid "e.g. Great Posters" -msgstr "" +msgstr "напр. Чудові писарі" #: src/view/com/modals/CreateOrEditList.tsx:284 msgid "e.g. Spammers" -msgstr "" +msgstr "напр. Спамери" #: src/view/com/modals/CreateOrEditList.tsx:312 msgid "e.g. The posters who never miss." -msgstr "" +msgstr "напр. Писарі, що нічого не пропускають." #: src/view/com/modals/CreateOrEditList.tsx:313 msgid "e.g. Users that repeatedly reply with ads." -msgstr "" +msgstr "напр. Користувачі, що неодноразово відповідали рекламою." #: src/view/com/modals/InviteCodes.tsx:96 msgid "Each code works once. You'll receive more invite codes periodically." @@ -1316,7 +1247,7 @@ msgstr "Кожен код запрошення працює лише один р #: src/view/com/lists/ListMembers.tsx:149 msgctxt "action" msgid "Edit" -msgstr "" +msgstr "Редагувати" #: src/view/com/composer/photos/Gallery.tsx:144 #: src/view/com/modals/EditImage.tsx:207 @@ -1329,7 +1260,7 @@ msgstr "Редагувати опис списку" #: src/view/com/modals/CreateOrEditList.tsx:250 msgid "Edit Moderation List" -msgstr "" +msgstr "Редагування списку" #: src/Navigation.tsx:244 #: src/view/screens/Feeds.tsx:434 @@ -1356,19 +1287,19 @@ msgstr "Редагувати збережені стрічки" #: src/view/com/modals/CreateOrEditList.tsx:245 msgid "Edit User List" -msgstr "" +msgstr "Редагувати список користувачів" #: src/view/com/modals/EditProfile.tsx:193 msgid "Edit your display name" -msgstr "" +msgstr "Редагувати ваш псевдонім для показу" #: src/view/com/modals/EditProfile.tsx:211 msgid "Edit your profile description" -msgstr "" +msgstr "Редагувати опис вашого профілю" #: src/screens/Onboarding/index.tsx:34 msgid "Education" -msgstr "" +msgstr "Освіта" #: src/view/com/auth/create/Step1.tsx:176 #: src/view/com/auth/login/ForgotPasswordForm.tsx:156 @@ -1384,7 +1315,7 @@ msgstr "Адреса електронної пошти" #: src/view/com/modals/ChangeEmail.tsx:56 #: src/view/com/modals/ChangeEmail.tsx:88 msgid "Email updated" -msgstr "" +msgstr "Електронну адресу змінено" #: src/view/com/modals/ChangeEmail.tsx:111 msgid "Email Updated" @@ -1392,7 +1323,7 @@ msgstr "Ел. адресу оновлено" #: src/view/com/modals/VerifyEmail.tsx:78 msgid "Email verified" -msgstr "" +msgstr "Електронну адресу перевірено" #: src/view/screens/Settings/index.tsx:312 msgid "Email:" @@ -1404,12 +1335,12 @@ msgstr "Увімкнути лише {0}" #: src/view/com/modals/ContentFilteringSettings.tsx:167 msgid "Enable Adult Content" -msgstr "" +msgstr "Дозволити вміст для дорослих" #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:76 #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:77 msgid "Enable adult content in your feeds" -msgstr "" +msgstr "Увімкнути вміст для дорослих у ваших стрічках" #: src/view/com/modals/EmbedConsent.tsx:97 msgid "Enable External Media" @@ -1417,11 +1348,11 @@ msgstr "Увімкнути зовнішні медіа" #: src/view/screens/PreferencesExternalEmbeds.tsx:75 msgid "Enable media players for" -msgstr "" +msgstr "Увімкнути медіапрогравачі для" #: src/view/screens/PreferencesFollowingFeed.tsx:147 msgid "Enable this setting to only see replies between people you follow." -msgstr "Увімкніть цей параметр, щоб бачити відповіді тільки між людьми, на яких ви підписані." +msgstr "Увімкніть цей параметр, щоб бачити відповіді тільки від людей, на яких ви підписані." #: src/view/screens/Profile.tsx:455 msgid "End of feed" @@ -1429,24 +1360,20 @@ msgstr "Кінець стрічки" #: src/view/com/modals/AddAppPasswords.tsx:166 msgid "Enter a name for this App Password" -msgstr "" +msgstr "Введіть ім'я для цього пароля застосунку" #: src/components/dialogs/MutedWords.tsx:100 #: src/components/dialogs/MutedWords.tsx:101 msgid "Enter a word or tag" -msgstr "" +msgstr "Введіть слово або тег" #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" -msgstr "" - -#: src/view/com/auth/create/Step1.tsx:71 -#~ msgid "Enter the address of your provider:" -#~ msgstr "Введіть адресу вашого хостинг-провайдера:" +msgstr "Введіть код підтвердження" #: src/view/com/modals/ChangePassword.tsx:151 msgid "Enter the code you received to change your password." -msgstr "" +msgstr "Введіть код, який ви отримали, щоб змінити пароль." #: src/view/com/modals/ChangeHandle.tsx:371 msgid "Enter the domain you want to use" @@ -1459,7 +1386,7 @@ msgstr "Введіть адресу електронної пошти, яку в #: src/view/com/auth/create/Step1.tsx:228 #: src/view/com/modals/BirthDateSettings.tsx:74 msgid "Enter your birth date" -msgstr "" +msgstr "Введіть вашу дату народження" #: src/view/com/modals/Waitlist.tsx:78 #~ msgid "Enter your email" @@ -1471,7 +1398,7 @@ msgstr "Введіть адресу електронної пошти" #: src/view/com/modals/ChangeEmail.tsx:41 msgid "Enter your new email above" -msgstr "" +msgstr "Введіть вашу нову електронну пошту вище" #: src/view/com/modals/ChangeEmail.tsx:117 msgid "Enter your new email address below." @@ -1487,7 +1414,7 @@ msgstr "Введіть псевдонім та пароль" #: src/view/com/auth/create/Step3.tsx:67 msgid "Error receiving captcha response." -msgstr "" +msgstr "Помилка отримання відповіді Captcha." #: src/view/screens/Search/Search.tsx:110 msgid "Error:" @@ -1499,16 +1426,16 @@ msgstr "Усі" #: src/view/com/modals/ChangeHandle.tsx:150 msgid "Exits handle change process" -msgstr "" +msgstr "Вихід з процесу зміни псевдоніму користувача" #: src/view/com/lightbox/Lightbox.web.tsx:120 msgid "Exits image view" -msgstr "" +msgstr "Вийти з режиму перегляду" #: src/view/com/modals/ListAddRemoveUsers.tsx:88 #: src/view/shell/desktop/Search.tsx:235 msgid "Exits inputting search query" -msgstr "" +msgstr "Вихід із пошуку" #: src/view/com/modals/Waitlist.tsx:138 #~ msgid "Exits signing up for waitlist with {email}" @@ -1516,21 +1443,21 @@ msgstr "" #: src/view/com/lightbox/Lightbox.web.tsx:163 msgid "Expand alt text" -msgstr "Розгорнути альтернативний текст" +msgstr "Розгорнути опис" #: src/view/com/composer/ComposerReplyTo.tsx:81 #: src/view/com/composer/ComposerReplyTo.tsx:84 msgid "Expand or collapse the full post you are replying to" -msgstr "" +msgstr "Розгорнути або згорнути весь пост, на який ви відповідаєте" #: src/view/screens/Settings/index.tsx:753 msgid "Export my data" -msgstr "" +msgstr "Експорт моїх даних" #: src/view/screens/Settings/ExportCarDialog.tsx:44 #: src/view/screens/Settings/index.tsx:764 msgid "Export My Data" -msgstr "" +msgstr "Експорт моїх даних" #: src/view/com/modals/EmbedConsent.tsx:64 msgid "External Media" @@ -1549,20 +1476,20 @@ msgstr "Налаштування зовнішніх медіа" #: src/view/screens/Settings/index.tsx:648 msgid "External media settings" -msgstr "" +msgstr "Налаштування зовнішніх медіа" #: src/view/com/modals/AddAppPasswords.tsx:115 #: src/view/com/modals/AddAppPasswords.tsx:119 msgid "Failed to create app password." -msgstr "" +msgstr "Не вдалося створити пароль застосунку." #: src/view/com/modals/CreateOrEditList.tsx:206 msgid "Failed to create the list. Check your internet connection and try again." -msgstr "" +msgstr "Не вдалося створити список. Перевірте інтернет-з'єднання і спробуйте ще раз." #: src/view/com/util/forms/PostDropdownBtn.tsx:128 msgid "Failed to delete post, please try again" -msgstr "" +msgstr "Не вдалося видалити пост, спробуйте ще раз" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:109 #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:141 @@ -1571,11 +1498,11 @@ msgstr "Не вдалося завантажити рекомендації ст #: src/Navigation.tsx:194 msgid "Feed" -msgstr "" +msgstr "Стрічка" #: src/view/com/feeds/FeedSourceCard.tsx:231 msgid "Feed by {0}" -msgstr "" +msgstr "Стрічка від {0}" #: src/view/screens/Feeds.tsx:605 msgid "Feed offline" @@ -1583,12 +1510,12 @@ msgstr "Стрічка не працює" #: src/view/com/feeds/FeedPage.tsx:143 #~ msgid "Feed Preferences" -#~ msgstr "Налаштування стрічки" +#~ msgstr "" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 msgid "Feedback" -msgstr "Надіслати відгук" +msgstr "Зворотний зв'язок" #: src/Navigation.tsx:452 #: src/view/screens/Feeds.tsx:419 @@ -1615,21 +1542,21 @@ msgstr "Стрічки створюються користувачами для #: src/view/screens/SavedFeeds.tsx:156 msgid "Feeds are custom algorithms that users build with a little coding expertise. <0/> for more information." -msgstr "Стрічки - це алгоритми, створені користувачами з деяким досвідом програмування. <0/> для додаткової інформації." +msgstr "Стрічки – це алгоритми, створені користувачами з деяким досвідом програмування. <0/> для додаткової інформації." #: src/screens/Onboarding/StepTopicalFeeds.tsx:76 msgid "Feeds can be topical as well!" -msgstr "" +msgstr "Стрічки також можуть бути тематичними!" #: src/screens/Onboarding/StepFinished.tsx:151 msgid "Finalizing" -msgstr "" +msgstr "Завершення" #: src/view/com/posts/CustomFeedEmptyState.tsx:47 #: src/view/com/posts/FollowingEmptyState.tsx:57 #: src/view/com/posts/FollowingEndOfFeed.tsx:58 msgid "Find accounts to follow" -msgstr "" +msgstr "Знайдіть облікові записи для стеження" #: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" @@ -1637,19 +1564,19 @@ msgstr "Знайти користувачів у Bluesky" #: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" -msgstr "Знайти користувачів за допомогою поля пошуку справа вгорі" +msgstr "Знайдіть користувачів за допомогою інструменту пошуку праворуч" #: src/view/com/auth/onboarding/RecommendedFollowsItem.tsx:150 msgid "Finding similar accounts..." -msgstr "Пошук схожих користувачів..." +msgstr "Пошук подібних облікових записів..." #: src/view/screens/PreferencesFollowingFeed.tsx:111 msgid "Fine-tune the content you see on your Following feed." -msgstr "" +msgstr "Оберіть, що ви хочете бачити у своїй стрічці підписок." #: src/view/screens/PreferencesHomeFeed.tsx:111 #~ msgid "Fine-tune the content you see on your home screen." -#~ msgstr "Оберіть, що ви хочете бачити у своїй домашній стрічці." +#~ msgstr "" #: src/view/screens/PreferencesThreads.tsx:60 msgid "Fine-tune the discussion threads." @@ -1657,20 +1584,20 @@ msgstr "Налаштуйте відображення обговорень." #: src/screens/Onboarding/index.tsx:38 msgid "Fitness" -msgstr "" +msgstr "Фітнес" #: src/screens/Onboarding/StepFinished.tsx:131 msgid "Flexible" -msgstr "" +msgstr "Гнучкий" #: src/view/com/modals/EditImage.tsx:115 msgid "Flip horizontal" -msgstr "" +msgstr "Віддзеркалити горизонтально" #: src/view/com/modals/EditImage.tsx:120 #: src/view/com/modals/EditImage.tsx:287 msgid "Flip vertically" -msgstr "" +msgstr "Віддзеркалити вертикально" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:181 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:136 @@ -1681,29 +1608,21 @@ msgstr "Підписатися" #: src/view/com/profile/FollowButton.tsx:64 msgctxt "action" msgid "Follow" -msgstr "" +msgstr "Підписатись" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:58 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:122 #: src/view/com/profile/ProfileHeader.tsx:504 msgid "Follow {0}" -msgstr "" +msgstr "Підписатися на {0}" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:179 msgid "Follow All" -msgstr "" +msgstr "Підписатися на всіх" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:174 msgid "Follow selected accounts and continue to the next step" -msgstr "" - -#: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:174 -#~ msgid "Follow selected accounts and continue to then next step" -#~ msgstr "" - -#: src/view/com/auth/onboarding/RecommendedFollows.tsx:42 -#~ msgid "Follow some" -#~ msgstr "" +msgstr "Підпишіться на обрані облікові записи і переходьте до наступного кроку" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:64 msgid "Follow some users to get started. We can recommend you more users based on who you find interesting." @@ -1711,7 +1630,7 @@ msgstr "Підпишіться на кількох користувачів що #: src/view/com/profile/ProfileCard.tsx:194 msgid "Followed by {0}" -msgstr "" +msgstr "Підписані {0}" #: src/view/com/modals/Threadgate.tsx:98 msgid "Followed users" @@ -1723,16 +1642,12 @@ msgstr "Тільки ваші підписки" #: src/view/com/notifications/FeedItem.tsx:166 msgid "followed you" -msgstr "" +msgstr "підписка на вас" #: src/view/screens/ProfileFollowers.tsx:25 msgid "Followers" msgstr "Підписники" -#: src/view/com/profile/ProfileHeader.tsx:624 -#~ msgid "following" -#~ msgstr "підписок" - #: src/view/com/post-thread/PostThreadFollowBtn.tsx:136 #: src/view/com/profile/ProfileHeader.tsx:495 #: src/view/screens/ProfileFollows.tsx:25 @@ -1741,7 +1656,7 @@ msgstr "Підписані" #: src/view/com/profile/ProfileHeader.tsx:149 msgid "Following {0}" -msgstr "" +msgstr "Підписання на \"{0}\"" #: src/Navigation.tsx:250 #: src/view/com/home/HomeHeaderLayout.web.tsx:50 @@ -1749,7 +1664,7 @@ msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 msgid "Following Feed Preferences" -msgstr "" +msgstr "Налаштування стрічки підписок" #: src/view/com/profile/ProfileHeader.tsx:546 msgid "Follows you" @@ -1757,11 +1672,11 @@ msgstr "Підписаний(-на) на вас" #: src/view/com/profile/ProfileCard.tsx:141 msgid "Follows You" -msgstr "" +msgstr "Підписаний(-на) на вас" #: src/screens/Onboarding/index.tsx:43 msgid "Food" -msgstr "" +msgstr "Їжа" #: src/view/com/modals/DeleteAccount.tsx:111 msgid "For security reasons, we'll need to send a confirmation code to your email address." @@ -1787,12 +1702,12 @@ msgstr "Забули пароль" #: src/screens/Hashtag.tsx:108 #: src/screens/Hashtag.tsx:148 msgid "From @{sanitizedAuthor}" -msgstr "" +msgstr "Від @{sanitizedAuthor}" #: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" -msgstr "" +msgstr "Зі стрічки \"<0/>\"" #: src/view/com/composer/photos/SelectPhotoBtn.tsx:43 msgid "Gallery" @@ -1820,12 +1735,12 @@ msgstr "Назад" #: src/screens/Onboarding/Layout.tsx:104 #: src/screens/Onboarding/Layout.tsx:193 msgid "Go back to previous step" -msgstr "" +msgstr "Повернутися до попереднього кроку" #: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" -msgstr "" +msgstr "Перейти до @{queryMaybeHandle}" #: src/view/com/auth/login/ForgotPasswordForm.tsx:189 #: src/view/com/auth/login/ForgotPasswordForm.tsx:218 @@ -1841,7 +1756,7 @@ msgstr "Псевдонім" #: src/Navigation.tsx:270 msgid "Hashtag" -msgstr "" +msgstr "Хештег" #: src/components/RichText.tsx:188 #~ msgid "Hashtag: {tag}" @@ -1849,11 +1764,11 @@ msgstr "" #: src/components/RichText.tsx:190 msgid "Hashtag: #{tag}" -msgstr "" +msgstr "Хештег: #{tag}" #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" -msgstr "" +msgstr "Виникли проблеми?" #: src/view/shell/desktop/RightNav.tsx:90 #: src/view/shell/Drawer.tsx:321 @@ -1862,19 +1777,15 @@ msgstr "Довідка" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:132 msgid "Here are some accounts for you to follow" -msgstr "" - -#: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:132 -#~ msgid "Here are some accounts for your to follow" -#~ msgstr "" +msgstr "Ось деякі облікові записи, на які ви підписані" #: src/screens/Onboarding/StepTopicalFeeds.tsx:85 msgid "Here are some popular topical feeds. You can choose to follow as many as you like." -msgstr "" +msgstr "Ось декілька популярних тематичних стрічок. Ви можете підписатися на скільки забажаєте з них." #: src/screens/Onboarding/StepTopicalFeeds.tsx:80 msgid "Here are some topical feeds based on your interests: {interestsText}. You can choose to follow as many as you like." -msgstr "" +msgstr "Ось декілька тематичних стрічок на основі ваших інтересів: {interestsText}. Ви можете підписатися на скільки забажаєте з них." #: src/view/com/modals/AddAppPasswords.tsx:153 msgid "Here is your app password." @@ -1891,33 +1802,29 @@ msgstr "Приховати" #: src/view/com/notifications/FeedItem.tsx:326 msgctxt "action" msgid "Hide" -msgstr "" +msgstr "Сховати" #: src/view/com/util/forms/PostDropdownBtn.tsx:276 #: src/view/com/util/forms/PostDropdownBtn.tsx:287 msgid "Hide post" -msgstr "Приховати пост" +msgstr "Сховати пост" #: src/view/com/util/moderation/ContentHider.tsx:67 #: src/view/com/util/moderation/PostHider.tsx:61 msgid "Hide the content" -msgstr "" +msgstr "Приховати вміст" #: src/view/com/util/forms/PostDropdownBtn.tsx:280 msgid "Hide this post?" -msgstr "Приховати цей пост?" +msgstr "Сховати цей пост?" #: src/view/com/notifications/FeedItem.tsx:316 msgid "Hide user list" -msgstr "Приховати список користувачів" +msgstr "Сховати список користувачів" #: src/view/com/profile/ProfileHeader.tsx:487 msgid "Hides posts from {0} in your feed" -msgstr "" - -#: src/view/com/posts/FeedErrorMessage.tsx:102 -#~ msgid "Hmm, some kind of issue occured when contacting the feed server. Please let the feed owner know about this issue." -#~ msgstr "" +msgstr "Приховує пости з {0} у вашій стрічці" #: src/view/com/posts/FeedErrorMessage.tsx:111 msgid "Hmm, some kind of issue occurred when contacting the feed server. Please let the feed owner know about this issue." @@ -1939,10 +1846,6 @@ msgstr "Хм, сервер стрічки надіслав нам незрозу msgid "Hmm, we're having trouble finding this feed. It may have been deleted." msgstr "Хм, ми не можемо знайти цю стрічку. Можливо вона була видалена." -#: src/view/com/posts/FeedErrorMessage.tsx:87 -#~ msgid "Hmmm, we're having trouble finding this feed. It may have been deleted." -#~ msgstr "" - #: src/Navigation.tsx:442 #: src/view/shell/bottom-bar/BottomBar.tsx:137 #: src/view/shell/desktop/LeftNav.tsx:306 @@ -1956,21 +1859,16 @@ msgstr "Головна" #: src/view/screens/PreferencesHomeFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 #~ msgid "Home Feed Preferences" -#~ msgstr "Налаштування домашньої стрічки" +#~ msgstr "" #: src/view/com/auth/create/Step1.tsx:75 #: src/view/com/auth/login/ForgotPasswordForm.tsx:120 msgid "Hosting provider" msgstr "Хостинг-провайдер" -#: src/view/com/auth/create/Step1.tsx:76 -#: src/view/com/auth/create/Step1.tsx:81 -#~ msgid "Hosting provider address" -#~ msgstr "Адреса хостинг-провайдера" - #: src/view/com/modals/InAppBrowserConsent.tsx:44 msgid "How should we open this link?" -msgstr "" +msgstr "Як ви хочете відкрити це посилання?" #: src/view/com/modals/VerifyEmail.tsx:214 msgid "I have a code" @@ -1978,7 +1876,7 @@ msgstr "У мене є код" #: src/view/com/modals/VerifyEmail.tsx:216 msgid "I have a confirmation code" -msgstr "" +msgstr "У мене є код підтвердження" #: src/view/com/modals/ChangeHandle.tsx:283 msgid "I have my own domain" @@ -1986,7 +1884,7 @@ msgstr "Я маю власний домен" #: src/view/com/lightbox/Lightbox.web.tsx:165 msgid "If alt text is long, toggles alt text expanded state" -msgstr "" +msgstr "Розкриває альтернативний текст, якщо текст задовгий" #: src/view/com/modals/SelfLabel.tsx:127 msgid "If none are selected, suitable for all ages." @@ -1994,61 +1892,48 @@ msgstr "Якщо не вибрано жодного варіанту - підх #: src/view/com/modals/ChangePassword.tsx:146 msgid "If you want to change your password, we will send you a code to verify that this is your account." -msgstr "" +msgstr "Якщо ви хочете змінити пароль, ми надішлемо вам код, щоб переконатися, що це ваш обліковий запис." #: src/view/com/util/images/Gallery.tsx:38 msgid "Image" -msgstr "" +msgstr "Зображення" #: src/view/com/modals/AltImage.tsx:120 msgid "Image alt text" -msgstr "Альтернативний текст" +msgstr "Опис зображення" #: src/view/com/util/UserAvatar.tsx:311 #: src/view/com/util/UserBanner.tsx:118 msgid "Image options" msgstr "Редагування зображення" -#: src/view/com/search/Suggestions.tsx:104 -#: src/view/com/search/Suggestions.tsx:115 -#~ msgid "In Your Network" -#~ msgstr "" - #: src/view/com/auth/login/SetNewPasswordForm.tsx:138 msgid "Input code sent to your email for password reset" -msgstr "" +msgstr "Введіть код, надісланий на вашу електронну пошту для скидання пароля" #: src/view/com/modals/DeleteAccount.tsx:184 msgid "Input confirmation code for account deletion" -msgstr "" +msgstr "Введіть код підтвердження для видалення облікового запису" #: src/view/com/auth/create/Step1.tsx:177 msgid "Input email for Bluesky account" -msgstr "" - -#: src/view/com/auth/create/Step2.tsx:109 -#~ msgid "Input email for Bluesky waitlist" -#~ msgstr "" - -#: src/view/com/auth/create/Step1.tsx:80 -#~ msgid "Input hosting provider address" -#~ msgstr "" +msgstr "Введіть адресу електронної пошти для облікового запису Bluesky" #: src/view/com/auth/create/Step1.tsx:151 msgid "Input invite code to proceed" -msgstr "" +msgstr "Введіть код запрошення, щоб продовжити" #: src/view/com/modals/AddAppPasswords.tsx:180 msgid "Input name for app password" -msgstr "" +msgstr "Введіть ім'я для пароля застосунку" #: src/view/com/auth/login/SetNewPasswordForm.tsx:162 msgid "Input new password" -msgstr "" +msgstr "Введіть новий пароль" #: src/view/com/modals/DeleteAccount.tsx:203 msgid "Input password for account deletion" -msgstr "" +msgstr "Введіть пароль для видалення облікового запису" #: src/view/com/auth/create/Step2.tsx:196 #~ msgid "Input phone number for SMS verification" @@ -2056,11 +1941,11 @@ msgstr "" #: src/view/com/auth/login/LoginForm.tsx:230 msgid "Input the password tied to {identifier}" -msgstr "" +msgstr "Введіть пароль, прив'язаний до {identifier}" #: src/view/com/auth/login/LoginForm.tsx:197 msgid "Input the username or email address you used at signup" -msgstr "" +msgstr "Введіть псевдонім або ел. адресу, які ви використовували для реєстрації" #: src/view/com/auth/create/Step2.tsx:271 #~ msgid "Input the verification code we have texted to you" @@ -2072,15 +1957,15 @@ msgstr "" #: src/view/com/auth/login/LoginForm.tsx:229 msgid "Input your password" -msgstr "" +msgstr "Введіть ваш пароль" #: src/view/com/auth/create/Step2.tsx:80 msgid "Input your user handle" -msgstr "" +msgstr "Введіть ваш псевдонім" #: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" -msgstr "" +msgstr "Невірний або непідтримуваний пост" #: src/view/com/auth/login/LoginForm.tsx:113 msgid "Invalid username or password" @@ -2088,7 +1973,7 @@ msgstr "Невірне ім'я користувача або пароль" #: src/view/screens/Settings.tsx:411 #~ msgid "Invite" -#~ msgstr "Запросити" +#~ msgstr "" #: src/view/com/modals/InviteCodes.tsx:93 msgid "Invite a Friend" @@ -2105,19 +1990,19 @@ msgstr "Код запрошення не прийнято. Переконайт #: src/view/com/modals/InviteCodes.tsx:170 msgid "Invite codes: {0} available" -msgstr "" +msgstr "Коди запрошення: {0}" #: src/view/shell/Drawer.tsx:645 #~ msgid "Invite codes: {invitesAvailable} available" -#~ msgstr "Коди запрошення: {invitesAvailable}" +#~ msgstr "" #: src/view/com/modals/InviteCodes.tsx:169 msgid "Invite codes: 1 available" -msgstr "" +msgstr "Коди запрошення: 1" #: src/screens/Onboarding/StepFollowingFeed.tsx:64 msgid "It shows posts from the people you follow as they happen." -msgstr "" +msgstr "Ми показуємо пости людей, за якими ви слідкуєте в тому порядку в якому вони публікуються." #: src/view/com/auth/HomeLoggedOutCTA.tsx:99 #: src/view/com/auth/SplashScreen.web.tsx:138 @@ -2126,20 +2011,20 @@ msgstr "Вакансії" #: src/view/com/modals/Waitlist.tsx:67 #~ msgid "Join the waitlist" -#~ msgstr "Приєднатися до черги очікування" +#~ msgstr "" #: src/view/com/auth/create/Step1.tsx:174 #: src/view/com/auth/create/Step1.tsx:178 #~ msgid "Join the waitlist." -#~ msgstr "Приєднатися до черги очікування." +#~ msgstr "" #: src/view/com/modals/Waitlist.tsx:128 #~ msgid "Join Waitlist" -#~ msgstr "Приєднатися до черги очікування" +#~ msgstr "" #: src/screens/Onboarding/index.tsx:24 msgid "Journalism" -msgstr "" +msgstr "Журналістика" #: src/view/com/composer/select-language/SelectLangBtn.tsx:104 msgid "Language selection" @@ -2147,7 +2032,7 @@ msgstr "Вибір мови" #: src/view/screens/Settings/index.tsx:594 msgid "Language settings" -msgstr "" +msgstr "Налаштування мови" #: src/Navigation.tsx:142 #: src/view/screens/LanguageSettings.tsx:89 @@ -2160,7 +2045,7 @@ msgstr "Мови" #: src/view/com/auth/create/StepHeader.tsx:20 msgid "Last step!" -msgstr "" +msgstr "Останній крок!" #: src/view/com/util/moderation/ContentHider.tsx:103 msgid "Learn more" @@ -2194,11 +2079,11 @@ msgstr "Ви залишаєте Bluesky" #: src/screens/Deactivated.tsx:128 msgid "left to go." -msgstr "" +msgstr "ще залишилося." #: src/view/screens/Settings/index.tsx:278 msgid "Legacy storage cleared, you need to restart the app now." -msgstr "" +msgstr "Старе сховище очищено, тепер вам потрібно перезапустити застосунок." #: src/view/com/auth/login/Login.tsx:128 #: src/view/com/auth/login/Login.tsx:144 @@ -2207,7 +2092,7 @@ msgstr "Давайте відновимо ваш пароль!" #: src/screens/Onboarding/StepFinished.tsx:151 msgid "Let's go!" -msgstr "" +msgstr "Злітаємо!" #: src/view/com/util/UserAvatar.tsx:248 #: src/view/com/util/UserBanner.tsx:62 @@ -2216,11 +2101,11 @@ msgstr "Галерея" #: src/view/screens/Settings/index.tsx:479 msgid "Light" -msgstr "" +msgstr "Світла" #: src/view/com/util/post-ctrls/PostCtrls.tsx:182 msgid "Like" -msgstr "" +msgstr "Вподобати" #: src/view/screens/ProfileFeed.tsx:591 msgid "Like this feed" @@ -2233,31 +2118,23 @@ msgstr "Сподобалося" #: src/view/screens/PostLikedBy.tsx:27 #: src/view/screens/ProfileFeedLikedBy.tsx:27 msgid "Liked By" -msgstr "" +msgstr "Сподобався користувачу" #: src/view/com/feeds/FeedSourceCard.tsx:279 msgid "Liked by {0} {1}" -msgstr "" +msgstr "Вподобано {0} {1}" #: src/view/screens/ProfileFeed.tsx:606 msgid "Liked by {likeCount} {0}" -msgstr "" +msgstr "Вподобано {likeCount} {0}" #: src/view/com/notifications/FeedItem.tsx:170 msgid "liked your custom feed" -msgstr "" - -#: src/view/com/notifications/FeedItem.tsx:171 -#~ msgid "liked your custom feed '{0}'" -#~ msgstr "" - -#: src/view/com/notifications/FeedItem.tsx:171 -#~ msgid "liked your custom feed{0}" -#~ msgstr "" +msgstr "вподобав(-ла) вашу стрічку" #: src/view/com/notifications/FeedItem.tsx:155 msgid "liked your post" -msgstr "" +msgstr "сподобався ваш пост" #: src/view/screens/Profile.tsx:183 msgid "Likes" @@ -2265,19 +2142,11 @@ msgstr "Вподобання" #: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" -msgstr "" - -#: src/view/screens/Moderation.tsx:203 -#~ msgid "Limit the visibility of my account" -#~ msgstr "" - -#: src/view/screens/Moderation.tsx:203 -#~ msgid "Limit the visibility of my account to logged-out users" -#~ msgstr "" +msgstr "Вподобайки цього поста" #: src/Navigation.tsx:168 msgid "List" -msgstr "" +msgstr "Список" #: src/view/com/modals/CreateOrEditList.tsx:261 msgid "List Avatar" @@ -2285,19 +2154,19 @@ msgstr "Аватар списку" #: src/view/screens/ProfileList.tsx:324 msgid "List blocked" -msgstr "" +msgstr "Список заблоковано" #: src/view/com/feeds/FeedSourceCard.tsx:233 msgid "List by {0}" -msgstr "" +msgstr "Список від {0}" #: src/view/screens/ProfileList.tsx:378 msgid "List deleted" -msgstr "" +msgstr "Список видалено" #: src/view/screens/ProfileList.tsx:283 msgid "List muted" -msgstr "" +msgstr "Список ігнорується" #: src/view/com/modals/CreateOrEditList.tsx:275 msgid "List Name" @@ -2305,11 +2174,11 @@ msgstr "Назва списку" #: src/view/screens/ProfileList.tsx:343 msgid "List unblocked" -msgstr "" +msgstr "Список розблоковано" #: src/view/screens/ProfileList.tsx:302 msgid "List unmuted" -msgstr "" +msgstr "Список більше не ігнорується" #: src/Navigation.tsx:112 #: src/view/screens/Profile.tsx:185 @@ -2341,22 +2210,18 @@ msgstr "Завантаження..." #: src/view/com/modals/ServerInput.tsx:50 #~ msgid "Local dev server" -#~ msgstr "Локальний сервер розробки" +#~ msgstr "" #: src/Navigation.tsx:209 msgid "Log" -msgstr "" +msgstr "Звіт" #: src/screens/Deactivated.tsx:149 #: src/screens/Deactivated.tsx:152 #: src/screens/Deactivated.tsx:178 #: src/screens/Deactivated.tsx:181 msgid "Log out" -msgstr "" - -#: src/view/screens/Moderation.tsx:134 -#~ msgid "Logged-out users" -#~ msgstr "" +msgstr "Вийти" #: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" @@ -2366,25 +2231,21 @@ msgstr "Видимість для користувачів без обліков msgid "Login to account that is not listed" msgstr "Увійти до облікового запису, якого немає в списку" -#: src/view/screens/ProfileFeed.tsx:472 -#~ msgid "Looks like this feed is only available to users with a Bluesky account. Please sign up or sign in to view this feed!" -#~ msgstr "" - #: src/view/com/modals/LinkWarning.tsx:65 msgid "Make sure this is where you intend to go!" msgstr "Переконайтеся, що це дійсно той сайт, що ви збираєтеся відвідати!" #: src/components/dialogs/MutedWords.tsx:83 msgid "Manage your muted words and tags" -msgstr "" +msgstr "Налаштовуйте ваші ігноровані слова та теги" #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" -msgstr "" +msgstr "Не може бути довшим за 253 символи" #: src/view/com/auth/create/Step2.tsx:109 msgid "May only contain letters and numbers" -msgstr "" +msgstr "Може містити лише літери та цифри" #: src/view/screens/Profile.tsx:182 msgid "Media" @@ -2403,13 +2264,9 @@ msgstr "Згадані користувачі" msgid "Menu" msgstr "Меню" -#: src/view/com/posts/FeedErrorMessage.tsx:194 -#~ msgid "Message from server" -#~ msgstr "Повідомлення від сервера" - #: src/view/com/posts/FeedErrorMessage.tsx:197 msgid "Message from server: {0}" -msgstr "" +msgstr "Повідомлення від сервера: {0}" #: src/Navigation.tsx:117 #: src/view/screens/Moderation.tsx:66 @@ -2423,25 +2280,25 @@ msgstr "Модерація" #: src/view/com/lists/ListCard.tsx:93 #: src/view/com/modals/UserAddRemoveLists.tsx:206 msgid "Moderation list by {0}" -msgstr "" +msgstr "Список модерації від {0}" #: src/view/screens/ProfileList.tsx:775 msgid "Moderation list by <0/>" -msgstr "" +msgstr "Список модерації від <0/>" #: src/view/com/lists/ListCard.tsx:91 #: src/view/com/modals/UserAddRemoveLists.tsx:204 #: src/view/screens/ProfileList.tsx:773 msgid "Moderation list by you" -msgstr "" +msgstr "Список модерації від вас" #: src/view/com/modals/CreateOrEditList.tsx:197 msgid "Moderation list created" -msgstr "" +msgstr "Список модерації створено" #: src/view/com/modals/CreateOrEditList.tsx:183 msgid "Moderation list updated" -msgstr "" +msgstr "Список модерації оновлено" #: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" @@ -2454,11 +2311,11 @@ msgstr "Списки для модерації" #: src/view/screens/Settings/index.tsx:619 msgid "Moderation settings" -msgstr "" +msgstr "Налаштування модерації" #: src/view/com/modals/ModerationDetails.tsx:35 msgid "Moderator has chosen to set a general warning on the content." -msgstr "" +msgstr "Модератор вирішив встановити загальне попередження на вміст." #: src/view/shell/desktop/Feeds.tsx:65 msgid "More feeds" @@ -2480,15 +2337,15 @@ msgstr "За кількістю вподобань" #: src/view/com/auth/create/Step2.tsx:122 msgid "Must be at least 3 characters" -msgstr "" +msgstr "Має містити щонайменше 3 символи" #: src/components/TagMenu/index.tsx:249 msgid "Mute" -msgstr "" +msgstr "Ігнорувати" #: src/components/TagMenu/index.web.tsx:105 msgid "Mute {truncatedTag}" -msgstr "" +msgstr "Ігнорувати {truncatedTag}" #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" @@ -2500,7 +2357,7 @@ msgstr "Ігнорувати облікові записи" #: src/components/TagMenu/index.tsx:209 msgid "Mute all {displayTag} posts" -msgstr "" +msgstr "Ігнорувати всі пости {displayTag}" #: src/components/TagMenu/index.tsx:211 #~ msgid "Mute all {tag} posts" @@ -2508,11 +2365,11 @@ msgstr "" #: src/components/dialogs/MutedWords.tsx:149 msgid "Mute in tags only" -msgstr "" +msgstr "Ігнорувати лише в тегах" #: src/components/dialogs/MutedWords.tsx:134 msgid "Mute in text & tags" -msgstr "" +msgstr "Ігнорувати в тексті та тегах" #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" @@ -2524,29 +2381,29 @@ msgstr "Ігнорувати ці облікові записи?" #: src/view/screens/ProfileList.tsx:279 msgid "Mute this List" -msgstr "" +msgstr "Ігнорувати цей список" #: src/components/dialogs/MutedWords.tsx:127 msgid "Mute this word in post text and tags" -msgstr "" +msgstr "Ігнорувати це слово у постах і тегах" #: src/components/dialogs/MutedWords.tsx:142 msgid "Mute this word in tags only" -msgstr "" +msgstr "Ігнорувати це слово лише у тегах" #: src/view/com/util/forms/PostDropdownBtn.tsx:251 #: src/view/com/util/forms/PostDropdownBtn.tsx:257 msgid "Mute thread" -msgstr "Ігнорувати пост" +msgstr "Ігнорувати обговорення" #: src/view/com/util/forms/PostDropdownBtn.tsx:267 #: src/view/com/util/forms/PostDropdownBtn.tsx:269 msgid "Mute words & tags" -msgstr "" +msgstr "Ігнорувати слова та теги" #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" -msgstr "" +msgstr "Ігнорується" #: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" @@ -2563,16 +2420,12 @@ msgstr "Ігноровані облікові записи автоматичн #: src/view/screens/Moderation.tsx:100 msgid "Muted words & tags" -msgstr "" +msgstr "Ігноровані слова та теги" #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "Ігнорування є приватним. Ігноровані користувачі можуть взаємодіяти з вами, але ви не бачитимете їх пости і не отримуватимете від них сповіщень." -#: src/view/screens/Moderation.tsx:134 -#~ msgid "My Account" -#~ msgstr "" - #: src/view/com/modals/BirthDateSettings.tsx:56 msgid "My Birthday" msgstr "Мій день народження" @@ -2587,11 +2440,11 @@ msgstr "Мій профіль" #: src/view/screens/Settings/index.tsx:582 msgid "My Saved Feeds" -msgstr "Мої збережені стрічки" +msgstr "Мої збережені канали" #: src/view/com/auth/server-input/index.tsx:118 msgid "my-server.com" -msgstr "" +msgstr "my-server.com" #: src/view/com/modals/AddAppPasswords.tsx:179 #: src/view/com/modals/CreateOrEditList.tsx:290 @@ -2600,11 +2453,11 @@ msgstr "Ім'я" #: src/view/com/modals/CreateOrEditList.tsx:145 msgid "Name is required" -msgstr "" +msgstr "Необхідна назва" #: src/screens/Onboarding/index.tsx:25 msgid "Nature" -msgstr "" +msgstr "Природа" #: src/view/com/auth/login/ForgotPasswordForm.tsx:190 #: src/view/com/auth/login/ForgotPasswordForm.tsx:219 @@ -2612,11 +2465,11 @@ msgstr "" #: src/view/com/auth/login/SetNewPasswordForm.tsx:196 #: src/view/com/modals/ChangePassword.tsx:166 msgid "Navigates to the next screen" -msgstr "" +msgstr "Переходить до наступного екрана" #: src/view/shell/Drawer.tsx:71 msgid "Navigates to your profile" -msgstr "" +msgstr "Переходить до вашого профілю" #: src/view/com/modals/EmbedConsent.tsx:107 #: src/view/com/modals/EmbedConsent.tsx:123 @@ -2630,16 +2483,16 @@ msgstr "Ніколи не втрачайте доступ до ваших дан #: src/screens/Onboarding/StepFinished.tsx:119 msgid "Never lose access to your followers or data." -msgstr "" +msgstr "Ніколи не втрачайте доступ до ваших підписників та даних." #: src/components/dialogs/MutedWords.tsx:293 msgid "Nevermind" -msgstr "" +msgstr "Скасувати" #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" -msgstr "" +msgstr "Новий" #: src/view/screens/ModerationModlists.tsx:78 msgid "New" @@ -2647,20 +2500,20 @@ msgstr "Новий" #: src/view/com/modals/CreateOrEditList.tsx:252 msgid "New Moderation List" -msgstr "" +msgstr "Новий список модерації" #: src/view/com/auth/login/SetNewPasswordForm.tsx:150 msgid "New password" -msgstr "" +msgstr "Новий пароль" #: src/view/com/modals/ChangePassword.tsx:215 msgid "New Password" -msgstr "" +msgstr "Новий Пароль" #: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" -msgstr "" +msgstr "Новий пост" #: src/view/screens/Feeds.tsx:555 #: src/view/screens/Notifications.tsx:168 @@ -2675,15 +2528,11 @@ msgstr "Новий пост" #: src/view/shell/desktop/LeftNav.tsx:258 msgctxt "action" msgid "New Post" -msgstr "" - -#: src/view/shell/desktop/LeftNav.tsx:258 -#~ msgid "New Post" -#~ msgstr "Новий пост" +msgstr "Новий пост" #: src/view/com/modals/CreateOrEditList.tsx:247 msgid "New User List" -msgstr "" +msgstr "Новий список користувачів" #: src/view/screens/PreferencesThreads.tsx:79 msgid "Newest replies first" @@ -2691,7 +2540,7 @@ msgstr "Спочатку найновіші" #: src/screens/Onboarding/index.tsx:23 msgid "News" -msgstr "" +msgstr "Новини" #: src/view/com/auth/create/CreateAccount.tsx:172 #: src/view/com/auth/login/ForgotPasswordForm.tsx:182 @@ -2708,7 +2557,7 @@ msgstr "Далі" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 msgctxt "action" msgid "Next" -msgstr "" +msgstr "Далі" #: src/view/com/lightbox/Lightbox.web.tsx:149 msgid "Next image" @@ -2730,11 +2579,11 @@ msgstr "Опис відсутній" #: src/view/com/profile/ProfileHeader.tsx:170 msgid "No longer following {0}" -msgstr "" +msgstr "Ви більше не підписані на {0}" #: src/view/com/notifications/Feed.tsx:109 msgid "No notifications yet!" -msgstr "" +msgstr "Ще ніяких сповіщень!" #: src/view/com/composer/text-input/mobile/Autocomplete.tsx:97 #: src/view/com/composer/text-input/web/Autocomplete.tsx:191 @@ -2743,17 +2592,12 @@ msgstr "Результати відсутні" #: src/components/Lists.tsx:192 msgid "No results found" -msgstr "" +msgstr "Нічого не знайдено" #: src/view/screens/Feeds.tsx:495 msgid "No results found for \"{query}\"" msgstr "Нічого не знайдено за запитом «{query}»" -#: src/view/com/modals/ListAddUser.tsx:142 -#: src/view/shell/desktop/Search.tsx:112 -#~ msgid "No results found for {0}" -#~ msgstr "" - #: src/view/com/modals/ListAddRemoveUsers.tsx:127 #: src/view/screens/Search/Search.tsx:281 #: src/view/screens/Search/Search.tsx:309 @@ -2768,10 +2612,6 @@ msgstr "Ні, дякую" msgid "Nobody" msgstr "Ніхто" -#: src/view/com/modals/SelfLabel.tsx:136 -#~ msgid "Not Applicable" -#~ msgstr "" - #: src/view/com/modals/SelfLabel.tsx:135 msgid "Not Applicable." msgstr "Не застосовно." @@ -2779,25 +2619,17 @@ msgstr "Не застосовно." #: src/Navigation.tsx:107 #: src/view/screens/Profile.tsx:106 msgid "Not Found" -msgstr "" +msgstr "Не знайдено" #: src/view/com/modals/VerifyEmail.tsx:246 #: src/view/com/modals/VerifyEmail.tsx:252 msgid "Not right now" -msgstr "" - -#: src/view/screens/Moderation.tsx:227 -#~ msgid "Note: Bluesky is an open and public network, and enabling this will not make your profile private or limit the ability of logged in users to see your posts. This setting only limits the visibility of posts on the Bluesky app and website; third-party apps that display Bluesky content may not respect this setting, and could show your content to logged-out users." -#~ msgstr "" +msgstr "Пізніше" #: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "Примітка: Bluesky є відкритою і публічною мережею. Цей параметр обмежує видимість вашого вмісту лише у застосунках і на сайті Bluesky, але інші застосунки можуть цього не дотримуватися. Ваш вміст все ще може бути показаний відвідувачам без облікового запису іншими застосунками і вебсайтами." -#: src/view/screens/Moderation.tsx:227 -#~ msgid "Note: Third-party apps that display Bluesky content may not respect this setting." -#~ msgstr "" - #: src/Navigation.tsx:457 #: src/view/screens/Notifications.tsx:124 #: src/view/screens/Notifications.tsx:148 @@ -2810,7 +2642,7 @@ msgstr "Сповіщення" #: src/view/com/modals/SelfLabel.tsx:103 msgid "Nudity" -msgstr "" +msgstr "Оголеність" #: src/view/com/util/ErrorBoundary.tsx:35 msgid "Oh no!" @@ -2818,7 +2650,7 @@ msgstr "О, ні!" #: src/screens/Onboarding/StepInterests/index.tsx:128 msgid "Oh no! Something went wrong." -msgstr "" +msgstr "Ой! Щось пішло не так." #: src/view/com/auth/login/PasswordUpdatedForm.tsx:41 msgid "Okay" @@ -2830,11 +2662,11 @@ msgstr "Спочатку найдавніші" #: src/view/screens/Settings/index.tsx:234 msgid "Onboarding reset" -msgstr "" +msgstr "Скинути ознайомлення" #: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." -msgstr "Для одного або кількох зображень відсутній альтернативний текст." +msgstr "Для одного або кількох зображень відсутній опис." #: src/view/com/threadgate/WhoCanReply.tsx:100 msgid "Only {0} can reply." @@ -2842,21 +2674,21 @@ msgstr "Тільки {0} можуть відповідати." #: src/components/Lists.tsx:82 msgid "Oops, something went wrong!" -msgstr "" +msgstr "Ой, щось пішло не так!" #: src/components/Lists.tsx:188 #: src/view/screens/AppPasswords.tsx:65 #: src/view/screens/Profile.tsx:106 msgid "Oops!" -msgstr "" +msgstr "Ой!" #: src/screens/Onboarding/StepFinished.tsx:115 msgid "Open" -msgstr "" +msgstr "Відкрити" #: src/view/screens/Moderation.tsx:75 msgid "Open content filtering settings" -msgstr "" +msgstr "Відкрити налаштування фільтрації контенту" #: src/view/com/composer/Composer.tsx:477 #: src/view/com/composer/Composer.tsx:478 @@ -2865,11 +2697,11 @@ msgstr "Емоджі" #: src/view/screens/Settings/index.tsx:712 msgid "Open links with in-app browser" -msgstr "" +msgstr "Вбудований браузер" #: src/view/screens/Moderation.tsx:92 msgid "Open muted words settings" -msgstr "" +msgstr "Відкрити налаштування ігнорування слів" #: src/view/com/home/HomeHeaderLayoutMobile.tsx:50 msgid "Open navigation" @@ -2877,31 +2709,31 @@ msgstr "Відкрити навігацію" #: src/view/com/util/forms/PostDropdownBtn.tsx:175 msgid "Open post options menu" -msgstr "" +msgstr "Відкрити меню налаштувань посту" #: src/view/screens/Settings/index.tsx:804 msgid "Open storybook page" -msgstr "" +msgstr "Відкрити storybook сторінку" #: src/view/com/util/forms/DropdownButton.tsx:154 msgid "Opens {numItems} options" -msgstr "" +msgstr "Відкриває меню з {numItems} опціями" #: src/view/screens/Log.tsx:54 msgid "Opens additional details for a debug entry" -msgstr "" +msgstr "Відкриває додаткову інформацію про запис для налагодження" #: src/view/com/notifications/FeedItem.tsx:349 msgid "Opens an expanded list of users in this notification" -msgstr "" +msgstr "Відкрити розширений список користувачів у цьому сповіщенні" #: src/view/com/composer/photos/OpenCameraBtn.tsx:61 msgid "Opens camera on device" -msgstr "" +msgstr "Відкриває камеру на пристрої" #: src/view/com/composer/Prompt.tsx:25 msgid "Opens composer" -msgstr "" +msgstr "Відкрити редактор" #: src/view/screens/Settings/index.tsx:595 msgid "Opens configurable language settings" @@ -2909,11 +2741,11 @@ msgstr "Відкриває налаштування мов" #: src/view/com/composer/photos/SelectPhotoBtn.tsx:44 msgid "Opens device photo gallery" -msgstr "" +msgstr "Відкриває фотогалерею пристрою" #: src/view/com/profile/ProfileHeader.tsx:420 msgid "Opens editor for profile display name, avatar, background image, and description" -msgstr "" +msgstr "Відкриває редактор для назви профілю, аватара, фонового зображення та опису" #: src/view/screens/Settings/index.tsx:649 msgid "Opens external embeds settings" @@ -2921,11 +2753,11 @@ msgstr "Відкриває налаштування зовнішніх вбуд #: src/view/com/profile/ProfileHeader.tsx:575 msgid "Opens followers list" -msgstr "" +msgstr "Відкриває список підписників" #: src/view/com/profile/ProfileHeader.tsx:594 msgid "Opens following list" -msgstr "" +msgstr "Відкриває список нижче" #: src/view/screens/Settings.tsx:412 #~ msgid "Opens invite code list" @@ -2937,7 +2769,7 @@ msgstr "Відкриває список кодів запрошення" #: src/view/screens/Settings/index.tsx:774 msgid "Opens modal for account deletion confirmation. Requires email code." -msgstr "" +msgstr "Відкриється модальне повідомлення для видалення облікового запису. Потрібен код електронної пошти." #: src/view/com/modals/ChangeHandle.tsx:281 msgid "Opens modal for using custom domain" @@ -2949,16 +2781,16 @@ msgstr "Відкриває налаштування модерації" #: src/view/com/auth/login/LoginForm.tsx:239 msgid "Opens password reset form" -msgstr "" +msgstr "Відкриває форму скидання пароля" #: src/view/com/home/HomeHeaderLayout.web.tsx:63 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" -msgstr "" +msgstr "Відкриває сторінку з усіма збереженими стрічками" #: src/view/screens/Settings/index.tsx:576 msgid "Opens screen with all saved feeds" -msgstr "Відкриває сторінку з усіма збереженими стрічками" +msgstr "Відкриває сторінку з усіма збереженими каналами" #: src/view/screens/Settings/index.tsx:676 msgid "Opens the app password settings page" @@ -2966,7 +2798,7 @@ msgstr "Відкриває налаштування паролів для зас #: src/view/screens/Settings/index.tsx:535 msgid "Opens the home feed preferences" -msgstr "Відкриває налаштування домашньої стрічки" +msgstr "Відкриває налаштування Головного каналу" #: src/view/screens/Settings/index.tsx:805 msgid "Opens the storybook page" @@ -2982,23 +2814,19 @@ msgstr "Відкриває налаштування гілок" #: src/view/com/util/forms/DropdownButton.tsx:280 msgid "Option {0} of {numItems}" -msgstr "" +msgstr "Опція {0} з {numItems}" #: src/view/com/modals/Threadgate.tsx:89 msgid "Or combine these options:" msgstr "Або якісь із наступних варіантів:" -#: src/screens/Onboarding/StepAlgoFeeds/index.tsx:122 -#~ msgid "Or you can try our \"Discover\" algorithm:" -#~ msgstr "" - #: src/view/com/auth/login/ChooseAccountForm.tsx:138 msgid "Other account" msgstr "Інший обліковий запис" #: src/view/com/modals/ServerInput.tsx:88 #~ msgid "Other service" -#~ msgstr "Інший хостинг-провайдер" +#~ msgstr "" #: src/view/com/composer/select-language/SelectLangBtn.tsx:91 msgid "Other..." @@ -3011,7 +2839,7 @@ msgstr "Сторінку не знайдено" #: src/view/screens/NotFound.tsx:42 msgid "Page Not Found" -msgstr "" +msgstr "Сторінку не знайдено" #: src/view/com/auth/create/Step1.tsx:191 #: src/view/com/auth/create/Step1.tsx:201 @@ -3031,23 +2859,23 @@ msgstr "Пароль змінено!" #: src/Navigation.tsx:162 msgid "People followed by @{0}" -msgstr "" +msgstr "Люди, на яких підписаний(-на) @{0}" #: src/Navigation.tsx:155 msgid "People following @{0}" -msgstr "" +msgstr "Люди, які підписані на @{0}" #: src/view/com/lightbox/Lightbox.tsx:66 msgid "Permission to access camera roll is required." -msgstr "" +msgstr "Потрібен дозвіл на доступ до камери." #: src/view/com/lightbox/Lightbox.tsx:72 msgid "Permission to access camera roll was denied. Please enable it in your system settings." -msgstr "" +msgstr "Дозвіл на доступ до камери був заборонений. Будь ласка, включіть його в налаштуваннях системи." #: src/screens/Onboarding/index.tsx:31 msgid "Pets" -msgstr "" +msgstr "Домашні улюбленці" #: src/view/com/auth/create/Step2.tsx:183 #~ msgid "Phone number" @@ -3060,7 +2888,7 @@ msgstr "Зображення, призначені для дорослих." #: src/view/screens/ProfileFeed.tsx:354 #: src/view/screens/ProfileList.tsx:581 msgid "Pin to home" -msgstr "" +msgstr "Закріпити" #: src/view/screens/SavedFeeds.tsx:88 msgid "Pinned Feeds" @@ -3089,7 +2917,7 @@ msgstr "Будь ласка, оберіть ваш пароль." #: src/view/com/auth/create/state.ts:131 msgid "Please complete the verification captcha." -msgstr "" +msgstr "Будь ласка, завершіть перевірку Captcha." #: src/view/com/modals/ChangeEmail.tsx:67 msgid "Please confirm your email before changing it. This is a temporary requirement while email-updating tools are added, and it will soon be removed." @@ -3097,7 +2925,7 @@ msgstr "Будь ласка, підтвердіть вашу електронн #: src/view/com/modals/AddAppPasswords.tsx:90 msgid "Please enter a name for your app password. All spaces is not allowed." -msgstr "" +msgstr "Будь ласка, введіть ім'я для пароля застосунку. Пробіли і пропуски не допускаються." #: src/view/com/auth/create/Step2.tsx:206 #~ msgid "Please enter a phone number that can receive SMS text messages." @@ -3109,7 +2937,7 @@ msgstr "Будь ласка, введіть унікальну назву для #: src/components/dialogs/MutedWords.tsx:68 msgid "Please enter a valid word, tag, or phrase to mute" -msgstr "" +msgstr "Будь ласка, введіть допустиме слово, тег або фразу для ігнорування" #: src/view/com/auth/create/state.ts:170 #~ msgid "Please enter the code you received by SMS." @@ -3139,7 +2967,7 @@ msgstr "Будь ласка, вкажіть чому ви вважаєте що #: src/view/com/modals/VerifyEmail.tsx:101 msgid "Please Verify Your Email" -msgstr "" +msgstr "Підтвердьте свою адресу електронної пошти" #: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" @@ -3147,42 +2975,36 @@ msgstr "Будь ласка, зачекайте доки завершиться #: src/screens/Onboarding/index.tsx:37 msgid "Politics" -msgstr "" +msgstr "Політика" #: src/view/com/modals/SelfLabel.tsx:111 msgid "Porn" -msgstr "" +msgstr "Порнографія" #: src/view/com/composer/Composer.tsx:357 #: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" -msgstr "" +msgstr "Запостити" #: src/view/com/post-thread/PostThread.tsx:303 msgctxt "description" msgid "Post" -msgstr "" - -#: src/view/com/composer/Composer.tsx:346 -#: src/view/com/post-thread/PostThread.tsx:225 -#: src/view/screens/PostThread.tsx:80 -#~ msgid "Post" -#~ msgstr "Пост" +msgstr "Пост" #: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" -msgstr "" +msgstr "Пост від {0}" #: src/Navigation.tsx:174 #: src/Navigation.tsx:181 #: src/Navigation.tsx:188 msgid "Post by @{0}" -msgstr "" +msgstr "Пост від @{0}" #: src/view/com/util/forms/PostDropdownBtn.tsx:108 msgid "Post deleted" -msgstr "" +msgstr "Пост видалено" #: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" @@ -3202,7 +3024,7 @@ msgstr "Пост не знайдено" #: src/components/TagMenu/index.tsx:253 msgid "posts" -msgstr "" +msgstr "пости" #: src/view/screens/Profile.tsx:180 msgid "Posts" @@ -3210,11 +3032,11 @@ msgstr "Пости" #: src/components/dialogs/MutedWords.tsx:90 msgid "Posts can be muted based on their text, their tags, or both." -msgstr "" +msgstr "Пости можуть бути ігноровані за їхнім текстом, тегами чи за обома." #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" -msgstr "" +msgstr "Пости приховано" #: src/view/com/modals/LinkWarning.tsx:46 msgid "Potentially Misleading Link" @@ -3258,7 +3080,7 @@ msgstr "Профіль" #: src/view/com/modals/EditProfile.tsx:128 msgid "Profile updated" -msgstr "" +msgstr "Профіль оновлено" #: src/view/screens/Settings/index.tsx:949 msgid "Protect your account by verifying your email." @@ -3266,7 +3088,7 @@ msgstr "Захистіть свій обліковий запис, підтве #: src/screens/Onboarding/StepFinished.tsx:101 msgid "Public" -msgstr "" +msgstr "Публічний" #: src/view/screens/ModerationModlists.tsx:61 msgid "Public, shareable lists of users to mute or block in bulk." @@ -3278,16 +3100,16 @@ msgstr "Публічні, поширювані списки для створе #: src/view/com/composer/Composer.tsx:342 msgid "Publish post" -msgstr "" +msgstr "Опублікувати пост" #: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" -msgstr "" +msgstr "Опублікувати відповідь" #: src/view/com/modals/Repost.tsx:65 msgctxt "action" msgid "Quote post" -msgstr "" +msgstr "Цитувати" #: src/view/com/util/post-ctrls/RepostButton.web.tsx:58 msgid "Quote post" @@ -3296,11 +3118,7 @@ msgstr "Цитувати пост" #: src/view/com/modals/Repost.tsx:70 msgctxt "action" msgid "Quote Post" -msgstr "" - -#: src/view/com/modals/Repost.tsx:56 -#~ msgid "Quote Post" -#~ msgstr "Цитувати пост" +msgstr "Цитувати" #: src/view/screens/PreferencesThreads.tsx:86 msgid "Random (aka \"Poster's Roulette\")" @@ -3310,11 +3128,6 @@ msgstr "У випадковому порядку" msgid "Ratios" msgstr "Співвідношення сторін" -#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:73 -#: src/view/com/auth/onboarding/RecommendedFollows.tsx:50 -#~ msgid "Recommended" -#~ msgstr "" - #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:116 msgid "Recommended Feeds" msgstr "Рекомендовані стрічки" @@ -3330,7 +3143,7 @@ msgstr "Рекомендовані користувачі" #: src/view/com/util/UserAvatar.tsx:285 #: src/view/com/util/UserBanner.tsx:91 msgid "Remove" -msgstr "Вилучити" +msgstr "Видалити" #: src/view/com/feeds/FeedSourceCard.tsx:108 msgid "Remove {0} from my feeds?" @@ -3338,12 +3151,12 @@ msgstr "Вилучити {0} зі збережених стрічок?" #: src/view/com/util/AccountDropdownBtn.tsx:22 msgid "Remove account" -msgstr "Вилучити обліковий запис" +msgstr "Видалити обліковий запис" #: src/view/com/posts/FeedErrorMessage.tsx:131 #: src/view/com/posts/FeedErrorMessage.tsx:166 msgid "Remove feed" -msgstr "Вилучити стрічку" +msgstr "Видалити стрічку" #: src/view/com/feeds/FeedSourceCard.tsx:107 #: src/view/com/feeds/FeedSourceCard.tsx:169 @@ -3363,11 +3176,11 @@ msgstr "Вилучити попередній перегляд зображен #: src/components/dialogs/MutedWords.tsx:343 msgid "Remove mute word from your list" -msgstr "" +msgstr "Вилучити ігноровані слова з вашого списку" #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" -msgstr "" +msgstr "Видалити репост" #: src/view/com/feeds/FeedSourceCard.tsx:175 msgid "Remove this feed from my feeds?" @@ -3385,11 +3198,11 @@ msgstr "Вилучено зі списку" #: src/view/com/feeds/FeedSourceCard.tsx:113 #: src/view/com/feeds/FeedSourceCard.tsx:180 msgid "Removed from my feeds" -msgstr "" +msgstr "Вилучено з моїх стрічок" #: src/view/com/composer/ExternalEmbed.tsx:71 msgid "Removes default thumbnail from {0}" -msgstr "" +msgstr "Видаляє мініатюру за замовчуванням з {0}" #: src/view/screens/Profile.tsx:181 msgid "Replies" @@ -3402,7 +3215,7 @@ msgstr "Відповіді до цього посту вимкнено" #: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" -msgstr "" +msgstr "Відповісти" #: src/view/screens/PreferencesFollowingFeed.tsx:144 msgid "Reply Filters" @@ -3412,7 +3225,7 @@ msgstr "Які відповіді показувати" #: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" -msgstr "" +msgstr "У відповідь <0/>" #: src/view/com/modals/report/Modal.tsx:166 msgid "Report {collectionName}" @@ -3442,7 +3255,7 @@ msgstr "Поскаржитись на пост" #: src/view/com/util/post-ctrls/RepostButton.tsx:61 msgctxt "action" msgid "Repost" -msgstr "" +msgstr "Репост" #: src/view/com/util/post-ctrls/RepostButton.web.tsx:48 msgid "Repost" @@ -3453,33 +3266,25 @@ msgstr "Репостити" msgid "Repost or quote post" msgstr "Репостити або цитувати" -#: src/view/screens/PostRepostedBy.tsx:27 -#~ msgid "Reposted by" -#~ msgstr "Репост" - #: src/view/screens/PostRepostedBy.tsx:27 msgid "Reposted By" -msgstr "" +msgstr "Зробив(-ла) репост" #: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" -msgstr "" - -#: src/view/com/posts/FeedItem.tsx:206 -#~ msgid "Reposted by {0})" -#~ msgstr "" +msgstr "{0} зробив(-ла) репост" #: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" -msgstr "" +msgstr "<0/> зробив(-ла) репост" #: src/view/com/notifications/FeedItem.tsx:162 msgid "reposted your post" -msgstr "" +msgstr "зробив(-ла) репост вашого допису" #: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" -msgstr "" +msgstr "Репости цього поста" #: src/view/com/modals/ChangeEmail.tsx:181 #: src/view/com/modals/ChangeEmail.tsx:183 @@ -3493,15 +3298,11 @@ msgstr "Змінити" #: src/view/com/modals/ChangePassword.tsx:239 #: src/view/com/modals/ChangePassword.tsx:241 msgid "Request Code" -msgstr "" - -#: src/view/screens/Moderation.tsx:188 -#~ msgid "Request to limit the visibility of my account" -#~ msgstr "" +msgstr "Надіслати запит на код" #: src/view/screens/Settings/index.tsx:456 msgid "Require alt text before posting" -msgstr "Вимагати альтернативний текст до зображень перед публікацією" +msgstr "Вимагати опис зображень перед публікацією" #: src/view/com/auth/create/Step1.tsx:146 msgid "Required for this provider" @@ -3514,11 +3315,11 @@ msgstr "Код підтвердження" #: src/view/com/modals/ChangePassword.tsx:190 msgid "Reset Code" -msgstr "" +msgstr "Код скидання" #: src/view/screens/Settings/index.tsx:824 msgid "Reset onboarding" -msgstr "" +msgstr "Скинути ознайомлення" #: src/view/screens/Settings/index.tsx:827 msgid "Reset onboarding state" @@ -3530,7 +3331,7 @@ msgstr "Скинути пароль" #: src/view/screens/Settings/index.tsx:814 msgid "Reset preferences" -msgstr "" +msgstr "Скинути налаштування" #: src/view/screens/Settings/index.tsx:817 msgid "Reset preferences state" @@ -3546,12 +3347,12 @@ msgstr "" #: src/view/com/auth/login/LoginForm.tsx:269 msgid "Retries login" -msgstr "" +msgstr "Повторити спробу" #: src/view/com/util/error/ErrorMessage.tsx:57 #: src/view/com/util/error/ErrorScreen.tsx:74 msgid "Retries the last action, which errored out" -msgstr "" +msgstr "Повторити останню дію, яка спричинила помилку" #: src/screens/Onboarding/StepInterests/index.tsx:221 #: src/screens/Onboarding/StepInterests/index.tsx:224 @@ -3564,17 +3365,13 @@ msgstr "" msgid "Retry" msgstr "Повторити спробу" -#: src/view/com/modals/ChangeHandle.tsx:169 -#~ msgid "Retry change handle" -#~ msgstr "" - #: src/view/com/auth/create/Step2.tsx:247 #~ msgid "Retry." #~ msgstr "" #: src/view/screens/ProfileList.tsx:903 msgid "Return to previous page" -msgstr "" +msgstr "Повернутися до попередньої сторінки" #: src/view/shell/desktop/RightNav.tsx:55 #~ msgid "SANDBOX. Posts and accounts are not permanent." @@ -3584,7 +3381,7 @@ msgstr "" #: src/view/com/modals/CreateOrEditList.tsx:345 msgctxt "action" msgid "Save" -msgstr "" +msgstr "Зберегти" #: src/view/com/modals/BirthDateSettings.tsx:94 #: src/view/com/modals/BirthDateSettings.tsx:97 @@ -3597,11 +3394,7 @@ msgstr "Зберегти" #: src/view/com/modals/AltImage.tsx:130 msgid "Save alt text" -msgstr "Зберегти альтернативний текст" - -#: src/view/com/modals/UserAddRemoveLists.tsx:212 -#~ msgid "Save changes" -#~ msgstr "" +msgstr "Зберегти опис" #: src/view/com/modals/EditProfile.tsx:232 msgid "Save Changes" @@ -3621,19 +3414,19 @@ msgstr "Збережені стрічки" #: src/view/com/modals/EditProfile.tsx:225 msgid "Saves any changes to your profile" -msgstr "" +msgstr "Зберігає зміни вашого профілю" #: src/view/com/modals/ChangeHandle.tsx:171 msgid "Saves handle change to {handle}" -msgstr "" +msgstr "Зберігає зміню псевдоніму на {handle}" #: src/screens/Onboarding/index.tsx:36 msgid "Science" -msgstr "" +msgstr "Наука" #: src/view/screens/ProfileList.tsx:859 msgid "Scroll to top" -msgstr "" +msgstr "Прогорнути вгору" #: src/Navigation.tsx:447 #: src/view/com/auth/LoggedOut.tsx:122 @@ -3655,11 +3448,11 @@ msgstr "Пошук" #: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" -msgstr "" +msgstr "Шукати \"{query}\"" #: src/components/TagMenu/index.tsx:145 msgid "Search for all posts by @{authorHandle} with tag {displayTag}" -msgstr "" +msgstr "Пошук усіх повідомлень @{authorHandle} з тегом {displayTag}" #: src/components/TagMenu/index.tsx:145 #~ msgid "Search for all posts by @{authorHandle} with tag {tag}" @@ -3667,16 +3460,12 @@ msgstr "" #: src/components/TagMenu/index.tsx:94 msgid "Search for all posts with tag {displayTag}" -msgstr "" +msgstr "Пошук усіх повідомлень з тегом {displayTag}" #: src/components/TagMenu/index.tsx:90 #~ msgid "Search for all posts with tag {tag}" #~ msgstr "" -#: src/view/screens/Search/Search.tsx:390 -#~ msgid "Search for posts and users." -#~ msgstr "" - #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 @@ -3689,19 +3478,19 @@ msgstr "Потрібен код підтвердження" #: src/components/TagMenu/index.web.tsx:66 msgid "See {truncatedTag} posts" -msgstr "" +msgstr "Переглянути дописи {truncatedTag}" #: src/components/TagMenu/index.web.tsx:83 msgid "See {truncatedTag} posts by user" -msgstr "" +msgstr "Переглянути пости користувача з {truncatedTag}" #: src/components/TagMenu/index.tsx:128 msgid "See <0>{displayTag}</0> posts" -msgstr "" +msgstr "Переглянути пости з <0>{displayTag}</0>" #: src/components/TagMenu/index.tsx:187 msgid "See <0>{displayTag}</0> posts by this user" -msgstr "" +msgstr "Переглянути пости цього користувача з <0>{displayTag}</0>" #: src/components/TagMenu/index.tsx:128 #~ msgid "See <0>{tag}</0> posts" @@ -3713,7 +3502,7 @@ msgstr "" #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" -msgstr "" +msgstr "Перегляньте цей посібник" #: src/view/com/auth/HomeLoggedOutCTA.tsx:39 msgid "See what's next" @@ -3721,11 +3510,11 @@ msgstr "Що далі?" #: src/view/com/util/Selector.tsx:106 msgid "Select {item}" -msgstr "" +msgstr "Обрати {item}" #: src/view/com/modals/ServerInput.tsx:75 #~ msgid "Select Bluesky Social" -#~ msgstr "Вибрати Bluesky Social" +#~ msgstr "" #: src/view/com/auth/login/Login.tsx:117 msgid "Select from an existing account" @@ -3733,7 +3522,7 @@ msgstr "Вибрати існуючий обліковий запис" #: src/view/com/util/Selector.tsx:107 msgid "Select option {i} of {numItems}" -msgstr "" +msgstr "Обрати варіант {i} із {numItems}" #: src/view/com/auth/create/Step1.tsx:96 #: src/view/com/auth/login/LoginForm.tsx:150 @@ -3742,11 +3531,11 @@ msgstr "Вибрати хостинг-провайдера" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:52 msgid "Select some accounts below to follow" -msgstr "" +msgstr "Оберіть деякі облікові записи, щоб підписатися" #: src/view/com/auth/server-input/index.tsx:82 msgid "Select the service that hosts your data." -msgstr "" +msgstr "Виберіть хостинг-провайдера для ваших даних." #: src/screens/Onboarding/StepModeration/index.tsx:49 #~ msgid "Select the types of content that you want to see (or not see), and we'll handle the rest." @@ -3754,15 +3543,15 @@ msgstr "" #: src/screens/Onboarding/StepTopicalFeeds.tsx:96 msgid "Select topical feeds to follow from the list below" -msgstr "" +msgstr "Підпишіться на тематичні стрічки зі списку нижче" #: src/screens/Onboarding/StepModeration/index.tsx:75 msgid "Select what you want to see (or not see), and we’ll handle the rest." -msgstr "" +msgstr "Виберіть, що ви хочете бачити (або не бачити), а решту ми зробимо за вас." #: src/view/screens/LanguageSettings.tsx:281 msgid "Select which languages you want your subscribed feeds to include. If none are selected, all languages will be shown." -msgstr "Оберіть мови постів, які ви хочете бачити у збережених стрічках. Якщо не вибрано жодної - буде показано пости всіма мовами." +msgstr "Оберіть мови постів, які ви хочете бачити у збережених каналах. Якщо не вибрано жодної – буде показано пости всіма мовами." #: src/view/screens/LanguageSettings.tsx:98 msgid "Select your app language for the default text to display in the app" @@ -3770,7 +3559,7 @@ msgstr "Оберіть мову інтерфейсу" #: src/screens/Onboarding/StepInterests/index.tsx:196 msgid "Select your interests from the options below" -msgstr "" +msgstr "Виберіть ваші інтереси із нижченаведених варіантів" #: src/view/com/auth/create/Step2.tsx:155 #~ msgid "Select your phone's country" @@ -3782,11 +3571,11 @@ msgstr "Оберіть бажану мову для перекладів у ва #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:116 msgid "Select your primary algorithmic feeds" -msgstr "" +msgstr "Оберіть ваші основні алгоритмічні стрічки" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:142 msgid "Select your secondary algorithmic feeds" -msgstr "" +msgstr "Оберіть ваші другорядні алгоритмічні стрічки" #: src/view/com/modals/VerifyEmail.tsx:202 #: src/view/com/modals/VerifyEmail.tsx:204 @@ -3800,11 +3589,7 @@ msgstr "Надіслати ел. листа" #: src/view/com/modals/DeleteAccount.tsx:144 msgctxt "action" msgid "Send Email" -msgstr "" - -#: src/view/com/modals/DeleteAccount.tsx:138 -#~ msgid "Send Email" -#~ msgstr "Надіслати ел. листа" +msgstr "Надіслати ел. лист" #: src/view/shell/Drawer.tsx:295 #: src/view/shell/Drawer.tsx:316 @@ -3817,41 +3602,41 @@ msgstr "Поскаржитись" #: src/view/com/modals/DeleteAccount.tsx:133 msgid "Sends email with confirmation code for account deletion" -msgstr "" +msgstr "Надсилає електронний лист з кодом підтвердження видалення облікового запису" #: src/view/com/auth/server-input/index.tsx:110 msgid "Server address" -msgstr "" +msgstr "Адреса сервера" #: src/view/com/modals/ContentFilteringSettings.tsx:311 msgid "Set {value} for {labelGroup} content moderation policy" -msgstr "" +msgstr "Встановити {value} для політики модерації вмісту {labelGroup}" #: src/view/com/modals/ContentFilteringSettings.tsx:160 #: src/view/com/modals/ContentFilteringSettings.tsx:179 msgctxt "action" msgid "Set Age" -msgstr "" +msgstr "Встановити вік" #: src/view/screens/Settings/index.tsx:488 msgid "Set color theme to dark" -msgstr "" +msgstr "Встановити темне оформлення" #: src/view/screens/Settings/index.tsx:481 msgid "Set color theme to light" -msgstr "" +msgstr "Встановити світле оформлення" #: src/view/screens/Settings/index.tsx:475 msgid "Set color theme to system setting" -msgstr "" +msgstr "Встановити системне оформлення" #: src/view/screens/Settings/index.tsx:514 msgid "Set dark theme to the dark theme" -msgstr "" +msgstr "Встановити темну тему" #: src/view/screens/Settings/index.tsx:507 msgid "Set dark theme to the dim theme" -msgstr "" +msgstr "Встановити темну тьмяну тему" #: src/view/com/auth/login/SetNewPasswordForm.tsx:104 msgid "Set new password" @@ -3859,19 +3644,19 @@ msgstr "Зміна пароля" #: src/view/com/auth/create/Step1.tsx:202 msgid "Set password" -msgstr "" +msgstr "Встановити пароль" #: src/view/screens/PreferencesFollowingFeed.tsx:225 msgid "Set this setting to \"No\" to hide all quote posts from your feed. Reposts will still be visible." -msgstr "Вимкніть це налаштування, щоб приховати всі цитовані пости у вашій стрічці. Не впливає на репости без цитування." +msgstr "Вимкніть цей параметр, щоб приховати всі цитовані пости у вашій стрічці. Не впливає на репости без цитування." #: src/view/screens/PreferencesFollowingFeed.tsx:122 msgid "Set this setting to \"No\" to hide all replies from your feed." -msgstr "Вимкніть це налаштування, щоб приховати всі відповіді у вашій стрічці." +msgstr "Вимкніть цей параметр, щоб приховати всі відповіді у вашій стрічці." #: src/view/screens/PreferencesFollowingFeed.tsx:191 msgid "Set this setting to \"No\" to hide all reposts from your feed." -msgstr "Вимкніть це налаштування, щоб приховати всі репости у вашій стрічці." +msgstr "Вимкніть цей параметр, щоб приховати всі репости у вашій стрічці." #: src/view/screens/PreferencesThreads.tsx:122 msgid "Set this setting to \"Yes\" to show replies in a threaded view. This is an experimental feature." @@ -3879,36 +3664,32 @@ msgstr "Увімкніть це налаштування, щоб показув #: src/view/screens/PreferencesHomeFeed.tsx:261 #~ msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your following feed. This is an experimental feature." -#~ msgstr "Увімкніть це налаштування, щоб іноді бачити пости зі збережених стрічок у вашій домашній стрічці. Це експериментальна функція." +#~ msgstr "" #: src/view/screens/PreferencesFollowingFeed.tsx:261 msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your Following feed. This is an experimental feature." -msgstr "" +msgstr "Увімкніть це налаштування, щоб іноді бачити пости зі збережених стрічок у вашій домашній стрічці. Це експериментальна функція." #: src/screens/Onboarding/Layout.tsx:50 msgid "Set up your account" -msgstr "" +msgstr "Налаштуйте ваш обліковий запис" #: src/view/com/modals/ChangeHandle.tsx:266 msgid "Sets Bluesky username" -msgstr "" +msgstr "Встановлює псевдонім Bluesky" #: src/view/com/auth/login/ForgotPasswordForm.tsx:157 msgid "Sets email for password reset" -msgstr "" +msgstr "Встановлює ел. адресу для скидання пароля" #: src/view/com/auth/login/ForgotPasswordForm.tsx:122 msgid "Sets hosting provider for password reset" -msgstr "" - -#: src/view/com/auth/create/Step1.tsx:143 -#~ msgid "Sets hosting provider to {label}" -#~ msgstr "" +msgstr "Встановлює хостинг-провайдером для скидання пароля" #: src/view/com/auth/create/Step1.tsx:97 #: src/view/com/auth/login/LoginForm.tsx:151 msgid "Sets server for the Bluesky client" -msgstr "" +msgstr "Встановлює сервер для застосунку Bluesky" #: src/Navigation.tsx:137 #: src/view/screens/Settings/index.tsx:294 @@ -3925,7 +3706,7 @@ msgstr "Сексуальна активність або еротична ого #: src/view/com/lightbox/Lightbox.tsx:141 msgctxt "action" msgid "Share" -msgstr "" +msgstr "Поширити" #: src/view/com/profile/ProfileHeader.tsx:295 #: src/view/com/util/forms/PostDropdownBtn.tsx:231 @@ -3939,21 +3720,17 @@ msgstr "Поширити" msgid "Share feed" msgstr "Поширити стрічку" -#: src/view/screens/ProfileFeed.tsx:276 -#~ msgid "Share link" -#~ msgstr "" - #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:43 #: src/view/com/modals/ContentFilteringSettings.tsx:266 #: src/view/com/util/moderation/ContentHider.tsx:107 #: src/view/com/util/moderation/PostHider.tsx:108 #: src/view/screens/Settings/index.tsx:344 msgid "Show" -msgstr "Показати" +msgstr "Показувати" #: src/view/screens/PreferencesFollowingFeed.tsx:68 msgid "Show all replies" -msgstr "" +msgstr "Показати всі відповіді" #: src/view/com/util/moderation/ScreenHider.tsx:132 msgid "Show anyway" @@ -3965,13 +3742,13 @@ msgstr "Показати вбудування з {0}" #: src/view/com/profile/ProfileHeader.tsx:459 msgid "Show follows similar to {0}" -msgstr "" +msgstr "Показати підписки, схожі на {0}" #: src/view/com/post-thread/PostThreadItem.tsx:538 #: src/view/com/post/Post.tsx:198 #: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" -msgstr "" +msgstr "Показати більше" #: src/view/screens/PreferencesFollowingFeed.tsx:258 msgid "Show Posts from My Feeds" @@ -3983,15 +3760,15 @@ msgstr "Показувати цитати" #: src/screens/Onboarding/StepFollowingFeed.tsx:118 msgid "Show quote-posts in Following feed" -msgstr "" +msgstr "Показувати цитування у стрічці \"Following\"" #: src/screens/Onboarding/StepFollowingFeed.tsx:134 msgid "Show quotes in Following" -msgstr "" +msgstr "Показувати цитування у стрічці \"Following\"" #: src/screens/Onboarding/StepFollowingFeed.tsx:94 msgid "Show re-posts in Following feed" -msgstr "" +msgstr "Показувати репости у стрічці \"Following\"" #: src/view/screens/PreferencesFollowingFeed.tsx:119 msgid "Show Replies" @@ -4003,15 +3780,15 @@ msgstr "Показувати відповіді від людей, за яким #: src/screens/Onboarding/StepFollowingFeed.tsx:86 msgid "Show replies in Following" -msgstr "" +msgstr "Показувати відповіді у стрічці \"Following\"" #: src/screens/Onboarding/StepFollowingFeed.tsx:70 msgid "Show replies in Following feed" -msgstr "" +msgstr "Показувати відповіді у стрічці \"Following\"" #: src/view/screens/PreferencesFollowingFeed.tsx:70 msgid "Show replies with at least {value} {0}" -msgstr "" +msgstr "Показувати відповіді від {value} {0}" #: src/view/screens/PreferencesFollowingFeed.tsx:188 msgid "Show Reposts" @@ -4019,12 +3796,12 @@ msgstr "Показувати репости" #: src/screens/Onboarding/StepFollowingFeed.tsx:110 msgid "Show reposts in Following" -msgstr "" +msgstr "Показувати репости у стрічці \"Following\"" #: src/view/com/util/moderation/ContentHider.tsx:67 #: src/view/com/util/moderation/PostHider.tsx:61 msgid "Show the content" -msgstr "" +msgstr "Показати вміст" #: src/view/com/notifications/FeedItem.tsx:347 msgid "Show users" @@ -4032,12 +3809,12 @@ msgstr "Показати користувачів" #: src/view/com/profile/ProfileHeader.tsx:462 msgid "Shows a list of users similar to this user." -msgstr "" +msgstr "Показує список користувачів, схожих на цього." #: src/view/com/post-thread/PostThreadFollowBtn.tsx:124 #: src/view/com/profile/ProfileHeader.tsx:506 msgid "Shows posts from {0} in your feed" -msgstr "" +msgstr "Показує дописи з {0} у вашій стрічці" #: src/view/com/auth/HomeLoggedOutCTA.tsx:70 #: src/view/com/auth/login/Login.tsx:98 @@ -4105,11 +3882,11 @@ msgstr "Ви увійшли як" #: src/view/com/auth/login/ChooseAccountForm.tsx:103 msgid "Signed in as @{0}" -msgstr "" +msgstr "Ви увійшли як @{0}" #: src/view/com/modals/SwitchAccount.tsx:66 msgid "Signs {0} out of Bluesky" -msgstr "" +msgstr "Виходить з Bluesky облікового запису {0}" #: src/screens/Onboarding/StepInterests/index.tsx:235 #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:195 @@ -4119,7 +3896,7 @@ msgstr "Пропустити" #: src/screens/Onboarding/StepInterests/index.tsx:232 msgid "Skip this flow" -msgstr "" +msgstr "Пропустити цей процес" #: src/view/com/auth/create/Step2.tsx:82 #~ msgid "SMS verification" @@ -4127,7 +3904,7 @@ msgstr "" #: src/screens/Onboarding/index.tsx:40 msgid "Software Dev" -msgstr "" +msgstr "Розробка П/З" #: src/view/com/modals/ProfilePreview.tsx:62 #~ msgid "Something went wrong and we're not sure what." @@ -4135,7 +3912,7 @@ msgstr "" #: src/components/Lists.tsx:203 msgid "Something went wrong!" -msgstr "" +msgstr "Щось пішло не так!" #: src/view/com/modals/Waitlist.tsx:51 #~ msgid "Something went wrong. Check your email and try again." @@ -4143,7 +3920,7 @@ msgstr "" #: src/App.native.tsx:66 msgid "Sorry! Your session expired. Please log in again." -msgstr "" +msgstr "Даруйте! Ваш сеанс вичерпався. Будь ласка, увійдіть знову." #: src/view/screens/PreferencesThreads.tsx:69 msgid "Sort Replies" @@ -4155,7 +3932,7 @@ msgstr "Оберіть, як сортувати відповіді до пост #: src/screens/Onboarding/index.tsx:30 msgid "Sports" -msgstr "" +msgstr "Спорт" #: src/view/com/modals/crop-image/CropImage.web.tsx:122 msgid "Square" @@ -4171,15 +3948,11 @@ msgstr "Сторінка стану" #: src/view/com/auth/create/StepHeader.tsx:22 msgid "Step {0} of {numSteps}" -msgstr "" - -#: src/view/com/auth/create/StepHeader.tsx:15 -#~ msgid "Step {step} of 3" -#~ msgstr "" +msgstr "Крок {0} / {numSteps}" #: src/view/screens/Settings/index.tsx:274 msgid "Storage cleared, you need to restart the app now." -msgstr "" +msgstr "Сховище очищено, тепер вам треба перезапустити застосунок." #: src/Navigation.tsx:204 #: src/view/screens/Settings/index.tsx:807 @@ -4197,27 +3970,23 @@ msgstr "Підписатися" #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:173 #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:308 msgid "Subscribe to the {0} feed" -msgstr "" +msgstr "Підписатися на {0} стрічку" #: src/view/screens/ProfileList.tsx:604 msgid "Subscribe to this list" msgstr "Підписатися на цей список" -#: src/view/com/lists/ListCard.tsx:101 -#~ msgid "Subscribed" -#~ msgstr "" - #: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" msgstr "Пропоновані підписки" #: src/view/com/profile/ProfileHeaderSuggestedFollows.tsx:64 msgid "Suggested for you" -msgstr "" +msgstr "Пропозиції для вас" #: src/view/com/modals/SelfLabel.tsx:95 msgid "Suggestive" -msgstr "" +msgstr "Непристойний" #: src/Navigation.tsx:214 #: src/view/screens/Support.tsx:30 @@ -4236,16 +4005,16 @@ msgstr "Перемикнути обліковий запис" #: src/view/com/modals/SwitchAccount.tsx:97 #: src/view/screens/Settings/index.tsx:130 msgid "Switch to {0}" -msgstr "" +msgstr "Переключитися на {0}" #: src/view/com/modals/SwitchAccount.tsx:98 #: src/view/screens/Settings/index.tsx:131 msgid "Switches the account you are logged in to" -msgstr "" +msgstr "Переключає обліковий запис" #: src/view/screens/Settings/index.tsx:472 msgid "System" -msgstr "" +msgstr "Системне" #: src/view/screens/Settings/index.tsx:795 msgid "System log" @@ -4253,11 +4022,11 @@ msgstr "Системний журнал" #: src/components/dialogs/MutedWords.tsx:337 msgid "tag" -msgstr "" +msgstr "тег" #: src/components/TagMenu/index.tsx:78 msgid "Tag menu: {displayTag}" -msgstr "" +msgstr "Меню тегів: {displayTag}" #: src/components/TagMenu/index.tsx:74 #~ msgid "Tag menu: {tag}" @@ -4269,11 +4038,11 @@ msgstr "Високе" #: src/view/com/util/images/AutoSizedImage.tsx:70 msgid "Tap to view fully" -msgstr "" +msgstr "Торкніться, щоб переглянути повністю" #: src/screens/Onboarding/index.tsx:39 msgid "Tech" -msgstr "" +msgstr "Технології" #: src/view/shell/desktop/RightNav.tsx:81 msgid "Terms" @@ -4288,7 +4057,7 @@ msgstr "Умови Використання" #: src/components/dialogs/MutedWords.tsx:337 msgid "text" -msgstr "" +msgstr "текст" #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 @@ -4297,7 +4066,7 @@ msgstr "Поле вводу тексту" #: src/view/com/auth/create/CreateAccount.tsx:94 msgid "That handle is already taken." -msgstr "" +msgstr "Цей псевдонім вже зайнятий." #: src/view/com/profile/ProfileHeader.tsx:263 msgid "The account will be able to interact with you after unblocking." @@ -4313,7 +4082,7 @@ msgstr "Політику захисту авторського права пер #: src/screens/Onboarding/Layout.tsx:60 msgid "The following steps will help customize your Bluesky experience." -msgstr "" +msgstr "Наступні кроки допоможуть налаштувати Ваш досвід використання Bluesky." #: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." @@ -4325,11 +4094,7 @@ msgstr "Політика конфіденційності була перемі #: src/view/screens/Support.tsx:36 msgid "The support form has been moved. If you need help, please <0/> or visit {HELP_DESK_URL} to get in touch with us." -msgstr "" - -#: src/view/screens/Support.tsx:36 -#~ msgid "The support form has been moved. If you need help, please<0/> or visit {HELP_DESK_URL} to get in touch with us." -#~ msgstr "Форма підтримки була переміщена. Якщо вам потрібна допомога, будь ласка, <0/> або відвідайте {HELP_DESK_URL}, щоб зв'язатися з нами." +msgstr "Форму підтримки переміщено. Якщо вам потрібна допомога, будь ласка, <0/> або відвідайте {HELP_DESK_URL}, щоб зв'язатися з нами." #: src/view/screens/TermsOfService.tsx:33 msgid "The Terms of Service have been moved to" @@ -4337,19 +4102,19 @@ msgstr "Умови Використання перенесено до" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:150 msgid "There are many feeds to try:" -msgstr "" +msgstr "Також є багато інших стрічок, щоб спробувати:" #: src/view/screens/ProfileFeed.tsx:550 msgid "There was an an issue contacting the server, please check your internet connection and try again." -msgstr "" +msgstr "Виникла проблема з доступом до сервера. Перевірте підключення до Інтернету і повторіть спробу знову." #: src/view/com/posts/FeedErrorMessage.tsx:139 msgid "There was an an issue removing this feed. Please check your internet connection and try again." -msgstr "" +msgstr "Виникла проблема при видаленні цієї стрічки. Перевірте підключення до Інтернету і повторіть спробу." #: src/view/screens/ProfileFeed.tsx:210 msgid "There was an an issue updating your feeds, please check your internet connection and try again." -msgstr "" +msgstr "Виникла проблема з оновленням ваших стрічок. Перевірте підключення до Інтернету і повторіть спробу." #: src/view/screens/ProfileFeed.tsx:237 #: src/view/screens/ProfileList.tsx:267 @@ -4357,7 +4122,7 @@ msgstr "" #: src/view/screens/SavedFeeds.tsx:231 #: src/view/screens/SavedFeeds.tsx:252 msgid "There was an issue contacting the server" -msgstr "" +msgstr "При з'єднанні з сервером виникла проблема" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:57 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:66 @@ -4365,33 +4130,33 @@ msgstr "" #: src/view/com/feeds/FeedSourceCard.tsx:129 #: src/view/com/feeds/FeedSourceCard.tsx:183 msgid "There was an issue contacting your server" -msgstr "" +msgstr "При з'єднанні з вашим сервером виникла проблема" #: src/view/com/notifications/Feed.tsx:117 msgid "There was an issue fetching notifications. Tap here to try again." -msgstr "" +msgstr "Виникла проблема з завантаженням сповіщень. Натисніть тут, щоб повторити спробу." #: src/view/com/posts/Feed.tsx:265 msgid "There was an issue fetching posts. Tap here to try again." -msgstr "" +msgstr "Виникла проблема з завантаженням постів. Натисніть тут, щоб повторити спробу." #: src/view/com/lists/ListMembers.tsx:172 msgid "There was an issue fetching the list. Tap here to try again." -msgstr "" +msgstr "Виникла проблема з завантаженням списку. Натисніть тут, щоб повторити спробу." #: src/view/com/feeds/ProfileFeedgens.tsx:148 #: src/view/com/lists/ProfileLists.tsx:155 msgid "There was an issue fetching your lists. Tap here to try again." -msgstr "" +msgstr "Виникла проблема з завантаженням ваших списків. Натисніть тут, щоб повторити спробу." #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:63 #: src/view/com/modals/ContentFilteringSettings.tsx:126 msgid "There was an issue syncing your preferences with the server" -msgstr "" +msgstr "Виникла проблема під час синхронізації ваших налаштувань із сервером" #: src/view/screens/AppPasswords.tsx:66 msgid "There was an issue with fetching your app passwords" -msgstr "" +msgstr "Виникла проблема з завантаженням ваших паролів для застосунків" #: src/view/com/post-thread/PostThreadFollowBtn.tsx:93 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:105 @@ -4402,14 +4167,14 @@ msgstr "" #: src/view/com/profile/ProfileHeader.tsx:250 #: src/view/com/profile/ProfileHeader.tsx:272 msgid "There was an issue! {0}" -msgstr "" +msgstr "Виникла проблема! {0}" #: src/view/screens/ProfileList.tsx:288 #: src/view/screens/ProfileList.tsx:307 #: src/view/screens/ProfileList.tsx:329 #: src/view/screens/ProfileList.tsx:348 msgid "There was an issue. Please check your internet connection and try again." -msgstr "" +msgstr "Виникла проблема. Перевірте підключення до Інтернету і повторіть спробу." #: src/view/com/util/ErrorBoundary.tsx:36 msgid "There was an unexpected issue in the application. Please let us know if this happened to you!" @@ -4417,7 +4182,7 @@ msgstr "У застосунку сталася неочікувана пробл #: src/screens/Deactivated.tsx:106 msgid "There's been a rush of new users to Bluesky! We'll activate your account as soon as we can." -msgstr "" +msgstr "Відбувався наплив нових користувачів у Bluesky! Ми активуємо ваш обліковий запис як тільки зможемо." #: src/view/com/auth/create/Step2.tsx:55 #~ msgid "There's something wrong with this number. Please choose your country and enter your full phone number!" @@ -4425,15 +4190,7 @@ msgstr "" #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:138 msgid "These are popular accounts you might like:" -msgstr "" - -#: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:138 -#~ msgid "These are popular accounts you might like." -#~ msgstr "" - -#: src/view/com/util/moderation/LabelInfo.tsx:45 -#~ msgid "This {0} has been labeled." -#~ msgstr "" +msgstr "Ці популярні користувачі можуть вам сподобатися:" #: src/view/com/util/moderation/ScreenHider.tsx:88 msgid "This {screenDescription} has been flagged:" @@ -4449,7 +4206,7 @@ msgstr "Цей вміст розміщено {0}. Увімкнути зовні #: src/view/com/modals/ModerationDetails.tsx:67 msgid "This content is not available because one of the users involved has blocked the other." -msgstr "" +msgstr "Цей контент недоступний, оскільки один із залучених користувачів заблокував іншого." #: src/view/com/posts/FeedErrorMessage.tsx:108 msgid "This content is not viewable without a Bluesky account." @@ -4457,7 +4214,7 @@ msgstr "Цей вміст не доступний для перегляду бе #: src/view/screens/Settings/ExportCarDialog.tsx:75 msgid "This feature is in beta. You can read more about repository exports in <0>this blogpost.</0>" -msgstr "" +msgstr "Ця функція знаходиться в беті. Ви можете дізнатися більше про експорт репозиторіїв в <0>у цьому блозі.</0>" #: src/view/com/posts/FeedErrorMessage.tsx:114 msgid "This feed is currently receiving high traffic and is temporarily unavailable. Please try again later." @@ -4467,11 +4224,11 @@ msgstr "Ця стрічка зараз отримує забагато запи #: src/view/screens/ProfileFeed.tsx:476 #: src/view/screens/ProfileList.tsx:661 msgid "This feed is empty!" -msgstr "" +msgstr "Стрічка порожня!" #: src/view/com/posts/CustomFeedEmptyState.tsx:37 msgid "This feed is empty! You may need to follow more users or tune your language settings." -msgstr "" +msgstr "Ця стрічка порожня! Можливо, вам треба підписатися на більшу кількість користувачів або змінити ваші налаштування мови." #: src/view/com/modals/BirthDateSettings.tsx:61 msgid "This information is not shared with other users." @@ -4481,21 +4238,17 @@ msgstr "Ця інформація не розкривається іншим к msgid "This is important in case you ever need to change your email or reset your password." msgstr "Це важливо для випадку, якщо вам коли-небудь потрібно буде змінити адресу електронної пошти або відновити пароль." -#: src/view/com/auth/create/Step1.tsx:55 -#~ msgid "This is the service that keeps you online." -#~ msgstr "Це сервіс який зберігає дані вашого облікового запису." - #: src/view/com/modals/LinkWarning.tsx:58 msgid "This link is taking you to the following website:" msgstr "Це посилання веде на сайт:" #: src/view/screens/ProfileList.tsx:839 msgid "This list is empty!" -msgstr "" +msgstr "Список порожній!" #: src/view/com/modals/AddAppPasswords.tsx:106 msgid "This name is already in use" -msgstr "" +msgstr "Це ім'я вже використовується" #: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." @@ -4503,15 +4256,15 @@ msgstr "Цей пост було видалено." #: src/view/com/modals/ModerationDetails.tsx:62 msgid "This user has blocked you. You cannot view their content." -msgstr "" +msgstr "Цей користувач заблокував вас. Ви не можете бачити їх пости." #: src/view/com/modals/ModerationDetails.tsx:42 msgid "This user is included in the <0/> list which you have blocked." -msgstr "" +msgstr "Цей користувач в списку \"<0/>\" на який ви підписались та заблокували." #: src/view/com/modals/ModerationDetails.tsx:74 msgid "This user is included in the <0/> list which you have muted." -msgstr "" +msgstr "Цей користувач в списку \"<0/>\" який ви ігноруєте." #: src/view/com/modals/ModerationDetails.tsx:74 #~ msgid "This user is included the <0/> list which you have muted." @@ -4523,11 +4276,11 @@ msgstr "Це попередження доступне тільки для за #: src/components/dialogs/MutedWords.tsx:285 msgid "This will delete {0} from your muted words. You can always add it back later." -msgstr "" +msgstr "Це видалить {0} зі ваших ігнорованих слів. Ви завжди можете додати його назад." #: src/view/com/util/forms/PostDropdownBtn.tsx:282 msgid "This will hide this post from your feeds." -msgstr "Це приховає цей пост із вашої стрічки." +msgstr "Це дія приховає цей пост із вашої стрічки." #: src/view/screens/PreferencesThreads.tsx:53 #: src/view/screens/Settings/index.tsx:565 @@ -4540,11 +4293,11 @@ msgstr "Режим гілок" #: src/Navigation.tsx:257 msgid "Threads Preferences" -msgstr "" +msgstr "Налаштування обговорень" #: src/components/dialogs/MutedWords.tsx:113 msgid "Toggle between muted word options." -msgstr "" +msgstr "Перемикання між опціями ігнорування слів." #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" @@ -4564,11 +4317,7 @@ msgstr "Перекласти" #: src/view/com/util/error/ErrorScreen.tsx:82 msgctxt "action" msgid "Try again" -msgstr "" - -#: src/view/com/util/error/ErrorScreen.tsx:73 -#~ msgid "Try again" -#~ msgstr "Спробувати ще раз" +msgstr "Спробувати ще раз" #: src/view/screens/ProfileList.tsx:506 msgid "Un-block list" @@ -4594,7 +4343,7 @@ msgstr "Розблокувати" #: src/view/com/profile/ProfileHeader.tsx:436 msgctxt "action" msgid "Unblock" -msgstr "" +msgstr "Розблокувати" #: src/view/com/profile/ProfileHeader.tsx:261 #: src/view/com/profile/ProfileHeader.tsx:345 @@ -4611,11 +4360,11 @@ msgstr "Скасувати репост" #: src/view/com/profile/FollowButton.tsx:55 msgctxt "action" msgid "Unfollow" -msgstr "" +msgstr "Відписатись" #: src/view/com/profile/ProfileHeader.tsx:485 msgid "Unfollow {0}" -msgstr "" +msgstr "Відписатися від {0}" #: src/view/com/auth/create/state.ts:262 msgid "Unfortunately, you do not meet the requirements to create an account." @@ -4623,16 +4372,16 @@ msgstr "На жаль, ви не відповідаєте вимогам для #: src/view/com/util/post-ctrls/PostCtrls.tsx:182 msgid "Unlike" -msgstr "" +msgstr "Прибрати вподобання" #: src/components/TagMenu/index.tsx:249 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" -msgstr "" +msgstr "Не ігнорувати" #: src/components/TagMenu/index.web.tsx:104 msgid "Unmute {truncatedTag}" -msgstr "" +msgstr "Не ігнорувати {truncatedTag}" #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" @@ -4640,7 +4389,7 @@ msgstr "Перестати ігнорувати" #: src/components/TagMenu/index.tsx:208 msgid "Unmute all {displayTag} posts" -msgstr "" +msgstr "Перестати ігнорувати всі пости {displayTag}" #: src/components/TagMenu/index.tsx:210 #~ msgid "Unmute all {tag} posts" @@ -4654,7 +4403,7 @@ msgstr "Перестати ігнорувати" #: src/view/screens/ProfileFeed.tsx:354 #: src/view/screens/ProfileList.tsx:581 msgid "Unpin" -msgstr "" +msgstr "Відкріпити" #: src/view/screens/ProfileList.tsx:474 msgid "Unpin moderation list" @@ -4662,7 +4411,7 @@ msgstr "Відкріпити список модерації" #: src/view/screens/ProfileFeed.tsx:346 msgid "Unsave" -msgstr "" +msgstr "Скасувати збереження" #: src/view/com/modals/UserAddRemoveLists.tsx:70 msgid "Update {displayName} in Lists" @@ -4691,12 +4440,12 @@ msgstr "Використовувати провайдера за замовчу #: src/view/com/modals/InAppBrowserConsent.tsx:56 #: src/view/com/modals/InAppBrowserConsent.tsx:58 msgid "Use in-app browser" -msgstr "" +msgstr "У вбудованому браузері" #: src/view/com/modals/InAppBrowserConsent.tsx:66 #: src/view/com/modals/InAppBrowserConsent.tsx:68 msgid "Use my default browser" -msgstr "" +msgstr "У звичайному браузері" #: src/view/com/modals/AddAppPasswords.tsx:155 msgid "Use this to sign into the other app along with your handle." @@ -4712,15 +4461,15 @@ msgstr "Використано:" #: src/view/com/modals/ModerationDetails.tsx:54 msgid "User Blocked" -msgstr "" +msgstr "Користувача заблоковано" #: src/view/com/modals/ModerationDetails.tsx:40 msgid "User Blocked by List" -msgstr "" +msgstr "Користувача заблоковано списком" #: src/view/com/modals/ModerationDetails.tsx:60 msgid "User Blocks You" -msgstr "" +msgstr "Користувач заблокував вас" #: src/view/com/auth/create/Step2.tsx:79 msgid "User handle" @@ -4729,25 +4478,25 @@ msgstr "Псевдонім" #: src/view/com/lists/ListCard.tsx:85 #: src/view/com/modals/UserAddRemoveLists.tsx:198 msgid "User list by {0}" -msgstr "" +msgstr "Список користувачів від {0}" #: src/view/screens/ProfileList.tsx:763 msgid "User list by <0/>" -msgstr "" +msgstr "Список користувачів від <0/>" #: src/view/com/lists/ListCard.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:196 #: src/view/screens/ProfileList.tsx:761 msgid "User list by you" -msgstr "" +msgstr "Список користувачів від вас" #: src/view/com/modals/CreateOrEditList.tsx:196 msgid "User list created" -msgstr "" +msgstr "Список користувачів створено" #: src/view/com/modals/CreateOrEditList.tsx:182 msgid "User list updated" -msgstr "" +msgstr "Список користувачів оновлено" #: src/view/screens/Lists.tsx:58 msgid "User Lists" @@ -4766,10 +4515,6 @@ msgstr "Користувачі" msgid "users followed by <0/>" msgstr "користувачі, на яких підписані <0/>" -#: src/view/com/threadgate/WhoCanReply.tsx:115 -#~ msgid "Users followed by <0/>" -#~ msgstr "" - #: src/view/com/modals/Threadgate.tsx:106 msgid "Users in \"{0}\"" msgstr "Користувачі в «{0}»" @@ -4797,15 +4542,15 @@ msgstr "Підтвердити нову адресу електронної по #: src/view/com/modals/VerifyEmail.tsx:103 msgid "Verify Your Email" -msgstr "" +msgstr "Підтвердьте адресу вашої електронної пошти" #: src/screens/Onboarding/index.tsx:42 msgid "Video Games" -msgstr "" +msgstr "Відеоігри" #: src/view/com/profile/ProfileHeader.tsx:662 msgid "View {0}'s avatar" -msgstr "" +msgstr "Переглянути аватар {0}" #: src/view/screens/Log.tsx:52 msgid "View debug entry" @@ -4813,11 +4558,11 @@ msgstr "Переглянути запис для налагодження" #: src/view/com/posts/FeedSlice.tsx:103 msgid "View full thread" -msgstr "" +msgstr "Переглянути обговорення" #: src/view/com/posts/FeedErrorMessage.tsx:172 msgid "View profile" -msgstr "" +msgstr "Переглянути профіль" #: src/view/com/profile/ProfileSubpageHeader.tsx:128 msgid "View the avatar" @@ -4830,31 +4575,27 @@ msgstr "Відвідати сайт" #: src/screens/Onboarding/StepModeration/ModerationOption.tsx:42 #: src/view/com/modals/ContentFilteringSettings.tsx:259 msgid "Warn" -msgstr "" +msgstr "Попереджати" #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:134 msgid "We also think you'll like \"For You\" by Skygaze:" -msgstr "" +msgstr "Гадаємо, вам також сподобається «For You» від Skygaze:" #: src/screens/Hashtag.tsx:132 msgid "We couldn't find any results for that hashtag." -msgstr "" +msgstr "Ми не змогли знайти жодних результатів для цього хештегу." #: src/screens/Deactivated.tsx:133 msgid "We estimate {estimatedTime} until your account is ready." -msgstr "" +msgstr "Ми оцінюємо {estimatedTime} до готовності вашого облікового запису." #: src/screens/Onboarding/StepFinished.tsx:93 msgid "We hope you have a wonderful time. Remember, Bluesky is:" -msgstr "" - -#: src/view/com/posts/DiscoverFallbackHeader.tsx:29 -#~ msgid "We ran out of posts from your follows. Here's the latest from" -#~ msgstr "" +msgstr "Ми сподіваємося, що ви проведете чудово свій час. Пам'ятайте, Bluesky — це:" #: src/view/com/posts/DiscoverFallbackHeader.tsx:29 msgid "We ran out of posts from your follows. Here's the latest from <0/>." -msgstr "" +msgstr "У нас закінчилися дописи у ваших підписках. Ось останні пости зі стрічки <0/>." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:118 #~ msgid "We recommend \"For You\" by Skygaze:" @@ -4862,47 +4603,39 @@ msgstr "" #: src/components/dialogs/MutedWords.tsx:204 msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." -msgstr "" +msgstr "Ми рекомендуємо уникати загальних слів, що зʼявляються у багатьох постах, оскільки це може призвести до того, що жодного поста не буде показано." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" -msgstr "" +msgstr "Ми рекомендуємо стрічку «Discover»:" #: src/screens/Onboarding/StepInterests/index.tsx:133 msgid "We weren't able to connect. Please try again to continue setting up your account. If it continues to fail, you can skip this flow." -msgstr "" +msgstr "Ми не змогли під'єднатися. Будь ласка, спробуйте ще раз, щоб продовжити налаштування свого облікового запису. Якщо помилка повторюється, то ви можете пропустити цей процес." #: src/screens/Deactivated.tsx:137 msgid "We will let you know when your account is ready." -msgstr "" +msgstr "Ми повідомимо вас, коли ваш обліковий запис буде готовий." #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." -msgstr "" +msgstr "Ми скоро розглянемо вашу апеляцію." #: src/screens/Onboarding/StepInterests/index.tsx:138 msgid "We'll use this to help customize your experience." -msgstr "" +msgstr "Ми скористаємося цим, щоб підлаштувати Ваш досвід." #: src/view/com/auth/create/CreateAccount.tsx:134 msgid "We're so excited to have you join us!" msgstr "Ми дуже раді, що ви приєдналися!" -#: src/view/com/posts/FeedErrorMessage.tsx:99 -#~ msgid "We're sorry, but this content is not viewable without a Bluesky account." -#~ msgstr "" - -#: src/view/com/posts/FeedErrorMessage.tsx:105 -#~ msgid "We're sorry, but this feed is currently receiving high traffic and is temporarily unavailable. Please try again later." -#~ msgstr "" - #: src/view/screens/ProfileList.tsx:86 msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." -msgstr "" +msgstr "Дуже прикро, але нам не вдалося знайти цей список. Якщо це продовжується, будь ласка, зв'яжіться з його автором: @{handleOrDid}." #: src/components/dialogs/MutedWords.tsx:230 msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." -msgstr "" +msgstr "На жаль, ми не змогли зараз завантажити ваші ігноровані слова. Будь ласка, спробуйте ще раз." #: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." @@ -4919,7 +4652,7 @@ msgstr "Ласкаво просимо до <0>Bluesky</0>" #: src/screens/Onboarding/StepInterests/index.tsx:130 msgid "What are your interests?" -msgstr "" +msgstr "Чим ви цікавитесь?" #: src/view/com/modals/report/Modal.tsx:169 msgid "What is the issue with this {collectionName}?" @@ -4943,10 +4676,6 @@ msgstr "Якими мовами ви хочете бачити пости у а msgid "Who can reply" msgstr "Хто може відповідати" -#: src/view/com/threadgate/WhoCanReply.tsx:79 -#~ msgid "Who can reply?" -#~ msgstr "" - #: src/view/com/modals/crop-image/CropImage.web.tsx:102 msgid "Wide" msgstr "Широке" @@ -4962,7 +4691,7 @@ msgstr "Написати відповідь" #: src/screens/Onboarding/index.tsx:28 msgid "Writers" -msgstr "" +msgstr "Письменники" #: src/view/com/auth/create/Step2.tsx:263 #~ msgid "XXXXXX" @@ -4984,24 +4713,20 @@ msgstr "Так" #: src/screens/Deactivated.tsx:130 msgid "You are in line." -msgstr "" +msgstr "Ви в черзі." #: src/view/com/posts/FollowingEmptyState.tsx:67 #: src/view/com/posts/FollowingEndOfFeed.tsx:68 msgid "You can also discover new Custom Feeds to follow." -msgstr "" +msgstr "Також ви можете знайти кастомні стрічки для підписання." #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:123 #~ msgid "You can also try our \"Discover\" algorithm:" #~ msgstr "" -#: src/view/com/auth/create/Step1.tsx:106 -#~ msgid "You can change hosting providers at any time." -#~ msgstr "Ви можете змінити хостинг-провайдера у будь-який час." - #: src/screens/Onboarding/StepFollowingFeed.tsx:142 msgid "You can change these settings later." -msgstr "" +msgstr "Ви можете змінити ці налаштування пізніше." #: src/view/com/auth/login/Login.tsx:158 #: src/view/com/auth/login/PasswordUpdatedForm.tsx:31 @@ -5030,18 +4755,18 @@ msgstr "Ви заблокували автора або автор заблок #: src/view/com/modals/ModerationDetails.tsx:56 msgid "You have blocked this user. You cannot view their content." -msgstr "" +msgstr "Ви заблокували цього користувача. Ви не можете бачити їх вміст." #: src/view/com/auth/login/SetNewPasswordForm.tsx:57 #: src/view/com/auth/login/SetNewPasswordForm.tsx:92 #: src/view/com/modals/ChangePassword.tsx:87 #: src/view/com/modals/ChangePassword.tsx:121 msgid "You have entered an invalid code. It should look like XXXXX-XXXXX." -msgstr "" +msgstr "Ви ввели неправильний код. Він має виглядати так: XXXXX-XXXXX." #: src/view/com/modals/ModerationDetails.tsx:87 msgid "You have muted this user." -msgstr "" +msgstr "Ви включили функцію ігнорування цього користувача." #: src/view/com/feeds/ProfileFeedgens.tsx:136 msgid "You have no feeds." @@ -5066,23 +4791,23 @@ msgstr "Ви ще не ігноруєте жодного облікового з #: src/components/dialogs/MutedWords.tsx:250 msgid "You haven't muted any words or tags yet" -msgstr "" +msgstr "У вас ще немає ігнорованих слів чи тегів" #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." -msgstr "" +msgstr "Щоб увімкнути відображення вмісту для дорослих вам повинно бути не менше 18 років." #: src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx:103 msgid "You must be 18 years or older to enable adult content" -msgstr "" +msgstr "Ви повинні бути старше 18 років, щоб дозволити перегляд контенту для дорослих" #: src/view/com/util/forms/PostDropdownBtn.tsx:147 msgid "You will no longer receive notifications for this thread" -msgstr "" +msgstr "Ви більше не будете отримувати сповіщення з цього обговорення" #: src/view/com/util/forms/PostDropdownBtn.tsx:150 msgid "You will now receive notifications for this thread" -msgstr "" +msgstr "Ви будете отримувати сповіщення з цього обговорення" #: src/view/com/auth/login/SetNewPasswordForm.tsx:107 msgid "You will receive an email with a \"reset code.\" Enter that code here, then enter your new password." @@ -5090,21 +4815,21 @@ msgstr "Ви отримаєте електронний лист із кодом #: src/screens/Onboarding/StepModeration/index.tsx:72 msgid "You're in control" -msgstr "" +msgstr "Все під вашим контролем" #: src/screens/Deactivated.tsx:87 #: src/screens/Deactivated.tsx:88 #: src/screens/Deactivated.tsx:103 msgid "You're in line" -msgstr "" +msgstr "Ви в черзі" #: src/screens/Onboarding/StepFinished.tsx:90 msgid "You're ready to go!" -msgstr "" +msgstr "Все готово!" #: src/view/com/posts/FollowingEndOfFeed.tsx:48 msgid "You've reached the end of your feed! Find some more accounts to follow." -msgstr "" +msgstr "Ваша домашня стрічка закінчилась! Підпишіться на більше користувачів щоб отримувати більше постів." #: src/view/com/auth/create/Step1.tsx:67 msgid "Your account" @@ -5112,11 +4837,11 @@ msgstr "Ваш акаунт" #: src/view/com/modals/DeleteAccount.tsx:67 msgid "Your account has been deleted" -msgstr "" +msgstr "Ваш обліковий запис видалено" #: src/view/screens/Settings/ExportCarDialog.tsx:47 msgid "Your account repository, containing all public data records, can be downloaded as a \"CAR\" file. This file does not include media embeds, such as images, or your private data, which must be fetched separately." -msgstr "" +msgstr "Дані з вашого облікового запису, які містять усі загальнодоступні записи, можна завантажити як \"CAR\" файл. Цей файл не містить медіафайлів, таких як зображення, або особисті дані, які необхідно отримати окремо." #: src/view/com/auth/create/Step1.tsx:215 msgid "Your birth date" @@ -5124,11 +4849,11 @@ msgstr "Ваша дата народження" #: src/view/com/modals/InAppBrowserConsent.tsx:47 msgid "Your choice will be saved, but can be changed later in settings." -msgstr "" +msgstr "Ваш вибір буде запам'ятовано, ви у будь-який момент зможете змінити його в налаштуваннях." #: src/screens/Onboarding/StepFollowingFeed.tsx:61 msgid "Your default feed is \"Following\"" -msgstr "" +msgstr "Ваша стрічка за замовчуванням \"Following\"" #: src/view/com/auth/create/state.ts:110 #: src/view/com/auth/login/ForgotPasswordForm.tsx:70 @@ -5138,7 +4863,7 @@ msgstr "Не вдалося розпізнати адресу електронн #: src/view/com/modals/Waitlist.tsx:109 #~ msgid "Your email has been saved! We'll be in touch soon." -#~ msgstr "Вашу електронну адресу збережено! Ми скоро зв'яжемося з вами." +#~ msgstr "" #: src/view/com/modals/ChangeEmail.tsx:125 msgid "Your email has been updated but not verified. As a next step, please verify your new email." @@ -5150,7 +4875,7 @@ msgstr "Ваша електронна пошта ще не підтвердже #: src/view/com/posts/FollowingEmptyState.tsx:47 msgid "Your following feed is empty! Follow more users to see what's happening." -msgstr "" +msgstr "Ваша домашня стрічка порожня! Підпишіться на більше користувачів щоб отримувати більше постів." #: src/view/com/auth/create/Step2.tsx:83 msgid "Your full handle will be" @@ -5158,29 +4883,25 @@ msgstr "Ваш повний псевдонім буде" #: src/view/com/modals/ChangeHandle.tsx:270 msgid "Your full handle will be <0>@{0}</0>" -msgstr "" - -#: src/view/com/auth/create/Step1.tsx:53 -#~ msgid "Your hosting provider" -#~ msgstr "Ваш хостинг-провайдер" +msgstr "Вашим повним псевдонімом буде <0>@{0}</0>" #: src/view/screens/Settings.tsx:430 #: src/view/shell/desktop/RightNav.tsx:137 #: src/view/shell/Drawer.tsx:660 #~ msgid "Your invite codes are hidden when logged in using an App Password" -#~ msgstr "Ваші коди запрошення приховано, якщо ви увійшли за допомогою пароля для застосунків" +#~ msgstr "" #: src/components/dialogs/MutedWords.tsx:221 msgid "Your muted words" -msgstr "" +msgstr "Ваші ігноровані слова" #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" -msgstr "" +msgstr "Ваш пароль успішно змінено!" #: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" -msgstr "" +msgstr "Пост опубліковано" #: src/screens/Onboarding/StepFinished.tsx:105 #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:59 @@ -5193,22 +4914,11 @@ msgstr "Ваші повідомлення, вподобання і блоки є msgid "Your profile" msgstr "Ваш профіль" -#: src/view/screens/Moderation.tsx:205 -#~ msgid "Your profile and account will not be visible to anyone visiting the Bluesky app without an account, or to account holders who are not logged in. Enabling this will not make your profile private." -#~ msgstr "" - -#: src/view/screens/Moderation.tsx:220 -#~ msgid "Your profile and content will not be visible to anyone visiting the Bluesky app without an account. Enabling this will not make your profile private." -#~ msgstr "" - -#: src/view/screens/Moderation.tsx:220 -#~ msgid "Your profile and posts will not be visible to people visiting the Bluesky app or website without having an account and being logged in." -#~ msgstr "" - #: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" -msgstr "" +msgstr "Відповідь опубліковано" #: src/view/com/auth/create/Step2.tsx:65 msgid "Your user handle" msgstr "Ваш псевдонім" + From ebf8644df9d677a57e565f1c8b2983e33dab5749 Mon Sep 17 00:00:00 2001 From: dan <dan.abramov@gmail.com> Date: Tue, 19 Mar 2024 20:19:11 +0000 Subject: [PATCH 106/109] Track notification open (#3274) --- src/lib/notifications/notifications.ts | 2 ++ src/lib/statsig/events.ts | 1 + 2 files changed, 3 insertions(+) diff --git a/src/lib/notifications/notifications.ts b/src/lib/notifications/notifications.ts index 62d0bfc4b1..e811f690ed 100644 --- a/src/lib/notifications/notifications.ts +++ b/src/lib/notifications/notifications.ts @@ -7,6 +7,7 @@ import {logger} from '#/logger' import {RQKEY as RQKEY_NOTIFS} from '#/state/queries/notifications/feed' import {truncateAndInvalidate} from '#/state/queries/util' import {SessionAccount, getAgent} from '#/state/session' +import {logEvent} from '../statsig/statsig' const SERVICE_DID = (serviceUrl?: string) => serviceUrl?.includes('staging') @@ -123,6 +124,7 @@ export function init(queryClient: QueryClient) { logger.DebugContext.notifications, ) track('Notificatons:OpenApp') + logEvent('notifications:openApp', {}) truncateAndInvalidate(queryClient, RQKEY_NOTIFS()) resetToTab('NotificationsTab') // open notifications tab } diff --git a/src/lib/statsig/events.ts b/src/lib/statsig/events.ts index cb9f3fe924..b91a15ecb1 100644 --- a/src/lib/statsig/events.ts +++ b/src/lib/statsig/events.ts @@ -2,6 +2,7 @@ export type LogEvents = { init: { initMs: number } + 'notifications:openApp': {} 'state:background': {} 'state:foreground': {} 'feed:endReached': { From ccf53af2ba1120e423679f5c0803349de4331443 Mon Sep 17 00:00:00 2001 From: Hailey <me@haileyok.com> Date: Tue, 19 Mar 2024 13:26:25 -0700 Subject: [PATCH 107/109] Prevent linking to post from an embed in composer (#3275) --- src/view/com/composer/Composer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index ab7551b609..ddb01a8fa6 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -447,7 +447,7 @@ export const ComposePost = observer(function ComposePost({ /> )} {quote ? ( - <View style={[s.mt5, isWeb && s.mb10]}> + <View style={[s.mt5, isWeb && s.mb10, {pointerEvents: 'none'}]}> <QuoteEmbed quote={quote} /> </View> ) : undefined} From e433a1c968af548327c15bcc2e7fcb5a80760d36 Mon Sep 17 00:00:00 2001 From: Paul Frazee <pfrazee@gmail.com> Date: Tue, 19 Mar 2024 14:06:04 -0700 Subject: [PATCH 108/109] Remove dead style --- .../ImageViewing/components/ImageDefaultHeader.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx b/src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx index 3a040b5d08..88476c8e1f 100644 --- a/src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx +++ b/src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx @@ -57,13 +57,6 @@ const styles = StyleSheet.create({ borderRadius: 22, backgroundColor: '#00000077', }, - closeText: { - lineHeight: 22, - fontSize: 19, - textAlign: 'center', - color: '#FFF', - includeFontPadding: false, - }, blurredBackground: { backdropFilter: 'blur(10px)', WebkitBackdropFilter: 'blur(10px)', From 89709949ab4c48afd37ca9502c4847d4b2e6412e Mon Sep 17 00:00:00 2001 From: Eric Bailey <git@esb.lol> Date: Tue, 19 Mar 2024 16:08:07 -0500 Subject: [PATCH 109/109] Bump sdk for mute words updates (#3277) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 97fd91b03a..e744d8cd91 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "make-deploy-bundle": "bash scripts/bundleUpdate.sh" }, "dependencies": { - "@atproto/api": "^0.12.1", + "@atproto/api": "^0.12.2", "@bam.tech/react-native-image-resizer": "^3.0.4", "@braintree/sanitize-url": "^6.0.2", "@emoji-mart/react": "^1.1.1", diff --git a/yarn.lock b/yarn.lock index e9783d786b..0716a313da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,10 +34,10 @@ jsonpointer "^5.0.0" leven "^3.1.0" -"@atproto/api@^0.12.1": - version "0.12.1" - resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.1.tgz#3340cbbd6a51a8c2f3248dae55a01415ab71084e" - integrity sha512-Grigs9neuQxytXr2yHq/IfNlgXQVptWDO9KTQr5FDmgMY4Zly2X7Sa99u9c1CW9auwUTbcd+yRFBNEtbA3n3qg== +"@atproto/api@^0.12.2": + version "0.12.2" + resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.2.tgz#5df6d4f60dea0395c84fdebd9e81a7e853edf130" + integrity sha512-UVzCiDZH2j0wrr/O8nb1edD5cYLVqB5iujueXUCbHS3rAwIxgmyLtA3Hzm2QYsGPo/+xsIg1fNvpq9rNT6KWUA== dependencies: "@atproto/common-web" "^0.3.0" "@atproto/lexicon" "^0.4.0"