From 9a3b50ea1fed53f3bce5e71a2cf2fbbe3d0490fc Mon Sep 17 00:00:00 2001 From: surfdude29 <149612116+surfdude29@users.noreply.github.com> Date: Tue, 19 Mar 2024 23:04:03 +0000 Subject: [PATCH] Rm unused (#4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Mark more texts for localization * Update Drawer.tsx * Update src/view/screens/Settings/index.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update src/view/screens/Settings/index.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update src/view/com/modals/LinkWarning.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update src/view/com/modals/LinkWarning.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update src/view/screens/Moderation.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update index.tsx * Update index.tsx * Update ProfileFeed.tsx * Update LanguageSettings.tsx * Update Moderation.tsx * Update index.tsx * Update Moderation.tsx * Update ExportCarDialog.tsx * Add files via upload * Update messages.po * Update messages.po Corrected a small grammatical error * Update messages.po Changed translation for the word "Following" in the header section * Update messages.po changes some wordings, corrected a typo * Update messages.po Changed the tense of a grammatical sentence to present * Update messages.po grammatical changes related to the subject * Update messages.po Additional grammatical changes * Update messages.po Updated Nozioni di Base to Preferenze, which has a more logical contest * Update messages.po Additional grammatical correction related to subject gender * Create messages.po Finnish tranlation for Bluesky * Update messages.po Some fixes. * Update messages.po Minor changes. (Handle=käyttäjätunnus) * Update messages.po * Update messages.po * Update languages.ts Added Finnish - Suomi * Update languages.ts Suomi - Finnish * Update helpers.ts Added Finnish * Update i18n.ts Added Finnish * Update i18n.web.ts Added Finnish * Update languages.ts Typo * Update i18n.ts Fixed typo in line 9 * Update Finnish to lingui.config.js Added Finnish localization * Update NotFound.tsx * Update NotFound.tsx * accessibilityLabel * Update NotFound.tsx * Update messages.po Translation updated with minor corrections * Update messages.po Corrected small typo * Update ChangePassword.tsx * Update ChangePassword.tsx * Update Search.tsx * Update messages.po sentence updated * Update messages.po Changed a longer sentence for a shorter version in order to fit on the app screen. * Update Lists.tsx * Update messages.po Updated two expression * Update messages.po Updated new strings * Update messages.po * Update messages.po Updated latest strings * Add files via upload * Update src/view/screens/Settings/index.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update src/view/screens/Settings/index.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Convert profile edit avatar/banner dropdown menus to new menu (#3177) * convert profile edit dropdown menu to new menu fix banner text add `showCancel` prop to menu outer banner dropdown to menu add Cancel button to menu replace user avatar dropdown with menu add StreamingLive icon add camera icon * remove export * use new camera icon * adjust icon color * Combine actions, convert to new menu (#3174) * Combine actions, convert to new menu * remove about tab and move content to header * Tweak alignment * fix missing rkey * hog the like button * Add a little more whitespace * Improve a11y * Yeah toast * Update usage * Pin to Home --------- Co-authored-by: Samuel Newman * Small fixes (#3184) * Fix alignment of MutedWords close button * Add cancel button to dropdowns * Revert "Add cancel button to dropdowns" This reverts commit b8f5ddce924311e439aeaa844a80d38f6e7da051. * `npx update-browserslist-db@latest` (#3166) Should silence the annoying warning for a bit. * Use new menu for Profile (#3168) * use new menu on profile * organize imports * fix testID * add person icons * use `style` prop for minWidth * use new icons * rm circleban * Add unfollow option if account is blocked/blocking * use `StyleProp` 🤯 * ts after merge --------- Co-authored-by: Samuel Newman * ALF confirmation dialogs (Dialogs Pt. 3) (#3143) * Improve a11y on ios * Format * Remove android * Fix android * ALF confirmation dialog * Use ALF for Delete Post confirmation organize diff fix text minimize change copy alternative confirm prompt revert type changes add ButtonColor param * small adjustment to buttons in prompt * full width below gtmobile * update hide post dialog * space out dialogs * update dialogs for lists * add example * add to app passwords * Revert some changes * use sharedvalue for `importantForAccessibility` * add back `isOpen` * fix some more types * small adjustment to buttons in prompt * full width below gtmobile * update the rest of the prompts rm old confirm modal rm update prompt feed error prompt feed source card and profile block/unblock composer discard * Update src/view/screens/AppPasswords.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * lint * How about a default * Reverse reverse * Port over confirm dialogs * Add some comments * Remove unused file * complete merge * add testID where needed --------- Co-authored-by: Eric Bailey Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Fix sensitivity while scrolling (#3190) * Fix dropdown close via a portaled backdrop (#3191) * Unfork Statsig for web (#3192) * Tweak prompt styles on mobile web (#3193) * Update index.tsx * Update index.tsx * Send route name with Statsig events (#3194) * Add types to Statsig events * Send route name with events * filter out files with non-image mime types * 1.73 Version Bump (#3200) * [Statsig] Track likes, reposts, follows (#3195) * [Statsig] Track likes * Move tracking to intent * Track repost/unrepost * Track profile follows/unfollows * Less copy paste * Reorder * [Statsig] Track posting, end reached (#3206) * Track post create * Track feed endReached * use prompt.basic instead of full prompt * add warning to profile as well * Remove `FixedTouchableHighlight` , fix Android press issues (#3214) * rm `FixedTouchableHighlight` * adjust delay for highlight * remove unnecessary background colors to support background ripple * ALF the birthday modal and remove legacy one * rename BirthdaySettings -> BirthDateSettings + remove legacy modal * center date input * make alignment platform specific rather than size specific * change to scrollable inner * add padding to the `ScrollableInner` * Add package diff PR labeler (#3212) * add PR labeler * test cache * rm change * Adjust PR Labeler (#3224) * Update Lists.tsx * Update ReasonOptions.tsx * Update ReasonOptions.tsx * Update Modal.tsx * Update Modal.tsx * Update Modal.tsx * Add 'Liberation Sans' font for FireFox on Linux; lightbox buttons adjustments * remove scrollbar gutter for Chrome when body scroll is locked * change usage of t to msg * Fix PR labeler bot comment delete (#3249) * Add missing macro Co-authored-by: Gildásio Filho * Properly fill container for YT Shorts videos (#3238) account for jest account for jest yt iframe fill container * Use [bot] in action username (#3250) * 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 * change outer border radius to 10 * change default avi to use a rect instead of a path * Use entryway for labeler getServices (#3256) * Update the reporting flow to first select a recipient if the user has multiple labelers (#3258) * Bump @atproto/api@0.12.0 (#3260) * Bump @atproto/api@0.12.0 * Fix unit tests * fix borders for labels tab (#3261) * fix borders for labels tab * rm entire wrapping view * 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 * add `Partial` to `.open()` (#3227) * 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 * 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 * Update German translations (#2917) * Update German translations * Apply suggestions from code review Co-authored-by: Felix Siebeneicker * 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 * 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 * Update messages.po * Apply suggestions from code review Co-authored-by: Felix Siebeneicker * 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 * Apply suggestions from code review Co-authored-by: Felix Siebeneicker * 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 * Apply suggested change from code review by @cdfzo * Update revision date of messages.po --------- Co-authored-by: Felix Siebeneicker Co-authored-by: cdfzo * Update French translation (#3117) * Update French translation * Apply suggestions from code review Co-authored-by: Stanislas Signoud * Update src/locale/locales/fr/messages.po Co-authored-by: Stanislas Signoud * 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 * Update messages.po * Remove superseded strings and match some * Add new translations * Update revision date --------- Co-authored-by: Stanislas Signoud * add expo-updates github action (#3270) * add expo-updates github action * add two scripts * 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 * Use default label prefs for pwi (#3271) * Update trusted hosts, allow `#`, and add more tests (#3232) * Update trusted hosts, allow `#`, and add more tests * update comments * prevent duplicate pickers from opening on android (#3240) * prevent duplicate pickers from opening on android * revert unnecessary changes * test * one more test * patch-fix `RCTRefreshControl` (#3259) * `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` * 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` * 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 * 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 * 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 Co-authored-by: Daniel S. Park * 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 * Update messages.po --------- Co-authored-by: Gleydson Rodrigues * 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 * Update catalan localization messages.po (#2904) * Update catalan localization messages.po Localization of new lines * Update messages.po * Update messages.po Corrections applied * Fix merge error * Fix formatting * [Statsig] Include OS and track app state changes (#3273) * Include platform in identify * Track back/foregrounding * 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 * Update Ukrainian translation (#2951) Co-authored-by: Ukrainians * Track notification open (#3274) * Prevent linking to post from an embed in composer (#3275) * Remove dead style * Bump sdk for mute words updates (#3277) * Fix typo in tagMenuSearchByUser (#3181) * Fix detection of !no-unauthenticated (#3279) --------- Co-authored-by: Minseo Lee Co-authored-by: Gabriella N <152436322+Titianbeetle@users.noreply.github.com> Co-authored-by: jaoler Co-authored-by: Hailey Co-authored-by: Eric Bailey Co-authored-by: Samuel Newman Co-authored-by: Alice <81575558+aliceisjustplaying@users.noreply.github.com> Co-authored-by: dan Co-authored-by: Alexander K Co-authored-by: Gildásio Filho Co-authored-by: Paul Frazee Co-authored-by: Takayuki KUSANO <65759+tkusano@users.noreply.github.com> Co-authored-by: Felix Siebeneicker Co-authored-by: cdfzo Co-authored-by: Stanislas Signoud Co-authored-by: Lens0021 / Leslie Co-authored-by: Daniel S. Park Co-authored-by: Gleydson Rodrigues Co-authored-by: Leonid Co-authored-by: Frudrax Cheng Co-authored-by: Ivan Beà Co-authored-by: Dovgonosyk <159719660+Dovgonosyk@users.noreply.github.com> Co-authored-by: Ukrainians --- .../workflows/build-and-push-bskyweb-aws.yaml | 4 +- .../workflows/bundle-deploy-eas-update.yml | 55 + .github/workflows/pull-request-commit.yml | 185 + __tests__/lib/strings/url-helpers.test.ts | 38 + ...TriangleBottom_stroke2_corner1_rounded.svg | 1 + .../icons/bars3_stroke2_corner0_rounded.svg | 1 + .../camera_filled_stroke2_corner0_rounded.svg | 1 + .../icons/camera_stroke2_corner0_rounded.svg | 1 + .../chevronBottom_stroke2_corner0_rounded.svg | 1 + .../chevronTop_stroke2_corner0_rounded.svg | 1 + .../circleBanSign_stroke2_corner0_rounded.svg | 1 + ...d1x3Horizontal_stroke2_corner2_rounded.svg | 1 + assets/icons/flag_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 + .../peopleRemove2_stroke2_corner0_rounded.svg | 1 + .../personCheck_stroke2_corner0_rounded.svg | 1 + .../icons/personX_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 + .../streamingLive_stroke2_corner0_rounded.svg | 1 + ...gleExclamation_stroke2_corner2_rounded.svg | 1 + bskyweb/cmd/bskyweb/server.go | 2 + bskyweb/static/iframe/youtube.html | 12 +- bskyweb/templates/base.html | 4 +- code-signing/certificate.pem | 18 + jest/jestSetup.js | 2 + lingui.config.js | 1 + package.json | 11 +- patches/expo-image-picker+14.7.1.patch | 62 +- patches/react-native+0.73.2.patch | 103 +- patches/react-native+0.73.2.patch.md | 8 +- scripts/bundleUpdate.js | 104 + scripts/bundleUpdate.sh | 26 + src/App.native.tsx | 47 +- src/App.web.tsx | 47 +- src/Navigation.tsx | 25 +- src/alf/atoms.ts | 19 +- src/alf/index.tsx | 4 + src/alf/tokens.ts | 3 + src/components/Button.tsx | 28 +- src/components/Dialog/index.tsx | 8 +- src/components/Dialog/index.web.tsx | 2 +- src/components/Dialog/types.ts | 11 +- src/components/Error.tsx | 90 + 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 | 6 +- src/components/Lists.tsx | 182 +- src/components/Menu/index.tsx | 37 +- src/components/Menu/index.web.tsx | 33 +- src/components/Menu/types.ts | 5 + src/components/Prompt.tsx | 91 +- .../ReportDialog/SelectLabelerView.tsx | 92 + .../ReportDialog/SelectReportOptionView.tsx | 200 + src/components/ReportDialog/SubmitView.tsx | 264 + src/components/ReportDialog/const.ts | 1 + src/components/ReportDialog/index.tsx | 95 + src/components/ReportDialog/types.ts | 15 + src/components/TagMenu/index.tsx | 6 +- src/components/TagMenu/index.web.tsx | 4 +- src/components/Typography.tsx | 9 +- src/components/dialogs/BirthDateSettings.tsx | 132 + src/components/dialogs/Context.tsx | 2 +- src/components/dialogs/MutedWords.tsx | 41 +- 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/Camera.tsx | 9 + src/components/icons/Chevron.tsx | 8 + src/components/icons/CircleBanSign.tsx | 5 + src/components/icons/DotGrid.tsx | 5 + src/components/icons/Flag.tsx | 5 + src/components/icons/Gear.tsx | 5 + .../icons/{Group3.tsx => Group.tsx} | 0 src/components/icons/Heart2.tsx | 9 + src/components/icons/PeopleRemove2.tsx | 5 + src/components/icons/PersonCheck.tsx | 5 + src/components/icons/PersonX.tsx | 5 + 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/icons/StreamingLive.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 | 177 + src/components/moderation/PostAlerts.tsx | 66 + .../moderation/PostHider.tsx | 93 +- .../moderation/ProfileHeaderAlerts.tsx | 66 + src/components/moderation/ScreenHider.tsx | 172 + .../__tests__/moderatePost_wrapped.test.ts | 692 --- src/lib/constants.ts | 4 + src/lib/hooks/useOTAUpdate.ts | 52 +- src/lib/hooks/useWebBodyScrollLock.ts | 2 + src/lib/media/picker.shared.ts | 21 +- src/lib/moderatePost_wrapped.ts | 384 +- src/lib/moderation.ts | 196 +- 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/notifications/notifications.ts | 2 + src/lib/react-query.ts | 20 + src/lib/routes/types.ts | 2 + src/lib/statsig/events.ts | 50 + src/lib/statsig/statsig.tsx | 49 +- src/lib/statsig/statsig.web.tsx | 75 - src/lib/strings/display-names.ts | 3 +- src/lib/strings/embed-player.ts | 13 +- src/lib/strings/url-helpers.ts | 38 +- src/lib/themes.ts | 2 +- src/locale/helpers.ts | 2 + src/locale/i18n.ts | 5 + src/locale/i18n.web.ts | 4 + src/locale/languages.ts | 2 + src/locale/locales/ca/messages.po | 248 +- src/locale/locales/de/messages.po | 1466 ++--- src/locale/locales/en/messages.po | 6 +- src/locale/locales/fi/messages.po | 4838 +++++++++++++++++ src/locale/locales/fr/messages.po | 848 +-- src/locale/locales/it/messages.po | 699 ++- src/locale/locales/ko/messages.po | 2407 ++++---- src/locale/locales/pt-BR/messages.po | 329 +- src/locale/locales/uk/messages.po | 1416 ++--- src/locale/locales/zh-CN/messages.po | 518 +- src/routes.ts | 2 + src/screens/Hashtag.tsx | 4 +- src/screens/Moderation/index.tsx | 556 ++ .../AdultContentEnabledPref.tsx | 21 +- .../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 | 215 + src/screens/Profile/Sections/types.ts | 3 + src/state/modals/index.tsx | 56 +- src/state/preferences/index.tsx | 1 + src/state/preferences/label-defs.tsx | 25 + src/state/queries/actor-autocomplete.ts | 27 +- 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/post.ts | 47 +- src/state/queries/preferences/const.ts | 18 +- src/state/queries/preferences/index.ts | 113 +- src/state/queries/preferences/moderation.ts | 218 +- 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/profile.ts | 17 +- 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 | 11 +- 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/state.ts | 4 +- src/view/com/auth/login/ChooseAccountForm.tsx | 6 +- src/view/com/auth/login/LoginForm.tsx | 2 +- .../onboarding/RecommendedFollowsItem.tsx | 23 +- .../com/auth/onboarding/WelcomeMobile.tsx | 6 +- src/view/com/auth/server-input/index.tsx | 2 +- src/view/com/composer/Composer.tsx | 64 +- src/view/com/composer/ComposerReplyTo.tsx | 7 +- src/view/com/composer/Prompt.tsx | 6 +- .../select-language/SelectLangBtn.tsx | 8 +- .../text-input/mobile/Autocomplete.tsx | 6 +- .../composer/text-input/web/Autocomplete.tsx | 6 +- src/view/com/feeds/FeedSourceCard.tsx | 254 +- .../components/ImageDefaultHeader.tsx | 60 +- src/view/com/lightbox/Lightbox.tsx | 4 +- src/view/com/lightbox/Lightbox.web.tsx | 54 +- src/view/com/modals/AppealLabel.tsx | 139 - src/view/com/modals/BirthDateSettings.tsx | 151 - src/view/com/modals/ChangeHandle.tsx | 46 +- src/view/com/modals/ChangePassword.tsx | 8 +- src/view/com/modals/Confirm.tsx | 132 - .../com/modals/ContentFilteringSettings.tsx | 401 -- src/view/com/modals/DeleteAccount.tsx | 6 +- src/view/com/modals/InAppBrowserConsent.tsx | 2 +- src/view/com/modals/LinkWarning.tsx | 8 +- src/view/com/modals/ListAddRemoveUsers.tsx | 6 +- src/view/com/modals/Modal.tsx | 26 +- src/view/com/modals/Modal.web.tsx | 20 +- src/view/com/modals/ModerationDetails.tsx | 142 - src/view/com/modals/SwitchAccount.tsx | 6 +- src/view/com/modals/UserAddRemoveLists.tsx | 2 +- src/view/com/modals/VerifyEmail.tsx | 2 +- .../com/modals/crop-image/CropImage.web.tsx | 12 +- .../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 | 18 +- .../com/pager/FixedTouchableHighlight.tsx | 42 - src/view/com/post-thread/PostLikedBy.tsx | 4 +- src/view/com/post-thread/PostThread.tsx | 451 +- .../com/post-thread/PostThreadFollowBtn.tsx | 5 +- src/view/com/post-thread/PostThreadItem.tsx | 103 +- src/view/com/post/Post.tsx | 42 +- src/view/com/posts/Feed.tsx | 16 +- src/view/com/posts/FeedErrorMessage.tsx | 89 +- src/view/com/posts/FeedItem.tsx | 58 +- src/view/com/posts/FeedSlice.tsx | 6 +- src/view/com/profile/FollowButton.tsx | 7 +- src/view/com/profile/ProfileCard.tsx | 100 +- src/view/com/profile/ProfileFollowers.tsx | 124 +- src/view/com/profile/ProfileFollows.tsx | 123 +- src/view/com/profile/ProfileHeader.tsx | 785 --- .../profile/ProfileHeaderSuggestedFollows.tsx | 31 +- src/view/com/profile/ProfileMenu.tsx | 380 ++ .../com/util/BottomSheetCustomBackdrop.tsx | 7 +- src/view/com/util/ErrorBoundary.tsx | 23 +- src/view/com/util/Link.tsx | 40 +- src/view/com/util/PostMeta.tsx | 18 +- src/view/com/util/UserAvatar.tsx | 263 +- src/view/com/util/UserBanner.tsx | 240 +- .../com/util/forms/NativeDropdown.web.tsx | 2 +- src/view/com/util/forms/PostDropdownBtn.tsx | 119 +- 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 | 12 +- src/view/com/util/post-embeds/QuoteEmbed.tsx | 129 +- src/view/com/util/post-embeds/index.tsx | 106 +- src/view/com/util/text/Text.tsx | 15 +- src/view/screens/AppPasswords.tsx | 36 +- src/view/screens/DebugMod.tsx | 923 ++++ src/view/screens/LanguageSettings.tsx | 4 +- src/view/screens/Moderation.tsx | 304 -- .../screens/ModerationBlockedAccounts.tsx | 2 +- src/view/screens/ModerationMutedAccounts.tsx | 4 +- src/view/screens/NotFound.tsx | 8 +- src/view/screens/PostThread.tsx | 6 +- src/view/screens/Profile.tsx | 253 +- src/view/screens/ProfileFeed.tsx | 386 +- src/view/screens/ProfileFollowers.tsx | 2 +- src/view/screens/ProfileFollows.tsx | 2 +- src/view/screens/ProfileList.tsx | 218 +- src/view/screens/Search/Search.tsx | 3 +- src/view/screens/Settings/ExportCarDialog.tsx | 3 +- src/view/screens/Settings/index.tsx | 82 +- src/view/screens/Storybook/Buttons.tsx | 41 + src/view/screens/Storybook/Dialogs.tsx | 2 +- src/view/screens/Storybook/index.tsx | 1 + src/view/shell/Drawer.tsx | 11 +- src/view/shell/NavSignupCard.tsx | 2 +- src/view/shell/bottom-bar/BottomBar.tsx | 2 + src/view/shell/desktop/LeftNav.tsx | 6 +- src/view/shell/desktop/Search.tsx | 9 +- src/view/shell/index.tsx | 2 +- src/view/shell/index.web.tsx | 14 +- web/index.html | 4 +- yarn.lock | 114 +- 284 files changed, 18703 insertions(+), 11749 deletions(-) create mode 100644 .github/workflows/bundle-deploy-eas-update.yml create mode 100644 .github/workflows/pull-request-commit.yml 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/camera_filled_stroke2_corner0_rounded.svg create mode 100644 assets/icons/camera_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/dotGrid1x3Horizontal_stroke2_corner2_rounded.svg create mode 100644 assets/icons/flag_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/peopleRemove2_stroke2_corner0_rounded.svg create mode 100644 assets/icons/personCheck_stroke2_corner0_rounded.svg create mode 100644 assets/icons/personX_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/streamingLive_stroke2_corner0_rounded.svg create mode 100644 assets/icons/triangleExclamation_stroke2_corner2_rounded.svg create mode 100644 code-signing/certificate.pem create mode 100644 scripts/bundleUpdate.js create mode 100644 scripts/bundleUpdate.sh create mode 100644 src/components/Error.tsx 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/SelectLabelerView.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/dialogs/BirthDateSettings.tsx 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/Camera.tsx create mode 100644 src/components/icons/CircleBanSign.tsx create mode 100644 src/components/icons/DotGrid.tsx create mode 100644 src/components/icons/Flag.tsx create mode 100644 src/components/icons/Gear.tsx rename src/components/icons/{Group3.tsx => Group.tsx} (100%) create mode 100644 src/components/icons/Heart2.tsx create mode 100644 src/components/icons/PeopleRemove2.tsx create mode 100644 src/components/icons/PersonCheck.tsx create mode 100644 src/components/icons/PersonX.tsx 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/icons/StreamingLive.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/lib/statsig/events.ts delete mode 100644 src/lib/statsig/statsig.web.tsx create mode 100644 src/locale/locales/fi/messages.po 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/BirthDateSettings.tsx delete mode 100644 src/view/com/modals/Confirm.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/pager/FixedTouchableHighlight.tsx delete mode 100644 src/view/com/profile/ProfileHeader.tsx create mode 100644 src/view/com/profile/ProfileMenu.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/.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/.github/workflows/pull-request-commit.yml b/.github/workflows/pull-request-commit.yml new file mode 100644 index 0000000000..85ebae4dba --- /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_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: 'github-actions[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, + }); 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/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/camera_filled_stroke2_corner0_rounded.svg b/assets/icons/camera_filled_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..fa0101cf0d --- /dev/null +++ b/assets/icons/camera_filled_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/camera_stroke2_corner0_rounded.svg b/assets/icons/camera_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..ce0c29ae50 --- /dev/null +++ b/assets/icons/camera_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + \ No newline at end of file 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/dotGrid1x3Horizontal_stroke2_corner2_rounded.svg b/assets/icons/dotGrid1x3Horizontal_stroke2_corner2_rounded.svg new file mode 100644 index 0000000000..c3b456b100 --- /dev/null +++ b/assets/icons/dotGrid1x3Horizontal_stroke2_corner2_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/flag_stroke2_corner0_rounded.svg b/assets/icons/flag_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..9f9cc5cdd1 --- /dev/null +++ b/assets/icons/flag_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + \ No newline at end of file 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/peopleRemove2_stroke2_corner0_rounded.svg b/assets/icons/peopleRemove2_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..2e798cbe29 --- /dev/null +++ b/assets/icons/peopleRemove2_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/personCheck_stroke2_corner0_rounded.svg b/assets/icons/personCheck_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..b3231c2780 --- /dev/null +++ b/assets/icons/personCheck_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/personX_stroke2_corner0_rounded.svg b/assets/icons/personX_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..073015bc54 --- /dev/null +++ b/assets/icons/personX_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + \ No newline at end of file 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/streamingLive_stroke2_corner0_rounded.svg b/assets/icons/streamingLive_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..b6cdd34d77 --- /dev/null +++ b/assets/icons/streamingLive_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/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/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/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/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/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', diff --git a/package.json b/package.json index 2571fe772d..e744d8cd91 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bsky.app", - "version": "1.72.0", + "version": "1.73.0", "private": true, "engines": { "node": ">=18" @@ -41,10 +41,12 @@ "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.10.5", + "@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", @@ -76,7 +78,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", @@ -179,7 +183,6 @@ "react-responsive": "^9.0.2", "rn-fetch-blob": "^0.12.0", "sentry-expo": "~7.0.1", - "statsig-react": "^1.36.0", "statsig-react-native-expo": "^4.6.1", "tippy.js": "^6.3.7", "tlds": "^1.234.0", 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?) = 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 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 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 8a9f69b5de..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,7 +79,8 @@ import {createNativeStackNavigatorWithAuth} from './view/shell/createNativeStack import {msg} from '@lingui/macro' import {i18n, MessageDescriptor} from '@lingui/core' import HashtagScreen from '#/screens/Hashtag' -import {logEvent} from './lib/statsig/statsig' +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} @@ -543,6 +555,7 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) { linking={LINKING} theme={theme} onReady={() => { + attachRouteToLogEvents(getCurrentRouteName) logModuleInitTime() onReady() }}> @@ -551,6 +564,10 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) { ) } +function getCurrentRouteName() { + return navigationRef.getCurrentRoute()?.name +} + /** * These helpers can be used from outside of the RoutesContainer * (eg in the state models). @@ -656,7 +673,9 @@ function logModuleInitTime() { performance.now() - global.__BUNDLE_START_TIME__, ) console.log(`Time to first paint: ${initMs} ms`) - logEvent('init', initMs) + logEvent('init', { + initMs, + }) if (__DEV__) { // This log is noisy, so keep false committed diff --git a/src/alf/atoms.ts b/src/alf/atoms.ts index fff3a4d8bd..0b473ba903 100644 --- a/src/alf/atoms.ts +++ b/src/alf/atoms.ts @@ -1,3 +1,4 @@ +import {Platform} from 'react-native' import {web, native} from '#/alf/util/platform' import * as tokens from '#/alf/tokens' @@ -6,7 +7,7 @@ export const atoms = { * Positioning */ fixed: { - position: 'fixed', + position: Platform.select({web: 'fixed', native: 'absolute'}) as 'absolute', }, absolute: { position: 'absolute', @@ -49,6 +50,9 @@ export const atoms = { h_full: { height: '100%', }, + h_full_vh: web({ + height: '100vh', + }), /* * Border radius @@ -111,6 +115,12 @@ export const atoms = { flex_row: { flexDirection: 'row', }, + flex_col_reverse: { + flexDirection: 'column-reverse', + }, + flex_row_reverse: { + flexDirection: 'row-reverse', + }, flex_wrap: { flexWrap: 'wrap', }, @@ -236,6 +246,9 @@ export const atoms = { font_normal: { fontWeight: tokens.fontWeight.normal, }, + font_semibold: { + fontWeight: '500', + }, font_bold: { fontWeight: tokens.fontWeight.semibold, }, @@ -521,6 +534,10 @@ export const atoms = { /* * Margin */ + mx_auto: { + marginLeft: 'auto', + marginRight: 'auto', + }, m_2xs: { margin: tokens.space._2xs, }, 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/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.tsx b/src/components/Dialog/index.tsx index f0e7b7e82b..0da2919c56 100644 --- a/src/components/Dialog/index.tsx +++ b/src/components/Dialog/index.tsx @@ -23,6 +23,7 @@ import { DialogInnerProps, } from '#/components/Dialog/types' import {Context} from '#/components/Dialog/context' +import {isNative} from 'platform/detection' export {useDialogControl, useDialogContext} from '#/components/Dialog/context' export * from '#/components/Dialog/types' @@ -75,6 +76,7 @@ export function Outer({ control, onClose, nativeOptions, + testID, }: React.PropsWithChildren) { const t = useTheme() const sheet = React.useRef(null) @@ -145,7 +147,8 @@ export function Outer({ accessibilityViewIsModal // Android importantForAccessibility="yes" - style={[a.absolute, a.inset_0]}> + style={[a.absolute, a.inset_0]} + testID={testID}> + ]} + contentContainerStyle={isNative ? a.pb_4xl : undefined}> {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/Dialog/types.ts b/src/components/Dialog/types.ts index 4fc60ec394..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 * 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` 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, + ) => void close: (callback?: () => void) => void } @@ -46,6 +52,7 @@ export type DialogOuterProps = { sheet?: Omit } webOptions?: {} + testID?: string } type DialogInnerPropsBase = React.PropsWithChildren & T 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() + 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 ( + + + {title} + + {message} + + + + {onRetry && ( + + )} + + + + ) +} 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..f924f0f594 --- /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 ff72a08cec..7d0e833329 100644 --- a/src/components/Link.tsx +++ b/src/components/Link.tsx @@ -228,6 +228,7 @@ export function InlineLink({ onPress: outerOnPress, download, selectable, + label, ...rest }: InlineLinkProps) { const t = useTheme() @@ -250,12 +251,13 @@ export function InlineLink({ onIn: onPressIn, onOut: onPressOut, } = useInteractionState() - const flattenedStyle = flatten(style) + const flattenedStyle = flatten(style) || {} return ( <Text selectable={selectable} - label={href} + accessibilityHint="" + accessibilityLabel={label || href} {...rest} style={[ {color: t.palette.primary_500}, diff --git a/src/components/Lists.tsx b/src/components/Lists.tsx index bb0d247971..d3e0720286 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 {Trans, msg} from '@lingui/macro' + import {CenteredView} from 'view/com/util/Views' import {Loader} from '#/components/Loader' -import {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: 100}, + {height: height ?? 180, paddingTop: 30}, ]}> {isFetching ? ( <Loader size="xl" /> @@ -53,11 +54,12 @@ function ListFooterMaybeError({ error, onRetry, }: { - isError: boolean + isError?: boolean error?: string onRetry?: () => Promise<unknown> }) { const t = useTheme() + const {_} = useLingui() if (!isError) return null @@ -83,7 +85,7 @@ function ListFooterMaybeError({ </Text> <Button variant="gradient" - label="Press to retry" + label={_(msg`Press to retry`)} style={[ a.align_center, a.justify_center, @@ -93,7 +95,7 @@ function ListFooterMaybeError({ a.py_sm, ]} onPress={onRetry}> - Retry + <Trans>Retry</Trans> </Button> </View> </View> @@ -128,121 +130,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') - - // 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 (!isLoading && isError) { + return ( + <Error + title={errorTitle ?? _(msg`Oops!`)} + message={errorMessage ?? _(`Something went wrong!`)} + onRetry={onRetry} + /> + ) + } - 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/components/Menu/index.tsx b/src/components/Menu/index.tsx index ee96a5667e..051e95b956 100644 --- a/src/components/Menu/index.tsx +++ b/src/components/Menu/index.tsx @@ -1,5 +1,5 @@ import React from 'react' -import {View, Pressable} from 'react-native' +import {View, Pressable, ViewStyle, StyleProp} from 'react-native' import flattenReactChildren from 'react-keyed-flatten-children' import {atoms as a, useTheme} from '#/alf' @@ -16,6 +16,10 @@ import { ItemTextProps, ItemIconProps, } from '#/components/Menu/types' +import {Button, ButtonText} from '#/components/Button' +import {Trans, msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {isNative} from 'platform/detection' export {useDialogControl as useMenuControl} from '#/components/Dialog' @@ -68,7 +72,13 @@ export function Trigger({children, label}: TriggerProps) { }) } -export function Outer({children}: React.PropsWithChildren<{}>) { +export function Outer({ + children, + showCancel, +}: React.PropsWithChildren<{ + showCancel?: boolean + style?: StyleProp<ViewStyle> +}>) { const context = React.useContext(Context) return ( @@ -78,7 +88,10 @@ export function Outer({children}: React.PropsWithChildren<{}>) { {/* Re-wrap with context since Dialogs are portal-ed to root */} <Context.Provider value={context}> <Dialog.ScrollableInner label="Menu TODO"> - <View style={[a.gap_lg]}>{children}</View> + <View style={[a.gap_lg]}> + {children} + {isNative && showCancel && <Cancel />} + </View> <View style={{height: a.gap_lg.gap}} /> </Dialog.ScrollableInner> </Context.Provider> @@ -185,6 +198,24 @@ export function Group({children, style}: GroupProps) { ) } +function Cancel() { + const {_} = useLingui() + const {control} = React.useContext(Context) + + return ( + <Button + label={_(msg`Close this dialog`)} + size="small" + variant="ghost" + color="secondary" + onPress={() => control.close()}> + <ButtonText> + <Trans>Cancel</Trans> + </ButtonText> + </Button> + ) +} + export function Divider() { return null } diff --git a/src/components/Menu/index.web.tsx b/src/components/Menu/index.web.tsx index f23c39ced5..60b2342034 100644 --- a/src/components/Menu/index.web.tsx +++ b/src/components/Menu/index.web.tsx @@ -1,8 +1,10 @@ /* eslint-disable react/prop-types */ import React from 'react' -import {View, Pressable} from 'react-native' +import {View, Pressable, ViewStyle, StyleProp} from 'react-native' import * as DropdownMenu from '@radix-ui/react-dropdown-menu' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' import * as Dialog from '#/components/Dialog' import {useInteractionState} from '#/components/hooks/useInteractionState' @@ -19,6 +21,7 @@ import { RadixPassThroughTriggerProps, } from '#/components/Menu/types' import {Context} from '#/components/Menu/context' +import {Portal} from '#/components/Portal' export function useMenuControl(): Dialog.DialogControlProps { const id = React.useId() @@ -50,6 +53,7 @@ export function Root({ }: React.PropsWithChildren<{ control?: Dialog.DialogOuterProps['control'] }>) { + const {_} = useLingui() const defaultControl = useMenuControl() const context = React.useMemo<ContextType>( () => ({ @@ -70,6 +74,18 @@ export function Root({ return ( <Context.Provider value={context}> + {context.control.isOpen && ( + <Portal> + <Pressable + style={[a.fixed, a.inset_0, a.z_50]} + onPress={() => context.control.close()} + accessibilityHint="" + accessibilityLabel={_( + msg`Context menu backdrop, click to close the menu.`, + )} + /> + </Portal> + )} <DropdownMenu.Root open={context.control.isOpen} onOpenChange={onOpenChange}> @@ -119,6 +135,10 @@ export function Trigger({children, label}: TriggerProps) { }, props: { ...props, + // disable on web, use `onPress` + onPointerDown: () => false, + onPress: () => + control.isOpen ? control.close() : control.open(), onFocus: onFocus, onBlur: onBlur, onMouseEnter, @@ -132,7 +152,13 @@ export function Trigger({children, label}: TriggerProps) { ) } -export function Outer({children}: React.PropsWithChildren<{}>) { +export function Outer({ + children, + style, +}: React.PropsWithChildren<{ + showCancel?: boolean + style?: StyleProp<ViewStyle> +}>) { const t = useTheme() return ( @@ -144,6 +170,7 @@ export function Outer({children}: React.PropsWithChildren<{}>) { a.p_xs, t.name === 'light' ? t.atoms.bg : t.atoms.bg_contrast_25, t.atoms.shadow_md, + style, ]}> {children} </View> @@ -196,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/Menu/types.ts b/src/components/Menu/types.ts index 7d04a33441..e710971ee9 100644 --- a/src/components/Menu/types.ts +++ b/src/components/Menu/types.ts @@ -23,6 +23,10 @@ export type RadixPassThroughTriggerProps = { ['aria-haspopup']?: boolean ['aria-expanded']?: AccessibilityProps['aria-expanded'] onKeyDown: (e: React.KeyboardEvent) => void + /** + * Radix provides this, but we override on web to use `onPress` instead, + * which is less sensitive while scrolling. + */ onPointerDown: PressableProps['onPointerDown'] } export type TriggerProps = { @@ -69,6 +73,7 @@ export type TriggerChildProps = pressed: false } props: RadixPassThroughTriggerProps & { + onPress: () => void onFocus: () => void onBlur: () => void onMouseEnter: () => void diff --git a/src/components/Prompt.tsx b/src/components/Prompt.tsx index 3b245c440f..b81b207075 100644 --- a/src/components/Prompt.tsx +++ b/src/components/Prompt.tsx @@ -1,11 +1,11 @@ import React from 'react' -import {View, PressableProps} from 'react-native' +import {View} from 'react-native' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useTheme, atoms as a, useBreakpoints} from '#/alf' import {Text} from '#/components/Typography' -import {Button} from '#/components/Button' +import {Button, ButtonColor, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' @@ -22,8 +22,10 @@ const Context = React.createContext<{ export function Outer({ children, control, + testID, }: React.PropsWithChildren<{ control: Dialog.DialogOuterProps['control'] + testID?: string }>) { const {gtMobile} = useBreakpoints() const titleId = React.useId() @@ -35,7 +37,7 @@ export function Outer({ ) return ( - <Dialog.Outer control={control}> + <Dialog.Outer control={control} testID={testID}> <Context.Provider value={context}> <Dialog.Handle /> @@ -80,7 +82,9 @@ export function Actions({children}: React.PropsWithChildren<{}>) { a.w_full, a.gap_sm, a.justify_end, - gtMobile ? [a.flex_row] : [a.flex_col, a.pt_md, a.pb_4xl], + gtMobile + ? [a.flex_row, a.flex_row_reverse, a.justify_start] + : [a.flex_col], ]}> {children} </View> @@ -89,18 +93,29 @@ export function Actions({children}: React.PropsWithChildren<{}>) { export function Cancel({ children, -}: React.PropsWithChildren<{onPress?: PressableProps['onPress']}>) { + cta, +}: React.PropsWithChildren<{ + /** + * Optional i18n string, used in lieu of `children` for simple buttons. If + * undefined (and `children` is undefined), it will default to "Cancel". + */ + cta?: string +}>) { const {_} = useLingui() const {gtMobile} = useBreakpoints() const {close} = Dialog.useDialogContext() + const onPress = React.useCallback(() => { + close() + }, [close]) + return ( <Button variant="solid" color="secondary" size={gtMobile ? 'small' : 'medium'} - label={_(msg`Cancel`)} - onPress={() => close()}> - {children} + label={cta || _(msg`Cancel`)} + onPress={onPress}> + {children ? children : <ButtonText>{cta || _(msg`Cancel`)}</ButtonText>} </Button> ) } @@ -108,22 +123,70 @@ export function Cancel({ export function Action({ children, onPress, -}: React.PropsWithChildren<{onPress?: () => void}>) { + color = 'primary', + cta, + testID, +}: React.PropsWithChildren<{ + onPress: () => void + color?: ButtonColor + /** + * Optional i18n string, used in lieu of `children` for simple buttons. If + * undefined (and `children` is undefined), it will default to "Confirm". + */ + cta?: string + testID?: string +}>) { const {_} = useLingui() const {gtMobile} = useBreakpoints() const {close} = Dialog.useDialogContext() const handleOnPress = React.useCallback(() => { close() - onPress?.() + onPress() }, [close, onPress]) + return ( <Button variant="solid" - color="primary" + color={color} size={gtMobile ? 'small' : 'medium'} - label={_(msg`Confirm`)} - onPress={handleOnPress}> - {children} + label={cta || _(msg`Confirm`)} + onPress={handleOnPress} + testID={testID}> + {children ? children : <ButtonText>{cta || _(msg`Confirm`)}</ButtonText>} </Button> ) } + +export function Basic({ + control, + title, + description, + cancelButtonCta, + confirmButtonCta, + onConfirm, + confirmButtonColor, +}: React.PropsWithChildren<{ + control: Dialog.DialogOuterProps['control'] + title: string + description: string + cancelButtonCta?: string + confirmButtonCta?: string + onConfirm: () => void + confirmButtonColor?: ButtonColor +}>) { + return ( + <Outer control={control} testID="confirmModal"> + <Title>{title} + {description} + + + + + + ) +} diff --git a/src/components/ReportDialog/SelectLabelerView.tsx b/src/components/ReportDialog/SelectLabelerView.tsx new file mode 100644 index 0000000000..817426355d --- /dev/null +++ b/src/components/ReportDialog/SelectLabelerView.tsx @@ -0,0 +1,92 @@ +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 {getLabelingServiceTitle} from '#/lib/moderation' + +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 * as LabelingServiceCard from '#/components/LabelingServiceCard' + +import {ReportDialogProps} from './types' + +export function SelectLabelerView({ + ...props +}: ReportDialogProps & { + labelers: AppBskyLabelerDefs.LabelerViewDetailed[] + onSelectLabeler: (v: string) => void +}) { + const t = useTheme() + const {_} = useLingui() + const {gtMobile} = useBreakpoints() + + return ( + + + + Select moderator + + + To whom would you like to send this report? + + + + + + + {props.labelers.map(labeler => { + return ( + + ) + })} + + + ) +} + +function LabelerButton({ + labeler, +}: { + labeler: AppBskyLabelerDefs.LabelerViewDetailed +}) { + const t = useTheme() + const {hovered, pressed} = useButtonContext() + const interacted = hovered || pressed + + const styles = React.useMemo(() => { + return { + interacted: { + backgroundColor: t.palette.contrast_50, + }, + } + }, [t]) + + return ( + + + + + + @{labeler.creator.handle} + + + + ) +} diff --git a/src/components/ReportDialog/SelectReportOptionView.tsx b/src/components/ReportDialog/SelectReportOptionView.tsx new file mode 100644 index 0000000000..bacf5a8670 --- /dev/null +++ b/src/components/ReportDialog/SelectReportOptionView.tsx @@ -0,0 +1,200 @@ +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, useBreakpoints} 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, + 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' + +export function SelectReportOptionView({ + ...props +}: ReportDialogProps & { + labelers: AppBskyLabelerDefs.LabelerViewDetailed[] + onSelectReportOption: (reportOption: ReportOption) => void + goBack: () => void +}) { + const t = useTheme() + const {_} = useLingui() + const {gtMobile} = useBreakpoints() + 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 ( + + {props.labelers?.length > 1 ? ( + + ) : null} + + + {i18n.title} + + {i18n.description} + + + + + + + {reportOptions.map(reportOption => { + return ( + + ) + })} + + {(props.params.type === 'post' || props.params.type === 'account') && ( + + + + Need to report a copyright violation? + + + + View details + + + + + + )} + + + ) +} + +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 ( + + + + {title} + + {description} + + + + + + + ) +} diff --git a/src/components/ReportDialog/SubmitView.tsx b/src/components/ReportDialog/SubmitView.tsx new file mode 100644 index 0000000000..d47211c81c --- /dev/null +++ b/src/components/ReportDialog/SubmitView.tsx @@ -0,0 +1,264 @@ +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, + selectedLabeler, + selectedReportOption, + goBack, + onSubmitComplete, +}: ReportDialogProps & { + labelers: AppBskyLabelerDefs.LabelerViewDetailed[] + selectedLabeler: string + selectedReportOption: ReportOption + goBack: () => void + onSubmitComplete: () => void +}) { + const t = useTheme() + const {_} = useLingui() + const [details, setDetails] = React.useState('') + const [submitting, setSubmitting] = React.useState(false) + const [selectedServices, setSelectedServices] = React.useState([ + selectedLabeler, + ]) + 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 ( + + + + + + + {selectedReportOption.title} + + + {selectedReportOption.description} + + + + + + + + + Select the moderation service(s) to report to + + + + + {labelers.map(labeler => { + const title = getLabelingServiceTitle({ + displayName: labeler.creator.displayName, + handle: labeler.creator.handle, + }) + return ( + + + + ) + })} + + + + + + Optionally provide additional information below: + + + + + + + + + + + + + {!selectedServices.length || + (error && ( + + {error ? ( + error + ) : ( + You must select at least one labeler for a report + )} + + ))} + + + + + ) +} + +function LabelerToggle({title}: {title: string}) { + const t = useTheme() + const ctx = Toggle.useItemContext() + + return ( + + + + + {title} + + + + ) +} 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..f01ff3f3b1 --- /dev/null +++ b/src/components/ReportDialog/index.tsx @@ -0,0 +1,95 @@ +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 {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 ( + + + + + + ) +} + +function ReportDialogInner(props: ReportDialogProps) { + const { + isLoading: isLabelerLoading, + data: labelers, + error, + } = useMyLabelersQuery() + const isLoading = useDelayedLoading(500, isLabelerLoading) + + return ( + + {isLoading ? ( + + + {/* Here to capture focus for a hot sec to prevent flash */} + + + ) : error || !labelers ? ( + + + Something went wrong, please try again. + + + ) : ( + + )} + + + + ) +} + +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 ( + setSelectedReportOption(undefined)} + onSubmitComplete={() => props.control.close()} + /> + ) + } + if (selectedLabeler) { + return ( + setSelectedLabeler(undefined)} + onSelectReportOption={setSelectedReportOption} + /> + ) + } + return +} 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..0ed7036671 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( @@ -264,7 +264,9 @@ export function TagMenu({ variant="ghost" color="secondary" onPress={() => control.close()}> - Cancel + + Cancel + )} diff --git a/src/components/TagMenu/index.web.tsx b/src/components/TagMenu/index.web.tsx index 8245bd0191..4336223861 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( @@ -87,7 +87,7 @@ export function TagMenu({ author: authorHandle, }) }, - testID: 'tagMenuSeachByUser', + testID: 'tagMenuSearchByUser', icon: { ios: { name: 'magnifyingglass', 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) { 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/BirthDateSettings.tsx b/src/components/dialogs/BirthDateSettings.tsx new file mode 100644 index 0000000000..4a3e96e56d --- /dev/null +++ b/src/components/dialogs/BirthDateSettings.tsx @@ -0,0 +1,132 @@ +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, 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 {isIOS, isWeb} from '#/platform/detection' +import {Loader} from '#/components/Loader' + +export function BirthDateSettingsDialog({ + control, +}: { + control: Dialog.DialogControlProps +}) { + const t = useTheme() + const {_} = useLingui() + const {isLoading, error, data: preferences} = usePreferencesQuery() + + return ( + + + + + + + My Birthday + + + This information is not shared with other users. + + + + {isLoading ? ( + + ) : error || !preferences ? ( + + ) : ( + + )} + + + + + ) +} + +function BirthdayInner({ + control, + preferences, +}: { + control: Dialog.DialogControlProps + preferences: UsePreferencesQueryResponse +}) { + const {_} = useLingui() + const [date, setDate] = React.useState(preferences.birthDate || new Date()) + const { + isPending, + isError, + error, + mutateAsync: setBirthDate, + } = usePreferencesSetBirthDateMutation() + const hasChanged = date !== preferences.birthDate + + const onSave = React.useCallback(async () => { + try { + // skip if date is the same + if (hasChanged) { + await setBirthDate({birthDate: date}) + } + control.close() + } catch (e: any) { + logger.error(`setBirthDate failed`, {message: e.message}) + } + }, [date, setBirthDate, control, hasChanged]) + + return ( + + + + + + {isError ? ( + + ) : undefined} + + + + + + ) +} 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( () => ({mutedWordsDialogControl}), [mutedWordsDialogControl], ) diff --git a/src/components/dialogs/MutedWords.tsx b/src/components/dialogs/MutedWords.tsx index 658ba2aae0..46f319adfe 100644 --- a/src/components/dialogs/MutedWords.tsx +++ b/src/components/dialogs/MutedWords.tsx @@ -233,8 +233,8 @@ function MutedWordsInner({}: {control: Dialog.DialogOuterProps['control']}) { - ) : preferences.mutedWords.length ? ( - [...preferences.mutedWords] + ) : preferences.moderationPrefs.mutedWords.length ? ( + [...preferences.moderationPrefs.mutedWords] .reverse() .map((word, i) => ( {isNative && } - - + + ) } @@ -277,29 +277,16 @@ function MutedWordRow({ return ( <> - - - Are you sure? - - - - This will delete {word.value} from your muted words. You can always - add it back later. - - - - - - Nevermind - - - - - Remove - - - - + + style={[a.flex_row, a.align_center, a.gap_sm, flatten(style)]}> {typeof children === 'function' ? children(state) : children} ) } -export function Label({children}: React.PropsWithChildren<{}>) { +export function Label({ + children, + style, +}: React.PropsWithChildren) { 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} @@ -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 ? : null} @@ -385,7 +391,7 @@ export function Switch() { width: 30, }, baseStyles, - hovered || focused ? baseHoverStyles : {}, + hovered ? baseHoverStyles : {}, ]}> {selected ? ( & AccessibilityProps & - React.PropsWithChildren<{testID?: string}> + React.PropsWithChildren<{ + testID?: string + }> export type GroupProps = Omit & { 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' ? ( { + 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/Camera.tsx b/src/components/icons/Camera.tsx new file mode 100644 index 0000000000..ced8e7442e --- /dev/null +++ b/src/components/icons/Camera.tsx @@ -0,0 +1,9 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Camera_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M8.371 3.89A2 2 0 0 1 10.035 3h3.93a2 2 0 0 1 1.664.89L17.035 6H20a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h2.965L8.37 3.89ZM13.965 5h-3.93L8.63 7.11A2 2 0 0 1 6.965 8H4v11h16V8h-2.965a2 2 0 0 1-1.664-.89L13.965 5ZM12 11a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm-4 2a4 4 0 1 1 8 0 4 4 0 0 1-8 0Z', +}) + +export const Camera_Filled_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M8.371 3.89A2 2 0 0 1 10.035 3h3.93a2 2 0 0 1 1.664.89L17.035 6H20a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h2.965L8.37 3.89ZM12 9a3.5 3.5 0 1 0 0 7 3.5 3.5 0 0 0 0-7Z', +}) 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/DotGrid.tsx b/src/components/icons/DotGrid.tsx new file mode 100644 index 0000000000..c50d7a440f --- /dev/null +++ b/src/components/icons/DotGrid.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const DotGrid_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M2 12a2 2 0 1 1 4 0 2 2 0 0 1-4 0Zm16 0a2 2 0 1 1 4 0 2 2 0 0 1-4 0Zm-6-2a2 2 0 1 0 0 4 2 2 0 0 0 0-4Z', +}) diff --git a/src/components/icons/Flag.tsx b/src/components/icons/Flag.tsx new file mode 100644 index 0000000000..d986db75a3 --- /dev/null +++ b/src/components/icons/Flag.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Flag_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M4 4a2 2 0 0 1 2-2h13.131c1.598 0 2.55 1.78 1.665 3.11L18.202 9l2.594 3.89c.886 1.33-.067 3.11-1.665 3.11H6v5a1 1 0 1 1-2 0V4Zm2 10h13.131l-2.593-3.89a2 2 0 0 1 0-2.22L19.13 4H6v10Z', +}) 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/Heart2.tsx b/src/components/icons/Heart2.tsx new file mode 100644 index 0000000000..07f5a1d2c8 --- /dev/null +++ b/src/components/icons/Heart2.tsx @@ -0,0 +1,9 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Heart2_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M16.734 5.091c-1.238-.276-2.708.047-4.022 1.38a1 1 0 0 1-1.424 0C9.974 5.137 8.504 4.814 7.266 5.09c-1.263.282-2.379 1.206-2.92 2.556C3.33 10.18 4.252 14.84 12 19.348c7.747-4.508 8.67-9.168 7.654-11.7-.541-1.351-1.657-2.275-2.92-2.557Zm4.777 1.812c1.604 4-.494 9.69-9.022 14.47a1 1 0 0 1-.978 0C2.983 16.592.885 10.902 2.49 6.902c.779-1.942 2.414-3.334 4.342-3.764 1.697-.378 3.552.003 5.169 1.286 1.617-1.283 3.472-1.664 5.17-1.286 1.927.43 3.562 1.822 4.34 3.764Z', +}) + +export const Heart2_Filled_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M12.489 21.372c8.528-4.78 10.626-10.47 9.022-14.47-.779-1.941-2.414-3.333-4.342-3.763-1.697-.378-3.552.003-5.169 1.287-1.617-1.284-3.472-1.665-5.17-1.287-1.927.43-3.562 1.822-4.34 3.764-1.605 4 .493 9.69 9.021 14.47a1 1 0 0 0 .978 0Z', +}) diff --git a/src/components/icons/PeopleRemove2.tsx b/src/components/icons/PeopleRemove2.tsx new file mode 100644 index 0000000000..3d16ed9682 --- /dev/null +++ b/src/components/icons/PeopleRemove2.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const PeopleRemove2_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M10 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM5.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM16 11a1 1 0 0 1 1-1h5a1 1 0 1 1 0 2h-5a1 1 0 0 1-1-1ZM3.678 19h12.644c-.71-2.909-3.092-5-6.322-5s-5.613 2.091-6.322 5Zm-2.174.906C1.917 15.521 5.242 12 10 12c4.758 0 8.083 3.521 8.496 7.906A1 1 0 0 1 17.5 21h-15a1 1 0 0 1-.996-1.094Z', +}) diff --git a/src/components/icons/PersonCheck.tsx b/src/components/icons/PersonCheck.tsx new file mode 100644 index 0000000000..097271d89a --- /dev/null +++ b/src/components/icons/PersonCheck.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const PersonCheck_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M12 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM7.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM5.679 19c.709-2.902 3.079-5 6.321-5a6.69 6.69 0 0 1 2.612.51 1 1 0 0 0 .776-1.844A8.687 8.687 0 0 0 12 12c-4.3 0-7.447 2.884-8.304 6.696-.29 1.29.767 2.304 1.902 2.304H11a1 1 0 1 0 0-2H5.679Zm14.835-4.857a1 1 0 0 1 .344 1.371l-3 5a1 1 0 0 1-1.458.286l-2-1.5a1 1 0 0 1 1.2-1.6l1.113.835 2.43-4.05a1 1 0 0 1 1.372-.342Z', +}) diff --git a/src/components/icons/PersonX.tsx b/src/components/icons/PersonX.tsx new file mode 100644 index 0000000000..a015e13765 --- /dev/null +++ b/src/components/icons/PersonX.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const PersonX_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M12 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM7.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM5.679 19c.709-2.902 3.079-5 6.321-5 .302 0 .595.018.878.053a1 1 0 0 0 .243-1.985A9.235 9.235 0 0 0 12 12c-4.3 0-7.447 2.884-8.304 6.696-.29 1.29.767 2.304 1.902 2.304H12a1 1 0 1 0 0-2H5.679Zm9.614-3.707a1 1 0 0 1 1.414 0L18 16.586l1.293-1.293a1 1 0 0 1 1.414 1.414L19.414 18l1.293 1.293a1 1 0 0 1-1.414 1.414L18 19.414l-1.293 1.293a1 1 0 0 1-1.414-1.414L16.586 18l-1.293-1.293a1 1 0 0 1 0-1.414Z', +}) 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/icons/StreamingLive.tsx b/src/components/icons/StreamingLive.tsx new file mode 100644 index 0000000000..8ab5099da7 --- /dev/null +++ b/src/components/icons/StreamingLive.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const StreamingLive_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M4 4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H4Zm8 12.5c1.253 0 2.197.609 2.674 1.5H9.326c.477-.891 1.42-1.5 2.674-1.5Zm0-2c2.404 0 4.235 1.475 4.822 3.5H20V6H4v12h3.178c.587-2.025 2.418-3.5 4.822-3.5Zm-1.25-3.75a1.25 1.25 0 1 1 2.5 0 1.25 1.25 0 0 1-2.5 0ZM12 7.5a3.25 3.25 0 1 0 0 6.5 3.25 3.25 0 0 0 0-6.5Zm5.75 2a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Z', +}) 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 + childContainerStyle?: StyleProp +}>) { + 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 ( + + {children} + + ) + } + + return ( + + + + + + {desc.source && blur.type === 'label' && !override && ( + + )} + + {override && {children}} + + ) +} + +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 ( + + + {labelStrings.name} + + {labelStrings.description} + + + + {!disabled && ( + + mutate({ + label: identifier, + visibility: newPref[0] as LabelPreference, + labelerDid: undefined, + }) + }> + + {labelOptions.ignore} + + + {labelOptions.warn} + + + {labelOptions.hide} + + + )} + + + ) +} 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 +}) { + 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 ( + + + + + + ) +} + +export function LabelsOnMyPost({ + post, + style, +}: { + post: AppBskyFeedDefs.PostView + style?: StyleProp +}) { + const {currentAccount} = useSession() + if (post.author.did !== currentAccount?.did) { + return null + } + return ( + + ) +} 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 ( + + {appealingLabel ? ( + setAppealingLabel(undefined)} + /> + ) : ( + <> + + {isAccount ? ( + Labels on your account + ) : ( + Labels on your content + )} + + + + You may appeal these labels if you feel they were placed in error. + + + + + {labels.map(label => ( + + + )} + + + + ) +} + +export function LabelsOnMeDialog(props: LabelsOnMeDialogProps) { + return ( + + + + + + ) +} + +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 ( + + + + {strings.name} + + {strings.description} + + + + + + + + + + + + Source:{' '} + control.close()}> + {labeler ? sanitizeHandle(labeler.creator.handle, '@') : label.src} + + + + + ) +} + +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 ( + <> + + Appeal "{strings.name}" label + + + + This appeal will be sent to{' '} + control.close()} + style={[a.text_md, a.leading_snug]}> + {labeler ? sanitizeHandle(labeler.creator.handle, '@') : label.src} + + . + + + + + + + + + + + + ) +} 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 ( + + + + + ) +} + +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 = ( + + This user is included in the{' '} + + {list.name} + {' '} + list which you have blocked. + + ) + } 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 = ( + + This user is included in the{' '} + + {list.name} + {' '} + list which you have muted. + + ) + } 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 ( + + + {name} + + + {description} + + + {modcause.type === 'label' && ( + <> + + + + This label was applied by{' '} + {modcause.source.type === 'user' ? ( + the author + ) : ( + control.close()} + style={a.text_md}> + {desc.source} + + )} + . + + + + )} + + {isNative && } + + + + ) +} diff --git a/src/components/moderation/ModerationLabelPref.tsx b/src/components/moderation/ModerationLabelPref.tsx new file mode 100644 index 0000000000..b16c248592 --- /dev/null +++ b/src/components/moderation/ModerationLabelPref.tsx @@ -0,0 +1,177 @@ +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, useBreakpoints} 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 {gtPhone} = useBreakpoints() + + 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 + const showConfig = !disabled && (gtPhone || !cantConfigure) + + // 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 ( + + + + {labelStrings.name} + + + {labelStrings.description} + + + {cantConfigure && ( + + + + + {adultDisabled ? ( + Adult content is disabled. + ) : isGlobalLabel ? ( + + Configured in{' '} + + moderation settings + + . + + ) : null} + + + )} + + + {showConfig && ( + + {cantConfigure ? ( + + + {currentPrefLabel} + + + ) : ( + + + mutate({ + label: identifier, + visibility: newPref[0] as LabelPreference, + labelerDid, + }) + }> + + {ignoreLabel} + + {canWarn && ( + + {warnLabel} + + )} + + {hideLabel} + + + + )} + + )} + + ) +} 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 +}) { + if (!modui.alert && !modui.inform) { + return null + } + + return ( + + + {modui.alerts.map(cause => ( + + ))} + {modui.informs.map(cause => ( + + ))} + + + ) +} + +function PostLabel({cause}: {cause: ModerationCause}) { + const control = useModerationDetailsDialogControl() + const desc = useModerationCauseDescription(cause) + + return ( + <> + + + + + ) +} 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 { iconSize: number iconStyles: StyleProp - 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 ( {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 ? ( { - 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, ]}> + { - openModal({ - name: 'moderation-details', - context: 'content', - moderation, - }) + control.open() }} accessibilityRole="button" accessibilityLabel={_(msg`Learn more about this warning`)} accessibilityHint=""> - {isMute ? ( - - ) : ( - - )} + - + {desc.name} - {!moderation.noOverride && ( - + {!modui.noOverride && ( + {override ? Hide : Show} )} @@ -114,26 +113,14 @@ export function PostHider({ testID={testID} style={addStyle(style, styles.child)} href={href} - noFeedback> + accessible={false} + {...props}> {children} ) } 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 +}) { + const modui = moderation.ui('profileView') + if (!modui.alert && !modui.inform) { + return null + } + + return ( + + + {modui.alerts.map(cause => ( + + ))} + {modui.informs.map(cause => ( + + ))} + + + ) +} + +function ProfileLabel({cause}: {cause: ModerationCause}) { + const control = useModerationDetailsDialogControl() + const desc = useModerationCauseDescription(cause) + + return ( + <> + + + + + ) +} diff --git a/src/components/moderation/ScreenHider.tsx b/src/components/moderation/ScreenHider.tsx new file mode 100644 index 0000000000..4e3a9680f5 --- /dev/null +++ b/src/components/moderation/ScreenHider.tsx @@ -0,0 +1,172 @@ +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 + containerStyle?: StyleProp +}>) { + const t = useTheme() + const {_} = useLingui() + const [override, setOverride] = React.useState(false) + const navigation = useNavigation() + const {isMobile} = useWebMediaQueries() + const control = useModerationDetailsDialogControl() + const blur = modui.blurs[0] + const desc = useModerationCauseDescription(blur) + + if (!blur || override) { + return ( + + {children} + + ) + } + + const isNoPwi = !!modui.blurs.find( + cause => + cause.type === 'label' && + cause.labelDef.identifier === '!no-unauthenticated', + ) + return ( + + + + + + + + {isNoPwi ? ( + Sign-in Required + ) : ( + Content Warning + )} + + + {isNoPwi ? ( + + This account has requested that users sign in to view their profile. + + ) : ( + <> + This {screenDescription} has been flagged: + + {desc.name}.{' '} + + { + control.open() + }} + accessibilityRole="button" + accessibilityLabel={_(msg`Learn more about this warning`)} + accessibilityHint=""> + + Learn More + + + + + + )}{' '} + + {isMobile && } + + + {!modui.noOverride && ( + + )} + + + ) +} 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/hooks/useOTAUpdate.ts b/src/lib/hooks/useOTAUpdate.ts index 53eab300e7..d35179256d 100644 --- a/src/lib/hooks/useOTAUpdate.ts +++ b/src/lib/hooks/useOTAUpdate.ts @@ -2,25 +2,9 @@ import * as Updates from 'expo-updates' import {useCallback, useEffect} from 'react' import {AppState} from 'react-native' import {logger} from '#/logger' -import {useModalControls} from '#/state/modals' -import {t} from '@lingui/macro' export function useOTAUpdate() { - const {openModal} = useModalControls() - // HELPER FUNCTIONS - const showUpdatePopup = useCallback(() => { - openModal({ - name: 'confirm', - title: t`Update Available`, - message: t`A new version of the app is available. Please update to continue using the app.`, - onPressConfirm: async () => { - Updates.reloadAsync().catch(err => { - throw err - }) - }, - }) - }, [openModal]) const checkForUpdate = useCallback(async () => { logger.debug('useOTAUpdate: Checking for update...') try { @@ -32,32 +16,26 @@ export function useOTAUpdate() { } // Otherwise fetch the update in the background, so even if the user rejects switching to latest version it will be done automatically on next relaunch. await Updates.fetchUpdateAsync() - // show a popup modal - showUpdatePopup() } catch (e) { logger.error('useOTAUpdate: Error while checking for update', { message: e, }) } - }, [showUpdatePopup]) - const updateEventListener = useCallback( - (event: Updates.UpdateEvent) => { - logger.debug('useOTAUpdate: Listening for update...') - if (event.type === Updates.UpdateEventType.ERROR) { - logger.error('useOTAUpdate: Error while listening for update', { - message: event.message, - }) - } else if (event.type === Updates.UpdateEventType.NO_UPDATE_AVAILABLE) { - // Handle no update available - // do nothing - } else if (event.type === Updates.UpdateEventType.UPDATE_AVAILABLE) { - // Handle update available - // open modal, ask for user confirmation, and reload the app - showUpdatePopup() - } - }, - [showUpdatePopup], - ) + }, []) + const updateEventListener = useCallback((event: Updates.UpdateEvent) => { + logger.debug('useOTAUpdate: Listening for update...') + if (event.type === Updates.UpdateEventType.ERROR) { + logger.error('useOTAUpdate: Error while listening for update', { + message: event.message, + }) + } else if (event.type === Updates.UpdateEventType.NO_UPDATE_AVAILABLE) { + // Handle no update available + // do nothing + } else if (event.type === Updates.UpdateEventType.UPDATE_AVAILABLE) { + // Handle update available + // open modal, ask for user confirmation, and reload the app + } + }, []) useEffect(() => { // ADD EVENT LISTENERS 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 = '' } } diff --git a/src/lib/media/picker.shared.ts b/src/lib/media/picker.shared.ts index 8bade34e25..96e82e4c72 100644 --- a/src/lib/media/picker.shared.ts +++ b/src/lib/media/picker.shared.ts @@ -18,11 +18,18 @@ export async function openPicker(opts?: ImagePickerOptions) { Toast.show('You may only select up to 4 images') } - return (response.assets ?? []).slice(0, 4).map(image => ({ - mime: 'image/jpeg', - height: image.height, - width: image.width, - path: image.uri, - size: getDataUriSize(image.uri), - })) + return (response.assets ?? []) + .slice(0, 4) + .filter(asset => { + if (asset.mimeType?.startsWith('image/')) return true + Toast.show('Only image files are supported') + return false + }) + .map(image => ({ + mime: 'image/jpeg', + height: image.height, + width: image.width, + path: image.uri, + size: getDataUriSize(image.uri), + })) } 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[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[1] export function moderatePost_wrapped( subject: Parameters[0], opts: Options, ) { - const {hiddenPosts = [], mutedWords = [], ...options} = opts - const moderations = moderatePost(subject, options) - const isOwnPost = subject.author.did === opts.userDid - - 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, - } - } - } + // HACK + // temporarily translate 'gore' into 'graphic-media' during the transition period + // can remove this in a few months + // -prf + translateOldLabels(subject) - 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, - }) - } - } - } + return moderatePost(subject, opts) +} - 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, - } +function translateOldLabels(subject: Parameters[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' } } } - - return moderations } 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,149 +1,81 @@ -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 -} +import {sanitizeDisplayName} from '#/lib/strings/display-names' +import {sanitizeHandle} from '#/lib/strings/handles' -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.`, - } +export function getModerationCauseKey(cause: ModerationCause): string { + const source = + cause.source.type === 'labeler' + ? cause.source.did + : cause.source.type === 'list' + ? cause.source.list.uri + : 'user' + if (cause.type === 'label') { + return `label:${cause.label.val}:${source}` } - return cause.labelDef.strings[context].en + return `${cause.type}:${source}` } -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 isJustAMute(modui: ModerationUI): boolean { + return modui.filters.length === 1 && modui.filters[0].type === 'muted' } -export function isPostMediaBlurred( - decisions: PostModeration['decisions'], -): boolean { - return decisions.post.blurMedia +export function getLabelingServiceTitle({ + displayName, + handle, +}: { + displayName?: string + handle: string +}) { + return displayName + ? sanitizeDisplayName(displayName) + : sanitizeHandle(handle, '@') } -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 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 isCauseALabelOnUri( - cause: ModerationCause | undefined, - uri: string, +export function isAppLabeler( + labeler: + | string + | AppBskyLabelerDefs.LabelerView + | AppBskyLabelerDefs.LabelerViewDetailed, ): boolean { - if (cause?.type !== 'label') { - return false + if (typeof labeler === 'string') { + return BskyAgent.appLabelers.includes(labeler) } - return cause.label.uri === uri + return BskyAgent.appLabelers.includes(labeler.creator.did) } -export function getModerationCauseKey(cause: ModerationCause): string { - const source = - cause.source.type === 'labeler' - ? cause.source.labeler.did - : cause.source.type === 'list' - ? cause.source.list.uri - : 'user' - if (cause.type === 'label') { - return `label:${cause.label.val}:${source}` +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 `${cause.type}:${source}` + 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, + 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 + 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/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/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/statsig/events.ts b/src/lib/statsig/events.ts new file mode 100644 index 0000000000..b91a15ecb1 --- /dev/null +++ b/src/lib/statsig/events.ts @@ -0,0 +1,50 @@ +export type LogEvents = { + init: { + initMs: number + } + 'notifications:openApp': {} + 'state:background': {} + 'state:foreground': {} + 'feed:endReached': { + feedType: string + itemCount: number + } + 'post:create': { + imageCount: number + isReply: boolean + hasLink: boolean + hasQuote: boolean + langs: string + logContext: 'Composer' + } + 'post:like': { + logContext: 'FeedItem' | 'PostThreadItem' | 'Post' + } + 'post:repost': { + logContext: 'FeedItem' | 'PostThreadItem' | 'Post' + } + 'post:unlike': { + logContext: 'FeedItem' | 'PostThreadItem' | 'Post' + } + 'post:unrepost': { + logContext: 'FeedItem' | 'PostThreadItem' | 'Post' + } + 'profile:follow': { + logContext: + | 'RecommendedFollowsItem' + | 'PostThreadItem' + | 'ProfileCard' + | 'ProfileHeader' + | 'ProfileHeaderSuggestedFollows' + | 'ProfileMenu' + } + 'profile:unfollow': { + logContext: + | 'RecommendedFollowsItem' + | 'PostThreadItem' + | 'ProfileCard' + | 'ProfileHeader' + | 'ProfileHeaderSuggestedFollows' + | 'ProfileMenu' + } +} diff --git a/src/lib/statsig/statsig.tsx b/src/lib/statsig/statsig.tsx index 6d9ebeb099..3abec5c4f9 100644 --- a/src/lib/statsig/statsig.tsx +++ b/src/lib/statsig/statsig.tsx @@ -1,11 +1,16 @@ 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' + +export type {LogEvents} const statsigOptions = { environment: { @@ -17,12 +22,28 @@ const statsigOptions = { initTimeoutMs: 1, } -export function logEvent( - eventName: string, - value?: string | number | null, - metadata?: Record | null, +type FlatJSONRecord = Record< + string, + string | number | boolean | null | undefined +> + +let getCurrentRouteName: () => string | null | undefined = () => null + +export function attachRouteToLogEvents( + getRouteName: () => string | null | undefined, +) { + getCurrentRouteName = getRouteName +} + +export function logEvent( + eventName: E & string, + rawMetadata: LogEvents[E] & FlatJSONRecord, ) { - Statsig.logEvent(eventName, value, metadata) + const fullMetadata = { + ...rawMetadata, + } as Record // Statsig typings are unnecessarily strict here. + fullMetadata.routeName = getCurrentRouteName() ?? '(Uninitialized)' + Statsig.logEvent(eventName, null, fullMetadata) } export function useGate(gateName: string) { @@ -39,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( diff --git a/src/lib/statsig/statsig.web.tsx b/src/lib/statsig/statsig.web.tsx deleted file mode 100644 index d1c9120194..0000000000 --- a/src/lib/statsig/statsig.web.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import React from 'react' -import { - Statsig, - StatsigProvider, - useGate as useStatsigGate, -} from 'statsig-react' -import {useSession} from '../../state/session' -import {sha256} from 'js-sha256' - -const statsigOptions = { - environment: { - tier: process.env.NODE_ENV === 'development' ? 'development' : 'production', - }, - // Don't block on waiting for network. The fetched config will kick in on next load. - // This ensures the UI is always consistent and doesn't update mid-session. - // Note this makes cold load (no local storage) and private mode return `false` for all gates. - initTimeoutMs: 1, -} - -export function logEvent( - eventName: string, - value?: string | number | null, - metadata?: Record | null, -) { - Statsig.logEvent(eventName, value, metadata) -} - -export function useGate(gateName: string) { - const {isLoading, value} = useStatsigGate(gateName) - if (isLoading) { - // This should not happen because of waitForInitialization={true}. - console.error('Did not expected isLoading to ever be true.') - } - return value -} - -function toStatsigUser(did: string | undefined) { - let userID: string | undefined - if (did) { - userID = sha256(did) - } - return {userID} -} - -export function Provider({children}: {children: React.ReactNode}) { - const {currentAccount} = useSession() - const currentStatsigUser = React.useMemo( - () => toStatsigUser(currentAccount?.did), - [currentAccount?.did], - ) - - React.useEffect(() => { - function refresh() { - // Intentionally refetching the config using the JS SDK rather than React SDK - // so that the new config is stored in cache but isn't used during this session. - // It will kick in for the next reload. - Statsig.updateUser(currentStatsigUser) - } - const id = setInterval(refresh, 3 * 60e3 /* 3 min */) - return () => clearInterval(id) - }, [currentStatsigUser]) - - return ( - - {children} - - ) -} 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/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}`, } } } 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 } 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/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': diff --git a/src/locale/i18n.ts b/src/locale/i18n.ts index e8addb0b4f..a1e950947b 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 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' @@ -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 diff --git a/src/locale/i18n.web.ts b/src/locale/i18n.web.ts index d8e51723ff..334b2586e5 100644 --- a/src/locale/i18n.web.ts +++ b/src/locale/i18n.web.ts @@ -20,6 +20,10 @@ export async function dynamicActivate(locale: AppLanguage) { 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`) break diff --git a/src/locale/languages.ts b/src/locale/languages.ts index 3fdabd02ec..1cbe8fa830 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: 'Suomi – Finnish'}, {code2: AppLanguage.fr, name: 'Français – French'}, {code2: AppLanguage.hi, name: 'हिंदी – Hindi'}, {code2: AppLanguage.id, name: 'Bahasa Indonesia – Indonesian'}, 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}?" #: 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." -msgstr "" +msgstr "Aquesta funcionalitat està en beta. En <0>aquesta entrada al blog 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" #: 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" 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} <1>following" -msgstr "" +msgstr "<0>{following} <1>folge ich" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:30 msgid "<0>Choose your<1>Recommended<2>Feeds" @@ -61,11 +43,11 @@ msgstr "<0>Folge einigen<1>empfohlenen<2>Nutzern" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:21 msgid "<0>Welcome to<1>Bluesky" -msgstr "" +msgstr "<0>Willkommen bei<1>Bluesky" #: 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." -#~ 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}?" -msgstr "" +msgstr "Schreibst du auf <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} posts" -msgstr "" +msgstr "Siehe <0>{displayTag}-Beiträge" #: src/components/TagMenu/index.tsx:187 msgid "See <0>{displayTag} posts by this user" -msgstr "" - -#: src/components/TagMenu/index.tsx:128 -#~ msgid "See <0>{tag} posts" -#~ msgstr "" - -#: src/components/TagMenu/index.tsx:189 -#~ msgid "See <0>{tag} posts by this user" -#~ msgstr "" +msgstr "Siehe <0>{displayTag}-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." -msgstr "" +msgstr "Diese Funktion befindet sich in der Beta-Phase. Du kannst mehr über Kontodepot-Exporte in <0>diesem Blogpost lesen." #: 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" #: 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}" -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}" #: 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" diff --git a/src/locale/locales/en/messages.po b/src/locale/locales/en/messages.po index 98ac7e51b6..803df9359c 100644 --- a/src/locale/locales/en/messages.po +++ b/src/locale/locales/en/messages.po @@ -4128,8 +4128,8 @@ msgstr "" msgid "Unmute thread" msgstr "" -#: 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 "" @@ -4614,4 +4614,4 @@ msgstr "" #: src/view/com/auth/create/Step2.tsx:65 msgid "Your user handle" -msgstr "" +msgstr "" \ No newline at end of file diff --git a/src/locale/locales/fi/messages.po b/src/locale/locales/fi/messages.po new file mode 100644 index 0000000000..f5b40f4214 --- /dev/null +++ b/src/locale/locales/fi/messages.po @@ -0,0 +1,4838 @@ +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:@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 "(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:593 +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:595 +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:558 +msgid "⚠Invalid Handle" +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 "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:647 +msgid "Access navigation links and settings" +msgstr "Siirry navigointilinkkeihin ja asetuksiin" + +#: src/view/com/home/HomeHeaderLayoutMobile.tsx:51 +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:246 +msgid "Account blocked" +msgstr "Tili on estetty" + +#: src/view/com/profile/ProfileHeader.tsx:213 +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 listalla" + +#: 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:268 +msgid "Account unblocked" +msgstr "Tilin esto poistettu" + +#: 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 +#: 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:453 +msgid "Add link card" +msgstr "Lisää linkkikortti" + +#: 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:310 +msgid "Add to Lists" +msgstr "Lisää listoihin" + +#: src/view/com/feeds/FeedSourceCard.tsx:245 +#: src/view/screens/ProfileFeed.tsx:273 +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:127 +msgid "Added to my feeds" +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 "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:295 +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:150 +msgid "Are you sure you'd like to discard this draft?" +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 "Oletko varma?" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:278 +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: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/util/ViewHeader.tsx:81 +msgid "Back" +msgstr "Takaisin" + +#: src/view/com/post-thread/PostThread.tsx:480 +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:239 +#: src/view/com/profile/ProfileHeader.tsx:346 +msgid "Block Account" +msgstr "Estä käyttäjä" + +#: src/view/screens/ProfileList.tsx:556 +msgid "Block accounts" +msgstr "Estä käyttäjät" + +#: src/view/screens/ProfileList.tsx:506 +msgid "Block list" +msgstr "Estettyjen lista" + +#: src/view/screens/ProfileList.tsx:316 +msgid "Block these accounts?" +msgstr "Estetäänkö nämä käyttäjät?" + +#: src/view/screens/ProfileList.tsx:320 +msgid "Block this List" +msgstr "Estä tämä lista" + +#: 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:142 +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: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." + +#: 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: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." + +#: 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: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ä." + +#: 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: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 +#: 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ätunnuksen 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ätunnus" + +#: src/view/com/modals/ChangeHandle.tsx:161 +#: src/view/screens/Settings/index.tsx:705 +msgid "Change Handle" +msgstr "Vaihda käyttäjätunnus" + +#: 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ätunnus 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:697 +msgid "Clear search query" +msgstr "Tyhjennä hakukysely" + +#: src/view/screens/Support.tsx:40 +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" + +#: src/view/com/modals/ChangePassword.tsx:265 +#: src/view/com/modals/ChangePassword.tsx:268 +msgid "Close" +msgstr "Sulje" + +#: src/components/Dialog/index.web.tsx:80 +#: src/components/Dialog/index.web.tsx:194 +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:51 +msgid "Close navigation footer" +msgstr "Sulje alanavigointi" + +#: 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" + +#: src/view/com/auth/login/PasswordUpdatedForm.tsx:39 +msgid "Closes password update alert" +msgstr "Sulkee salasanan päivitysilmoituksen" + +#: src/view/com/composer/Composer.tsx:309 +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:424 +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/PreferencesFollowingFeed.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:193 +#: src/view/com/auth/login/LoginForm.tsx:278 +msgid "Connecting..." +msgstr "Yhdistetään..." + +#: src/view/com/auth/create/CreateAccount.tsx:213 +msgid "Contact support" +msgstr "Ota yhteyttä tukeen" + +#: src/view/screens/Moderation.tsx:83 +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:114 +#: 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:111 +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:143 +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:418 +msgid "Copy link to list" +msgstr "Kopioi listan linkki" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 +msgid "Copy link to post" +msgstr "Kopioi julkaisun linkki" + +#: src/view/com/profile/ProfileHeader.tsx:295 +msgid "Copy link to profile" +msgstr "Kopioi linkki profiiliin" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:170 +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:97 +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:133 +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:455 +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 käyttäjä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:364 +#: src/view/screens/ProfileList.tsx:445 +msgid "Delete List" +msgstr "Poista lista" + +#: src/view/com/modals/DeleteAccount.tsx:223 +msgid "Delete my account" +msgstr "Poista käyttäjä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:273 +msgid "Delete post" +msgstr "Poista viesti" + +#: 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:70 +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:218 +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:151 +msgid "Discard" +msgstr "Hylkää" + +#: src/view/com/composer/Composer.tsx:145 +msgid "Discard draft" +msgstr "Hylkää luonnos" + +#: 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" + +#: 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/PreferencesFollowingFeed.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:249 +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:433 +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:418 +msgid "Edit profile" +msgstr "Muokkaa profiilia" + +#: 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ä" + +#: 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/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ä." + +#: 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 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" +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ätunnuksesi 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:110 +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 "Peruuttaa käyttäjätunnuksen vaihtamisen" + +#: 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 "Poistuu 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:261 +#: 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:110 +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:231 +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:76 +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:440 +msgid "Find users on Bluesky" +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 "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 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." + +#: 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:513 +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:504 +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/PreferencesFollowingFeed.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:495 +#: src/view/screens/ProfileFollows.tsx:25 +msgid "Following" +msgstr "Seuraa" + +#: src/view/com/profile/ProfileHeader.tsx:149 +msgid "Following {0}" +msgstr "Seuraa {0}" + +#: 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" + +#: 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:189 +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: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" + +#: 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:747 +#: 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/components/RichText.tsx:188 +msgid "Hashtag: {tag}" +msgstr "Tunniste: {tag}" + +#: src/view/com/auth/create/CreateAccount.tsx:208 +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: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: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." + +#: 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:232 +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:236 +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:487 +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:435 +#: 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:80 +msgid "Input your user handle" +msgstr "Syötä käyttäjätunnuksesi" + +#: src/view/com/post-thread/PostThreadItem.tsx:226 +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:262 +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:279 +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:183 +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:324 +msgid "List blocked" +msgstr "Lista estetty" + +#: src/view/com/feeds/FeedSourceCard.tsx:233 +msgid "List by {0}" +msgstr "Listan on luonut {0}" + +#: src/view/screens/ProfileList.tsx:378 +msgid "List deleted" +msgstr "Lista poistettu" + +#: src/view/screens/ProfileList.tsx:283 +msgid "List muted" +msgstr "Lista hiljennetty" + +#: src/view/com/modals/CreateOrEditList.tsx:275 +msgid "List Name" +msgstr "Listan nimi" + +#: src/view/screens/ProfileList.tsx:343 +msgid "List unblocked" +msgstr "Listaa estosta poistetut" + +#: src/view/screens/ProfileList.tsx:302 +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: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ä" + +#: 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:155 +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/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" + +#: 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:66 +#: 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:93 +#: 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:91 +#: 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:114 +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: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:315 +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/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: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/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:275 +msgid "Mute these accounts?" +msgstr "Hiljennä nämä käyttäjät?" + +#: src/view/screens/ProfileList.tsx:279 +msgid "Mute this List" +msgstr "Hiljennä tämä lista" + +#: src/components/dialogs/MutedWords.tsx:109 +msgid "Mute this word in post text and tags" +msgstr "Hiljennä tämä sana viesteissä ja tunnisteissa" + +#: 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:128 +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/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ä." + +#: 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/components/dialogs/MutedWords.tsx:244 +msgid "Nevermind" +msgstr "Ei väliä" + +#: 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:126 +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: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" + +#: 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: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 +#: 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/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" +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:170 +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:281 +#: src/view/screens/Search/Search.tsx:309 +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: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:450 +#: 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:382 +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/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" + +#: src/view/screens/Settings/index.tsx:712 +msgid "Open links with in-app browser" +msgstr "Avaa linkit sovelluksen sisäisellä selaimella" + +#: 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" + +#: 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: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" + +#: src/view/screens/Settings/index.tsx:649 +msgid "Opens external embeds settings" +msgstr "Avaa ulkoiset upotusasetukset" + +#: src/view/com/profile/ProfileHeader.tsx:575 +msgid "Opens followers list" +msgstr "Avaa seuraajalistan" + +#: src/view/com/profile/ProfileHeader.tsx:594 +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/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" + +#: 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:354 +#: src/view/screens/ProfileList.tsx:581 +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ätunnuksesi." + +#: 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:222 +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:357 +#: src/view/com/composer/Composer.tsx:365 +msgctxt "action" +msgid "Post" +msgstr "Lähetä" + +#: src/view/com/post-thread/PostThread.tsx:303 +msgctxt "description" +msgid "Post" +msgstr "Viesti" + +#: src/view/com/post-thread/PostThreadItem.tsx:175 +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:90 +msgid "Post deleted" +msgstr "Viesti poistettu" + +#: src/view/com/post-thread/PostThread.tsx:462 +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: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" + +#: 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:342 +msgid "Publish post" +msgstr "Julkaise viesti" + +#: src/view/com/composer/Composer.tsx:342 +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/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 +#: src/view/com/util/UserAvatar.tsx:285 +#: src/view/com/util/UserBanner.tsx:91 +msgid "Remove" +msgstr "Poista" + +#: src/view/com/feeds/FeedSourceCard.tsx:108 +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: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" + +#: 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/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:175 +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:113 +#: src/view/com/feeds/FeedSourceCard.tsx:180 +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:355 +msgctxt "action" +msgid "Reply" +msgstr "Vastaa" + +#: src/view/screens/PreferencesFollowingFeed.tsx:144 +msgid "Reply Filters" +msgstr "Vastaussuodattimet" + +#: 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/>" + +#: src/view/com/modals/report/Modal.tsx:166 +msgid "Report {collectionName}" +msgstr "Raportoi {collectionName}" + +#: src/view/com/profile/ProfileHeader.tsx:361 +msgid "Report Account" +msgstr "Ilmoita tili" + +#: src/view/screens/ProfileFeed.tsx:293 +msgid "Report feed" +msgstr "Ilmoita syöte" + +#: 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:255 +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:207 +msgid "Reposted by {0}" +msgstr "Uudelleenjakanut {0}" + +#: src/view/com/posts/FeedItem.tsx:224 +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:188 +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: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 +#: 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:346 +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: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: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 +#: 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: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 +msgid "Search for users" +msgstr "Hae käyttäjiä" + +#: src/view/com/modals/ChangeEmail.tsx:110 +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" + +#: 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:96 +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/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/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/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." + +#: 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/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 +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:295 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 +#: src/view/screens/ProfileList.tsx:418 +msgid "Share" +msgstr "Jaa" + +#: src/view/screens/ProfileFeed.tsx:305 +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/PreferencesFollowingFeed.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:459 +msgid "Show follows similar to {0}" +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 "Näytä lisää" + +#: src/view/screens/PreferencesFollowingFeed.tsx:258 +msgid "Show Posts from My Feeds" +msgstr "Näytä viestit omista syötteistäni" + +#: src/view/screens/PreferencesFollowingFeed.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/PreferencesFollowingFeed.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/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/PreferencesFollowingFeed.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: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:506 +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ätunnuksella @{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:63 +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:608 +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:604 +msgid "Subscribe to this list" +msgstr "Tilaa tämä lista" + +#: src/view/screens/Search/Search.tsx:374 +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/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ä" + +#: 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/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:94 +msgid "That handle is already taken." +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 "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:517 +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: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." + +#: 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: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: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 +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: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" + +#: 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: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: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." + +#: 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:476 +#: src/view/screens/ProfileList.tsx:661 +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:125 +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/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." + +#: 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: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" + +#: src/view/com/modals/EditImage.tsx:271 +msgid "Transformations" +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 "Käännä" + +#: src/view/com/util/error/ErrorScreen.tsx:82 +msgctxt "action" +msgid "Try again" +msgstr "Yritä uudelleen" + +#: src/view/screens/ProfileList.tsx:506 +msgid "Un-block list" +msgstr "Poista listan esto" + +#: src/view/screens/ProfileList.tsx:491 +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:433 +#: src/view/screens/ProfileList.tsx:590 +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:261 +#: src/view/com/profile/ProfileHeader.tsx:345 +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:485 +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/components/TagMenu/index.tsx:253 +#: src/view/screens/ProfileList.tsx:597 +msgid "Unmute" +msgstr "Poista hiljennys" + +#: 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/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" + +#: src/view/screens/ProfileFeed.tsx:353 +#: src/view/screens/ProfileList.tsx:580 +msgid "Unpin" +msgstr "Poista kiinnitys" + +#: src/view/screens/ProfileList.tsx:474 +msgid "Unpin moderation list" +msgstr "Poista moderointilistan kiinnitys" + +#: src/view/screens/ProfileFeed.tsx:346 +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:79 +msgid "User handle" +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 "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: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" + +#: 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:662 +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/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:" + +#: 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:134 +msgid "We're so excited to have you join us!" +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 "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 "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." + +#: 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:286 +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 "Leveä" + +#: src/view/com/composer/Composer.tsx:422 +msgid "Write post" +msgstr "Kirjoita viesti" + +#: src/view/com/composer/Composer.tsx:285 +#: 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/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" +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: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." + +#: 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/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öä." + +#: 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: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:132 +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:83 +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/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:274 +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:273 +msgid "Your reply has been published" +msgstr "Vastauksesi on julkaistu" + +#: src/view/com/auth/create/Step2.tsx:65 +msgid "Your user handle" +msgstr "Käyttäjätunnuksesi" 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} <1>abonnements" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:30 msgid "<0>Choose your<1>Recommended<2>Feeds" -msgstr "<0>Choisissez vos<1>fils d’actualité<2>recommandés" +msgstr "<0>Choisissez vos<1>fils d’actu<2>recommandés" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:37 msgid "<0>Follow some<1>Recommended<2>Users" @@ -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." -#~ 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}?" -msgstr "" +msgstr "Écrivez-vous en <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} posts" -msgstr "" +msgstr "Voir les posts <0>{displayTag}" #: src/components/TagMenu/index.tsx:187 msgid "See <0>{displayTag} posts by this user" -msgstr "" - -#: src/components/TagMenu/index.tsx:128 -#~ msgid "See <0>{tag} posts" -#~ msgstr "" - -#: src/components/TagMenu/index.tsx:189 -#~ msgid "See <0>{tag} posts by this user" -#~ msgstr "" +msgstr "Voir les posts <0>{displayTag} 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." -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." #: 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" @@ -4646,29 +4368,29 @@ msgstr "Bienvenue sur <0>Bluesky" #: 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}" msgstr "Votre pseudo complet sera <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" diff --git a/src/locale/locales/it/messages.po b/src/locale/locales/it/messages.po index 29c6ba178b..89f7b71063 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" +"PO-Revision-Date: 2024-02-18\n" "Last-Translator: Gabriella Nonino \n" -"Language-Team: \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,21 +32,6 @@ msgstr "(no email)" 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" @@ -162,8 +147,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" @@ -237,12 +221,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}" @@ -280,7 +264,7 @@ msgstr "e" #: src/screens/Onboarding/index.tsx:32 msgid "Animals" -msgstr "" +msgstr "Animali" #: src/view/screens/LanguageSettings.tsx:95 msgid "App Language" @@ -321,9 +305,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" @@ -359,7 +340,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." @@ -386,11 +367,11 @@ 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" -msgstr "Nozioni di base" +msgstr "Preferenze" #: src/view/com/auth/create/Step1.tsx:227 #: src/view/com/modals/BirthDateSettings.tsx:73 @@ -465,7 +446,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 @@ -490,13 +471,9 @@ msgstr "Bluesky è pubblico." 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}" @@ -507,10 +484,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—" @@ -528,8 +501,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" @@ -548,8 +520,7 @@ 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/screens/Search/Search.tsx:716 @@ -557,8 +528,7 @@ msgstr "Può contenere solo lettere, numeri, spazi, trattini e trattini bassi. D 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 @@ -571,9 +541,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" @@ -604,9 +571,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" @@ -622,11 +586,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}" @@ -634,16 +598,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." @@ -671,7 +634,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 @@ -680,7 +643,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:196 msgid "Choose your password" @@ -723,12 +686,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 "Chiudi" #: src/components/Dialog/index.web.tsx:84 #: src/components/Dialog/index.web.tsx:198 @@ -781,11 +744,11 @@ 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:229 #: src/view/screens/CommunityGuidelines.tsx:32 @@ -794,7 +757,7 @@ 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/auth/create/Step3.tsx:73 msgid "Complete the challenge" @@ -810,7 +773,7 @@ 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:124 #: src/view/com/modals/AppealLabel.tsx:98 @@ -822,8 +785,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" @@ -905,19 +867,19 @@ msgstr "Continua" #: src/screens/Onboarding/StepModeration/index.tsx:115 #: src/screens/Onboarding/StepTopicalFeeds.tsx:111 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 @@ -1018,12 +980,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 "Personalizzato" #: src/view/com/modals/ChangeHandle.tsx:389 msgid "Custom domain" @@ -1032,16 +994,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" @@ -1053,7 +1011,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" @@ -1067,8 +1025,7 @@ 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" @@ -1079,15 +1036,11 @@ 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:317 #: src/view/com/util/forms/PostDropdownBtn.tsx:326 @@ -1096,7 +1049,7 @@ msgstr "Elimina il post" #: src/view/com/util/forms/PostDropdownBtn.tsx:321 msgid "Delete this post?" -msgstr "Elimina questo post?" +msgstr "Eliminare questo post?" #: src/view/com/util/post-embeds/QuoteEmbed.tsx:70 msgid "Deleted" @@ -1126,7 +1079,7 @@ msgstr "Volevi dire qualcosa?" #: src/view/screens/Settings/index.tsx:504 msgid "Dim" -msgstr "" +msgstr "Fioco" #: src/view/com/composer/Composer.tsx:151 msgid "Discard" @@ -1143,15 +1096,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" - -#: src/view/screens/Feeds.tsx:409 -#~ msgid "Discover new feeds" -#~ msgstr "Scopri nuovi feeds" +msgstr "Scopri nuovi feeds personalizzati" #: src/view/screens/Feeds.tsx:689 msgid "Discover New Feeds" -msgstr "" +msgstr "Scopri nuovi feeds" #: src/view/com/modals/EditProfile.tsx:192 msgid "Display name" @@ -1172,8 +1121,7 @@ msgstr "Dominio verificato!" #: 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 @@ -1208,20 +1156,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:249 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" @@ -1306,7 +1254,7 @@ 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:176 #: src/view/com/auth/login/ForgotPasswordForm.tsx:156 @@ -1347,7 +1295,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 feeds" #: src/view/com/modals/EmbedConsent.tsx:97 msgid "Enable External Media" @@ -1378,12 +1326,9 @@ msgstr "" 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" @@ -1462,12 +1407,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" @@ -1512,7 +1457,7 @@ msgstr "Feed" #: src/view/com/feeds/FeedSourceCard.tsx:231 msgid "Feed by {0}" -msgstr "Feed realizzato da {0}" +msgstr "Feed fatto da {0}" #: src/view/screens/Feeds.tsx:605 msgid "Feed offline" @@ -1532,8 +1477,7 @@ msgstr "Commenti" #: 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" @@ -1548,11 +1492,11 @@ msgstr "I feed sono algoritmi personalizzati che gli utenti creano con un minimo #: src/screens/Onboarding/StepTopicalFeeds.tsx:76 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 @@ -1586,18 +1530,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" @@ -1620,11 +1563,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." @@ -1648,16 +1591,13 @@ msgstr "ti segue" #: src/view/screens/ProfileFollowers.tsx:25 msgid "Followers" -msgstr "Seguiti" - -#~ msgid "following" -#~ msgstr "seguint" +msgstr "Followers" #: src/view/com/post-thread/PostThreadFollowBtn.tsx:136 #: src/view/com/profile/ProfileHeader.tsx:495 #: src/view/screens/ProfileFollows.tsx:25 msgid "Following" -msgstr "Seguiti" +msgstr "Following" #: src/view/com/profile/ProfileHeader.tsx:149 msgid "Following {0}" @@ -1681,7 +1621,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." @@ -1699,8 +1639,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" @@ -1723,8 +1662,7 @@ 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" @@ -1737,10 +1675,9 @@ msgstr "Torna indietro" 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:747 #: src/view/shell/desktop/Search.tsx:262 @@ -1782,15 +1719,15 @@ 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:85 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:80 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." @@ -1859,8 +1796,7 @@ msgstr "Stiamo riscontrando problemi nel trovare questo feed. Potrebbe essere st 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" @@ -1871,9 +1807,6 @@ msgstr "Home" 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?" @@ -1900,7 +1833,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" @@ -1910,8 +1843,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" @@ -1979,10 +1911,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" @@ -2000,17 +1928,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 @@ -2032,7 +1956,7 @@ msgstr "Lavori" #: src/screens/Onboarding/index.tsx:24 msgid "Journalism" -msgstr "" +msgstr "Giornalismo" #: src/view/com/composer/select-language/SelectLangBtn.tsx:104 msgid "Language selection" @@ -2087,23 +2011,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" @@ -2121,32 +2043,28 @@ msgstr "Metti mi piace a questo feed" #: src/Navigation.tsx:199 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 "" +msgstr "Piace A" #: src/view/com/feeds/FeedSourceCard.tsx:279 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 "" - -#: src/view/com/notifications/FeedItem.tsx:171 -#~ msgid "liked your custom feed{0}" -#~ msgstr "è piaciuto il feed personalizzato{0}" +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" @@ -2228,24 +2146,19 @@ msgstr "Caricamento..." 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 "Disconnetta l'account" #: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" -msgstr "Visibilità degli utenti non connettati" +msgstr "Visibilità degli utenti disconnessi" #: src/view/com/auth/login/ChooseAccountForm.tsx:133 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!" @@ -2279,9 +2192,6 @@ msgstr "Utenti menzionati" 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}" @@ -2289,8 +2199,7 @@ msgstr "Messaggio dal server: {0}" #: src/Navigation.tsx:117 #: 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 +#: src/view/shell/desktop/LeftNav.tsx:397 src/view/shell/Drawer.tsx:511 #: src/view/shell/Drawer.tsx:512 msgid "Moderation" msgstr "Moderazione" @@ -2462,7 +2371,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 @@ -2475,7 +2384,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 @@ -2501,7 +2410,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/components/dialogs/MutedWords.tsx:293 msgid "Nevermind" @@ -2510,11 +2419,11 @@ msgstr "" #: 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" @@ -2526,7 +2435,7 @@ msgstr "Nuovo Password" #: src/view/com/modals/ChangePassword.tsx:215 msgid "New Password" -msgstr "" +msgstr "Nuovo Password" #: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" @@ -2548,12 +2457,9 @@ 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" +msgstr "Nuova lista" #: src/view/screens/PreferencesThreads.tsx:79 msgid "Newest replies first" @@ -2561,7 +2467,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:172 #: src/view/com/auth/login/ForgotPasswordForm.tsx:182 @@ -2655,11 +2561,10 @@ msgstr "Nota: Bluesky è una rete aperta e pubblica. Questa impostazione limita #: 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" @@ -2671,7 +2576,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" @@ -2679,7 +2584,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" @@ -2705,7 +2610,7 @@ msgstr "Ops!" #: src/screens/Onboarding/StepFinished.tsx:115 msgid "Open" -msgstr "" +msgstr "Apri" #: src/view/screens/Moderation.tsx:75 msgid "Open content filtering settings" @@ -2780,10 +2685,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" @@ -2845,10 +2746,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..." @@ -2860,7 +2757,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:191 #: src/view/com/auth/create/Step1.tsx:201 @@ -2896,7 +2793,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" @@ -2909,11 +2806,11 @@ msgstr "Immagini per adulti." #: src/view/screens/ProfileFeed.tsx:354 #: src/view/screens/ProfileList.tsx:581 msgid "Pin to home" -msgstr "Fissa sulla pagina principale" +msgstr "Fissa sulla home page" #: 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}" @@ -2981,9 +2878,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" @@ -2994,7 +2888,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" @@ -3093,10 +2987,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" @@ -3110,7 +3002,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." @@ -3118,7 +3010,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:342 msgid "Publish post" @@ -3142,9 +3034,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\")" @@ -3165,8 +3054,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" @@ -3240,7 +3128,7 @@ msgstr "Le risposte a questo thread sono disabilitate" #: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" -msgstr "Rispondi" +msgstr "Risposta" #: src/view/screens/PreferencesFollowingFeed.tsx:144 msgid "Reply Filters" @@ -3250,7 +3138,7 @@ msgstr "Filtri di risposta" #: 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}" @@ -3274,8 +3162,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" @@ -3291,33 +3178,25 @@ 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 "Repost di" #: 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 "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:188 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 @@ -3331,7 +3210,7 @@ msgstr "Richiedi un cambio" #: 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" @@ -3348,7 +3227,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" @@ -3455,7 +3334,7 @@ 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:859 msgid "Scroll to top" @@ -3470,10 +3349,8 @@ msgstr "Scorri verso l'alto" #: 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 -#: 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" @@ -3545,10 +3422,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" @@ -3564,19 +3437,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:96 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." @@ -3588,7 +3461,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" @@ -3600,11 +3473,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 @@ -3620,11 +3493,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" @@ -3638,7 +3507,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" @@ -3664,11 +3533,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" @@ -3704,7 +3573,7 @@ msgstr "" #: 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" @@ -3792,15 +3661,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/PreferencesFollowingFeed.tsx:119 msgid "Show Replies" @@ -3812,11 +3681,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/PreferencesFollowingFeed.tsx:70 msgid "Show replies with at least {value} {0}" @@ -3828,7 +3697,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 @@ -3849,16 +3718,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" @@ -3886,7 +3753,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 @@ -3894,8 +3761,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" @@ -3928,7 +3794,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" @@ -3936,7 +3802,7 @@ msgstr "" #: src/screens/Onboarding/index.tsx:40 msgid "Software Dev" -msgstr "" +msgstr "Sviluppo Software" #: src/view/com/modals/ProfilePreview.tsx:62 #~ msgid "Something went wrong and we're not sure what." @@ -3964,16 +3830,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" @@ -4002,7 +3864,7 @@ msgstr "Iscriviti" #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:173 #: src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx:308 msgid "Subscribe to the {0} feed" -msgstr "" +msgstr "Iscriviti a {0} feed" #: src/view/screens/ProfileList.tsx:604 msgid "Subscribe to this list" @@ -4026,10 +3888,6 @@ msgstr "Suggestivo" 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" @@ -4074,7 +3932,7 @@ msgstr "Tocca per visualizzare completamente" #: src/screens/Onboarding/index.tsx:39 msgid "Tech" -msgstr "" +msgstr "Tecnologia" #: src/view/shell/desktop/RightNav.tsx:81 msgid "Terms" @@ -4114,7 +3972,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:517 msgid "The post may have been deleted." @@ -4128,16 +3986,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:550 msgid "There was an an issue contacting the server, please check your internet connection and try again." @@ -4217,7 +4072,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!" @@ -4225,10 +4080,7 @@ msgstr "" #: 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:" @@ -4252,7 +4104,7 @@ 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." @@ -4276,9 +4128,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:" @@ -4305,11 +4154,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." @@ -4394,8 +4239,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" @@ -4495,10 +4339,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:" @@ -4522,29 +4362,29 @@ msgstr "Handle dell'utente" #: src/view/com/lists/ListCard.tsx:85 #: 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:763 msgid "User list by <0/>" -msgstr "Lista utenti di<0/>" +msgstr "Lista di<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 "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 @@ -4590,7 +4430,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:662 msgid "View {0}'s avatar" @@ -4623,7 +4463,7 @@ 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/Hashtag.tsx:132 msgid "We couldn't find any results for that hashtag." @@ -4631,11 +4471,11 @@ msgstr "" #: 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/>." @@ -4647,15 +4487,15 @@ msgstr "" #: 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." @@ -4663,7 +4503,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:134 msgid "We're so excited to have you join us!" @@ -4692,7 +4532,7 @@ 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}?" @@ -4734,7 +4574,7 @@ 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" @@ -4752,19 +4592,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 @@ -4800,18 +4637,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." @@ -4837,7 +4673,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:147 msgid "You will no longer receive notifications for this thread" @@ -4853,17 +4689,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." @@ -4879,7 +4714,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:215 msgid "Your birth date" @@ -4891,7 +4726,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:110 #: src/view/com/auth/login/ForgotPasswordForm.tsx:70 @@ -4937,7 +4772,7 @@ msgstr "" #: 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:274 msgid "Your post has been published" @@ -4961,3 +4796,153 @@ msgstr "La tua risposta è stata pubblicata" #: src/view/com/auth/create/Step2.tsx:65 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 "Lista {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 "Cambia" + +#~ msgid "Danger Zone" +#~ msgstr "Zona di Pericolo" + +#~ msgid "Delete my account…" +#~ msgstr "Cancella il mio account…" + +#~ msgid "Dev Server" +#~ msgstr "Server di sviluppo" + +#~ msgid "Developer Tools" +#~ msgstr "Strumenti per sviluppatori" + +#~ msgid "Discover new feeds" +#~ msgstr "Scopri nuovi feeds" + +#~ msgid "Enter the address of your provider:" +#~ msgstr "Inserisci l'indirizzo del tuo provider:" + +#~ msgid "following" +#~ msgstr "following" + +#~ msgid "Hosting provider address" +#~ msgstr "Indirizzo del fornitore di hosting" + +#~ msgid "Invite" +#~ msgstr "Invita" + +#~ msgid "Invite codes: {invitesAvailable} available" +#~ msgstr "Codici di invito: {invitesAvailable} disponibili" + +#~ msgid "liked your custom feed{0}" +#~ msgstr "piace 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 "Sembra che questo feed sia disponibile solo per gli utenti con un account Bluesky. Per favore registrati o accedi per visualizzare questo feed!" + +#~ msgid "Message from server" +#~ msgstr "Messaggio dal server" + +#~ msgid "New Post" +#~ msgstr "Nuovo Post" + +#~ 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 "Per favore spiegaci perché ritieni che questa decisione sia stata sbagliata." + +#~ msgid "Post" +#~ msgstr "Post" + +#~ msgid "Quote Post" +#~ msgstr "Cita il post" + +#~ msgid "Reposted by" +#~ msgstr "Repost di" + +#~ msgid "Reposted by {0})" +#~ msgstr "Repost di {0})" + +#~ msgid "Select Bluesky Social" +#~ msgstr "Seleziona Bluesky Social" + +#~ msgid "Send Email" +#~ msgstr "Envia Email" + +#~ 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 "Il modulo di supporto è stato spostato. Se hai bisogno di aiuto, <0/> o visita {HELP_DESK_URL} per metterti in contatto con noi." + +#~ msgid "This {0} has been labeled." +#~ msgstr "Questo {0} è stato etichettato." + +#~ msgid "This is the service that keeps you online." +#~ msgstr "Questo è il servizio che ti mantiene online." + +#~ msgid "This user is included the <0/> list which you have muted." +#~ msgstr "Questo utente è incluso nella lista <0/> che hai silenziato." + +#~ msgid "Try again" +#~ msgstr "Provalo di nuovo" + +#~ 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 "Qual è il prossimo?" + +#~ msgid "You can change hosting providers at any time." +#~ msgstr "Puoi cambiare provider di hosting in qualsiasi momento." + +#~ msgid "Your hosting provider" +#~ msgstr "Il tuo fornitore di hosting" + +#~ 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" 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} <1>following" msgstr "<0>{following} <1>팔로우 중" @@ -63,18 +45,10 @@ msgstr "<1>추천 사용자<0>팔로우하기" msgid "<0>Welcome to<1>Bluesky" msgstr "<1>Bluesky<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/view/com/modals/AppealLabel.tsx:65 -msgid "Appeal Content Warning" -msgstr "콘텐츠 경고 이의신청" +#: src/components/moderation/LabelsOnMeDialog.tsx:134 +#: src/components/moderation/LabelsOnMeDialog.tsx:137 +msgid "Appeal" +msgstr "이의신청" -#: src/view/com/util/moderation/LabelInfo.tsx:52 -msgid "Appeal this decision" -msgstr "이 결정에 이의신청" +#: src/components/moderation/LabelsOnMeDialog.tsx:202 +msgid "Appeal \"{0}\" label" +msgstr "\"{0}\" 라벨 이의신청" -#: src/view/com/util/moderation/LabelInfo.tsx:56 -msgid "Appeal this decision." -msgstr "이 결정에 이의신청합니다." +#: src/components/moderation/LabelsOnMeDialog.tsx:193 +msgid "Appeal submitted." +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}?" 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." +msgstr "<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/lib/moderation/useGlobalLabelStrings.ts:18 +msgid "Content Blocked" +msgstr "콘텐츠 차단됨" -#: src/view/com/modals/ContentFilteringSettings.tsx:44 -msgid "Content Filtering" -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 -msgid "Created {0}" -msgstr "{0} 생성됨" +#: src/components/ReportDialog/SelectReportOptionView.tsx:93 +msgid "Create report for {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/screens/AppPasswords.tsx:246 +msgid "Created {0}" +msgstr "{0}에 생성됨" -#: 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,33 +1136,20 @@ 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/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 "완료" - +#: 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/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 @@ -1178,6 +1160,19 @@ msgstr "완료" msgid "Done" msgstr "완료" +#: 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 "완료" + #: 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 +#: src/lib/moderation/useModerationCauseDescription.ts:85 +msgid "Muted by \"{0}\"" +msgstr "\"{0}\" 님이 뮤트함" + +#: src/screens/Moderation/index.tsx:234 msgid "Muted words & tags" -msgstr "" +msgstr "뮤트한 단어 및 태그" -#: src/view/screens/ProfileList.tsx:277 +#: 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 +#: src/view/screens/ProfileFeed.tsx:299 +msgid "Open feed options menu" +msgstr "피드 옵션 메뉴 열기" + +#: src/view/screens/Settings/index.tsx:730 msgid "Open links with in-app browser" -msgstr "링크를 인앱 브라우저로 엽니다" +msgstr "링크를 인앱 브라우저로 열기" -#: src/view/screens/Moderation.tsx:92 -msgid "Open muted words settings" -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} posts" -msgstr "" +msgstr "<0>{displayTag} 게시물 보기" #: src/components/TagMenu/index.tsx:187 msgid "See <0>{displayTag} posts by this user" -msgstr "" - -#: src/components/TagMenu/index.tsx:128 -#~ msgid "See <0>{tag} posts" -#~ msgstr "" - -#: src/components/TagMenu/index.tsx:189 -#~ msgid "See <0>{tag} posts by this user" -#~ msgstr "" +msgstr "이 사용자의 <0>{displayTag} 게시물 보기" #: 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 +#: 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/components/dialogs/MutedWords.tsx:324 msgid "text" -msgstr "" +msgstr "글" -#: src/view/com/modals/AppealLabel.tsx:70 -#: src/view/com/modals/report/InputIssueDetails.tsx:51 +#: 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}." +msgstr "이 이의신청은 <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." -msgstr "" +msgstr "이 기능은 베타 버전입니다. 저장소 내보내기에 대한 자세한 내용은 <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} list which you have blocked." +msgstr "이 사용자는 내가 차단한 <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} list which you have muted." +msgstr "이 사용자는 내가 뮤트한 <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" msgstr "<0>Bluesky에 오신 것을 환영합니다" #: 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/lib/moderation/useModerationCauseDescription.ts:109 +msgid "You have hidden this post" +msgstr "내가 이 게시물을 숨겼습니다" -#: src/view/com/modals/ModerationDetails.tsx:87 -msgid "You have muted this user." -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}" msgstr "내 전체 핸들: <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 "내 답글을 게시했습니다" 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." -#~ msgstr "Conteúdo adulto só pode ser habilitado no site: <0>bsky.app." - #: 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} posts" -msgstr "" +msgstr "Ver posts com <0>{displayTag}" #: src/components/TagMenu/index.tsx:187 msgid "See <0>{displayTag} posts by this user" -msgstr "" +msgstr "Ver posts com <0>{displayTag} deste usuário" #: src/components/TagMenu/index.tsx:128 #~ msgid "See <0>{tag} posts" -#~ msgstr "" +#~ msgstr "Ver posts com <0>{tag}" #: src/components/TagMenu/index.tsx:189 #~ msgid "See <0>{tag} posts by this user" -#~ msgstr "" +#~ msgstr "Ver posts com <0>{tag} 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." -msgstr "" +msgstr "Esta funcionalidade está em beta. Você pode ler mais sobre exportação de repositórios <0>neste post 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}" #: 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!" 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} <1>following" -msgstr "" +msgstr "<0>{following} <1>підписок" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:30 msgid "<0>Choose your<1>Recommended<2>Feeds" @@ -89,25 +64,13 @@ msgstr "<0>Оберіть свої<1>рекомендовані<2>стр msgid "<0>Follow some<1>Recommended<2>Users" msgstr "<0>Підпишіться на деяких <1>рекомендованих <2>користувачів" -#: src/view/com/modals/AddAppPasswords.tsx:132 -#~ msgid "<0>Here is your app password. 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." -#~ 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." -#~ msgstr "" - #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:21 msgid "<0>Welcome to<1>Bluesky" -msgstr "" +msgstr "<0>Ласкаво просимо до<1>Bluesky" #: 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." @@ -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}?" -msgstr "" +msgstr "Ви пишете <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} posts" -msgstr "" +msgstr "Переглянути пости з <0>{displayTag}" #: src/components/TagMenu/index.tsx:187 msgid "See <0>{displayTag} posts by this user" -msgstr "" +msgstr "Переглянути пости цього користувача з <0>{displayTag}" #: src/components/TagMenu/index.tsx:128 #~ msgid "See <0>{tag} 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." -msgstr "" +msgstr "Ця функція знаходиться в беті. Ви можете дізнатися більше про експорт репозиторіїв в <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" #: 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}" -msgstr "" - -#: src/view/com/auth/create/Step1.tsx:53 -#~ msgid "Your hosting provider" -#~ msgstr "Ваш хостинг-провайдер" +msgstr "Вашим повним псевдонімом буде <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 "Ваш псевдонім" + 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} <1>following" -msgstr "<0>{following} <1>正在关注" +msgstr "<0>{following} <1>个正在关注" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:30 msgid "<0>Choose your<1>Recommended<2>Feeds" @@ -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 "限制列表由 创建" +msgstr "由 创建的限制列表" #: 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} posts" -msgstr "" +msgstr "查看 <0>{displayTag} 的帖子" #: src/components/TagMenu/index.tsx:187 msgid "See <0>{displayTag} posts by this user" -msgstr "" +msgstr "查看该用户 <0>{displayTag} 的帖子" #: src/components/TagMenu/index.tsx:128 #~ msgid "See <0>{tag} posts" -#~ msgstr "" +#~ msgstr "查看 <0>{tag} 的帖子" #: src/components/TagMenu/index.tsx:189 #~ msgid "See <0>{tag} posts by this user" -#~ msgstr "" +#~ msgstr "查看该用户 <0>{tag} 的帖子" #: 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." -msgstr "" +msgstr "该功能正在测试。你可以在<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}" #: 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" 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/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 && ( diff --git a/src/screens/Moderation/index.tsx b/src/screens/Moderation/index.tsx new file mode 100644 index 0000000000..d73823fadf --- /dev/null +++ b/src/screens/Moderation/index.tsx @@ -0,0 +1,556 @@ +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 ( + + + + Hmmmm, it seems we're having trouble loading this data. See below for + more details. If this issue persists, please contact us. + + + + {error} + + + ) +} + +export function ModerationScreen( + _props: NativeStackScreenProps, +) { + 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 ( + + + + {isLoading ? ( + + + + ) : error || !preferences ? ( + + ) : ( + + )} + + ) +} + +function SubItem({ + title, + icon: Icon, + style, +}: ViewStyleProp & { + title: string + icon: React.ComponentType +}) { + const t = useTheme() + return ( + + + + {title} + + + + ) +} + +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 ( + + + Moderation tools + + + + + + + {state => ( + + )} + + + + {state => ( + + )} + + + + {state => ( + + )} + + + + + Content filters + + + + {ageNotSet && ( + <> + + + + + )} + + {!ageNotSet && !isUnderage && ( + <> + + + Enable adult content + + + + + {adultContentEnabled ? ( + Enabled + ) : ( + Disabled + )} + + + + + + + + )} + {!isUnderage && adultContentEnabled && ( + <> + + + + + + + + )} + + + + + + Advanced + + + {isLabelersLoading ? ( + + + + ) : labelersError || !labelers ? ( + + + + We were unable to load your configured labelers at this time. + + + + ) : ( + + {labelers.map((labeler, i) => { + return ( + + {i !== 0 && } + + {state => ( + + + + + + + + )} + + + ) + })} + + )} + + + Logged-out visibility + + + + + + + ) +} + +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 ( + + + + + + + Discourage apps from showing my account to logged-out users + + + + + {updateProfile.isPending && } + + + + + + 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. + + + + + 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. + + + + + Learn more about what is public on Bluesky. + + + + ) +} diff --git a/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx b/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx index 360025c02f..aaacaea0a4 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({ - Enable Adult Content + + Enable Adult Content + @@ -106,7 +113,9 @@ export function AdultContentEnabledPref({ )} - Adult Content + + Adult Content + Due to Apple policies, adult content can only be enabled on the web @@ -114,7 +123,9 @@ export function AdultContentEnabledPref({ - prompt.close()}>OK + prompt.close()}> + OK + 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 + 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 ( - - - {groupInfo.title} + ]}> + + {labelStrings.name} - {groupInfo.subtitle} + {labelStrings.description} - - - - {labels.hide} - - - {labels.warn} - - - {labels.show} - - + + {disabled ? ( + + Hide + + ) : ( + + + {labels.show} + + + {labels.warn} + + + {labels.hide} + + + )} - + ) } 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 ( - - - - ) -} - 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() { - {adultContentEnabled && - configurableAdultLabelGroups.map((g, index) => ( - - {index === 0 && } - - - - ))} - - {configurableOtherLabelGroups.map((g, index) => ( - - {!adultContentEnabled && index === 0 && } - - - - ))} + + + + )} 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({ 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([]) 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() + + const onPressBack = React.useCallback(() => { + if (navigation.canGoBack()) { + navigation.goBack() + } else { + navigation.navigate('Home') + } + }, [navigation]) + + return ( + + + + + Hmmmm, we couldn't load that moderation service. + + + + This moderation service is unavailable. See below for more details. If + this issue persists, contact us. + + + + {error} + + + + + + + ) +} 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 + moderation: ModerationDecision +}) { + const t = useTheme() + return ( + + + {sanitizeDisplayName( + profile.displayName || sanitizeHandle(profile.handle), + moderation.ui('displayName'), + )} + + + ) +} 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 +}) { + const t = useTheme() + const invalidHandle = isInvalidHandle(profile.handle) + const blockHide = profile.viewer?.blocking || profile.viewer?.blockedBy + return ( + + {profile.viewer?.followedBy && !blockHide ? ( + + + Follows you + + + ) : undefined} + + {invalidHandle ? ⚠Invalid Handle : `@${profile.handle}`} + + + ) +} 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 +}) { + 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 ( + + + {followers} + + {pluralizedFollowers} + + + + + {following} + + following + + + + + {formatCount(profile.postsCount || 0)}{' '} + + {pluralize(profile.postsCount || 0, 'post')} + + + + ) +} 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 = + 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( + 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 ( + + + + {isMe ? ( + + ) : !isAppLabeler(profile.did) ? ( + <> + + + ) : null} + + + + + + + {!isPlaceholderProfile && ( + <> + {isSelf && } + {descriptionRT && !moderation.ui('profileView').blur ? ( + + + + ) : undefined} + {!isAppLabeler(profile.did) && ( + + + + {typeof likeCount === 'number' && ( + + {({hovered, focused, pressed}) => ( + + + Liked by {likeCount} {pluralize(likeCount, 'user')} + + + )} + + )} + + )} + + )} + + + + ) +} +ProfileHeaderLabeler = memo(ProfileHeaderLabeler) +export {ProfileHeaderLabeler} + +function CantSubscribePrompt({ + control, +}: { + control: DialogOuterProps['control'] +}) { + return ( + + Unable to subscribe + + + We're sorry! You can only subscribe to ten labelers, and you've + reached your limit of ten. + + + + OK + + + ) +} 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 = + 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 ( + + + + {isMe ? ( + + ) : profile.viewer?.blocking ? ( + profile.viewer?.blockingByList ? null : ( + + ) + ) : !profile.viewer?.blockedBy ? ( + <> + {hasSession && ( + + )} + + + + ) : null} + + + + + + + {!isPlaceholderProfile && ( + <> + + {descriptionRT && !moderation.ui('profileView').blur ? ( + + + + ) : undefined} + + )} + + {showSuggestedFollows && ( + { + if (showSuggestedFollows) { + setShowSuggestedFollows(false) + } else { + track('ProfileHeader:SuggestedFollowsOpened') + setShowSuggestedFollows(true) + } + }} + /> + )} + + + ) +} +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..c470cb2861 --- /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 + moderation: ModerationDecision + hideBackButton?: boolean + isPlaceholderProfile?: boolean +} + +let ProfileHeaderShell = ({ + children, + profile, + moderation, + hideBackButton = false, + isPlaceholderProfile, +}: React.PropsWithChildren): React.ReactNode => { + const t = useTheme() + const {currentAccount} = useSession() + const {_} = useLingui() + const {openLightbox} = useLightboxControls() + const navigation = useNavigation() + 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 ( + + + {isPlaceholderProfile ? ( + + ) : ( + + )} + + + {children} + + + + {isMe && ( + + )} + + + {!isDesktop && !hideBackButton && ( + + + + + + + + )} + + + + + + + ) +} +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: 10, + }, +}) 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 ( + + + + + + + + + + + + ) +} +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 + } + return + } + return +} +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) { + 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 ( + + + + + ) +} 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 + }, [_]) + + return ( + + + {(isScrolledDown || hasNew) && ( + + )} + + ) +}) + +function ProfileEndOfFeed() { + const pal = usePalette('default') + + return ( + + + End of feed + + + ) +} diff --git a/src/screens/Profile/Sections/Labels.tsx b/src/screens/Profile/Sections/Labels.tsx new file mode 100644 index 0000000000..08db4a861d --- /dev/null +++ b/src/screens/Profile/Sections/Labels.tsx @@ -0,0 +1,215 @@ +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 {_} = 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 ( + + {isLabelerLoading ? ( + + + + ) : labelerError || !labelerInfo ? ( + + ) : ( + + )} + + ) +}) + +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 ( + + + + + + Labels are annotations on users and content. They can be used to + hide, warn, and categorize the network. + + + {labelerInfo.creator.viewer?.blocking ? ( + + + + + Blocking does not prevent this labeler from placing labels on + your account. + + + + ) : null} + {labelValues.length === 0 ? ( + + + This labeler hasn't declared what labels it publishes, and may + not be active. + + + ) : !isSubscribed ? ( + + + Subscribe to @{labelerInfo.creator.handle} to use these labels: + + + ) : null} + + {labelDefs.length > 0 && ( + + {labelDefs.map((labelDef, i) => { + return ( + + {i !== 0 && } + + + ) + })} + + )} + + + + + ) +} 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 691add0050..524dcb1bac 100644 --- a/src/state/modals/index.tsx +++ b/src/state/modals/index.tsx @@ -1,6 +1,5 @@ import React from 'react' -import {AppBskyActorDefs, AppBskyGraphDefs, ModerationUI} from '@atproto/api' -import {StyleProp, ViewStyle} from 'react-native' +import {AppBskyActorDefs, AppBskyGraphDefs} from '@atproto/api' import {Image as RNImage} from 'react-native-image-crop-picker' import {ImageModel} from '#/state/models/media/image' @@ -9,49 +8,12 @@ import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' import {EmbedPlayerSource} from '#/lib/strings/embed-player' import {ThreadgateSetting} from '../queries/threadgate' -export interface ConfirmModal { - name: 'confirm' - title: string - message: string | (() => JSX.Element) - onPressConfirm: () => void | Promise - onPressCancel?: () => void | Promise - confirmBtnText?: string - confirmBtnStyle?: StyleProp - cancelBtnText?: string -} - export interface EditProfileModal { name: 'edit-profile' profile: AppBskyActorDefs.ProfileViewDetailed 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 @@ -135,10 +97,6 @@ export interface AddAppPasswordModal { name: 'add-app-password' } -export interface ContentFilteringSettingsModal { - name: 'content-filtering-settings' -} - export interface ContentLanguagesSettingsModal { name: 'content-languages-settings' } @@ -147,10 +105,6 @@ export interface PostLanguagesSettingsModal { name: 'post-languages-settings' } -export interface BirthDateSettingsModal { - name: 'birth-date-settings' -} - export interface VerifyEmailModal { name: 'verify-email' showReminder?: boolean @@ -191,22 +145,15 @@ export type Modal = | ChangeHandleModal | DeleteAccountModal | EditProfileModal - | BirthDateSettingsModal | VerifyEmailModal | ChangeEmailModal | ChangePasswordModal | SwitchAccountModal // Curation - | ContentFilteringSettingsModal | ContentLanguagesSettingsModal | PostLanguagesSettingsModal - // Moderation - | ModerationDetailsModal - | ReportModal - | AppealLabelModal - // Lists | CreateOrEditListModal | UserAddRemoveListsModal @@ -225,7 +172,6 @@ export type Modal = | InviteCodesModal // Generic - | ConfirmModal | LinkWarningModal | EmbedConsentModal | InAppBrowserConsentModal 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 + labelers: AppBskyLabelerDefs.LabelerViewDetailed[] +} + +const stateContext = React.createContext({ + labelDefs: {}, + labelers: [], +}) + +export function Provider({children}: React.PropsWithChildren<{}>) { + const {labelDefs, labelers} = useLabelDefinitionsQuery() + + const state = {labelDefs, labelers} + + return {children} +} + +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..e6bf04ba3d 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] @@ -104,18 +101,12 @@ 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 => { - 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..b2f93c4a4a --- /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} 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 getAgent().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 getAgent().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 getAgent().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.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 - } + if (notif.author.viewer?.following) { + return false } - 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/post.ts b/src/state/queries/post.ts index eb59f7da40..e3682e304d 100644 --- a/src/state/queries/post.ts +++ b/src/state/queries/post.ts @@ -5,6 +5,7 @@ import {Shadow} from '#/state/cache/types' import {getAgent} from '#/state/session' import {updatePostShadow} from '#/state/cache/post-shadow' import {track} from '#/lib/analytics/analytics' +import {logEvent, LogEvents} from '#/lib/statsig/statsig' import {useToggleMutationQueue} from '#/lib/hooks/useToggleMutationQueue' export const RQKEY = (postUri: string) => ['post', postUri] @@ -58,12 +59,14 @@ export function useGetPost() { export function usePostLikeMutationQueue( post: Shadow, + logContext: LogEvents['post:like']['logContext'] & + LogEvents['post:unlike']['logContext'], ) { const postUri = post.uri const postCid = post.cid const initialLikeUri = post.viewer?.like - const likeMutation = usePostLikeMutation() - const unlikeMutation = usePostUnlikeMutation() + const likeMutation = usePostLikeMutation(logContext) + const unlikeMutation = usePostUnlikeMutation(logContext) const queueToggle = useToggleMutationQueue({ initialState: initialLikeUri, @@ -111,22 +114,30 @@ export function usePostLikeMutationQueue( return [queueLike, queueUnlike] } -function usePostLikeMutation() { +function usePostLikeMutation(logContext: LogEvents['post:like']['logContext']) { return useMutation< {uri: string}, // responds with the uri of the like Error, {uri: string; cid: string} // the post's uri and cid >({ - mutationFn: post => getAgent().like(post.uri, post.cid), + mutationFn: post => { + logEvent('post:like', {logContext}) + return getAgent().like(post.uri, post.cid) + }, onSuccess() { track('Post:Like') }, }) } -function usePostUnlikeMutation() { +function usePostUnlikeMutation( + logContext: LogEvents['post:unlike']['logContext'], +) { return useMutation({ - mutationFn: ({likeUri}) => getAgent().deleteLike(likeUri), + mutationFn: ({likeUri}) => { + logEvent('post:unlike', {logContext}) + return getAgent().deleteLike(likeUri) + }, onSuccess() { track('Post:Unlike') }, @@ -135,12 +146,14 @@ function usePostUnlikeMutation() { export function usePostRepostMutationQueue( post: Shadow, + logContext: LogEvents['post:repost']['logContext'] & + LogEvents['post:unrepost']['logContext'], ) { const postUri = post.uri const postCid = post.cid const initialRepostUri = post.viewer?.repost - const repostMutation = usePostRepostMutation() - const unrepostMutation = usePostUnrepostMutation() + const repostMutation = usePostRepostMutation(logContext) + const unrepostMutation = usePostUnrepostMutation(logContext) const queueToggle = useToggleMutationQueue({ initialState: initialRepostUri, @@ -188,22 +201,32 @@ export function usePostRepostMutationQueue( return [queueRepost, queueUnrepost] } -function usePostRepostMutation() { +function usePostRepostMutation( + logContext: LogEvents['post:repost']['logContext'], +) { return useMutation< {uri: string}, // responds with the uri of the repost Error, {uri: string; cid: string} // the post's uri and cid >({ - mutationFn: post => getAgent().repost(post.uri, post.cid), + mutationFn: post => { + logEvent('post:repost', {logContext}) + return getAgent().repost(post.uri, post.cid) + }, onSuccess() { track('Post:Repost') }, }) } -function usePostUnrepostMutation() { +function usePostUnrepostMutation( + logContext: LogEvents['post:unrepost']['logContext'], +) { return useMutation({ - mutationFn: ({repostUri}) => getAgent().deleteRepost(repostUri), + mutationFn: ({repostUri}) => { + logEvent('post:unrepost', {logContext}) + return getAgent().deleteRepost(repostUri) + }, onSuccess() { track('Post:Unrepost') }, 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..f9cd59cda8 100644 --- a/src/state/queries/preferences/index.ts +++ b/src/state/queries/preferences/index.ts @@ -1,29 +1,29 @@ -import {useMemo} from 'react' +import {useMemo, createContext, useContext} from 'react' import {useQuery, useMutation, useQueryClient} from '@tanstack/react-query' import { LabelPreference, BskyFeedViewPreference, + ModerationOpts, AppBskyActorDefs, + BSKY_LABELER_DID, } 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 {DEFAULT_LOGGED_OUT_LABEL_PREFERENCES} 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 +44,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 +61,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 +77,41 @@ 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(() => { + 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, + labelers: prefs.data.moderationPrefs.labelers.length + ? prefs.data.moderationPrefs.labelers + : [ + { + did: BSKY_LABELER_DID, + labels: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES, + }, + ], + hiddenPosts: hiddenPosts || [], + }, + labelDefs, } - }, [currentAccount?.did, prefs.data, hiddenPosts]) + }, [override, currentAccount, labelDefs, prefs.data, hiddenPosts]) return opts } @@ -138,10 +135,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 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 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 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 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/profile.ts b/src/state/queries/profile.ts index e81ea0f3f0..3c9e3e41c3 100644 --- a/src/state/queries/profile.ts +++ b/src/state/queries/profile.ts @@ -26,6 +26,7 @@ import {RQKEY as RQKEY_MY_MUTED} from './my-muted-accounts' import {RQKEY as RQKEY_MY_BLOCKED} from './my-blocked-accounts' import {STALE} from '#/state/queries' import {track} from '#/lib/analytics/analytics' +import {logEvent, LogEvents} from '#/lib/statsig/statsig' import {ThreadNode} from './post-thread' export const RQKEY = (did: string) => ['profile', did] @@ -186,11 +187,13 @@ export function useProfileUpdateMutation() { export function useProfileFollowMutationQueue( profile: Shadow, + logContext: LogEvents['profile:follow']['logContext'] & + LogEvents['profile:unfollow']['logContext'], ) { const did = profile.did const initialFollowingUri = profile.viewer?.following - const followMutation = useProfileFollowMutation() - const unfollowMutation = useProfileUnfollowMutation() + const followMutation = useProfileFollowMutation(logContext) + const unfollowMutation = useProfileUnfollowMutation(logContext) const queueToggle = useToggleMutationQueue({ initialState: initialFollowingUri, @@ -237,9 +240,12 @@ export function useProfileFollowMutationQueue( return [queueFollow, queueUnfollow] } -function useProfileFollowMutation() { +function useProfileFollowMutation( + logContext: LogEvents['profile:follow']['logContext'], +) { return useMutation<{uri: string; cid: string}, Error, {did: string}>({ mutationFn: async ({did}) => { + logEvent('profile:follow', {logContext}) return await getAgent().follow(did) }, onSuccess(data, variables) { @@ -248,9 +254,12 @@ function useProfileFollowMutation() { }) } -function useProfileUnfollowMutation() { +function useProfileUnfollowMutation( + logContext: LogEvents['profile:unfollow']['logContext'], +) { return useMutation({ mutationFn: async ({followUri}) => { + logEvent('profile:unfollow', {logContext}) track('Profile:Unfollow', {username: followUri}) return await getAgent().deleteFollow(followUri) }, 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 { + 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..5b4e505439 100644 --- a/src/state/shell/composer.tsx +++ b/src/state/shell/composer.tsx @@ -2,7 +2,8 @@ import React from 'react' import { AppBskyEmbedRecord, AppBskyRichtextFacet, - PostModeration, + ModerationDecision, + AppBskyActorDefs, } from '@atproto/api' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' @@ -10,13 +11,9 @@ export interface ComposerOptsPostRef { uri: string cid: string text: string - author: { - handle: string - displayName?: string - avatar?: string - } + author: AppBskyActorDefs.ProfileViewBasic embed?: AppBskyEmbedRecord.ViewRecord['embed'] - moderation?: PostModeration + moderation?: ModerationDecision } export interface ComposerOptsQuote { uri: string 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/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/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`)}> - + diff --git a/src/view/com/auth/login/LoginForm.tsx b/src/view/com/auth/login/LoginForm.tsx index fdba9f203f..3202d69c55 100644 --- a/src/view/com/auth/login/LoginForm.tsx +++ b/src/view/com/auth/login/LoginForm.tsx @@ -207,7 +207,7 @@ export const LoginForm = ({ testID="loginPasswordInput" ref={passwordInputRef} style={[pal.text, styles.textInput]} - placeholder="Password" + placeholder={_(msg`Password`)} placeholderTextColor={pal.colors.textLight} autoCapitalize="none" autoCorrect={false} diff --git a/src/view/com/auth/onboarding/RecommendedFollowsItem.tsx b/src/view/com/auth/onboarding/RecommendedFollowsItem.tsx index 07001068cc..dba3f8c569 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' @@ -11,14 +11,15 @@ import {Text} from 'view/com/util/text/Text' import Animated, {FadeInRight} from 'react-native-reanimated' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {useAnalytics} from 'lib/analytics/analytics' -import {Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {Trans, msg} from '@lingui/macro' import {Shadow, useProfileShadow} from '#/state/cache/profile-shadow' import {useProfileFollowMutationQueue} from '#/state/queries/profile' import {logger} from '#/logger' type Props = { profile: AppBskyActorDefs.ProfileViewBasic - moderation: ProfileModeration + moderation: ModerationDecision onFollowStateChange: (props: { did: string following: boolean @@ -56,13 +57,13 @@ export function RecommendedFollowsItem({ ) } -export function ProfileCard({ +function ProfileCard({ profile, onFollowStateChange, moderation, }: { profile: Shadow - moderation: ProfileModeration + moderation: ModerationDecision onFollowStateChange: (props: { did: string following: boolean @@ -70,9 +71,13 @@ export function ProfileCard({ }) { const {track} = useAnalytics() const pal = usePalette('default') + const {_} = useLingui() const [addingMoreSuggestions, setAddingMoreSuggestions] = React.useState(false) - const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue(profile) + const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( + profile, + 'RecommendedFollowsItem', + ) const onToggleFollow = React.useCallback(async () => { try { @@ -110,7 +115,7 @@ export function ProfileCard({ @@ -121,7 +126,7 @@ export function ProfileCard({ lineHeight={1.2}> {sanitizeDisplayName( profile.displayName || sanitizeHandle(profile.handle), - moderation.profile, + moderation.ui('displayName'), )} @@ -133,7 +138,7 @@ export function ProfileCard({ type={profile.viewer?.following ? 'default' : 'inverted'} labelStyle={styles.followButton} onPress={onToggleFollow} - label={profile.viewer?.following ? 'Unfollow' : 'Follow'} + label={profile.viewer?.following ? _(msg`Unfollow`) : _(msg`Follow`)} /> {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..4badc88aaa 100644 --- a/src/view/com/modals/ChangePassword.tsx +++ b/src/view/com/modals/ChangePassword.tsx @@ -137,7 +137,9 @@ export function Component() { - {stage !== Stages.Done ? 'Change Password' : 'Password Changed'} + {stage !== Stages.Done + ? _(msg`Change Password`) + : _(msg`Password Changed`)} @@ -180,7 +182,7 @@ export function Component() { (false) - const [error, setError] = useState('') - const onPress = async () => { - setError('') - setIsProcessing(true) - try { - await onPressConfirm() - closeModal() - return - } catch (e: any) { - setError(cleanError(e)) - setIsProcessing(false) - } - } - return ( - - - {title} - - {typeof message === 'string' ? ( - - {message} - - ) : ( - message() - )} - {error ? ( - - - - ) : undefined} - - {isProcessing ? ( - - - - ) : ( - - - {confirmBtnText ?? Confirm} - - - )} - {onPressCancel === undefined ? null : ( - - - {cancelBtnText ?? Cancel} - - - )} - - ) -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - padding: 10, - paddingBottom: isWeb ? 0 : 60, - }, - title: { - textAlign: 'center', - marginBottom: 12, - }, - description: { - textAlign: 'center', - paddingHorizontal: 22, - marginBottom: 10, - }, - btn: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'center', - borderRadius: 32, - padding: 14, - marginTop: 22, - marginHorizontal: 44, - backgroundColor: colors.blue3, - }, - btnCancel: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'center', - borderRadius: 32, - padding: 14, - marginHorizontal: 20, - }, -}) diff --git a/src/view/com/modals/ContentFilteringSettings.tsx b/src/view/com/modals/ContentFilteringSettings.tsx deleted file mode 100644 index 328d23dc29..0000000000 --- a/src/view/com/modals/ContentFilteringSettings.tsx +++ /dev/null @@ -1,401 +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' - -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 ( - - - Content Filtering - - - - - - - - - - - - - - - - - - - Done - - - - - - ) -} - -function AdultContentEnabledPref() { - const pal = usePalette('default') - const {_} = useLingui() - const {data: preferences} = usePreferencesQuery() - const {mutate, variables} = usePreferencesSetAdultContentMutation() - const {openModal} = useModalControls() - - const onSetAge = React.useCallback( - () => openModal({name: 'birth-date-settings'}), - [openModal], - ) - - 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 ( - - {isIOS ? ( - preferences?.adultContentEnabled ? null : ( - - - Adult content can only be enabled via the Web at{' '} - - . - - - ) - ) : typeof preferences?.birthDate === 'undefined' ? ( - - - Confirm your age to enable adult content. - - - - ) -} - -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/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 = ( - + 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({ }, ]}> - + - 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`)}> void - goBack: () => void - submitReport: () => void - isProcessing: boolean -}) { - const pal = usePalette('default') - const {_} = useLingui() - const {isMobile} = useWebMediaQueries() - - return ( - - - - - {' '} - Back - - - - - - - - - - - - - ) -} - -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('') - const [issue, setIssue] = useState('') - const [details, setDetails] = useState('') - 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 ( - - - {showDetailsInput ? ( - - ) : ( - - )} - - - ) -} - -// 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 ( - <> - - Report {collectionName} - - - What is the issue with this {collectionName}? - - - - - {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 ? ( - <> - - - - Add details to report - - - - ) : 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 -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 = { - [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 ( - - - {title} - - {description} - - ) -} - -// 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: ) @@ -355,7 +359,8 @@ function CondensedAuthorsList({ ))} @@ -413,7 +418,8 @@ function ExpandedAuthorsList({ diff --git a/src/view/com/pager/FixedTouchableHighlight.tsx b/src/view/com/pager/FixedTouchableHighlight.tsx deleted file mode 100644 index d071969757..0000000000 --- a/src/view/com/pager/FixedTouchableHighlight.tsx +++ /dev/null @@ -1,42 +0,0 @@ -// FixedTouchableHighlight.tsx -import React, {ComponentProps, useRef} from 'react' -import {GestureResponderEvent, TouchableHighlight} from 'react-native' - -type Position = {pageX: number; pageY: number} - -export default function FixedTouchableHighlight({ - onPress, - onPressIn, - ...props -}: ComponentProps) { - const _touchActivatePositionRef = useRef(null) - - function _onPressIn(e: GestureResponderEvent) { - const {pageX, pageY} = e.nativeEvent - - _touchActivatePositionRef.current = { - pageX, - pageY, - } - - onPressIn?.(e) - } - - function _onPress(e: GestureResponderEvent) { - const {pageX, pageY} = e.nativeEvent - - const absX = Math.abs(_touchActivatePositionRef.current?.pageX! - pageX) - const absY = Math.abs(_touchActivatePositionRef.current?.pageY! - pageY) - - const dragged = absX > 2 || absY > 2 - if (!dragged) { - onPress?.(e) - } - } - - return ( - - {props.children} - - ) -} 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..ba74ba6d8d 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,14 +104,23 @@ export function PostThread({ rootPost && moderationOpts ? 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.identifier === '!no-unauthenticated', + ) }, [rootPost, moderationOpts]) + // Values used for proper rendering of parents + const ref = useRef(null) + const highlightedPostRef = useRef(null) + const [maxParents, setMaxParents] = React.useState( + isWeb ? Infinity : PARENTS_CHUNK_SIZE, + ) + const [maxReplies, setMaxReplies] = React.useState(50) + useSetTitle( rootPost && !isNoPwi ? `${sanitizeDisplayName( @@ -120,62 +128,6 @@ export function PostThread({ )}: "${rootPostRecord!.text}"` : '', ) - useEffect(() => { - if (rootPost) { - onCanReply(!rootPost.viewer?.replyDisabled) - } - }, [rootPost, onCanReply]) - - if (isError || AppBskyFeedDefs.isNotFoundPost(thread)) { - return ( - - ) - } - if (AppBskyFeedDefs.isBlockedPost(thread)) { - return - } - if (!thread || isLoading || !preferences) { - return - } - return ( - - ) -} - -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(null) - const highlightedPostRef = useRef(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. @@ -183,18 +135,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') { @@ -230,17 +220,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 @@ -255,7 +239,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, @@ -279,10 +263,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 @@ -295,6 +279,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) { @@ -325,46 +314,6 @@ function PostThreadLoaded({ ) - } else if (item === LOAD_MORE) { - return ( - setMaxReplies(n => n + 50)} - style={[pal.border, pal.view, styles.itemContainer]} - accessibilityLabel={_(msg`Load more posts`)} - accessibilityHint=""> - - - Load more posts - - - - ) - } 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 ( - - ) - } else if (item === CHILD_SPINNER) { - return ( - - - - ) } else if (isThreadPost(item)) { const prev = isThreadPost(posts[index - 1]) ? (posts[index - 1] as ThreadPost) @@ -373,7 +322,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 ( ) @@ -402,142 +353,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 ( - 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() - - const onPressBack = React.useCallback(() => { - if (navigation.canGoBack()) { - navigation.goBack() - } else { - navigation.navigate('Home') - } - }, [navigation]) - - return ( - - - - Post hidden - - - - You have blocked the author or you have been blocked by the author. - - - - - + + {!error && thread && ( + - Back - - - - - ) -} - -function PostThreadError({ - onRefresh, - notFound, - error, -}: { - onRefresh: () => void - notFound: boolean - error: Error | null -}) { - const {_} = useLingui() - const pal = usePalette('default') - const navigation = useNavigation() - - const onPressBack = React.useCallback(() => { - if (navigation.canGoBack()) { - navigation.goBack() - } else { - navigation.navigate('Home') - } - }, [navigation]) - - if (notFound) { - return ( - - - - Post not found - - - The post may have been deleted. - - - - - Back - - - - - ) - } - return ( - - - + } + initialNumToRender={initialNumToRender} + windowSize={11} + /> + )} + ) } @@ -557,7 +428,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, @@ -614,7 +487,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 } @@ -628,20 +504,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, - }, }) diff --git a/src/view/com/post-thread/PostThreadFollowBtn.tsx b/src/view/com/post-thread/PostThreadFollowBtn.tsx index e5b747cc9a..45c3771f50 100644 --- a/src/view/com/post-thread/PostThreadFollowBtn.tsx +++ b/src/view/com/post-thread/PostThreadFollowBtn.tsx @@ -42,7 +42,10 @@ function PostThreadFollowBtnLoaded({ const {isTabletOrDesktop} = useWebMediaQueries() const profile: Shadow = useProfileShadow(profileUnshadowed) - const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue(profile) + const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( + profile, + 'PostThreadItem', + ) const requireAuth = useRequireAuth() const isFollowing = !!profile.viewer?.following diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index 9522ea6a07..6555bdf73c 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 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') @@ -206,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,7 +251,8 @@ let PostThreadItemLoaded = ({ did={post.author.did} handle={post.author.handle} avatar={post.author.avatar} - moderation={moderation.avatar} + moderation={moderation.ui('avatar')} + type={post.author.associated?.labeler ? 'labeler' : 'user'} /> @@ -271,35 +267,12 @@ let PostThreadItemLoaded = ({ {sanitizeDisplayName( post.author.displayName || sanitizeHandle(post.author.handle), + moderation.ui('displayName'), )} - {isAuthorMuted && ( - - - - Muted - - - )} {sanitizeHandle(post.author.handle, '@')} @@ -312,15 +285,16 @@ let PostThreadItemLoaded = ({ )} + {richText?.text ? ( ) : undefined} {post.embed && ( - - - + + + )} @@ -432,7 +398,7 @@ let PostThreadItemLoaded = ({ testID={`postThreadItem-by-${post.author.handle}`} href={postHref} style={[pal.view]} - moderation={moderation.content} + modui={moderation.ui('contentList')} iconSize={isThreadedChild ? 26 : 38} iconStyles={ isThreadedChild @@ -482,7 +448,8 @@ let PostThreadItemLoaded = ({ did={post.author.did} handle={post.author.handle} avatar={post.author.avatar} - moderation={moderation.avatar} + moderation={moderation.ui('avatar')} + type={post.author.associated?.labeler ? 'labeler' : 'user'} /> {showChildReplyLine && ( @@ -508,19 +475,21 @@ let PostThreadItemLoaded = ({ }> + {richText?.text ? ( @@ -542,24 +511,16 @@ let PostThreadItemLoaded = ({ /> ) : undefined} {post.embed && ( - - - + + + )} @@ -577,7 +538,7 @@ let PostThreadItemLoaded = ({ title={itemTitle} noFeedback> - More + More record: AppBskyFeedPost.Record richText: RichTextAPI - moderation: PostModeration + moderation: ModerationDecision showReplyLine?: boolean style?: StyleProp }) { @@ -117,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, }, @@ -133,7 +130,7 @@ function PostInner({ }, [setLimitLines]) return ( - + {showReplyLine && } @@ -142,12 +139,14 @@ function PostInner({ did={post.author.did} handle={post.author.handle} avatar={post.author.avatar} - moderation={moderation.avatar} + moderation={moderation.ui('avatar')} + type={post.author.associated?.labeler ? 'labeler' : 'user'} /> )} + - + {richText.text ? ( ) : undefined} {post.embed ? ( - - - + ) : null} diff --git a/src/view/com/posts/Feed.tsx b/src/view/com/posts/Feed.tsx index cd3e98785d..b86646a4dc 100644 --- a/src/view/com/posts/Feed.tsx +++ b/src/view/com/posts/Feed.tsx @@ -33,6 +33,7 @@ import {useLingui} from '@lingui/react' import {DiscoverFallbackHeader} from './DiscoverFallbackHeader' import {FALLBACK_MARKER_POST} from '#/lib/api/feed/home' import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender' +import {logEvent} from '#/lib/statsig/statsig' const LOADING_ITEM = {_reactKey: '__loading__'} const EMPTY_FEED_ITEM = {_reactKey: '__empty__'} @@ -223,16 +224,29 @@ let Feed = ({ setIsPTRing(false) }, [refetch, track, setIsPTRing, onHasNew]) + const feedType = feed.split('|')[0] const onEndReached = React.useCallback(async () => { if (isFetching || !hasNextPage || isError) return + logEvent('feed:endReached', { + feedType: feedType, + itemCount: feedItems.length, + }) track('Feed:onEndReached') try { await fetchNextPage() } catch (err) { logger.error('Failed to load more posts', {message: err}) } - }, [isFetching, hasNextPage, isError, fetchNextPage, track]) + }, [ + isFetching, + hasNextPage, + isError, + fetchNextPage, + track, + feedType, + feedItems.length, + ]) const onPressTryAgain = React.useCallback(() => { refetch() diff --git a/src/view/com/posts/FeedErrorMessage.tsx b/src/view/com/posts/FeedErrorMessage.tsx index 6d99c32f18..c52090f975 100644 --- a/src/view/com/posts/FeedErrorMessage.tsx +++ b/src/view/com/posts/FeedErrorMessage.tsx @@ -9,13 +9,13 @@ import {usePalette} from 'lib/hooks/usePalette' import {useNavigation} from '@react-navigation/native' import {NavigationProp} from 'lib/routes/types' import {logger} from '#/logger' -import {useModalControls} from '#/state/modals' import {msg as msgLingui, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {FeedDescriptor} from '#/state/queries/post-feed' import {EmptyState} from '../util/EmptyState' import {cleanError} from '#/lib/strings/errors' import {useRemoveFeedMutation} from '#/state/queries/preferences' +import * as Prompt from '#/components/Prompt' export enum KnownError { Block = 'Block', @@ -118,35 +118,29 @@ function FeedgenErrorMessage({ ) const [_, uri] = feedDesc.split('|') const [ownerDid] = safeParseFeedgenUri(uri) - const {openModal, closeModal} = useModalControls() + const removePromptControl = Prompt.usePromptControl() const {mutateAsync: removeFeed} = useRemoveFeedMutation() const onViewProfile = React.useCallback(() => { navigation.navigate('Profile', {name: ownerDid}) }, [navigation, ownerDid]) + const onPressRemoveFeed = React.useCallback(() => { + removePromptControl.open() + }, [removePromptControl]) + const onRemoveFeed = React.useCallback(async () => { - openModal({ - name: 'confirm', - title: _l(msgLingui`Remove feed`), - message: _l(msgLingui`Remove this feed from your saved feeds?`), - async onPressConfirm() { - try { - await removeFeed({uri}) - } catch (err) { - Toast.show( - _l( - msgLingui`There was an an issue removing this feed. Please check your internet connection and try again.`, - ), - ) - logger.error('Failed to remove feed', {message: err}) - } - }, - onPressCancel() { - closeModal() - }, - }) - }, [openModal, closeModal, uri, removeFeed, _l]) + try { + await removeFeed({uri}) + } catch (err) { + Toast.show( + _l( + msgLingui`There was an an issue removing this feed. Please check your internet connection and try again.`, + ), + ) + logger.error('Failed to remove feed', {message: err}) + } + }, [uri, removeFeed, _l]) const cta = React.useMemo(() => { switch (knownError) { @@ -179,27 +173,38 @@ function FeedgenErrorMessage({ }, [knownError, onViewProfile, onRemoveFeed, _l]) return ( - - {msg} + <> + + {msg} - {rawError?.message && ( - - Message from server: {rawError.message} - - )} + {rawError?.message && ( + + Message from server: {rawError.message} + + )} - {cta} - + {cta} + + + + ) } diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx index 7d29703e2d..0fbcc4a13c 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) { @@ -131,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, }, @@ -144,12 +135,11 @@ let FeedItemInner = ({ const outerStyles = [ styles.outer, - pal.view, { borderColor: pal.colors.border, paddingBottom: isThreadLastChild || (!isThreadChild && !isThreadParent) - ? 6 + ? 8 : undefined, }, isThreadChild ? styles.outerSmallTop : undefined, @@ -230,6 +220,7 @@ let FeedItemInner = ({ numberOfLines={1} text={sanitizeDisplayName( reason.by.displayName || sanitizeHandle(reason.by.handle), + moderation.ui('displayName'), )} href={makeProfileLink(reason.by)} /> @@ -247,7 +238,8 @@ let FeedItemInner = ({ did={post.author.did} handle={post.author.handle} avatar={post.author.avatar} - moderation={moderation.avatar} + moderation={moderation.ui('avatar')} + type={post.author.associated?.labeler ? 'labeler' : 'user'} /> {isThreadParent && ( )} + @@ -324,7 +316,7 @@ let PostContent = ({ postEmbed, postAuthor, }: { - moderation: PostModeration + moderation: ModerationDecision richText: RichTextAPI postEmbed: AppBskyFeedDefs.PostView['embed'] postAuthor: AppBskyFeedDefs.PostView['author'] @@ -342,10 +334,10 @@ let PostContent = ({ return ( - + {richText.text ? ( ) : undefined} {postEmbed ? ( - - - + + + ) : null} ) diff --git a/src/view/com/posts/FeedSlice.tsx b/src/view/com/posts/FeedSlice.tsx index 84edee4a11..49e48aa202 100644 --- a/src/view/com/posts/FeedSlice.tsx +++ b/src/view/com/posts/FeedSlice.tsx @@ -78,11 +78,7 @@ function ViewFullThread({slice}: {slice: FeedPostSlice}) { }, [slice.rootUri]) return ( - + labelStyle?: StyleProp + logContext: 'ProfileCard' }) { - const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue(profile) + const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( + profile, + logContext, + ) const {_} = useLingui() const onPressFollow = async () => { diff --git a/src/view/com/profile/ProfileCard.tsx b/src/view/com/profile/ProfileCard.tsx index 266adc51de..235139fff0 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,20 +43,19 @@ export function ProfileCard({ renderButton?: ( profile: Shadow, ) => React.ReactNode + onPress?: () => void style?: StyleProp }) { const pal = usePalette('default') const profile = useProfileShadow(profileUnshadowed) const moderationOpts = useModerationOpts() + const isLabeler = profile?.associated?.labeler if (!moderationOpts) { 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 +71,7 @@ export function ProfileCard({ ]} href={makeProfileLink(profile)} title={profile.handle} + onBeforePress={onPress} asAnchor anchorNoUnderline> @@ -80,7 +79,8 @@ export function ProfileCard({ @@ -91,7 +91,7 @@ export function ProfileCard({ lineHeight={1.2}> {sanitizeDisplayName( profile.displayName || sanitizeHandle(profile.handle), - moderation.profile, + moderation.ui('displayName'), )} @@ -103,7 +103,7 @@ export function ProfileCard({ /> {!!profile.viewer?.followedBy && } - {renderButton ? ( + {renderButton && !isLabeler ? ( {renderButton(profile)} ) : undefined} @@ -119,17 +119,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 +142,41 @@ function ProfileCardPills({ )} - {causes.map(cause => { - const desc = describeModerationCause(cause, 'account') - return ( - - - {cause?.type === 'label' ? '⚠' : ''} - {desc.name} - - - ) - })} + {modui.alerts.map(alert => ( + + ))} + {modui.informs.map(inform => ( + + ))} + + ) +} + +function ProfileCardPillModerationCause({ + cause, + severity, +}: { + cause: ModerationCause + severity: 'alert' | 'inform' +}) { + const pal = usePalette('default') + const {name} = useModerationCauseDescription(cause) + return ( + + + {severity === 'alert' ? '⚠ ' : ''} + {name} + ) } @@ -177,7 +199,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 +221,12 @@ function FollowersList({ {followersWithMods.slice(0, 3).map(({f, mod}) => ( - + ))} @@ -212,11 +239,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 @@ -230,8 +259,11 @@ export function ProfileCardWithFollowBtn({ renderButton={ isMe ? undefined - : profileShadow => + : profileShadow => ( + + ) } + onPress={onPress} /> ) } 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 +} + +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}) => ( - - ), - [], - ) - - if (isFetchingDid || !isFetched) { - return - } - - // error - // = - if (resolveError || isError) { - return ( - - - - ) - } - - // loaded - // = return ( - item.did} - refreshing={isPTRing} - onRefresh={onRefresh} - onEndReached={onEndReached} - renderItem={renderItem} - initialNumToRender={15} - // FIXME(dan) - // eslint-disable-next-line react/no-unstable-nested-components - ListFooterComponent={() => ( - - {(isFetching || isFetchingNextPage) && } - + + + {followers.length > 0 && ( + } + ListFooterComponent={} + // @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/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 +} + +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}) => ( - - ), - [], - ) - - if (isFetchingDid || !isFetched) { - return - } - - // error - // = - if (resolveError || isError) { - return ( - - - - ) - } - - // loaded - // = return ( - item.did} - refreshing={isPTRing} - onRefresh={onRefresh} - onEndReached={onEndReached} - renderItem={renderItem} - initialNumToRender={15} - // FIXME(dan) - // eslint-disable-next-line react/no-unstable-nested-components - ListFooterComponent={() => ( - - {(isFetching || isFetchingNextPage) && } - + <> + + {follows.length > 0 && ( + } + ListFooterComponent={} + // @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/com/profile/ProfileHeader.tsx b/src/view/com/profile/ProfileHeader.tsx deleted file mode 100644 index 3e479d7b53..0000000000 --- a/src/view/com/profile/ProfileHeader.tsx +++ /dev/null @@ -1,785 +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 {useQueryClient} from '@tanstack/react-query' -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, isWeb} 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 {NativeDropdown, DropdownItem} from '../util/forms/NativeDropdown' -import {Link} from '../util/Link' -import {ProfileHeaderSuggestedFollows} from './ProfileHeaderSuggestedFollows' -import {useModalControls} from '#/state/modals' -import {useLightboxControls, ProfileImageLightbox} from '#/state/lightbox' -import { - RQKEY as profileQueryKey, - useProfileMuteMutationQueue, - 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 {toShareUrl} from 'lib/strings/url-helpers' -import {sanitizeDisplayName} from 'lib/strings/display-names' -import {shareUrl} from 'lib/sharing' -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' - -let ProfileHeaderLoading = (_props: {}): React.ReactNode => { - const pal = usePalette('default') - return ( - - - - - - - - - - - - ) -} -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 = - 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() - const {track} = useAnalytics() - const invalidHandle = isInvalidHandle(profile.handle) - const {isDesktop} = useWebMediaQueries() - const [showSuggestedFollows, setShowSuggestedFollows] = React.useState(false) - const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue(profile) - const [queueMute, queueUnmute] = useProfileMuteMutationQueue(profile) - const [queueBlock, queueUnblock] = useProfileBlockMutationQueue(profile) - const queryClient = useQueryClient() - const moderation = useMemo( - () => moderateProfile(profile, moderationOpts), - [profile, moderationOpts], - ) - - const invalidateProfileQuery = React.useCallback(() => { - queryClient.invalidateQueries({ - queryKey: profileQueryKey(profile.did), - }) - }, [queryClient, profile.did]) - - 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 onPressShare = React.useCallback(() => { - track('ProfileHeader:ShareButtonClicked') - shareUrl(toShareUrl(makeProfileLink(profile))) - }, [track, profile]) - - const onPressAddRemoveLists = React.useCallback(() => { - track('ProfileHeader:AddToListsButtonClicked') - openModal({ - name: 'user-add-remove-lists', - subject: profile.did, - handle: profile.handle, - displayName: profile.displayName || profile.handle, - onAdd: invalidateProfileQuery, - onRemove: invalidateProfileQuery, - }) - }, [track, profile, openModal, invalidateProfileQuery]) - - const onPressMuteAccount = React.useCallback(async () => { - track('ProfileHeader:MuteAccountButtonClicked') - try { - await queueMute() - Toast.show(_(msg`Account muted`)) - } catch (e: any) { - if (e?.name !== 'AbortError') { - logger.error('Failed to mute account', {message: e}) - Toast.show(_(msg`There was an issue! ${e.toString()}`)) - } - } - }, [track, queueMute, _]) - - const onPressUnmuteAccount = React.useCallback(async () => { - track('ProfileHeader:UnmuteAccountButtonClicked') - try { - await queueUnmute() - Toast.show(_(msg`Account unmuted`)) - } catch (e: any) { - if (e?.name !== 'AbortError') { - logger.error('Failed to unmute account', {message: e}) - Toast.show(_(msg`There was an issue! ${e.toString()}`)) - } - } - }, [track, queueUnmute, _]) - - const onPressBlockAccount = React.useCallback(async () => { - track('ProfileHeader:BlockAccountButtonClicked') - openModal({ - name: 'confirm', - title: _(msg`Block Account`), - message: _( - msg`Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you.`, - ), - onPressConfirm: async () => { - try { - await queueBlock() - Toast.show(_(msg`Account blocked`)) - } catch (e: any) { - if (e?.name !== 'AbortError') { - logger.error('Failed to block account', {message: e}) - Toast.show(_(msg`There was an issue! ${e.toString()}`)) - } - } - }, - }) - }, [track, queueBlock, openModal, _]) - - const onPressUnblockAccount = React.useCallback(async () => { - track('ProfileHeader:UnblockAccountButtonClicked') - openModal({ - name: 'confirm', - title: _(msg`Unblock Account`), - message: _( - msg`The account will be able to interact with you after unblocking.`, - ), - onPressConfirm: async () => { - 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()}`)) - } - } - }, - }) - }, [track, queueUnblock, openModal, _]) - - const onPressReportAccount = React.useCallback(() => { - track('ProfileHeader:ReportAccountButtonClicked') - openModal({ - name: 'report', - did: profile.did, - }) - }, [track, openModal, profile]) - - const isMe = React.useMemo( - () => currentAccount?.did === profile.did, - [currentAccount, profile], - ) - const dropdownItems: DropdownItem[] = React.useMemo(() => { - let items: DropdownItem[] = [ - { - testID: 'profileHeaderDropdownShareBtn', - label: isWeb ? _(msg`Copy link to profile`) : _(msg`Share`), - onPress: onPressShare, - icon: { - ios: { - name: 'square.and.arrow.up', - }, - android: 'ic_menu_share', - web: 'share', - }, - }, - ] - if (hasSession) { - items.push({label: 'separator'}) - items.push({ - testID: 'profileHeaderDropdownListAddRemoveBtn', - label: _(msg`Add to Lists`), - onPress: onPressAddRemoveLists, - icon: { - ios: { - name: 'list.bullet', - }, - android: 'ic_menu_add', - web: 'list', - }, - }) - if (!isMe) { - if (!profile.viewer?.blocking) { - if (!profile.viewer?.mutedByList) { - items.push({ - testID: 'profileHeaderDropdownMuteBtn', - label: profile.viewer?.muted - ? _(msg`Unmute Account`) - : _(msg`Mute Account`), - onPress: profile.viewer?.muted - ? onPressUnmuteAccount - : onPressMuteAccount, - icon: { - ios: { - name: 'speaker.slash', - }, - android: 'ic_lock_silent_mode', - web: 'comment-slash', - }, - }) - } - } - if (!profile.viewer?.blockingByList) { - items.push({ - testID: 'profileHeaderDropdownBlockBtn', - label: profile.viewer?.blocking - ? _(msg`Unblock Account`) - : _(msg`Block Account`), - onPress: profile.viewer?.blocking - ? onPressUnblockAccount - : onPressBlockAccount, - icon: { - ios: { - name: 'person.fill.xmark', - }, - android: 'ic_menu_close_clear_cancel', - web: 'user-slash', - }, - }) - } - items.push({ - testID: 'profileHeaderDropdownReportBtn', - label: _(msg`Report Account`), - onPress: onPressReportAccount, - icon: { - ios: { - name: 'exclamationmark.triangle', - }, - android: 'ic_menu_report_image', - web: 'circle-exclamation', - }, - }) - } - } - return items - }, [ - isMe, - hasSession, - profile.viewer?.muted, - profile.viewer?.mutedByList, - profile.viewer?.blocking, - profile.viewer?.blockingByList, - onPressShare, - onPressUnmuteAccount, - onPressMuteAccount, - onPressUnblockAccount, - onPressBlockAccount, - onPressReportAccount, - onPressAddRemoveLists, - _, - ]) - - 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 ( - - - {isPlaceholderProfile ? ( - - ) : ( - - )} - - - - {isMe ? ( - - - Edit Profile - - - ) : profile.viewer?.blocking ? ( - profile.viewer?.blockingByList ? null : ( - - - Unblock - - - ) - ) : !profile.viewer?.blockedBy ? ( - <> - {hasSession && ( - 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.`, - )}> - - - )} - - {profile.viewer?.following ? ( - - - - Following - - - ) : ( - - - - Follow - - - )} - - ) : null} - {dropdownItems?.length ? ( - - - - - - ) : undefined} - - - - {sanitizeDisplayName( - profile.displayName || sanitizeHandle(profile.handle), - moderation.profile, - )} - - - - {profile.viewer?.followedBy && !blockHide ? ( - - - Follows you - - - ) : undefined} - - {invalidHandle ? _(msg`⚠Invalid Handle`) : `@${profile.handle}`} - - - {!isPlaceholderProfile && !blockHide && ( - <> - - - track(`ProfileHeader:FollowersButtonClicked`, { - handle: profile.handle, - }) - } - asAnchor - accessibilityLabel={`${followers} ${pluralizedFollowers}`} - accessibilityHint={_(msg`Opens followers list`)}> - - {followers}{' '} - - - {pluralizedFollowers} - - - - track(`ProfileHeader:FollowsButtonClicked`, { - handle: profile.handle, - }) - } - asAnchor - accessibilityLabel={_(msg`${following} following`)} - accessibilityHint={_(msg`Opens following list`)}> - - - {following}{' '} - - - following - - - - - {formatCount(profile.postsCount || 0)}{' '} - - {pluralize(profile.postsCount || 0, 'post')} - - - - {descriptionRT && !moderation.profile.blur ? ( - - - - ) : undefined} - - )} - - {isMe && ( - - )} - - - {showSuggestedFollows && ( - { - if (showSuggestedFollows) { - setShowSuggestedFollows(false) - } else { - track('ProfileHeader:SuggestedFollowsOpened') - setShowSuggestedFollows(true) - } - }} - /> - )} - - {!isDesktop && !hideBackButton && ( - - - - - - - - )} - - - - - - - ) -} -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 6edc61fcf8..3602cdb9a8 100644 --- a/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx +++ b/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx @@ -21,7 +21,8 @@ import {useModerationOpts} from '#/state/queries/preferences' import {useSuggestedFollowsByActorQuery} from '#/state/queries/suggested-follows' import {useProfileShadow} from '#/state/cache/profile-shadow' import {useProfileFollowMutationQueue} from '#/state/queries/profile' -import {Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {Trans, msg} from '@lingui/macro' const OUTER_PADDING = 10 const INNER_PADDING = 14 @@ -98,9 +99,11 @@ export function ProfileHeaderSuggestedFollows({ ) : data ? ( - data.suggestions.map(profile => ( - - )) + data.suggestions + .filter(s => (s.associated?.labeler ? false : true)) + .map(profile => ( + + )) ) : ( )} @@ -168,9 +171,13 @@ function SuggestedFollow({ }) { const {track} = useAnalytics() const pal = usePalette('default') + const {_} = useLingui() const moderationOpts = useModerationOpts() const profile = useProfileShadow(profileUnshadowed) - const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue(profile) + const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( + profile, + 'ProfileHeaderSuggestedFollows', + ) const onPressFollow = React.useCallback(async () => { try { @@ -178,20 +185,20 @@ function SuggestedFollow({ await queueFollow() } catch (e: any) { if (e?.name !== 'AbortError') { - Toast.show('An issue occurred, please try again.') + Toast.show(_(msg`An issue occurred, please try again.`)) } } - }, [queueFollow, track]) + }, [queueFollow, track, _]) const onPressUnfollow = React.useCallback(async () => { 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 @@ -214,7 +221,7 @@ function SuggestedFollow({ @@ -224,7 +231,7 @@ function SuggestedFollow({ numberOfLines={1}> {sanitizeDisplayName( profile.displayName || sanitizeHandle(profile.handle), - moderation.profile, + moderation.ui('displayName'), )} + {show && children} + + + ) +} + +function SmallToggler({ + label, + children, +}: React.PropsWithChildren<{label: string}>) { + const [show, setShow] = React.useState(false) + return ( + + + + + {show && children} + + ) +} + +function DataView({label, data}: {label: string; data: any}) { + return ( + + + {JSON.stringify(data, null, 2)} + + + ) +} + +function ModerationUIView({ + mod, + label, +}: { + mod: ModerationDecision + label: string +}) { + return ( + + + {[ + 'profileList', + 'profileView', + 'avatar', + 'banner', + 'displayName', + 'contentList', + 'contentView', + 'contentMedia', + ].map(key => { + const ui = mod.ui(key as keyof ModerationBehavior) + return ( + + {key} + + + + + + + ) + })} + + + ) +} + +function Spacer() { + return +} + +function MockPostFeedItem({ + post, + moderation, +}: { + post: AppBskyFeedDefs.PostView + moderation: ModerationDecision +}) { + const t = useTheme() + if (moderation.ui('contentList').filter) { + return ( +

+ Filtered from the feed +

+ ) + } + return ( + + ) +} + +function MockPostThreadItem({ + post, + reply, +}: { + post: AppBskyFeedDefs.PostView + moderation: ModerationDecision + reply?: boolean +}) { + return ( + {}} + /> + ) +} + +function MockNotifItem({ + notif, + moderationOpts, +}: { + notif: FeedNotification + moderationOpts: ModerationOpts +}) { + const t = useTheme() + if (shouldFilterNotif(notif.notification, moderationOpts)) { + return ( +

+ Filtered from the feed +

+ ) + } + return +} + +function MockAccountCard({ + profile, + moderation, +}: { + profile: AppBskyActorDefs.ProfileViewBasic + moderation: ModerationDecision +}) { + const t = useTheme() + + if (moderation.ui('profileList').filter) { + return ( +

+ Filtered from the listing +

+ ) + } + + return +} + +function MockAccountScreen({ + profile, + moderation, + moderationOpts, +}: { + profile: AppBskyActorDefs.ProfileViewBasic + moderation: ModerationDecision + moderationOpts: ModerationOpts +}) { + const t = useTheme() + const {_} = useLingui() + return ( + + + + + + ) +} + +function Flag({v, label}: {v: boolean | undefined; label: string}) { + const t = useTheme() + return ( + + + {v && } + +

{label}

+
+ ) +} diff --git a/src/view/screens/LanguageSettings.tsx b/src/view/screens/LanguageSettings.tsx index 819840a461..b86cd46e1c 100644 --- a/src/view/screens/LanguageSettings.tsx +++ b/src/view/screens/LanguageSettings.tsx @@ -97,7 +97,7 @@ export function LanguageSettingsScreen(_props: Props) { Select your app language for the default text to display in the - app + app. @@ -296,7 +296,7 @@ export function LanguageSettingsScreen(_props: Props) { type="button" style={[pal.text, {flexShrink: 1, overflow: 'hidden'}]} numberOfLines={1}> - {myLanguages.length ? myLanguages : 'Select languages'} + {myLanguages.length ? myLanguages : _(msg`Select languages`)}
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 -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 ( - - - - - - - - - - Content filtering - - - mutedWordsDialogControl.open()} - accessibilityRole="tab" - accessibilityHint="" - accessibilityLabel={_(msg`Open muted words settings`)}> - - - - - Muted words & tags - - - - - - - - Moderation lists - - - - - - - - Muted accounts - - - - - - - - Blocked accounts - - - - Logged-out visibility - - - - - ) -} - -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 ( - - - - {updateProfile.isPending && } - - - - - 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. - - - - - 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. - - - - - - ) -} - -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/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) { 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. 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) { 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.
diff --git a/src/view/screens/NotFound.tsx b/src/view/screens/NotFound.tsx index dfa840abbc..7d51619b37 100644 --- a/src/view/screens/NotFound.tsx +++ b/src/view/screens/NotFound.tsx @@ -51,7 +51,13 @@ export const NotFoundScreen = () => { - {typeof likeCount === 'number' && ( - - )} - - - {isOwner ? ( - Created by you + + + + + {isLiked ? ( + ) : ( - - Created by{' '} - - + )} - + + {typeof likeCount === 'number' && ( + + {_(msg`Liked by ${likeCount} ${pluralize(likeCount, 'user')}`)} + + )} - + ) } @@ -647,4 +608,9 @@ const styles = StyleSheet.create({ paddingVertical: 14, borderRadius: 6, }, + aboutSectionContainer: { + paddingVertical: 4, + paddingHorizontal: 16, + gap: 12, + }, }) 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 ( - + 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 ( - + diff --git a/src/view/screens/ProfileList.tsx b/src/view/screens/ProfileList.tsx index 9e98757efa..58b89f2399 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, @@ -61,6 +62,8 @@ import {logger} from '#/logger' import {useAnalytics} from '#/lib/analytics/analytics' import {listenSoftReset} from '#/state/events' import {atoms as a, useTheme} from '#/alf' +import * as Prompt from '#/components/Prompt' +import {useDialogControl} from '#/components/Dialog' const SECTION_TITLES_CURATE = ['Posts', 'About'] const SECTION_TITLES_MOD = ['About'] @@ -234,7 +237,8 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) { const {_} = useLingui() const navigation = useNavigation() const {currentAccount} = useSession() - const {openModal, closeModal} = useModalControls() + const reportDialogControl = useReportDialogControl() + const {openModal} = useModalControls() const listMuteMutation = useListMuteMutation() const listBlockMutation = useListBlockMutation() const listDeleteMutation = useListDeleteMutation() @@ -251,6 +255,10 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) { const {mutate: setSavedFeeds} = useSetSaveFeedsMutation() const {track} = useAnalytics() + const deleteListPromptControl = useDialogControl() + const subscribeMutePromptControl = useDialogControl() + const subscribeBlockPromptControl = useDialogControl() + const isPinned = preferences?.feeds?.pinned?.includes(list.uri) const isSaved = preferences?.feeds?.saved?.includes(list.uri) @@ -269,32 +277,19 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) { } }, [list.uri, isPinned, pinFeed, unpinFeed, _]) - const onSubscribeMute = useCallback(() => { - openModal({ - name: 'confirm', - title: _(msg`Mute these accounts?`), - message: _( - msg`Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them.`, - ), - confirmBtnText: _(msg`Mute this List`), - async onPressConfirm() { - try { - await listMuteMutation.mutateAsync({uri: list.uri, mute: true}) - Toast.show(_(msg`List muted`)) - track('Lists:Mute') - } catch { - Toast.show( - _( - msg`There was an issue. Please check your internet connection and try again.`, - ), - ) - } - }, - onPressCancel() { - closeModal() - }, - }) - }, [openModal, closeModal, list, listMuteMutation, track, _]) + const onSubscribeMute = useCallback(async () => { + try { + await listMuteMutation.mutateAsync({uri: list.uri, mute: true}) + Toast.show(_(msg`List muted`)) + track('Lists:Mute') + } catch { + Toast.show( + _( + msg`There was an issue. Please check your internet connection and try again.`, + ), + ) + } + }, [list, listMuteMutation, track, _]) const onUnsubscribeMute = useCallback(async () => { try { @@ -310,32 +305,19 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) { } }, [list, listMuteMutation, track, _]) - const onSubscribeBlock = useCallback(() => { - openModal({ - name: 'confirm', - title: _(msg`Block these accounts?`), - message: _( - msg`Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you.`, - ), - confirmBtnText: _(msg`Block this List`), - async onPressConfirm() { - try { - await listBlockMutation.mutateAsync({uri: list.uri, block: true}) - Toast.show(_(msg`List blocked`)) - track('Lists:Block') - } catch { - Toast.show( - _( - msg`There was an issue. Please check your internet connection and try again.`, - ), - ) - } - }, - onPressCancel() { - closeModal() - }, - }) - }, [openModal, closeModal, list, listBlockMutation, track, _]) + const onSubscribeBlock = useCallback(async () => { + try { + await listBlockMutation.mutateAsync({uri: list.uri, block: true}) + Toast.show(_(msg`List blocked`)) + track('Lists:Block') + } catch { + Toast.show( + _( + msg`There was an issue. Please check your internet connection and try again.`, + ), + ) + } + }, [list, listBlockMutation, track, _]) const onUnsubscribeBlock = useCallback(async () => { try { @@ -358,34 +340,26 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) { }) }, [openModal, list]) - const onPressDelete = useCallback(() => { - openModal({ - name: 'confirm', - title: _(msg`Delete List`), - message: _(msg`Are you sure?`), - async onPressConfirm() { - await listDeleteMutation.mutateAsync({uri: list.uri}) - - if (isSaved || isPinned) { - const {saved, pinned} = preferences!.feeds - - setSavedFeeds({ - saved: isSaved ? saved.filter(uri => uri !== list.uri) : saved, - pinned: isPinned ? pinned.filter(uri => uri !== list.uri) : pinned, - }) - } + const onPressDelete = useCallback(async () => { + await listDeleteMutation.mutateAsync({uri: list.uri}) - Toast.show(_(msg`List deleted`)) - track('Lists:Delete') - if (navigation.canGoBack()) { - navigation.goBack() - } else { - navigation.navigate('Home') - } - }, - }) + if (isSaved || isPinned) { + const {saved, pinned} = preferences!.feeds + + setSavedFeeds({ + saved: isSaved ? saved.filter(uri => uri !== list.uri) : saved, + pinned: isPinned ? pinned.filter(uri => uri !== list.uri) : pinned, + }) + } + + Toast.show(_(msg`List deleted`)) + track('Lists:Delete') + if (navigation.canGoBack()) { + navigation.goBack() + } else { + navigation.navigate('Home') + } }, [ - openModal, list, listDeleteMutation, navigation, @@ -398,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}`) @@ -443,7 +413,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) { items.push({ testID: 'listHeaderDropdownDeleteBtn', label: _(msg`Delete List`), - onPress: onPressDelete, + onPress: deleteListPromptControl.open, icon: { ios: { name: 'trash', @@ -489,7 +459,9 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) { items.push({ testID: 'listHeaderDropdownMuteBtn', label: isMuting ? _(msg`Un-mute list`) : _(msg`Mute list`), - onPress: isMuting ? onUnsubscribeMute : onSubscribeMute, + onPress: isMuting + ? onUnsubscribeMute + : subscribeMutePromptControl.open, icon: { ios: { name: isMuting ? 'eye' : 'eye.slash', @@ -504,7 +476,9 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) { items.push({ testID: 'listHeaderDropdownBlockBtn', label: isBlocking ? _(msg`Un-block list`) : _(msg`Block list`), - onPress: isBlocking ? onUnsubscribeBlock : onSubscribeBlock, + onPress: isBlocking + ? onUnsubscribeBlock + : subscribeBlockPromptControl.open, icon: { ios: { name: 'person.fill.xmark', @@ -517,24 +491,24 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) { } return items }, [ - isOwner, - onPressShare, - onPressEdit, - onPressDelete, - onPressReport, _, + onPressShare, + isOwner, isModList, isPinned, - unpinFeed, + isCurateList, + onPressEdit, + deleteListPromptControl.open, + onPressReport, isPending, + unpinFeed, list.uri, - isCurateList, - isMuting, isBlocking, + isMuting, onUnsubscribeMute, - onSubscribeMute, + subscribeMutePromptControl.open, onUnsubscribeBlock, - onSubscribeBlock, + subscribeBlockPromptControl.open, ]) const subscribeDropdownItems: DropdownItem[] = useMemo(() => { @@ -542,7 +516,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) { { testID: 'subscribeDropdownMuteBtn', label: _(msg`Mute accounts`), - onPress: onSubscribeMute, + onPress: subscribeMutePromptControl.open, icon: { ios: { name: 'speaker.slash', @@ -554,7 +528,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) { { testID: 'subscribeDropdownBlockBtn', label: _(msg`Block accounts`), - onPress: onSubscribeBlock, + onPress: subscribeBlockPromptControl.open, icon: { ios: { name: 'person.fill.xmark', @@ -564,7 +538,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) { }, }, ] - }, [onSubscribeMute, onSubscribeBlock, _]) + }, [_, subscribeMutePromptControl.open, subscribeBlockPromptControl.open]) return ( + {isCurateList || isPinned ? ( + + @@ -148,6 +157,14 @@ export function Buttons() { label="Link out"> + + @@ -183,6 +208,14 @@ export function Buttons() { label="Link out"> + + ) diff --git a/src/view/screens/Storybook/Dialogs.tsx b/src/view/screens/Storybook/Dialogs.tsx index 09be124db5..c2eaf19acf 100644 --- a/src/view/screens/Storybook/Dialogs.tsx +++ b/src/view/screens/Storybook/Dialogs.tsx @@ -68,7 +68,7 @@ export function Dialogs() { Cancel - Confirm + {}}>Confirm 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() { + diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx index 2a37d1fe96..1bf5647f66 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'} /> {' '} {pluralize(profile?.followersCount || 0, 'follower')} ·{' '} - - {formatCountShortOnly(profile?.followsCount ?? 0)} - {' '} - following + + + {formatCountShortOnly(profile?.followsCount ?? 0)} + {' '} + following + ) diff --git a/src/view/shell/NavSignupCard.tsx b/src/view/shell/NavSignupCard.tsx index bae37e8380..83d1414984 100644 --- a/src/view/shell/NavSignupCard.tsx +++ b/src/view/shell/NavSignupCard.tsx @@ -58,7 +58,7 @@ let NavSignupCard = ({}: {}): React.ReactNode => { accessibilityHint={_(msg`Sign in`)} accessibilityLabel={_(msg`Sign in`)}> - Sign in + Sign in 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'} /> ) : ( @@ -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'} /> )} 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> - + ) : ( diff --git a/src/view/shell/desktop/Search.tsx b/src/view/shell/desktop/Search.tsx index 4a94837338..0c5bd452fa 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,8 @@ export function SearchProfileCard({ {sanitizeDisplayName( profile.displayName || sanitizeHandle(profile.handle), - moderation.profile, + moderation.ui('displayName'), )} 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() { - + ) } diff --git a/src/view/shell/index.web.tsx b/src/view/shell/index.web.tsx index 71dccb8c48..02993ac462 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) @@ -42,14 +45,15 @@ function ShellInner() { - + + {!isDesktop && isDrawerOpen && ( 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`)}> diff --git a/web/index.html b/web/index.html index de0abfc91b..7df097f224 100644 --- a/web/index.html +++ b/web/index.html @@ -48,7 +48,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 */ @@ -145,7 +145,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/yarn.lock b/yarn.lock index 386bc1a3be..0716a313da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,19 +34,17 @@ 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== - dependencies: - "@atproto/common-web" "^0.2.3" - "@atproto/lexicon" "^0.3.2" - "@atproto/syntax" "^0.2.0" - "@atproto/xrpc" "^0.4.2" +"@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" + "@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,6 +142,16 @@ uint8arrays "3.0.0" zod "^3.21.4" +"@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" + 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 +253,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.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.3" - "@atproto/syntax" "^0.2.0" + "@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" @@ -351,12 +359,10 @@ 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== - dependencies: - "@atproto/common-web" "^0.2.3" +"@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" @@ -383,12 +389,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.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.2" + "@atproto/lexicon" "^0.4.0" zod "^3.21.4" "@aws-crypto/crc32@3.0.0": @@ -7244,11 +7250,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" @@ -9475,9 +9507,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001517, caniuse-lite@^1.0.30001520: - version "1.0.30001522" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001522.tgz#44b87a406c901269adcdb834713e23582dd71856" - integrity sha512-TKiyTVZxJGhsTszLuzb+6vUZSjVOAhClszBr2Ta2k9IwtNBT/4dzmL6aywt0HCgEZlmwJzXJd8yNiob6HgwTRg== + version "1.0.30001596" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001596.tgz" + integrity sha512-zpkZ+kEr6We7w63ORkoJ2pOfBwBkY/bJrG/UZ90qNb45Isblu8wzDgevEOrRL1r9dWayHjYiiyCMEXPn4DweGQ== case-anything@^2.1.13: version "2.1.13" @@ -15059,11 +15091,6 @@ js-sha256@^0.10.1: resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.10.1.tgz#b40104ba1368e823fdd5f41b66b104b15a0da60d" integrity sha512-5obBtsz9301ULlsgggLg542s/jqtddfOpV5KJc4hajc9JV8GeY2gZHSVpYBn4nWqAUTJ9v+xwtbJ1mIBgIH5Vw== -js-sha256@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.11.0.tgz#256a921d9292f7fe98905face82e367abaca9576" - integrity sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q== - js-sha256@^0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" @@ -20082,14 +20109,6 @@ statsig-js@4.45.1: js-sha256 "^0.10.1" uuid "^8.3.2" -statsig-js@4.49.0: - version "4.49.0" - resolved "https://registry.yarnpkg.com/statsig-js/-/statsig-js-4.49.0.tgz#8470a9ac218a93d36f4b7b306ff9377e48064740" - integrity sha512-N4drx6fzI168Q4NndFY3IJbSDqpWSBWvS290H/RnT/g3Et58SvtXzG5qqgzmqy4CwcmwH+IL8K15pL7hPnfvUQ== - dependencies: - js-sha256 "^0.11.0" - uuid "^8.3.2" - statsig-react-native-expo@^4.6.1: version "4.6.1" resolved "https://registry.yarnpkg.com/statsig-react-native-expo/-/statsig-react-native-expo-4.6.1.tgz#0bdf49fee7112f7f28bff2405f4ba0c1727bb3d6" @@ -20110,13 +20129,6 @@ statsig-react@^1.21.1: dependencies: statsig-js "4.45.1" -statsig-react@^1.36.0: - version "1.36.0" - resolved "https://registry.yarnpkg.com/statsig-react/-/statsig-react-1.36.0.tgz#c2171268a6c76eee534849ec9556b836baba04b6" - integrity sha512-QcTHla3ypfn2RvrnHGNlqWbiC2W/ZjcMM5LT6ExNV4skH7Xhspto3dMS3JVzBhOb74OEDZK4DbxQj9Wdz6XW0w== - dependencies: - statsig-js "4.49.0" - statuses@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"