From 73f4866f15992b1e90faa8f5012c252c1e871691 Mon Sep 17 00:00:00 2001 From: "Stanislas Signoud (Signez)" Date: Fri, 12 Jan 2024 16:47:52 +0100 Subject: [PATCH 01/28] Extract new strings to translate in French --- src/locale/locales/fr/messages.po | 2189 ++++++++++++++++++++++++----- 1 file changed, 1826 insertions(+), 363 deletions(-) diff --git a/src/locale/locales/fr/messages.po b/src/locale/locales/fr/messages.po index 21e8904a65..11bc8f2511 100644 --- a/src/locale/locales/fr/messages.po +++ b/src/locale/locales/fr/messages.po @@ -13,29 +13,38 @@ msgstr "" "Language-Team: \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 {# invite code available} other {# invite codes available}}" -#: src/view/com/modals/Repost.tsx:44 +#: src/view/com/modals/CreateOrEditList.tsx:185 +#: src/view/screens/Settings.tsx:287 msgid "{0}" msgstr "{0}" #: src/view/com/modals/CreateOrEditList.tsx:176 -msgid "{0} {purposeLabel} List" -msgstr "{0} {purposeLabel} Liste" +#~ msgid "{0} {purposeLabel} List" +#~ msgstr "{0} {purposeLabel} Liste" + +#: src/view/com/profile/ProfileHeader.tsx:632 +msgid "{following} following" +msgstr "" #: src/view/shell/desktop/RightNav.tsx:151 msgid "{invitesAvailable, plural, one {Invite codes: # available} other {Invite codes: # available}}" msgstr "{invitesAvailable, plural, one {Invite codes: # available} other {Invite codes: # available}}" -#: src/view/screens/Settings.tsx:407 -#: src/view/shell/Drawer.tsx:659 +#: src/view/screens/Settings.tsx:422 +#: src/view/shell/Drawer.tsx:661 msgid "{invitesAvailable} invite code available" msgstr "{invitesAvailable} code d’invitation disponible" -#: src/view/screens/Settings.tsx:409 -#: src/view/shell/Drawer.tsx:661 +#: src/view/screens/Settings.tsx:424 +#: src/view/shell/Drawer.tsx:663 msgid "{invitesAvailable} invite codes available" msgstr "{invitesAvailable} codes d’invitation disponibles" @@ -43,10 +52,22 @@ msgstr "{invitesAvailable} codes d’invitation disponibles" msgid "{message}" msgstr "{message}" +#: src/view/shell/Drawer.tsx:440 +msgid "{numUnreadNotifications} unread" +msgstr "" + +#: src/Navigation.tsx:147 +msgid "@{0}" +msgstr "" + #: src/view/com/threadgate/WhoCanReply.tsx:158 msgid "<0/> members" msgstr "<0/> membres" +#: src/view/com/profile/ProfileHeader.tsx:634 +msgid "<0>{following} <1>following" +msgstr "" + #: 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" @@ -55,6 +76,14 @@ msgstr "<0>Choisissez vos<1>fils d’actualité<2>recommandés" msgid "<0>Follow some<1>Recommended<2>Users" msgstr "<0>Suivre certains<1>utilisateurs<2>recommandés" +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:21 +msgid "<0>Welcome to<1>Bluesky" +msgstr "" + +#: src/view/com/profile/ProfileHeader.tsx:597 +msgid "⚠Invalid Handle" +msgstr "" + #: src/view/com/util/moderation/LabelInfo.tsx:45 msgid "A content warning has been applied to this {0}." msgstr "Un avertissement sur le contenu a été appliqué sur ce {0}." @@ -63,23 +92,61 @@ msgstr "Un avertissement sur le contenu a été appliqué sur ce {0}." msgid "A new version of the app is available. Please update to continue using the app." msgstr "Une nouvelle version de l’application est disponible. Veuillez faire la mise à jour pour continuer à utiliser l’application." +#: src/view/com/util/ViewHeader.tsx:83 +#: src/view/screens/Search/Search.tsx:538 +msgid "Access navigation links and settings" +msgstr "" + +#: src/view/com/pager/FeedsTabBarMobile.tsx:78 +msgid "Access profile and other navigation links" +msgstr "" + #: src/view/com/modals/EditImage.tsx:299 -#: src/view/screens/Settings.tsx:417 +#: src/view/screens/Settings.tsx:432 msgid "Accessibility" msgstr "Accessibilité" #: src/view/com/auth/login/LoginForm.tsx:163 -#: src/view/screens/Settings.tsx:286 +#: src/view/screens/Settings.tsx:301 msgid "Account" msgstr "Compte" +#: src/view/com/profile/ProfileHeader.tsx:293 +msgid "Account blocked" +msgstr "" + +#: src/view/com/profile/ProfileHeader.tsx:260 +msgid "Account muted" +msgstr "" + +#: src/view/com/modals/ModerationDetails.tsx:86 +msgid "Account Muted" +msgstr "" + +#: src/view/com/modals/ModerationDetails.tsx:72 +msgid "Account Muted by List" +msgstr "" + #: src/view/com/util/AccountDropdownBtn.tsx:41 msgid "Account options" msgstr "Options de compte" +#: src/view/com/util/AccountDropdownBtn.tsx:25 +msgid "Account removed from quick access" +msgstr "" + +#: src/view/com/profile/ProfileHeader.tsx:315 +msgid "Account unblocked" +msgstr "" + +#: src/view/com/profile/ProfileHeader.tsx:273 +msgid "Account unmuted" +msgstr "" + +#: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 -#: src/view/com/modals/UserAddRemoveLists.tsx:193 -#: src/view/screens/ProfileList.tsx:763 +#: src/view/com/modals/UserAddRemoveLists.tsx:203 +#: src/view/screens/ProfileList.tsx:791 msgid "Add" msgstr "Ajouter" @@ -87,12 +154,12 @@ msgstr "Ajouter" msgid "Add a content warning" msgstr "Ajouter un avertissement sur le contenu" -#: src/view/screens/ProfileList.tsx:753 +#: src/view/screens/ProfileList.tsx:781 msgid "Add a user to this list" msgstr "Ajouter un utilisateur à cette liste" -#: src/view/screens/Settings.tsx:355 -#: src/view/screens/Settings.tsx:364 +#: src/view/screens/Settings.tsx:370 +#: src/view/screens/Settings.tsx:379 msgid "Add account" msgstr "Ajouter un compte" @@ -102,6 +169,12 @@ msgstr "Ajouter un compte" msgid "Add alt text" msgstr "Ajouter un texte alt" +#: src/view/screens/AppPasswords.tsx:102 +#: src/view/screens/AppPasswords.tsx:143 +#: src/view/screens/AppPasswords.tsx:156 +msgid "Add App Password" +msgstr "" + #: src/view/com/modals/report/InputIssueDetails.tsx:41 #: src/view/com/modals/report/Modal.tsx:191 msgid "Add details" @@ -111,7 +184,7 @@ msgstr "Ajouter des détails" msgid "Add details to report" msgstr "Ajouter des détails au rapport" -#: src/view/com/composer/Composer.tsx:447 +#: src/view/com/composer/Composer.tsx:445 msgid "Add link card" msgstr "Ajouter une carte de lien" @@ -119,24 +192,33 @@ msgstr "Ajouter une carte de lien" msgid "Add link card:" msgstr "Ajouter une carte de lien :" -#: src/view/com/modals/ChangeHandle.tsx:415 +#: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" msgstr "Ajoutez l’enregistrement DNS suivant à votre domaine :" -#: src/view/com/profile/ProfileHeader.tsx:353 +#: src/view/com/profile/ProfileHeader.tsx:357 msgid "Add to Lists" msgstr "Ajouter aux listes" -#: src/view/screens/ProfileFeed.tsx:271 +#: src/view/com/feeds/FeedSourceCard.tsx:243 +#: src/view/screens/ProfileFeed.tsx:281 msgid "Add to my feeds" msgstr "Ajouter à mes fils d’actu" +#: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:139 +msgid "Added" +msgstr "" + #: src/view/com/modals/ListAddRemoveUsers.tsx:191 #: src/view/com/modals/UserAddRemoveLists.tsx:128 msgid "Added to list" msgstr "Ajouté à la liste" -#: src/view/screens/PreferencesHomeFeed.tsx:170 +#: src/view/com/feeds/FeedSourceCard.tsx:125 +msgid "Added to my feeds" +msgstr "" + +#: src/view/screens/PreferencesHomeFeed.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é." @@ -144,10 +226,18 @@ msgstr "Définissez le nombre de likes qu’une réponse doit avoir pour être a msgid "Adult Content" msgstr "Contenu pour adultes" -#: src/view/screens/Settings.tsx:602 +#: src/view/com/modals/ContentFilteringSettings.tsx:137 +msgid "Adult content can only be enabled via the Web at <0/>." +msgstr "" + +#: src/view/screens/Settings.tsx:617 msgid "Advanced" msgstr "Avancé" +#: src/view/com/auth/login/ChooseAccountForm.tsx:98 +msgid "Already signed in as @{0}" +msgstr "" + #: src/view/com/composer/photos/Gallery.tsx:130 msgid "ALT" msgstr "ALT" @@ -160,7 +250,7 @@ msgstr "Texte Alt" msgid "Alt text describes images for blind and low-vision users, and helps give context to everyone." msgstr "Le texte Alt décrit les images pour les utilisateurs aveugles et malvoyants, et aide à donner un contexte à tout le monde." -#: src/view/com/modals/VerifyEmail.tsx:118 +#: 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 "Un e-mail a été envoyé à {0}. Il comprend un code de confirmation que vous pouvez saisir ici." @@ -168,7 +258,12 @@ msgstr "Un e-mail a été envoyé à {0}. Il comprend un code de confirmation qu msgid "An email has been sent to your previous address, {0}. It includes a confirmation code which you can enter below." msgstr "Un courriel a été envoyé à votre ancienne adresse, {0}. Il comprend un code de confirmation que vous pouvez saisir ici." -#: src/view/com/notifications/FeedItem.tsx:237 +#: src/view/com/profile/FollowButton.tsx:30 +#: src/view/com/profile/FollowButton.tsx:40 +msgid "An issue occurred, please try again." +msgstr "" + +#: src/view/com/notifications/FeedItem.tsx:240 #: src/view/com/threadgate/WhoCanReply.tsx:178 msgid "and" msgstr "et" @@ -177,15 +272,32 @@ msgstr "et" msgid "App Language" msgstr "Langue de l’application" -#: src/view/screens/Settings.tsx:622 +#: src/view/screens/AppPasswords.tsx:228 +msgid "App password deleted" +msgstr "" + +#: src/view/com/modals/AddAppPasswords.tsx:133 +msgid "App Password names can only contain letters, numbers, spaces, dashes, and underscores." +msgstr "" + +#: src/view/com/modals/AddAppPasswords.tsx:98 +msgid "App Password names must be at least 4 characters long." +msgstr "" + +#: src/view/screens/Settings.tsx:628 +msgid "App password settings" +msgstr "" + +#: src/view/screens/Settings.tsx:637 msgid "App passwords" msgstr "Mots de passe d’application" -#: src/view/screens/AppPasswords.tsx:186 +#: src/Navigation.tsx:239 +#: src/view/screens/AppPasswords.tsx:187 msgid "App Passwords" msgstr "Mots de passe d’application" -#: src/view/com/util/forms/PostDropdownBtn.tsx:236 +#: src/view/com/util/forms/PostDropdownBtn.tsx:248 msgid "Appeal content warning" msgstr "Faire appel de l’avertissement sur le contenu" @@ -204,23 +316,23 @@ msgstr "Faire appel de cette décision" msgid "Appeal this decision." msgstr "Faire appel de cette décision." -#: src/view/screens/Settings.tsx:432 +#: src/view/screens/Settings.tsx:447 msgid "Appearance" msgstr "Affichage" -#: src/view/screens/AppPasswords.tsx:223 +#: 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} » ?" -#: src/view/com/composer/Composer.tsx:143 +#: src/view/com/composer/Composer.tsx:142 msgid "Are you sure you'd like to discard this draft?" msgstr "Êtes-vous sûr de vouloir rejeter ce brouillon ?" -#: src/view/screens/ProfileList.tsx:353 +#: src/view/screens/ProfileList.tsx:364 msgid "Are you sure?" msgstr "Vous confirmez ?" -#: src/view/com/util/forms/PostDropdownBtn.tsx:219 +#: src/view/com/util/forms/PostDropdownBtn.tsx:231 msgid "Are you sure? This cannot be undone." msgstr "Vous confirmez ? Cela ne pourra pas être annulé." @@ -228,20 +340,26 @@ msgstr "Vous confirmez ? Cela ne pourra pas être annulé." msgid "Artistic or non-erotic nudity." msgstr "Nudité artistique ou non érotique." +#: src/view/com/post-thread/PostThread.tsx:400 +msgctxt "action" +msgid "Back" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:141 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 -#: src/view/com/auth/login/ForgotPasswordForm.tsx:166 -#: src/view/com/auth/login/LoginForm.tsx:254 -#: src/view/com/auth/login/SetNewPasswordForm.tsx:148 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:170 +#: src/view/com/auth/login/LoginForm.tsx:256 +#: src/view/com/auth/login/SetNewPasswordForm.tsx:150 #: src/view/com/modals/report/InputIssueDetails.tsx:46 -#: src/view/com/post-thread/PostThread.tsx:388 -#: src/view/com/post-thread/PostThread.tsx:438 -#: src/view/com/post-thread/PostThread.tsx:446 -#: src/view/com/profile/ProfileHeader.tsx:672 +#: src/view/com/post-thread/PostThread.tsx:392 +#: src/view/com/post-thread/PostThread.tsx:442 +#: src/view/com/post-thread/PostThread.tsx:450 +#: src/view/com/profile/ProfileHeader.tsx:688 +#: src/view/com/util/ViewHeader.tsx:81 msgid "Back" msgstr "Arrière" -#: src/view/screens/Settings.tsx:461 +#: src/view/screens/Settings.tsx:476 msgid "Basics" msgstr "Principes de base" @@ -250,36 +368,45 @@ msgstr "Principes de base" msgid "Birthday" msgstr "Date de naissance" -#: src/view/screens/Settings.tsx:312 +#: src/view/screens/Settings.tsx:327 msgid "Birthday:" msgstr "Date de naissance :" -#: src/view/com/profile/ProfileHeader.tsx:282 -#: src/view/com/profile/ProfileHeader.tsx:389 +#: src/view/com/profile/ProfileHeader.tsx:286 +#: src/view/com/profile/ProfileHeader.tsx:393 msgid "Block Account" msgstr "Bloquer ce compte" -#: src/view/screens/ProfileList.tsx:523 +#: src/view/screens/ProfileList.tsx:534 msgid "Block accounts" msgstr "Bloquer ces comptes" -#: src/view/screens/ProfileList.tsx:473 +#: src/view/screens/ProfileList.tsx:484 msgid "Block list" msgstr "Liste de blocage" -#: src/view/screens/ProfileList.tsx:308 +#: src/view/screens/ProfileList.tsx:315 msgid "Block these accounts?" msgstr "Bloquer ces comptes ?" +#: src/view/screens/ProfileList.tsx:319 +msgid "Block this List" +msgstr "" + +#: src/view/com/util/post-embeds/QuoteEmbed.tsx:57 +msgid "Blocked" +msgstr "" + #: src/view/screens/Moderation.tsx:123 msgid "Blocked accounts" msgstr "Comptes bloqués" +#: src/Navigation.tsx:131 #: src/view/screens/ModerationBlockedAccounts.tsx:107 msgid "Blocked Accounts" msgstr "Comptes bloqués" -#: src/view/com/profile/ProfileHeader.tsx:284 +#: src/view/com/profile/ProfileHeader.tsx:288 msgid "Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you." msgstr "Les comptes bloqués ne peuvent pas répondre à vos discussions, vous mentionner ou interagir avec vous." @@ -287,11 +414,11 @@ msgstr "Les comptes bloqués ne peuvent pas répondre à vos discussions, vous m 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 "Les comptes bloqués ne peuvent pas répondre à vos discussions, vous mentionner ou interagir avec vous. Vous ne verrez pas leur contenu et ils ne pourront pas voir le vôtre." -#: src/view/com/post-thread/PostThread.tsx:250 +#: src/view/com/post-thread/PostThread.tsx:254 msgid "Blocked post." msgstr "Post bloqué." -#: src/view/screens/ProfileList.tsx:310 +#: src/view/screens/ProfileList.tsx:317 msgid "Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you." msgstr "Le blocage est public. Les comptes bloqués ne peuvent pas répondre à vos discussions, vous mentionner ou interagir avec vous." @@ -303,14 +430,17 @@ msgstr "Blog" msgid "Bluesky" msgstr "Bluesky" +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:80 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:80 msgid "Bluesky is flexible." msgstr "Bluesky est adaptable." +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:69 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:69 msgid "Bluesky is open." msgstr "Bluesky est ouvert." +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:56 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:56 msgid "Bluesky is public." msgstr "Bluesky est public." @@ -327,7 +457,7 @@ msgstr "Bluesky n’affichera pas votre profil et vos messages à des utilisateu msgid "Bluesky.Social" msgstr "Bluesky.Social" -#: src/view/screens/Settings.tsx:751 +#: src/view/screens/Settings.tsx:768 msgid "Build version {0} {1}" msgstr "Version Build {0} {1}" @@ -335,37 +465,64 @@ 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 "" + +#: src/view/com/profile/ProfileSubpageHeader.tsx:157 +msgid "by —" +msgstr "" + +#: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:100 +msgid "by {0}" +msgstr "" + +#: src/view/com/profile/ProfileSubpageHeader.tsx:161 +msgid "by <0/>" +msgstr "" + +#: src/view/com/profile/ProfileSubpageHeader.tsx:159 +msgid "by you" +msgstr "" + #: src/view/com/composer/photos/OpenCameraBtn.tsx:60 #: src/view/com/util/UserAvatar.tsx:221 #: src/view/com/util/UserBanner.tsx:38 msgid "Camera" msgstr "Caméra" -#: src/view/com/modals/AddAppPasswords.tsx:214 +#: src/view/com/modals/AddAppPasswords.tsx:218 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 "Ne peut contenir que des lettres, des chiffres, des espaces, des tirets et des tirets bas. La longueur doit être d’au moins 4 caractères, mais pas plus de 32." -#: src/view/com/composer/Composer.tsx:294 -#: src/view/com/composer/Composer.tsx:297 +#: src/view/com/modals/Confirm.tsx:88 +#: src/view/com/modals/Confirm.tsx:91 +#: src/view/com/modals/CreateOrEditList.tsx:293 +#: src/view/com/modals/DeleteAccount.tsx:152 +#: src/view/com/modals/DeleteAccount.tsx:227 +msgctxt "action" +msgid "Cancel" +msgstr "" + +#: src/view/com/composer/Composer.tsx:299 +#: src/view/com/composer/Composer.tsx:304 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 -#: src/view/com/modals/Confirm.tsx:88 -#: src/view/com/modals/CreateOrEditList.tsx:267 -#: src/view/com/modals/CreateOrEditList.tsx:272 -#: src/view/com/modals/DeleteAccount.tsx:150 -#: src/view/com/modals/DeleteAccount.tsx:223 +#: src/view/com/modals/CreateOrEditList.tsx:288 #: src/view/com/modals/EditImage.tsx:323 -#: src/view/com/modals/EditProfile.tsx:248 +#: src/view/com/modals/EditProfile.tsx:249 #: src/view/com/modals/LinkWarning.tsx:85 -#: src/view/com/modals/Repost.tsx:73 -#: src/view/com/modals/Waitlist.tsx:136 -#: src/view/screens/Search/Search.tsx:601 -#: src/view/shell/desktop/Search.tsx:182 +#: 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:602 +#: src/view/shell/desktop/Search.tsx:185 msgid "Cancel" msgstr "Annuler" -#: src/view/com/modals/DeleteAccount.tsx:146 -#: src/view/com/modals/DeleteAccount.tsx:219 +#: src/view/com/modals/DeleteAccount.tsx:148 +#: src/view/com/modals/DeleteAccount.tsx:223 msgid "Cancel account deletion" msgstr "Annuler la suppression de compte" @@ -381,29 +538,34 @@ msgstr "Annuler le changement de pseudo" msgid "Cancel image crop" msgstr "Annuler le recadrage de l’image" -#: src/view/com/modals/EditProfile.tsx:243 +#: src/view/com/modals/EditProfile.tsx:244 msgid "Cancel profile editing" msgstr "Annuler la modification du profil" -#: src/view/com/modals/Repost.tsx:64 +#: src/view/com/modals/Repost.tsx:78 msgid "Cancel quote post" msgstr "Annuler la citation" #: src/view/com/modals/ListAddRemoveUsers.tsx:87 -#: src/view/shell/desktop/Search.tsx:178 +#: src/view/shell/desktop/Search.tsx:181 msgid "Cancel search" msgstr "Annuler la recherche" -#: src/view/com/modals/Waitlist.tsx:132 +#: src/view/com/modals/Waitlist.tsx:136 msgid "Cancel waitlist signup" msgstr "Annuler l’inscription sur la liste d’attente" -#: src/view/screens/Settings.tsx:306 +#: src/view/screens/Settings.tsx:321 +msgctxt "action" msgid "Change" -msgstr "Changer" +msgstr "" -#: src/view/screens/Settings.tsx:634 -#: src/view/screens/Settings.tsx:643 +#: src/view/screens/Settings.tsx:306 +#~ msgid "Change" +#~ msgstr "Changer" + +#: src/view/screens/Settings.tsx:649 +#: src/view/screens/Settings.tsx:658 msgid "Change handle" msgstr "Changer le pseudo" @@ -411,7 +573,7 @@ msgstr "Changer le pseudo" msgid "Change Handle" msgstr "Changer le pseudo" -#: src/view/com/modals/VerifyEmail.tsx:141 +#: src/view/com/modals/VerifyEmail.tsx:147 msgid "Change my email" msgstr "Modifier mon e-mail" @@ -427,7 +589,7 @@ msgstr "Consultez quelques fils d’actu recommandés. Appuyez sur + pour les aj msgid "Check out some recommended users. Follow them to see similar users." msgstr "Consultez quelques utilisateurs recommandés. Suivez-les pour voir des utilisateurs similaires." -#: src/view/com/modals/DeleteAccount.tsx:163 +#: src/view/com/modals/DeleteAccount.tsx:165 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 :" @@ -435,10 +597,15 @@ msgstr "Consultez votre boîte de réception, vous avez du recevoir un e-mail co msgid "Choose \"Everybody\" or \"Nobody\"" msgstr "Choisir « Tout le monde » ou « Personne »" +#: src/view/screens/Settings.tsx:650 +msgid "Choose a new Bluesky username or create" +msgstr "" + #: src/view/com/modals/ServerInput.tsx:38 msgid "Choose Service" msgstr "Choisir un service" +#: 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." @@ -447,27 +614,33 @@ msgstr "Choisissez les algorithmes qui alimentent votre expérience avec des fil msgid "Choose your password" msgstr "Choisissez votre mot de passe" -#: src/view/screens/Settings.tsx:727 +#: src/view/screens/Settings.tsx:743 +#: src/view/screens/Settings.tsx:744 msgid "Clear all legacy storage data" msgstr "Effacer toutes les données de stockage existantes" -#: src/view/screens/Settings.tsx:729 +#: src/view/screens/Settings.tsx:746 msgid "Clear all legacy storage data (restart after this)" msgstr "Effacer toutes les données de stockage existantes (redémarrer ensuite)" -#: src/view/screens/Settings.tsx:739 +#: src/view/screens/Settings.tsx:755 +#: src/view/screens/Settings.tsx:756 msgid "Clear all storage data" msgstr "Effacer toutes les données de stockage" -#: src/view/screens/Settings.tsx:741 +#: src/view/screens/Settings.tsx:758 msgid "Clear all storage data (restart after this)" msgstr "Effacer toutes les données de stockage (redémarrer ensuite)" #: src/view/com/util/forms/SearchInput.tsx:74 -#: src/view/screens/Search/Search.tsx:582 +#: src/view/screens/Search/Search.tsx:583 msgid "Clear search query" msgstr "Effacer la recherche" +#: src/view/screens/Support.tsx:40 +msgid "click here" +msgstr "" + #: src/view/com/auth/login/PasswordUpdatedForm.tsx:38 msgid "Close alert" msgstr "Fermer l’alerte" @@ -488,19 +661,50 @@ msgstr "Fermer la visionneuse d’images" msgid "Close navigation footer" msgstr "Fermer le pied de page de navigation" +#: src/view/shell/index.web.tsx:50 +msgid "Closes bottom navigation bar" +msgstr "" + +#: src/view/com/auth/login/PasswordUpdatedForm.tsx:39 +msgid "Closes password update alert" +msgstr "" + +#: src/view/com/composer/Composer.tsx:301 +msgid "Closes post composer and discards post draft" +msgstr "" + +#: src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx:27 +msgid "Closes viewer for header image" +msgstr "" + +#: src/view/com/notifications/FeedItem.tsx:321 +msgid "Collapses list of users for a given notification" +msgstr "" + +#: src/Navigation.tsx:229 #: src/view/screens/CommunityGuidelines.tsx:32 msgid "Community Guidelines" msgstr "Directives communautaires" +#: src/view/com/composer/Composer.tsx:416 +msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" +msgstr "" + #: src/view/com/composer/Prompt.tsx:24 msgid "Compose reply" msgstr "Rédiger une réponse" -#: src/view/com/modals/AppealLabel.tsx:98 #: src/view/com/modals/Confirm.tsx:75 +#: src/view/com/modals/Confirm.tsx:78 +msgctxt "action" +msgid "Confirm" +msgstr "" + +#: src/view/com/modals/AppealLabel.tsx:98 #: src/view/com/modals/SelfLabel.tsx:154 -#: src/view/com/modals/VerifyEmail.tsx:225 -#: src/view/screens/PreferencesHomeFeed.tsx:305 +#: src/view/com/modals/VerifyEmail.tsx:231 +#: src/view/com/modals/VerifyEmail.tsx:233 +#: src/view/screens/PreferencesHomeFeed.tsx:308 #: src/view/screens/PreferencesThreads.tsx:159 msgid "Confirm" msgstr "Confirmer" @@ -514,18 +718,26 @@ msgstr "Confirmer le changement" msgid "Confirm content language settings" msgstr "Confirmer les paramètres de langue" -#: src/view/com/modals/DeleteAccount.tsx:209 +#: src/view/com/modals/DeleteAccount.tsx:213 msgid "Confirm delete account" msgstr "Confirmer la suppression du compte" +#: src/view/com/modals/ContentFilteringSettings.tsx:151 +msgid "Confirm your age to enable adult content." +msgstr "" + #: src/view/com/modals/ChangeEmail.tsx:157 -#: src/view/com/modals/DeleteAccount.tsx:176 -#: src/view/com/modals/VerifyEmail.tsx:159 +#: src/view/com/modals/DeleteAccount.tsx:178 +#: src/view/com/modals/VerifyEmail.tsx:165 msgid "Confirmation code" msgstr "Code de confirmation" +#: src/view/com/modals/Waitlist.tsx:120 +msgid "Confirms signing up {email} to the waitlist" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:174 -#: src/view/com/auth/login/LoginForm.tsx:273 +#: src/view/com/auth/login/LoginForm.tsx:275 msgid "Connecting..." msgstr "Connexion…" @@ -542,6 +754,11 @@ msgstr "Filtrage du contenu" msgid "Content Languages" msgstr "Langues du contenu" +#: src/view/com/modals/ModerationDetails.tsx:65 +msgid "Content Not Available" +msgstr "" + +#: src/view/com/modals/ModerationDetails.tsx:33 #: src/view/com/util/moderation/ScreenHider.tsx:78 msgid "Content Warning" msgstr "Avertissement sur le contenu" @@ -555,31 +772,46 @@ msgstr "Avertissements sur le contenu" msgid "Continue" msgstr "Continuer" -#: src/view/com/modals/AddAppPasswords.tsx:193 -#: src/view/com/modals/InviteCodes.tsx:179 +#: src/view/com/modals/AddAppPasswords.tsx:197 +#: src/view/com/modals/InviteCodes.tsx:182 msgid "Copied" msgstr "Copié" -#: src/view/com/modals/AddAppPasswords.tsx:186 +#: src/view/screens/Settings.tsx:236 +msgid "Copied build version to clipboard" +msgstr "" + +#: src/view/com/modals/AddAppPasswords.tsx:75 +#: src/view/com/modals/InviteCodes.tsx:152 +#: src/view/com/util/forms/PostDropdownBtn.tsx:110 +msgid "Copied to clipboard" +msgstr "" + +#: src/view/com/modals/AddAppPasswords.tsx:191 +msgid "Copies app password" +msgstr "" + +#: src/view/com/modals/AddAppPasswords.tsx:190 msgid "Copy" msgstr "Copie" -#: src/view/screens/ProfileList.tsx:385 +#: src/view/screens/ProfileList.tsx:396 msgid "Copy link to list" msgstr "Copier le lien dans la liste" -#: src/view/com/util/forms/PostDropdownBtn.tsx:139 +#: src/view/com/util/forms/PostDropdownBtn.tsx:151 msgid "Copy link to post" msgstr "Copier le lien vers le post" -#: src/view/com/profile/ProfileHeader.tsx:338 +#: src/view/com/profile/ProfileHeader.tsx:342 msgid "Copy link to profile" msgstr "Copier le lien sur le profil" -#: src/view/com/util/forms/PostDropdownBtn.tsx:125 +#: src/view/com/util/forms/PostDropdownBtn.tsx:137 msgid "Copy post text" msgstr "Copier le texte du post" +#: src/Navigation.tsx:234 #: src/view/screens/CopyrightPolicy.tsx:29 msgid "Copyright Policy" msgstr "Politique sur les droits d’auteur" @@ -588,29 +820,50 @@ msgstr "Politique sur les droits d’auteur" msgid "Could not load feed" msgstr "Impossible de charger le fil d’actu" -#: src/view/screens/ProfileList.tsx:839 +#: src/view/screens/ProfileList.tsx:867 msgid "Could not load list" msgstr "Impossible de charger la liste" #: src/view/com/auth/HomeLoggedOutCTA.tsx:62 #: src/view/com/auth/SplashScreen.tsx:46 +#: src/view/com/auth/SplashScreen.web.tsx:77 msgid "Create a new account" msgstr "Créer un nouveau compte" +#: src/view/screens/Settings.tsx:371 +msgid "Create a new Bluesky account" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:121 msgid "Create Account" msgstr "Créer un compte" +#: src/view/com/modals/AddAppPasswords.tsx:228 +msgid "Create App Password" +msgstr "" + #: src/view/com/auth/HomeLoggedOutCTA.tsx:54 #: src/view/com/auth/SplashScreen.tsx:43 msgid "Create new account" msgstr "Créer un nouveau compte" -#: src/view/screens/AppPasswords.tsx:248 +#: src/view/screens/AppPasswords.tsx:249 msgid "Created {0}" msgstr "{0} créé" -#: src/view/com/modals/ChangeHandle.tsx:387 +#: src/view/screens/ProfileFeed.tsx:625 +msgid "Created by <0/>" +msgstr "" + +#: src/view/screens/ProfileFeed.tsx:623 +msgid "Created by you" +msgstr "" + +#: src/view/com/composer/Composer.tsx:447 +msgid "Creates a card with a thumbnail. The card links to {url}" +msgstr "" + +#: src/view/com/modals/ChangeHandle.tsx:389 #: src/view/com/modals/ServerInput.tsx:102 msgid "Custom domain" msgstr "Domaine personnalisé" @@ -619,11 +872,27 @@ msgstr "Domaine personnalisé" msgid "Customize media from external sites." msgstr "" -#: src/view/screens/Settings.tsx:648 +#: src/view/screens/Settings.tsx:663 msgid "Danger Zone" msgstr "Zone de danger" -#: src/view/screens/Settings.tsx:655 +#: src/view/screens/Settings.tsx:466 +msgid "Dark" +msgstr "" + +#: src/view/screens/Debug.tsx:63 +msgid "Dark mode" +msgstr "" + +#: src/Navigation.tsx:204 +msgid "Debug" +msgstr "" + +#: src/view/screens/Debug.tsx:83 +msgid "Debug panel" +msgstr "" + +#: src/view/screens/Settings.tsx:670 msgid "Delete account" msgstr "Supprimer le compte" @@ -631,40 +900,44 @@ msgstr "Supprimer le compte" msgid "Delete Account" msgstr "Supprimer le compte" -#: src/view/screens/AppPasswords.tsx:221 -#: src/view/screens/AppPasswords.tsx:241 +#: src/view/screens/AppPasswords.tsx:222 +#: src/view/screens/AppPasswords.tsx:242 msgid "Delete app password" msgstr "Supprimer le mot de passe de l’appli" -#: src/view/screens/ProfileList.tsx:352 -#: src/view/screens/ProfileList.tsx:412 +#: src/view/screens/ProfileList.tsx:363 +#: src/view/screens/ProfileList.tsx:423 msgid "Delete List" msgstr "Supprimer la liste" -#: src/view/com/modals/DeleteAccount.tsx:212 +#: src/view/com/modals/DeleteAccount.tsx:216 msgid "Delete my account" msgstr "Supprimer mon compte" -#: src/view/screens/Settings.tsx:665 +#: src/view/screens/Settings.tsx:682 msgid "Delete my account…" msgstr "Supprimer mon compte…" -#: src/view/com/util/forms/PostDropdownBtn.tsx:214 +#: src/view/com/util/forms/PostDropdownBtn.tsx:226 msgid "Delete post" msgstr "Supprimer le post" -#: src/view/com/util/forms/PostDropdownBtn.tsx:218 +#: src/view/com/util/forms/PostDropdownBtn.tsx:230 msgid "Delete this post?" msgstr "Supprimer ce post ?" -#: src/view/com/post-thread/PostThread.tsx:242 +#: src/view/com/util/post-embeds/QuoteEmbed.tsx:66 +msgid "Deleted" +msgstr "" + +#: src/view/com/post-thread/PostThread.tsx:246 msgid "Deleted post." msgstr "Post supprimé." -#: src/view/com/modals/CreateOrEditList.tsx:218 -#: src/view/com/modals/CreateOrEditList.tsx:234 -#: src/view/com/modals/EditProfile.tsx:197 -#: src/view/com/modals/EditProfile.tsx:209 +#: src/view/com/modals/CreateOrEditList.tsx:239 +#: src/view/com/modals/CreateOrEditList.tsx:255 +#: src/view/com/modals/EditProfile.tsx:198 +#: src/view/com/modals/EditProfile.tsx:210 msgid "Description" msgstr "Description" @@ -672,19 +945,19 @@ msgstr "Description" msgid "Dev Server" msgstr "Serveur de dév" -#: src/view/screens/Settings.tsx:670 +#: src/view/screens/Settings.tsx:687 msgid "Developer Tools" msgstr "Outils de dév" -#: src/view/com/composer/Composer.tsx:211 +#: src/view/com/composer/Composer.tsx:210 msgid "Did you want to say anything?" msgstr "Vous vouliez dire quelque chose ?" -#: src/view/com/composer/Composer.tsx:144 +#: src/view/com/composer/Composer.tsx:143 msgid "Discard" msgstr "Ignorer" -#: src/view/com/composer/Composer.tsx:138 +#: src/view/com/composer/Composer.tsx:137 msgid "Discard draft" msgstr "Ignorer le brouillon" @@ -692,35 +965,53 @@ msgstr "Ignorer le brouillon" msgid "Discourage apps from showing my account to logged-out users" msgstr "Empêcher les applis de montrer mon compte aux utilisateurs déconnectés" -#: src/view/screens/Feeds.tsx:405 +#: 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:409 msgid "Discover new feeds" msgstr "Découvrir de nouveaux fils d’actu" -#: src/view/com/modals/EditProfile.tsx:191 +#: src/view/com/modals/EditProfile.tsx:192 msgid "Display name" msgstr "Afficher le nom" -#: src/view/com/modals/EditProfile.tsx:179 +#: src/view/com/modals/EditProfile.tsx:180 msgid "Display Name" msgstr "Afficher le nom" -#: src/view/com/modals/ChangeHandle.tsx:485 +#: src/view/com/modals/ChangeHandle.tsx:487 msgid "Domain verified!" msgstr "Domaine vérifié !" +#: src/view/com/auth/create/Step2.tsx:83 +msgid "Don't have an invite code?" +msgstr "" + #: src/view/com/auth/onboarding/RecommendedFollows.tsx:86 -#: src/view/com/modals/AltImage.tsx:115 -#: 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/EditImage.tsx:333 -#: src/view/com/modals/ListAddRemoveUsers.tsx:142 +#: 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:79 -#: src/view/screens/PreferencesHomeFeed.tsx:308 +#: src/view/com/modals/UserAddRemoveLists.tsx:82 #: src/view/screens/PreferencesThreads.tsx:162 +msgctxt "action" +msgid "Done" +msgstr "" + +#: src/view/com/modals/AddAppPasswords.tsx:228 +#: src/view/com/modals/AltImage.tsx:115 +#: src/view/com/modals/ContentFilteringSettings.tsx:88 +#: src/view/com/modals/ContentFilteringSettings.tsx:96 +#: src/view/com/modals/crop-image/CropImage.web.tsx:152 +#: src/view/com/modals/InviteCodes.tsx:80 +#: src/view/com/modals/InviteCodes.tsx:123 +#: src/view/com/modals/ListAddRemoveUsers.tsx:142 +#: src/view/screens/PreferencesHomeFeed.tsx:311 msgid "Done" msgstr "Terminé" @@ -728,56 +1019,116 @@ msgstr "Terminé" msgid "Done{extraText}" msgstr "Terminé{extraText}" -#: src/view/com/modals/InviteCodes.tsx:94 +#: src/view/com/auth/login/ChooseAccountForm.tsx:45 +msgid "Double tap to sign in" +msgstr "" + +#: src/view/com/modals/EditProfile.tsx:185 +msgid "e.g. Alice Roberts" +msgstr "" + +#: src/view/com/modals/EditProfile.tsx:203 +msgid "e.g. Artist, dog-lover, and avid reader." +msgstr "" + +#: src/view/com/modals/CreateOrEditList.tsx:225 +msgid "e.g. Great Posters" +msgstr "" + +#: src/view/com/modals/CreateOrEditList.tsx:226 +msgid "e.g. Spammers" +msgstr "" + +#: src/view/com/modals/CreateOrEditList.tsx:246 +msgid "e.g. The posters who never miss." +msgstr "" + +#: src/view/com/modals/CreateOrEditList.tsx:247 +msgid "e.g. Users that repeatedly reply with ads." +msgstr "" + +#: src/view/com/modals/InviteCodes.tsx:96 msgid "Each code works once. You'll receive more invite codes periodically." msgstr "Chaque code ne fonctionne qu’une seule fois. Vous recevrez régulièrement d’autres codes d’invitation." +#: src/view/com/lists/ListMembers.tsx:149 +msgctxt "action" +msgid "Edit" +msgstr "" + #: src/view/com/composer/photos/Gallery.tsx:144 #: src/view/com/modals/EditImage.tsx:207 msgid "Edit image" msgstr "Modifier l’image" -#: src/view/screens/ProfileList.tsx:400 +#: src/view/screens/ProfileList.tsx:411 msgid "Edit list details" msgstr "Modifier les infos de la liste" -#: src/view/screens/Feeds.tsx:367 +#: src/view/com/modals/CreateOrEditList.tsx:193 +msgid "Edit Moderation List" +msgstr "" + +#: src/Navigation.tsx:244 +#: src/view/screens/Feeds.tsx:371 #: src/view/screens/SavedFeeds.tsx:84 msgid "Edit My Feeds" msgstr "Modifier mes fils d’actu" -#: src/view/com/modals/EditProfile.tsx:151 +#: src/view/com/modals/EditProfile.tsx:152 msgid "Edit my profile" msgstr "Modifier mon profil" -#: src/view/com/profile/ProfileHeader.tsx:453 +#: src/view/com/profile/ProfileHeader.tsx:457 msgid "Edit profile" msgstr "Modifier le profil" -#: src/view/com/profile/ProfileHeader.tsx:456 +#: src/view/com/profile/ProfileHeader.tsx:462 msgid "Edit Profile" msgstr "Modifier le profil" -#: src/view/screens/Feeds.tsx:330 +#: src/view/screens/Feeds.tsx:334 msgid "Edit Saved Feeds" msgstr "Modifier les fils d’actu enregistrés" +#: src/view/com/modals/CreateOrEditList.tsx:188 +msgid "Edit User List" +msgstr "" + +#: src/view/com/modals/EditProfile.tsx:193 +msgid "Edit your display name" +msgstr "" + +#: src/view/com/modals/EditProfile.tsx:211 +msgid "Edit your profile description" +msgstr "" + #: src/view/com/auth/create/Step2.tsx:108 -#: src/view/com/auth/login/ForgotPasswordForm.tsx:148 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:152 #: src/view/com/modals/ChangeEmail.tsx:141 #: src/view/com/modals/Waitlist.tsx:88 msgid "Email" msgstr "E-mail" #: src/view/com/auth/create/Step2.tsx:99 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:143 msgid "Email address" msgstr "Adresse e-mail" +#: src/view/com/modals/ChangeEmail.tsx:56 +#: src/view/com/modals/ChangeEmail.tsx:88 +msgid "Email updated" +msgstr "" + #: src/view/com/modals/ChangeEmail.tsx:111 msgid "Email Updated" msgstr "E-mail mis à jour" -#: src/view/screens/Settings.tsx:290 +#: src/view/com/modals/VerifyEmail.tsx:78 +msgid "Email verified" +msgstr "" + +#: src/view/screens/Settings.tsx:305 msgid "Email:" msgstr "E-mail :" @@ -785,34 +1136,63 @@ msgstr "E-mail :" msgid "Enable {0} only" msgstr "" +#: src/view/com/modals/ContentFilteringSettings.tsx:162 +msgid "Enable Adult Content" +msgstr "" + #: src/view/com/modals/EmbedConsent.tsx:97 msgid "Enable External Media" msgstr "" -#: src/view/screens/PreferencesHomeFeed.tsx:144 +#: src/view/screens/PreferencesExternalEmbeds.tsx:75 +msgid "Enable media players for" +msgstr "" + +#: src/view/screens/PreferencesHomeFeed.tsx:147 msgid "Enable this setting to only see replies between people you follow." msgstr "Activez ce paramètre pour ne voir que les réponses des personnes que vous suivez." -#: src/view/screens/Profile.tsx:426 +#: src/view/screens/Profile.tsx:427 msgid "End of feed" msgstr "Fin du fil d’actu" +#: src/view/com/modals/AddAppPasswords.tsx:165 +msgid "Enter a name for this App Password" +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 "Saisissez l’adresse de votre fournisseur :" -#: src/view/com/modals/ChangeHandle.tsx:369 +#: src/view/com/modals/ChangeHandle.tsx:371 msgid "Enter the domain you want to use" msgstr "Entrez le domaine que vous voulez utiliser" -#: src/view/com/auth/login/ForgotPasswordForm.tsx:101 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:103 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." +#: src/view/com/auth/create/Step2.tsx:157 +#: 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/Step2.tsx:104 msgid "Enter your email address" msgstr "Entrez votre e-mail" +#: src/view/com/modals/ChangeEmail.tsx:41 +msgid "Enter your new email above" +msgstr "" + #: src/view/com/modals/ChangeEmail.tsx:117 msgid "Enter your new email address below." msgstr "Entrez votre nouvelle e-mail ci-dessous." @@ -829,10 +1209,32 @@ msgstr "Erreur :" msgid "Everybody" msgstr "Tout le monde" +#: src/view/com/modals/ChangeHandle.tsx:150 +msgid "Exits handle change process" +msgstr "" + +#: src/view/com/lightbox/Lightbox.web.tsx:113 +msgid "Exits image view" +msgstr "" + +#: src/view/com/modals/ListAddRemoveUsers.tsx:88 +#: src/view/shell/desktop/Search.tsx:182 +msgid "Exits inputting search query" +msgstr "" + +#: src/view/com/modals/Waitlist.tsx:138 +msgid "Exits signing up for waitlist with {email}" +msgstr "" + #: src/view/com/lightbox/Lightbox.web.tsx:156 msgid "Expand alt text" msgstr "Développer le texte alt" +#: 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 "" + #: src/view/com/modals/EmbedConsent.tsx:64 msgid "External Media" msgstr "" @@ -842,17 +1244,43 @@ 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:260 #: src/view/screens/PreferencesExternalEmbeds.tsx:52 -#: src/view/screens/Settings.tsx:595 +#: src/view/screens/Settings.tsx:610 msgid "External Media Preferences" msgstr "" +#: src/view/screens/Settings.tsx:601 +msgid "External media settings" +msgstr "" + +#: src/view/com/modals/AddAppPasswords.tsx:114 +#: src/view/com/modals/AddAppPasswords.tsx:118 +msgid "Failed to create app password." +msgstr "" + +#: src/view/com/modals/CreateOrEditList.tsx:148 +msgid "Failed to create the list. Check your internet connection and try again." +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:86 +msgid "Failed to delete post, please try again" +msgstr "" + #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:109 #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:141 msgid "Failed to load recommended feeds" msgstr "Échec du chargement des fils d’actu recommandés" -#: src/view/screens/Feeds.tsx:556 +#: src/Navigation.tsx:194 +msgid "Feed" +msgstr "" + +#: src/view/com/feeds/FeedSourceCard.tsx:229 +msgid "Feed by {0}" +msgstr "" + +#: src/view/screens/Feeds.tsx:560 msgid "Feed offline" msgstr "Fil d’actu hors ligne" @@ -865,12 +1293,13 @@ msgstr "Préférences en matière de fil d’actu" msgid "Feedback" msgstr "Feedback" -#: src/view/screens/Feeds.tsx:475 +#: src/Navigation.tsx:442 +#: src/view/screens/Feeds.tsx:479 #: src/view/screens/Profile.tsx:165 #: src/view/shell/bottom-bar/BottomBar.tsx:181 #: src/view/shell/desktop/LeftNav.tsx:342 -#: src/view/shell/Drawer.tsx:474 -#: src/view/shell/Drawer.tsx:475 +#: src/view/shell/Drawer.tsx:476 +#: src/view/shell/Drawer.tsx:477 msgid "Feeds" msgstr "Fil d’actu" @@ -882,6 +1311,12 @@ msgstr "Les fils d’actu sont créés par les utilisateurs pour rassembler du c msgid "Feeds are custom algorithms that users build with a little coding expertise. <0/> for more information." msgstr "Les fils d’actu sont des algorithmes personnalisés que les utilisateurs construisent avec un peu d’expertise en codage. <0/> pour obtenir de plus amples informations." +#: 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 "" + #: src/view/screens/Search/Search.tsx:427 msgid "Find users on Bluesky" msgstr "Trouver des utilisateurs sur Bluesky" @@ -894,7 +1329,7 @@ msgstr "Trouvez des utilisateurs à l’aide de l’outil de recherche, à droit msgid "Finding similar accounts..." msgstr "Recherche de comptes similaires…" -#: src/view/screens/PreferencesHomeFeed.tsx:108 +#: src/view/screens/PreferencesHomeFeed.tsx:111 msgid "Fine-tune the content you see on your home screen." msgstr "Affinez le contenu de votre écran d’accueil." @@ -902,52 +1337,86 @@ msgstr "Affinez le contenu de votre écran d’accueil." msgid "Fine-tune the discussion threads." msgstr "Affiner les fils de discussion." -#: src/view/com/profile/ProfileHeader.tsx:538 +#: src/view/com/modals/EditImage.tsx:115 +msgid "Flip horizontal" +msgstr "" + +#: src/view/com/modals/EditImage.tsx:120 +#: src/view/com/modals/EditImage.tsx:287 +msgid "Flip vertically" +msgstr "" + +#: src/view/com/profile/FollowButton.tsx:64 +msgctxt "action" +msgid "Follow" +msgstr "" + +#: src/view/com/profile/ProfileHeader.tsx:552 msgid "Follow" msgstr "Suivre" +#: src/view/com/profile/ProfileHeader.tsx:543 +msgid "Follow {0}" +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 "Suivez quelques utilisateurs pour commencer. Nous pouvons vous recommander d’autres utilisateurs en fonction des personnes qui vous intéressent." +#: src/view/com/profile/ProfileCard.tsx:194 +msgid "Followed by {0}" +msgstr "" + #: src/view/com/modals/Threadgate.tsx:98 msgid "Followed users" msgstr "Utilisateurs suivis" -#: src/view/screens/PreferencesHomeFeed.tsx:151 +#: src/view/screens/PreferencesHomeFeed.tsx:154 msgid "Followed users only" msgstr "Utilisateurs suivis uniquement" +#: src/view/com/notifications/FeedItem.tsx:166 +msgid "followed you" +msgstr "" + #: src/view/screens/ProfileFollowers.tsx:25 msgid "Followers" msgstr "Followers" #: src/view/com/profile/ProfileHeader.tsx:624 -msgid "following" -msgstr "suivi" +#~ msgid "following" +#~ msgstr "suivi" -#: src/view/com/profile/ProfileHeader.tsx:522 +#: src/view/com/profile/ProfileHeader.tsx:534 #: src/view/screens/ProfileFollows.tsx:25 msgid "Following" msgstr "Suivi" -#: src/view/com/profile/ProfileHeader.tsx:571 +#: src/view/com/profile/ProfileHeader.tsx:196 +msgid "Following {0}" +msgstr "" + +#: src/view/com/profile/ProfileHeader.tsx:585 msgid "Follows you" msgstr "Vous suit" +#: src/view/com/profile/ProfileCard.tsx:141 +msgid "Follows You" +msgstr "" + #: src/view/com/modals/DeleteAccount.tsx:107 msgid "For security reasons, we'll need to send a confirmation code to your email address." msgstr "Pour des raisons de sécurité, nous devrons envoyer un code de confirmation à votre e-mail." -#: src/view/com/modals/AddAppPasswords.tsx:207 +#: src/view/com/modals/AddAppPasswords.tsx:211 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 "Pour des raisons de sécurité, vous ne pourrez plus afficher ceci. Si vous perdez ce mot de passe, vous devrez en générer un autre." -#: src/view/com/auth/login/LoginForm.tsx:236 +#: src/view/com/auth/login/LoginForm.tsx:238 msgid "Forgot" msgstr "Oublié" -#: src/view/com/auth/login/LoginForm.tsx:233 +#: src/view/com/auth/login/LoginForm.tsx:235 msgid "Forgot password" msgstr "Mot de passe oublié" @@ -956,11 +1425,17 @@ msgstr "Mot de passe oublié" msgid "Forgot Password" msgstr "Mot de passe oublié" +#: src/view/com/posts/FeedItem.tsx:188 +msgctxt "from-feed" +msgid "From <0/>" +msgstr "" + #: src/view/com/composer/photos/SelectPhotoBtn.tsx:43 msgid "Gallery" msgstr "Galerie" -#: src/view/com/modals/VerifyEmail.tsx:183 +#: src/view/com/modals/VerifyEmail.tsx:189 +#: src/view/com/modals/VerifyEmail.tsx:191 msgid "Get Started" msgstr "C’est parti" @@ -973,14 +1448,14 @@ msgstr "Retour" #: src/view/screens/ProfileFeed.tsx:104 #: src/view/screens/ProfileFeed.tsx:109 -#: src/view/screens/ProfileList.tsx:848 -#: src/view/screens/ProfileList.tsx:853 +#: src/view/screens/ProfileList.tsx:876 +#: src/view/screens/ProfileList.tsx:881 msgid "Go Back" msgstr "Retour" -#: src/view/com/auth/login/ForgotPasswordForm.tsx:181 -#: src/view/com/auth/login/LoginForm.tsx:283 -#: src/view/com/auth/login/SetNewPasswordForm.tsx:163 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:185 +#: src/view/com/auth/login/LoginForm.tsx:285 +#: src/view/com/auth/login/SetNewPasswordForm.tsx:165 msgid "Go to next" msgstr "Aller à la suite" @@ -993,47 +1468,64 @@ msgstr "Pseudo" msgid "Help" msgstr "Aide" -#: src/view/com/modals/AddAppPasswords.tsx:148 +#: src/view/com/modals/AddAppPasswords.tsx:152 msgid "Here is your app password." msgstr "Voici le mot de passe de votre appli." -#: src/view/com/notifications/FeedItem.tsx:324 -#: src/view/com/util/moderation/ContentHider.tsx:103 +#: src/view/com/modals/ContentFilteringSettings.tsx:219 +#: src/view/com/notifications/FeedItem.tsx:329 +msgctxt "action" +msgid "Hide" +msgstr "" + +#: src/view/com/modals/ContentFilteringSettings.tsx:246 +#: src/view/com/util/moderation/ContentHider.tsx:105 +#: src/view/com/util/moderation/PostHider.tsx:108 msgid "Hide" msgstr "Cacher" -#: src/view/com/util/forms/PostDropdownBtn.tsx:173 +#: src/view/com/util/forms/PostDropdownBtn.tsx:185 msgid "Hide post" msgstr "Cacher ce post" -#: src/view/com/util/forms/PostDropdownBtn.tsx:177 +#: src/view/com/util/moderation/ContentHider.tsx:67 +#: src/view/com/util/moderation/PostHider.tsx:61 +msgid "Hide the content" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:189 msgid "Hide this post?" msgstr "Cacher ce post ?" -#: src/view/com/notifications/FeedItem.tsx:316 +#: src/view/com/notifications/FeedItem.tsx:319 msgid "Hide user list" msgstr "Cacher la liste des utilisateurs" -#: src/view/com/posts/FeedErrorMessage.tsx:110 +#: src/view/com/profile/ProfileHeader.tsx:526 +msgid "Hides posts from {0} in your feed" +msgstr "" + +#: src/view/com/posts/FeedErrorMessage.tsx:111 msgid "Hmm, some kind of issue occurred when contacting the feed server. Please let the feed owner know about this issue." msgstr "Hmm, un problème s’est produit avec le serveur de fils d’actu. Veuillez informer le propriétaire du fil d’actu de ce problème." -#: src/view/com/posts/FeedErrorMessage.tsx:98 +#: 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, le serveur du fils d’actu semble être mal configuré. Veuillez informer le propriétaire du fil d’actu de ce problème." -#: src/view/com/posts/FeedErrorMessage.tsx:104 +#: 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 "Mmm… le serveur de fils d’actu semble être hors ligne. Veuillez informer le propriétaire du fil d’actu de ce problème." -#: src/view/com/posts/FeedErrorMessage.tsx:101 +#: 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 "Mmm… le serveur de fils d’actu ne répond pas. Veuillez informer le propriétaire du fil d’actu de ce problème." -#: src/view/com/posts/FeedErrorMessage.tsx:95 +#: src/view/com/posts/FeedErrorMessage.tsx:96 msgid "Hmm, we're having trouble finding this feed. It may have been deleted." msgstr "Hmm, nous n’arrivons pas à trouver ce fils d’actu. Il a peut-être été supprimé." +#: src/Navigation.tsx:432 #: src/view/shell/bottom-bar/BottomBar.tsx:137 #: src/view/shell/desktop/LeftNav.tsx:306 #: src/view/shell/Drawer.tsx:398 @@ -1041,13 +1533,14 @@ msgstr "Hmm, nous n’arrivons pas à trouver ce fils d’actu. Il a peut-être msgid "Home" msgstr "Accueil" -#: src/view/com/pager/FeedsTabBarMobile.tsx:96 -#: src/view/screens/PreferencesHomeFeed.tsx:101 -#: src/view/screens/Settings.tsx:481 +#: src/Navigation.tsx:249 +#: src/view/com/pager/FeedsTabBarMobile.tsx:98 +#: src/view/screens/PreferencesHomeFeed.tsx:104 +#: src/view/screens/Settings.tsx:496 msgid "Home Feed Preferences" msgstr "Préférences de fils d’actu de l’accueil" -#: src/view/com/auth/login/ForgotPasswordForm.tsx:114 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:116 msgid "Hosting provider" msgstr "Fournisseur d’hébergement" @@ -1056,18 +1549,30 @@ msgstr "Fournisseur d’hébergement" msgid "Hosting provider address" msgstr "Adresse de l’hébergeur" -#: src/view/com/modals/VerifyEmail.tsx:208 +#: src/view/com/modals/VerifyEmail.tsx:214 msgid "I have a code" msgstr "J’ai un code" -#: src/view/com/modals/ChangeHandle.tsx:281 +#: src/view/com/modals/VerifyEmail.tsx:216 +msgid "I have a confirmation code" +msgstr "" + +#: src/view/com/modals/ChangeHandle.tsx:283 msgid "I have my own domain" msgstr "J’ai mon propre domaine" +#: src/view/com/lightbox/Lightbox.web.tsx:158 +msgid "If alt text is long, toggles alt text expanded state" +msgstr "" + #: src/view/com/modals/SelfLabel.tsx:127 msgid "If none are selected, suitable for all ages." msgstr "Si rien n’est sélectionné, il n’y a pas de restriction d’âge." +#: src/view/com/util/images/Gallery.tsx:37 +msgid "Image" +msgstr "" + #: src/view/com/modals/AltImage.tsx:97 msgid "Image alt text" msgstr "Texte alt de l’image" @@ -1077,19 +1582,76 @@ msgstr "Texte alt de l’image" msgid "Image options" msgstr "Options d’images" +#: src/view/com/auth/login/SetNewPasswordForm.tsx:110 +msgid "Input code sent to your email for password reset" +msgstr "" + +#: src/view/com/modals/DeleteAccount.tsx:180 +msgid "Input confirmation code for account deletion" +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 "" + +#: src/view/com/auth/create/Step2.tsx:73 +msgid "Input invite code to proceed" +msgstr "" + +#: src/view/com/modals/AddAppPasswords.tsx:182 +msgid "Input name for app password" +msgstr "" + +#: src/view/com/auth/login/SetNewPasswordForm.tsx:133 +msgid "Input new password" +msgstr "" + +#: src/view/com/modals/DeleteAccount.tsx:196 +msgid "Input password for account deletion" +msgstr "" + +#: src/view/com/auth/login/LoginForm.tsx:227 +msgid "Input the password tied to {identifier}" +msgstr "" + +#: src/view/com/auth/login/LoginForm.tsx:194 +msgid "Input the username or email address you used at signup" +msgstr "" + +#: src/view/com/modals/Waitlist.tsx:90 +msgid "Input your email to get on the Bluesky waitlist" +msgstr "" + +#: src/view/com/auth/login/LoginForm.tsx:226 +msgid "Input your password" +msgstr "" + +#: src/view/com/auth/create/Step3.tsx:39 +msgid "Input your user handle" +msgstr "" + +#: src/view/com/post-thread/PostThreadItem.tsx:229 +msgid "Invalid or unsupported post record" +msgstr "" + #: src/view/com/auth/login/LoginForm.tsx:115 msgid "Invalid username or password" msgstr "Nom d’utilisateur ou mot de passe incorrect" -#: src/view/screens/Settings.tsx:383 +#: src/view/screens/Settings.tsx:398 msgid "Invite" msgstr "Inviter" -#: src/view/com/modals/InviteCodes.tsx:91 -#: src/view/screens/Settings.tsx:371 +#: src/view/com/modals/InviteCodes.tsx:93 +#: src/view/screens/Settings.tsx:386 msgid "Invite a Friend" msgstr "Inviter un ami" +#: src/view/com/auth/create/Step2.tsx:63 #: src/view/com/auth/create/Step2.tsx:72 msgid "Invite code" msgstr "Code d’invitation" @@ -1098,10 +1660,18 @@ msgstr "Code d’invitation" msgid "Invite code not accepted. Check that you input it correctly and try again." msgstr "Code d’invitation refusé. Vérifiez que vous l’avez saisi correctement et réessayez." -#: src/view/shell/Drawer.tsx:640 +#: src/view/com/modals/InviteCodes.tsx:170 +msgid "Invite codes: {0} available" +msgstr "" + +#: src/view/shell/Drawer.tsx:642 msgid "Invite codes: {invitesAvailable} available" msgstr "Codes d’invitation : {invitesAvailable} disponible" +#: src/view/com/modals/InviteCodes.tsx:169 +msgid "Invite codes: 1 available" +msgstr "" + #: src/view/com/auth/HomeLoggedOutCTA.tsx:99 msgid "Jobs" msgstr "Emplois" @@ -1115,7 +1685,7 @@ msgstr "S’inscrire sur la liste d’attente" msgid "Join the waitlist." msgstr "S’inscrire sur la liste d’attente." -#: src/view/com/modals/Waitlist.tsx:124 +#: src/view/com/modals/Waitlist.tsx:128 msgid "Join Waitlist" msgstr "S’inscrire sur la liste d’attente" @@ -1123,15 +1693,24 @@ msgstr "S’inscrire sur la liste d’attente" msgid "Language selection" msgstr "Sélection de la langue" +#: src/view/screens/Settings.tsx:547 +msgid "Language settings" +msgstr "" + +#: src/Navigation.tsx:141 #: src/view/screens/LanguageSettings.tsx:89 msgid "Language Settings" msgstr "Paramètres linguistiques" -#: src/view/screens/Settings.tsx:541 +#: src/view/screens/Settings.tsx:556 msgid "Languages" msgstr "Langues" -#: src/view/com/util/moderation/ContentHider.tsx:101 +#: src/view/com/auth/create/StepHeader.tsx:13 +msgid "Last step!" +msgstr "" + +#: src/view/com/util/moderation/ContentHider.tsx:103 msgid "Learn more" msgstr "En savoir plus" @@ -1141,9 +1720,9 @@ msgstr "En savoir plus" msgid "Learn More" msgstr "En savoir plus" -#: src/view/com/util/moderation/ContentHider.tsx:83 +#: src/view/com/util/moderation/ContentHider.tsx:85 #: src/view/com/util/moderation/PostAlerts.tsx:40 -#: src/view/com/util/moderation/PostHider.tsx:76 +#: 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" @@ -1161,6 +1740,10 @@ msgstr "Si vous ne cochez rien, toutes les langues s’afficheront." msgid "Leaving Bluesky" msgstr "Quitter Bluesky" +#: src/view/screens/Settings.tsx:273 +msgid "Legacy storage cleared, you need to restart the app now." +msgstr "" + #: src/view/com/auth/login/Login.tsx:128 #: src/view/com/auth/login/Login.tsx:144 msgid "Let's get your password reset!" @@ -1171,36 +1754,94 @@ msgstr "Réinitialisez votre mot de passe !" msgid "Library" msgstr "Bibliothèque" -#: src/view/screens/ProfileFeed.tsx:586 +#: src/view/screens/Settings.tsx:460 +msgid "Light" +msgstr "" + +#: src/view/com/util/post-ctrls/PostCtrls.tsx:189 +msgid "Like" +msgstr "" + +#: src/view/screens/ProfileFeed.tsx:600 msgid "Like this feed" msgstr "Liker ce fil d’actu" +#: src/Navigation.tsx:199 #: src/view/screens/PostLikedBy.tsx:27 #: src/view/screens/ProfileFeedLikedBy.tsx:27 msgid "Liked by" msgstr "Liké par" +#: src/view/com/feeds/FeedSourceCard.tsx:277 +msgid "Liked by {0} {1}" +msgstr "" + +#: src/view/screens/ProfileFeed.tsx:615 +msgid "Liked by {likeCount} {0}" +msgstr "" + +#: src/view/com/notifications/FeedItem.tsx:171 +msgid "liked your custom feed{0}" +msgstr "" + +#: src/view/com/notifications/FeedItem.tsx:155 +msgid "liked your post" +msgstr "" + #: src/view/screens/Profile.tsx:164 msgid "Likes" msgstr "Likes" -#: src/view/com/modals/CreateOrEditList.tsx:186 +#: src/view/com/post-thread/PostThreadItem.tsx:184 +msgid "Likes on this post" +msgstr "" + +#: src/Navigation.tsx:168 +msgid "List" +msgstr "" + +#: src/view/com/modals/CreateOrEditList.tsx:205 msgid "List Avatar" msgstr "Liste des avatars" -#: src/view/com/modals/CreateOrEditList.tsx:199 +#: src/view/screens/ProfileList.tsx:323 +msgid "List blocked" +msgstr "" + +#: src/view/com/feeds/FeedSourceCard.tsx:231 +msgid "List by {0}" +msgstr "" + +#: src/view/screens/ProfileList.tsx:367 +msgid "List deleted" +msgstr "" + +#: src/view/screens/ProfileList.tsx:282 +msgid "List muted" +msgstr "" + +#: src/view/com/modals/CreateOrEditList.tsx:218 msgid "List Name" msgstr "Nom de liste" +#: src/view/screens/ProfileList.tsx:342 +msgid "List unblocked" +msgstr "" + +#: src/view/screens/ProfileList.tsx:301 +msgid "List unmuted" +msgstr "" + +#: src/Navigation.tsx:111 #: src/view/screens/Profile.tsx:166 #: src/view/shell/desktop/LeftNav.tsx:379 -#: src/view/shell/Drawer.tsx:490 -#: src/view/shell/Drawer.tsx:491 +#: src/view/shell/Drawer.tsx:492 +#: src/view/shell/Drawer.tsx:493 msgid "Lists" msgstr "Listes" -#: src/view/com/post-thread/PostThread.tsx:259 -#: src/view/com/post-thread/PostThread.tsx:267 +#: src/view/com/post-thread/PostThread.tsx:263 +#: src/view/com/post-thread/PostThread.tsx:271 msgid "Load more posts" msgstr "Charger plus d’articles" @@ -1208,7 +1849,10 @@ msgstr "Charger plus d’articles" msgid "Load new notifications" msgstr "Charger les nouvelles notifications" -#: src/view/com/feeds/FeedPage.tsx:189 +#: src/view/com/feeds/FeedPage.tsx:190 +#: src/view/screens/Profile.tsx:412 +#: src/view/screens/ProfileFeed.tsx:503 +#: src/view/screens/ProfileList.tsx:659 msgid "Load new posts" msgstr "Charger les nouveaux messages" @@ -1220,6 +1864,10 @@ msgstr "Chargement…" msgid "Local dev server" msgstr "Serveur de dév local" +#: src/Navigation.tsx:209 +msgid "Log" +msgstr "" + #: src/view/screens/Moderation.tsx:136 msgid "Logged-out visibility" msgstr "Visibilité déconnectée" @@ -1244,61 +1892,107 @@ msgstr "utilisateurs mentionnés" msgid "Mentioned users" msgstr "Utilisateurs mentionnés" +#: src/view/com/util/ViewHeader.tsx:81 #: src/view/screens/Search/Search.tsx:537 msgid "Menu" msgstr "Menu" #: src/view/com/posts/FeedErrorMessage.tsx:194 -msgid "Message from server" -msgstr "Message du serveur" +#~ msgid "Message from server" +#~ msgstr "Message du serveur" +#: src/view/com/posts/FeedErrorMessage.tsx:197 +msgid "Message from server: {0}" +msgstr "" + +#: src/Navigation.tsx:116 #: src/view/screens/Moderation.tsx:64 -#: src/view/screens/Settings.tsx:563 +#: src/view/screens/Settings.tsx:578 #: src/view/shell/desktop/LeftNav.tsx:397 -#: src/view/shell/Drawer.tsx:509 -#: src/view/shell/Drawer.tsx:510 +#: src/view/shell/Drawer.tsx:511 +#: src/view/shell/Drawer.tsx:512 msgid "Moderation" msgstr "Modération" +#: src/view/com/lists/ListCard.tsx:92 +#: src/view/com/modals/UserAddRemoveLists.tsx:190 +msgid "Moderation list by {0}" +msgstr "" + +#: src/view/screens/ProfileList.tsx:753 +msgid "Moderation list by <0/>" +msgstr "" + +#: src/view/com/lists/ListCard.tsx:90 +#: src/view/com/modals/UserAddRemoveLists.tsx:188 +#: src/view/screens/ProfileList.tsx:751 +msgid "Moderation list by you" +msgstr "" + +#: src/view/com/modals/CreateOrEditList.tsx:139 +msgid "Moderation list created" +msgstr "" + +#: src/view/com/modals/CreateOrEditList.tsx:126 +msgid "Moderation list updated" +msgstr "" + #: src/view/screens/Moderation.tsx:95 msgid "Moderation lists" msgstr "Listes de modération" +#: src/Navigation.tsx:121 #: src/view/screens/ModerationModlists.tsx:58 msgid "Moderation Lists" msgstr "Listes de modération" +#: src/view/screens/Settings.tsx:572 +msgid "Moderation settings" +msgstr "" + +#: src/view/com/modals/ModerationDetails.tsx:35 +msgid "Moderator has chosen to set a general warning on the content." +msgstr "" + #: src/view/shell/desktop/Feeds.tsx:53 msgid "More feeds" msgstr "Plus de fils d’actu" -#: src/view/com/profile/ProfileHeader.tsx:548 -#: src/view/screens/ProfileFeed.tsx:361 -#: src/view/screens/ProfileList.tsx:584 +#: src/view/com/profile/ProfileHeader.tsx:562 +#: src/view/screens/ProfileFeed.tsx:371 +#: src/view/screens/ProfileList.tsx:595 msgid "More options" msgstr "Plus d’options" +#: src/view/com/util/forms/PostDropdownBtn.tsx:268 +msgid "More post options" +msgstr "" + #: src/view/screens/PreferencesThreads.tsx:82 msgid "Most-liked replies first" msgstr "Réponses les plus likées en premier" -#: src/view/com/profile/ProfileHeader.tsx:370 +#: src/view/com/profile/ProfileHeader.tsx:374 msgid "Mute Account" msgstr "Masquer le compte" -#: src/view/screens/ProfileList.tsx:511 +#: src/view/screens/ProfileList.tsx:522 msgid "Mute accounts" msgstr "Masquer les comptes" -#: src/view/screens/ProfileList.tsx:458 +#: src/view/screens/ProfileList.tsx:469 msgid "Mute list" msgstr "Masquer la liste" -#: src/view/screens/ProfileList.tsx:271 +#: src/view/screens/ProfileList.tsx:274 msgid "Mute these accounts?" msgstr "Masquer ces comptes ?" -#: src/view/com/util/forms/PostDropdownBtn.tsx:157 +#: src/view/screens/ProfileList.tsx:278 +msgid "Mute this List" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:169 msgid "Mute thread" msgstr "Masquer ce fil de discussion" @@ -1306,6 +2000,7 @@ msgstr "Masquer ce fil de discussion" msgid "Muted accounts" msgstr "Comptes masqués" +#: src/Navigation.tsx:126 #: src/view/screens/ModerationMutedAccounts.tsx:107 msgid "Muted Accounts" msgstr "Comptes masqués" @@ -1314,7 +2009,7 @@ msgstr "Comptes masqués" 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." -#: src/view/screens/ProfileList.tsx:273 +#: src/view/screens/ProfileList.tsx:276 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "Ce que vous masquez reste privé. Les comptes masqués peuvent interagir avec vous, mais vous ne verrez pas leurs posts et ne recevrez pas de notifications de leur part." @@ -1322,7 +2017,7 @@ msgstr "Ce que vous masquez reste privé. Les comptes masqués peuvent interagir msgid "My Birthday" msgstr "Ma date de naissance" -#: src/view/screens/Feeds.tsx:363 +#: src/view/screens/Feeds.tsx:367 msgid "My Feeds" msgstr "Mes fils d’actu" @@ -1330,53 +2025,98 @@ msgstr "Mes fils d’actu" msgid "My Profile" msgstr "Mon profil" -#: src/view/screens/Settings.tsx:520 +#: src/view/screens/Settings.tsx:535 msgid "My Saved Feeds" msgstr "Mes fils d’actu enregistrés" -#: src/view/com/modals/AddAppPasswords.tsx:177 -#: src/view/com/modals/CreateOrEditList.tsx:211 +#: src/view/com/modals/AddAppPasswords.tsx:181 +#: src/view/com/modals/CreateOrEditList.tsx:232 msgid "Name" msgstr "Nom" +#: src/view/com/modals/CreateOrEditList.tsx:108 +msgid "Name is required" +msgstr "" + +#: src/view/com/auth/login/ForgotPasswordForm.tsx:186 +#: src/view/com/auth/login/LoginForm.tsx:286 +#: src/view/com/auth/login/SetNewPasswordForm.tsx:166 +msgid "Navigates to the next screen" +msgstr "" + +#: src/view/shell/Drawer.tsx:71 +msgid "Navigates to your profile" +msgstr "" + #: src/view/com/modals/EmbedConsent.tsx:107 #: src/view/com/modals/EmbedConsent.tsx:123 msgid "Never load embeds from {0}" msgstr "" +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:72 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:72 msgid "Never lose access to your followers and data." msgstr "Ne perdez jamais l’accès à vos followers et à vos données." #: src/view/screens/Lists.tsx:76 +msgctxt "action" +msgid "New" +msgstr "" + #: src/view/screens/ModerationModlists.tsx:78 msgid "New" msgstr "Nouveau" -#: src/view/com/feeds/FeedPage.tsx:200 -#: src/view/screens/Feeds.tsx:507 +#: src/view/com/modals/CreateOrEditList.tsx:195 +msgid "New Moderation List" +msgstr "" + +#: src/view/com/auth/login/SetNewPasswordForm.tsx:122 +msgid "New password" +msgstr "" + +#: src/view/com/feeds/FeedPage.tsx:201 +msgctxt "action" +msgid "New post" +msgstr "" + +#: src/view/screens/Feeds.tsx:511 #: src/view/screens/Profile.tsx:354 -#: src/view/screens/ProfileFeed.tsx:431 -#: src/view/screens/ProfileList.tsx:194 -#: src/view/screens/ProfileList.tsx:222 +#: src/view/screens/ProfileFeed.tsx:441 +#: src/view/screens/ProfileList.tsx:197 +#: src/view/screens/ProfileList.tsx:225 #: src/view/shell/desktop/LeftNav.tsx:248 msgid "New post" msgstr "Nouveau post" #: src/view/shell/desktop/LeftNav.tsx:258 +msgctxt "action" msgid "New Post" -msgstr "Nouveau post" +msgstr "" + +#: src/view/shell/desktop/LeftNav.tsx:258 +#~ msgid "New Post" +#~ msgstr "Nouveau post" + +#: src/view/com/modals/CreateOrEditList.tsx:190 +msgid "New User List" +msgstr "" #: src/view/screens/PreferencesThreads.tsx:79 msgid "Newest replies first" msgstr "" +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 +msgctxt "action" +msgid "Next" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:154 -#: src/view/com/auth/login/ForgotPasswordForm.tsx:174 -#: src/view/com/auth/login/ForgotPasswordForm.tsx:184 -#: src/view/com/auth/login/LoginForm.tsx:286 -#: src/view/com/auth/login/SetNewPasswordForm.tsx:156 -#: src/view/com/auth/login/SetNewPasswordForm.tsx:166 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:178 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:188 +#: src/view/com/auth/login/LoginForm.tsx:288 +#: src/view/com/auth/login/SetNewPasswordForm.tsx:158 +#: src/view/com/auth/login/SetNewPasswordForm.tsx:168 #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:79 msgid "Next" msgstr "Suivant" @@ -1385,33 +2125,42 @@ msgstr "Suivant" msgid "Next image" msgstr "Image suivante" -#: src/view/screens/PreferencesHomeFeed.tsx:126 -#: src/view/screens/PreferencesHomeFeed.tsx:197 -#: src/view/screens/PreferencesHomeFeed.tsx:232 -#: src/view/screens/PreferencesHomeFeed.tsx:269 +#: src/view/screens/PreferencesHomeFeed.tsx:129 +#: src/view/screens/PreferencesHomeFeed.tsx:200 +#: src/view/screens/PreferencesHomeFeed.tsx:235 +#: src/view/screens/PreferencesHomeFeed.tsx:272 #: src/view/screens/PreferencesThreads.tsx:106 #: src/view/screens/PreferencesThreads.tsx:129 msgid "No" msgstr "Non" -#: src/view/screens/ProfileFeed.tsx:579 -#: src/view/screens/ProfileList.tsx:720 +#: src/view/screens/ProfileFeed.tsx:593 +#: src/view/screens/ProfileList.tsx:733 msgid "No description" msgstr "Aucune description" +#: src/view/com/profile/ProfileHeader.tsx:217 +msgid "No longer following {0}" +msgstr "" + +#: src/view/com/notifications/Feed.tsx:107 +msgid "No notifications yet!" +msgstr "" + #: src/view/com/composer/text-input/mobile/Autocomplete.tsx:97 +#: src/view/com/composer/text-input/web/Autocomplete.tsx:191 msgid "No result" msgstr "Aucun résultat" -#: src/view/screens/Feeds.tsx:452 +#: src/view/screens/Feeds.tsx:456 msgid "No results found for \"{query}\"" msgstr "Aucun résultat trouvé pour « {query} »" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 #: src/view/screens/Search/Search.tsx:270 #: src/view/screens/Search/Search.tsx:298 -#: src/view/screens/Search/Search.tsx:629 -#: src/view/shell/desktop/Search.tsx:210 +#: src/view/screens/Search/Search.tsx:630 +#: src/view/shell/desktop/Search.tsx:213 msgid "No results found for {query}" msgstr "Aucun résultat trouvé pour {query}" @@ -1427,10 +2176,20 @@ msgstr "Personne" msgid "Not Applicable." msgstr "Sans objet." +#: src/Navigation.tsx:106 +msgid "Not Found" +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:232 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 utilisateurs déconnectés par d’autres applications et sites Web." +#: src/Navigation.tsx:447 #: src/view/screens/Notifications.tsx:113 #: src/view/screens/Notifications.tsx:137 #: src/view/shell/bottom-bar/BottomBar.tsx:205 @@ -1440,6 +2199,10 @@ msgstr "Remarque : Bluesky est un réseau ouvert et public. Ce paramètre limit msgid "Notifications" msgstr "Notifications" +#: src/view/com/modals/SelfLabel.tsx:103 +msgid "Nudity" +msgstr "" + #: src/view/com/util/ErrorBoundary.tsx:34 msgid "Oh no!" msgstr "Oh non !" @@ -1452,7 +2215,11 @@ msgstr "D’accord" msgid "Oldest replies first" msgstr "Plus anciennes réponses en premier" -#: src/view/com/composer/Composer.tsx:363 +#: src/view/screens/Settings.tsx:229 +msgid "Onboarding reset" +msgstr "" + +#: src/view/com/composer/Composer.tsx:374 msgid "One or more images is missing alt text." msgstr "Une ou plusieurs images n’ont pas de texte alt." @@ -1460,6 +2227,12 @@ msgstr "Une ou plusieurs images n’ont pas de texte alt." msgid "Only {0} can reply." msgstr "Seul {0} peut répondre." +#: src/view/com/modals/ProfilePreview.tsx:49 +#: src/view/com/modals/ProfilePreview.tsx:61 +#: src/view/screens/AppPasswords.tsx:65 +msgid "Oops!" +msgstr "" + #: src/view/com/composer/Composer.tsx:468 #: src/view/com/composer/Composer.tsx:469 msgid "Open emoji picker" @@ -1469,51 +2242,112 @@ msgstr "Ouvrir le sélecteur d’emoji" msgid "Open navigation" msgstr "Navigation ouverte" -#: src/view/screens/Settings.tsx:533 +#: src/view/screens/Settings.tsx:713 +msgid "Open storybook page" +msgstr "" + +#: src/view/com/util/forms/DropdownButton.tsx:147 +msgid "Opens {numItems} options" +msgstr "" + +#: src/view/screens/Log.tsx:54 +msgid "Opens additional details for a debug entry" +msgstr "" + +#: src/view/com/notifications/FeedItem.tsx:352 +msgid "Opens an expanded list of users in this notification" +msgstr "" + +#: src/view/com/composer/photos/OpenCameraBtn.tsx:61 +msgid "Opens camera on device" +msgstr "" + +#: src/view/com/composer/Prompt.tsx:25 +msgid "Opens composer" +msgstr "" + +#: src/view/screens/Settings.tsx:548 msgid "Opens configurable language settings" msgstr "Ouvre les paramètres linguistiques configurables" -#: src/view/screens/Settings.tsx:587 +#: src/view/com/composer/photos/SelectPhotoBtn.tsx:44 +msgid "Opens device photo gallery" +msgstr "" + +#: src/view/com/profile/ProfileHeader.tsx:459 +msgid "Opens editor for profile display name, avatar, background image, and description" +msgstr "" + +#: src/view/screens/Settings.tsx:602 msgid "Opens external embeds settings" msgstr "" +#: src/view/com/profile/ProfileHeader.tsx:614 +msgid "Opens followers list" +msgstr "" + +#: src/view/com/profile/ProfileHeader.tsx:633 +msgid "Opens following list" +msgstr "" + +#: src/view/screens/Settings.tsx:399 +msgid "Opens invite code list" +msgstr "" + +#: src/view/com/modals/InviteCodes.tsx:172 #: src/view/shell/desktop/RightNav.tsx:156 -#: src/view/shell/Drawer.tsx:641 +#: src/view/shell/Drawer.tsx:643 msgid "Opens list of invite codes" msgstr "Ouvre la liste des codes d’invitation" -#: src/view/com/modals/ChangeHandle.tsx:279 +#: src/view/screens/Settings.tsx:672 +msgid "Opens modal for account deletion confirmation. Requires email code." +msgstr "" + +#: src/view/com/modals/ChangeHandle.tsx:281 msgid "Opens modal for using custom domain" msgstr "Ouvre une fenêtre modale pour utiliser un domaine personnalisé" -#: src/view/screens/Settings.tsx:558 +#: src/view/screens/Settings.tsx:573 msgid "Opens moderation settings" msgstr "Ouvre les paramètres de modération" -#: src/view/screens/Settings.tsx:514 +#: src/view/com/auth/login/LoginForm.tsx:236 +msgid "Opens password reset form" +msgstr "" + +#: src/view/screens/Feeds.tsx:335 +msgid "Opens screen to edit Saved Feeds" +msgstr "" + +#: src/view/screens/Settings.tsx:529 msgid "Opens screen with all saved feeds" msgstr "Ouvre l’écran avec tous les fils d’actu enregistrés" -#: src/view/screens/Settings.tsx:614 +#: src/view/screens/Settings.tsx:629 msgid "Opens the app password settings page" msgstr "Ouvre la page de configuration du mot de passe" -#: src/view/screens/Settings.tsx:473 +#: src/view/screens/Settings.tsx:488 msgid "Opens the home feed preferences" msgstr "Ouvre les préférences du fil d’accueil" -#: src/view/screens/Settings.tsx:697 +#: src/view/screens/Settings.tsx:714 msgid "Opens the storybook page" msgstr "Ouvre la page de l’historique" -#: src/view/screens/Settings.tsx:677 +#: src/view/screens/Settings.tsx:694 msgid "Opens the system log page" msgstr "Ouvre la page du journal système" -#: src/view/screens/Settings.tsx:494 +#: src/view/screens/Settings.tsx:509 msgid "Opens the threads preferences" msgstr "Ouvre les préférences relatives aux fils de discussion" +#: src/view/com/util/forms/DropdownButton.tsx:254 +msgid "Option {0} of {numItems}" +msgstr "" + #: src/view/com/modals/Threadgate.tsx:89 msgid "Or combine these options:" msgstr "Ou une combinaison de ces options :" @@ -1537,9 +2371,9 @@ msgstr "Page introuvable" #: src/view/com/auth/create/Step2.tsx:122 #: src/view/com/auth/create/Step2.tsx:132 -#: src/view/com/auth/login/LoginForm.tsx:221 -#: src/view/com/auth/login/SetNewPasswordForm.tsx:130 -#: src/view/com/modals/DeleteAccount.tsx:191 +#: src/view/com/auth/login/LoginForm.tsx:223 +#: src/view/com/auth/login/SetNewPasswordForm.tsx:132 +#: src/view/com/modals/DeleteAccount.tsx:195 msgid "Password" msgstr "Mot de passe" @@ -1551,10 +2385,31 @@ msgstr "Mise à jour du mot de passe" msgid "Password updated!" msgstr "Mot de passe mis à jour !" +#: src/Navigation.tsx:162 +msgid "People followed by @{0}" +msgstr "" + +#: src/Navigation.tsx:155 +msgid "People following @{0}" +msgstr "" + +#: src/view/com/lightbox/Lightbox.tsx:66 +msgid "Permission to access camera roll is required." +msgstr "" + +#: src/view/com/lightbox/Lightbox.tsx:72 +msgid "Permission to access camera roll was denied. Please enable it in your system settings." +msgstr "" + #: src/view/com/modals/SelfLabel.tsx:121 msgid "Pictures meant for adults." msgstr "Images destinées aux adultes." +#: src/view/screens/ProfileFeed.tsx:362 +#: src/view/screens/ProfileList.tsx:559 +msgid "Pin to home" +msgstr "" + #: src/view/screens/SavedFeeds.tsx:88 msgid "Pinned Feeds" msgstr "Fils épinglés" @@ -1584,7 +2439,11 @@ msgstr "Veuillez choisir votre mot de passe." 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 "Veuillez confirmer votre e-mail avant de le modifier. Ceci est temporairement requis pendant que des outils de mise à jour d’e-mail sont ajoutés, cette étape ne sera bientôt plus nécessaire." -#: src/view/com/modals/AddAppPasswords.tsx:140 +#: src/view/com/modals/AddAppPasswords.tsx:89 +msgid "Please enter a name for your app password. All spaces is not allowed." +msgstr "" + +#: src/view/com/modals/AddAppPasswords.tsx:144 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." @@ -1592,7 +2451,7 @@ msgstr "Veuillez saisir un nom unique pour le mot de passe de l’application ou msgid "Please enter your email." msgstr "Veuillez entrer votre e-mail." -#: src/view/com/modals/DeleteAccount.tsx:180 +#: src/view/com/modals/DeleteAccount.tsx:184 msgid "Please enter your password as well:" msgstr "Veuillez également entrer votre mot de passe :" @@ -1604,17 +2463,51 @@ msgstr "Dites-nous donc pourquoi vous pensez que cet avertissement de contenu a #~ msgid "Please tell us why you think this decision was incorrect." #~ msgstr "Dites-nous pourquoi vous pensez que cette décision était incorrecte." -#: src/view/com/composer/Composer.tsx:215 +#: src/view/com/modals/VerifyEmail.tsx:101 +msgid "Please Verify Your Email" +msgstr "" + +#: src/view/com/composer/Composer.tsx:214 msgid "Please wait for your link card to finish loading" msgstr "Veuillez patienter le temps que votre carte de lien soit chargée" +#: src/view/com/modals/SelfLabel.tsx:111 +msgid "Porn" +msgstr "" + +#: src/view/com/composer/Composer.tsx:349 +#: src/view/com/composer/Composer.tsx:357 +msgctxt "action" +msgid "Post" +msgstr "" + +#: src/view/com/post-thread/PostThread.tsx:227 +#: src/view/screens/PostThread.tsx:82 +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 "Post" +#~ msgid "Post" +#~ msgstr "Post" -#: src/view/com/post-thread/PostThread.tsx:378 +#: src/view/com/post-thread/PostThreadItem.tsx:176 +msgid "Post by {0}" +msgstr "" + +#: src/Navigation.tsx:174 +#: src/Navigation.tsx:181 +#: src/Navigation.tsx:188 +msgid "Post by @{0}" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:82 +msgid "Post deleted" +msgstr "" + +#: src/view/com/post-thread/PostThread.tsx:382 msgid "Post hidden" msgstr "Posts cachés" @@ -1626,7 +2519,7 @@ msgstr "Langue du post" msgid "Post Languages" msgstr "Langues du post" -#: src/view/com/post-thread/PostThread.tsx:430 +#: src/view/com/post-thread/PostThread.tsx:434 msgid "Post not found" msgstr "Post introuvable" @@ -1634,6 +2527,10 @@ msgstr "Post introuvable" msgid "Posts" msgstr "Posts" +#: src/view/com/posts/FeedErrorMessage.tsx:64 +msgid "Posts hidden" +msgstr "" + #: src/view/com/modals/LinkWarning.tsx:44 msgid "Potentially Misleading Link" msgstr "Lien potentiellement trompeur" @@ -1650,30 +2547,35 @@ msgstr "Langue principale" msgid "Prioritize Your Follows" msgstr "Définissez des priorités de vos suivis" -#: src/view/screens/Settings.tsx:570 +#: src/view/screens/Settings.tsx:585 #: src/view/shell/desktop/RightNav.tsx:84 msgid "Privacy" msgstr "Vie privée" +#: src/Navigation.tsx:219 #: src/view/screens/PrivacyPolicy.tsx:29 -#: src/view/screens/Settings.tsx:783 +#: src/view/screens/Settings.tsx:800 #: src/view/shell/Drawer.tsx:262 msgid "Privacy Policy" msgstr "Charte de confidentialité" -#: src/view/com/auth/login/ForgotPasswordForm.tsx:190 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:194 msgid "Processing..." msgstr "Traitement…" #: 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:544 -#: src/view/shell/Drawer.tsx:545 +#: src/view/shell/Drawer.tsx:546 +#: src/view/shell/Drawer.tsx:547 msgid "Profile" msgstr "Profil" -#: src/view/screens/Settings.tsx:841 +#: src/view/com/modals/EditProfile.tsx:128 +msgid "Profile updated" +msgstr "" + +#: src/view/screens/Settings.tsx:858 msgid "Protect your account by verifying your email." msgstr "Protégez votre compte en vérifiant votre e-mail." @@ -1685,14 +2587,31 @@ msgstr "Listes publiques et partageables d’utilisateurs à masquer ou à bloqu msgid "Public, shareable lists which can drive feeds." msgstr "Les listes publiques et partageables qui peuvent alimenter les fils d’actu." -#: src/view/com/modals/Repost.tsx:52 +#: src/view/com/composer/Composer.tsx:334 +msgid "Publish post" +msgstr "" + +#: src/view/com/composer/Composer.tsx:334 +msgid "Publish reply" +msgstr "" + +#: src/view/com/modals/Repost.tsx:65 +msgctxt "action" +msgid "Quote post" +msgstr "" + #: src/view/com/util/post-ctrls/RepostButton.web.tsx:58 msgid "Quote post" msgstr "Citer le post" -#: src/view/com/modals/Repost.tsx:56 +#: src/view/com/modals/Repost.tsx:70 +msgctxt "action" msgid "Quote Post" -msgstr "Citer un post" +msgstr "" + +#: src/view/com/modals/Repost.tsx:56 +#~ msgid "Quote Post" +#~ msgstr "Citer un post" #: src/view/screens/PreferencesThreads.tsx:86 msgid "Random (aka \"Poster's Roulette\")" @@ -1712,7 +2631,7 @@ msgstr "Utilisateurs recommandés" #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 -#: src/view/com/modals/UserAddRemoveLists.tsx:193 +#: src/view/com/modals/UserAddRemoveLists.tsx:203 #: src/view/com/util/UserAvatar.tsx:282 #: src/view/com/util/UserBanner.tsx:89 msgid "Remove" @@ -1726,13 +2645,16 @@ msgstr "Supprimer {0} de mes fils d’actu ?" msgid "Remove account" msgstr "Supprimer compte" -#: src/view/com/posts/FeedErrorMessage.tsx:130 +#: src/view/com/posts/FeedErrorMessage.tsx:131 +#: src/view/com/posts/FeedErrorMessage.tsx:166 msgid "Remove feed" msgstr "Supprimer fil d’actu" #: src/view/com/feeds/FeedSourceCard.tsx:105 +#: src/view/com/feeds/FeedSourceCard.tsx:167 #: src/view/com/feeds/FeedSourceCard.tsx:172 -#: src/view/screens/ProfileFeed.tsx:271 +#: src/view/com/feeds/FeedSourceCard.tsx:243 +#: src/view/screens/ProfileFeed.tsx:281 msgid "Remove from my feeds" msgstr "Supprimer de mes fils d’actu" @@ -1744,11 +2666,15 @@ msgstr "Supprimer l’image" msgid "Remove image preview" msgstr "Supprimer l’aperçu d’image" +#: src/view/com/modals/Repost.tsx:47 +msgid "Remove repost" +msgstr "" + #: src/view/com/feeds/FeedSourceCard.tsx:173 msgid "Remove this feed from my feeds?" msgstr "Supprimer ce fil d’actu ?" -#: src/view/com/posts/FeedErrorMessage.tsx:131 +#: 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 ?" @@ -1757,6 +2683,15 @@ msgstr "Supprimer ce fil d’actu de vos fils d’actu enregistrés ?" msgid "Removed from list" msgstr "Supprimé de la liste" +#: src/view/com/feeds/FeedSourceCard.tsx:111 +#: src/view/com/feeds/FeedSourceCard.tsx:178 +msgid "Removed from my feeds" +msgstr "" + +#: src/view/com/composer/ExternalEmbed.tsx:71 +msgid "Removes default thumbnail from {0}" +msgstr "" + #: src/view/screens/Profile.tsx:162 msgid "Replies" msgstr "Réponses" @@ -1765,31 +2700,50 @@ msgstr "Réponses" msgid "Replies to this thread are disabled" msgstr "Les réponses à ce fil de discussion sont désactivées" -#: src/view/screens/PreferencesHomeFeed.tsx:141 +#: src/view/com/composer/Composer.tsx:347 +msgctxt "action" +msgid "Reply" +msgstr "" + +#: src/view/screens/PreferencesHomeFeed.tsx:144 msgid "Reply Filters" msgstr "Filtres de réponse" +#: src/view/com/post/Post.tsx:165 +#: src/view/com/posts/FeedItem.tsx:286 +msgctxt "description" +msgid "Reply to <0/>" +msgstr "" + #: src/view/com/modals/report/Modal.tsx:166 msgid "Report {collectionName}" msgstr "Signaler {collectionName}" -#: src/view/com/profile/ProfileHeader.tsx:404 +#: src/view/com/profile/ProfileHeader.tsx:408 msgid "Report Account" msgstr "Signaler le compte" -#: src/view/screens/ProfileFeed.tsx:291 +#: src/view/screens/ProfileFeed.tsx:301 msgid "Report feed" msgstr "Signaler le fil d’actu" -#: src/view/screens/ProfileList.tsx:426 +#: src/view/screens/ProfileList.tsx:437 msgid "Report List" msgstr "Signaler la liste" #: src/view/com/modals/report/SendReportButton.tsx:37 -#: src/view/com/util/forms/PostDropdownBtn.tsx:196 +#: src/view/com/util/forms/PostDropdownBtn.tsx:208 msgid "Report post" msgstr "Signaler le post" +#: 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 "" + #: src/view/com/util/post-ctrls/RepostButton.web.tsx:48 msgid "Repost" msgstr "Republier" @@ -1803,12 +2757,28 @@ msgstr "Republier ou citer" msgid "Reposted by" msgstr "Republié par" +#: src/view/com/posts/FeedItem.tsx:206 +msgid "Reposted by {0})" +msgstr "" + +#: src/view/com/posts/FeedItem.tsx:223 +msgid "Reposted by <0/>" +msgstr "" + +#: src/view/com/notifications/FeedItem.tsx:162 +msgid "reposted your post" +msgstr "" + +#: src/view/com/post-thread/PostThreadItem.tsx:189 +msgid "Reposts of this post" +msgstr "" + #: src/view/com/modals/ChangeEmail.tsx:181 #: src/view/com/modals/ChangeEmail.tsx:183 msgid "Request Change" msgstr "Demande de modification" -#: src/view/screens/Settings.tsx:422 +#: src/view/screens/Settings.tsx:437 msgid "Require alt text before posting" msgstr "Nécessiter un texte alt avant de publier" @@ -1816,45 +2786,77 @@ msgstr "Nécessiter un texte alt avant de publier" msgid "Required for this provider" msgstr "Obligatoire pour ce fournisseur" +#: src/view/com/auth/login/SetNewPasswordForm.tsx:98 #: src/view/com/auth/login/SetNewPasswordForm.tsx:108 msgid "Reset code" msgstr "Réinitialiser le code" -#: src/view/screens/Settings.tsx:719 +#: src/view/screens/Settings.tsx:733 +msgid "Reset onboarding" +msgstr "" + +#: src/view/screens/Settings.tsx:736 msgid "Reset onboarding state" msgstr "Réinitialisation de l’état d’accueil" -#: src/view/com/auth/login/ForgotPasswordForm.tsx:98 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:100 msgid "Reset password" msgstr "Réinitialiser mot de passe" -#: src/view/screens/Settings.tsx:709 +#: src/view/screens/Settings.tsx:723 +msgid "Reset preferences" +msgstr "" + +#: src/view/screens/Settings.tsx:726 msgid "Reset preferences state" msgstr "Réinitialiser l’état des préférences" -#: src/view/screens/Settings.tsx:717 +#: src/view/screens/Settings.tsx:734 msgid "Resets the onboarding state" msgstr "Réinitialise l’état d’accueil" -#: src/view/screens/Settings.tsx:707 +#: src/view/screens/Settings.tsx:724 msgid "Resets the preferences state" msgstr "Réinitialise l’état des préférences" +#: src/view/com/auth/login/LoginForm.tsx:266 +msgid "Retries login" +msgstr "" + +#: src/view/com/util/error/ErrorMessage.tsx:57 +#: src/view/com/util/error/ErrorScreen.tsx:67 +msgid "Retries the last action, which errored out" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:163 #: src/view/com/auth/create/CreateAccount.tsx:167 -#: src/view/com/auth/login/LoginForm.tsx:263 -#: src/view/com/auth/login/LoginForm.tsx:266 +#: src/view/com/auth/login/LoginForm.tsx:265 +#: src/view/com/auth/login/LoginForm.tsx:268 #: src/view/com/util/error/ErrorMessage.tsx:55 #: src/view/com/util/error/ErrorScreen.tsx:65 msgid "Retry" msgstr "Réessayer" +#: src/view/screens/ProfileList.tsx:877 +msgid "Return to previous page" +msgstr "" + +#: src/view/shell/desktop/RightNav.tsx:59 +msgid "SANDBOX. Posts and accounts are not permanent." +msgstr "" + +#: src/view/com/lightbox/Lightbox.tsx:125 +#: src/view/com/modals/CreateOrEditList.tsx:278 +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:249 -#: src/view/com/modals/CreateOrEditList.tsx:257 -#: src/view/com/modals/EditProfile.tsx:223 +#: src/view/com/modals/CreateOrEditList.tsx:270 +#: src/view/com/modals/EditProfile.tsx:224 +#: src/view/screens/ProfileFeed.tsx:354 msgid "Save" msgstr "Enregistrer" @@ -1862,7 +2864,7 @@ msgstr "Enregistrer" msgid "Save alt text" msgstr "Enregistrer le texte alt" -#: src/view/com/modals/EditProfile.tsx:231 +#: src/view/com/modals/EditProfile.tsx:232 msgid "Save Changes" msgstr "Enregistrer les modifications" @@ -1878,9 +2880,25 @@ msgstr "Enregistrer le recadrage de l’image" msgid "Saved Feeds" msgstr "Fils d’actu enregistrés" +#: src/view/com/modals/EditProfile.tsx:225 +msgid "Saves any changes to your profile" +msgstr "" + +#: src/view/com/modals/ChangeHandle.tsx:171 +msgid "Saves handle change to {handle}" +msgstr "" + +#: src/view/screens/ProfileList.tsx:833 +msgid "Scroll to top" +msgstr "" + +#: src/Navigation.tsx:437 +#: src/view/com/auth/LoggedOut.tsx:122 #: src/view/com/modals/ListAddRemoveUsers.tsx:75 +#: src/view/com/util/forms/SearchInput.tsx:53 #: src/view/com/util/forms/SearchInput.tsx:65 #: src/view/screens/Search/Search.tsx:406 +#: src/view/screens/Search/Search.tsx:559 #: src/view/screens/Search/Search.tsx:572 #: src/view/shell/bottom-bar/BottomBar.tsx:159 #: src/view/shell/desktop/LeftNav.tsx:324 @@ -1893,6 +2911,7 @@ msgstr "Recherche" #: 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 "Rechercher des utilisateurs" @@ -1900,10 +2919,18 @@ msgstr "Rechercher des utilisateurs" msgid "Security Step Required" msgstr "Étape de sécurité requise" +#: src/view/screens/SavedFeeds.tsx:163 +msgid "See this guide" +msgstr "" + #: src/view/com/auth/HomeLoggedOutCTA.tsx:39 msgid "See what's next" msgstr "Voir la suite" +#: src/view/com/util/Selector.tsx:106 +msgid "Select {item}" +msgstr "" + #: src/view/com/modals/ServerInput.tsx:75 msgid "Select Bluesky Social" msgstr "Sélectionner Bluesky Social" @@ -1912,6 +2939,10 @@ msgstr "Sélectionner Bluesky Social" msgid "Select from an existing account" msgstr "Sélectionner un compte existant" +#: src/view/com/util/Selector.tsx:107 +msgid "Select option {i} of {numItems}" +msgstr "" + #: src/view/com/auth/login/LoginForm.tsx:147 msgid "Select service" msgstr "Sélectionner un service" @@ -1928,7 +2959,8 @@ msgstr "Sélectionnez la langue de votre application à afficher par défaut" msgid "Select your preferred language for translations in your feed." msgstr "Sélectionnez votre langue préférée pour traduire votre fils d’actu." -#: src/view/com/modals/VerifyEmail.tsx:196 +#: src/view/com/modals/VerifyEmail.tsx:202 +#: src/view/com/modals/VerifyEmail.tsx:204 msgid "Send Confirmation Email" msgstr "Envoyer un e-mail de confirmation" @@ -1936,9 +2968,14 @@ msgstr "Envoyer un e-mail de confirmation" msgid "Send email" msgstr "Envoyer e-mail" -#: src/view/com/modals/DeleteAccount.tsx:138 +#: src/view/com/modals/DeleteAccount.tsx:140 +msgctxt "action" msgid "Send Email" -msgstr "Envoyer e-mail" +msgstr "" + +#: src/view/com/modals/DeleteAccount.tsx:138 +#~ msgid "Send Email" +#~ msgstr "Envoyer e-mail" #: src/view/shell/Drawer.tsx:295 #: src/view/shell/Drawer.tsx:316 @@ -1949,19 +2986,49 @@ msgstr "Envoyer des commentaires" msgid "Send Report" msgstr "Envoyer le rapport" +#: src/view/com/modals/DeleteAccount.tsx:129 +msgid "Sends email with confirmation code for account deletion" +msgstr "" + +#: src/view/com/modals/ContentFilteringSettings.tsx:306 +msgid "Set {value} for {labelGroup} content moderation policy" +msgstr "" + +#: src/view/com/modals/ContentFilteringSettings.tsx:155 +#: src/view/com/modals/ContentFilteringSettings.tsx:174 +msgctxt "action" +msgid "Set Age" +msgstr "" + +#: src/view/screens/Settings.tsx:469 +msgid "Set color theme to dark" +msgstr "" + +#: src/view/screens/Settings.tsx:462 +msgid "Set color theme to light" +msgstr "" + +#: src/view/screens/Settings.tsx:456 +msgid "Set color theme to system setting" +msgstr "" + #: src/view/com/auth/login/SetNewPasswordForm.tsx:78 msgid "Set new password" msgstr "Définir un nouveau mot de passe" -#: src/view/screens/PreferencesHomeFeed.tsx:222 +#: src/view/com/auth/create/Step2.tsx:133 +msgid "Set password" +msgstr "" + +#: src/view/screens/PreferencesHomeFeed.tsx:225 msgid "Set this setting to \"No\" to hide all quote posts from your feed. Reposts will still be visible." msgstr "Choisissez « Non » pour cacher toutes les citations sur votre fils d’actu. Les reposts seront toujours visibles." -#: src/view/screens/PreferencesHomeFeed.tsx:119 +#: src/view/screens/PreferencesHomeFeed.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." -#: src/view/screens/PreferencesHomeFeed.tsx:188 +#: src/view/screens/PreferencesHomeFeed.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." @@ -1969,14 +3036,35 @@ msgstr "Choisissez « Non » pour cacher toutes les reposts de votre fils d’ 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:258 +#: 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." -#: src/view/screens/Settings.tsx:277 +#: src/view/com/modals/ChangeHandle.tsx:266 +msgid "Sets Bluesky username" +msgstr "" + +#: src/view/com/auth/login/ForgotPasswordForm.tsx:153 +msgid "Sets email for password reset" +msgstr "" + +#: src/view/com/auth/login/ForgotPasswordForm.tsx:118 +msgid "Sets hosting provider for password reset" +msgstr "" + +#: src/view/com/auth/create/Step1.tsx:143 +msgid "Sets hosting provider to {label}" +msgstr "" + +#: src/view/com/auth/login/LoginForm.tsx:148 +msgid "Sets server for the Bluesky client" +msgstr "" + +#: src/Navigation.tsx:136 +#: src/view/screens/Settings.tsx:287 #: src/view/shell/desktop/LeftNav.tsx:433 -#: src/view/shell/Drawer.tsx:565 -#: src/view/shell/Drawer.tsx:566 +#: src/view/shell/Drawer.tsx:567 +#: src/view/shell/Drawer.tsx:568 msgid "Settings" msgstr "Paramètres" @@ -1984,21 +3072,32 @@ msgstr "Paramètres" msgid "Sexual activity or erotic nudity." msgstr "Activité sexuelle ou nudité érotique." -#: src/view/com/profile/ProfileHeader.tsx:338 -#: src/view/com/util/forms/PostDropdownBtn.tsx:139 -#: src/view/screens/ProfileList.tsx:385 +#: src/view/com/lightbox/Lightbox.tsx:134 +msgctxt "action" +msgid "Share" +msgstr "" + +#: src/view/com/profile/ProfileHeader.tsx:342 +#: src/view/com/util/forms/PostDropdownBtn.tsx:151 +#: src/view/screens/ProfileList.tsx:396 msgid "Share" msgstr "Partager" -#: src/view/screens/ProfileFeed.tsx:303 +#: src/view/screens/ProfileFeed.tsx:313 msgid "Share feed" msgstr "Partager le fil d’actu" -#: src/view/com/util/moderation/ContentHider.tsx:105 -#: src/view/screens/Settings.tsx:316 +#: src/view/com/modals/ContentFilteringSettings.tsx:261 +#: src/view/com/util/moderation/ContentHider.tsx:107 +#: src/view/com/util/moderation/PostHider.tsx:108 +#: src/view/screens/Settings.tsx:331 msgid "Show" msgstr "Afficher" +#: src/view/screens/PreferencesHomeFeed.tsx:68 +msgid "Show all replies" +msgstr "" + #: src/view/com/util/moderation/ScreenHider.tsx:132 msgid "Show anyway" msgstr "Afficher quand même" @@ -2007,15 +3106,25 @@ msgstr "Afficher quand même" msgid "Show embeds from {0}" msgstr "" -#: src/view/screens/PreferencesHomeFeed.tsx:255 +#: src/view/com/profile/ProfileHeader.tsx:498 +msgid "Show follows similar to {0}" +msgstr "" + +#: src/view/com/post-thread/PostThreadItem.tsx:569 +#: src/view/com/post/Post.tsx:196 +#: src/view/com/posts/FeedItem.tsx:362 +msgid "Show More" +msgstr "" + +#: src/view/screens/PreferencesHomeFeed.tsx:258 msgid "Show Posts from My Feeds" msgstr "Afficher les posts de mes fils d’actu" -#: src/view/screens/PreferencesHomeFeed.tsx:219 +#: src/view/screens/PreferencesHomeFeed.tsx:222 msgid "Show Quote Posts" msgstr "Afficher les posts de citation" -#: src/view/screens/PreferencesHomeFeed.tsx:116 +#: src/view/screens/PreferencesHomeFeed.tsx:119 msgid "Show Replies" msgstr "Afficher les réponses" @@ -2023,14 +3132,31 @@ msgstr "Afficher les réponses" msgid "Show replies by people you follow before all other replies." msgstr "Afficher les réponses des personnes que vous suivez avant toutes les autres réponses." -#: src/view/screens/PreferencesHomeFeed.tsx:185 +#: src/view/screens/PreferencesHomeFeed.tsx:70 +msgid "Show replies with at least {value} {0}" +msgstr "" + +#: src/view/screens/PreferencesHomeFeed.tsx:188 msgid "Show Reposts" msgstr "Afficher les reposts" -#: src/view/com/notifications/FeedItem.tsx:345 +#: src/view/com/util/moderation/ContentHider.tsx:67 +#: src/view/com/util/moderation/PostHider.tsx:61 +msgid "Show the content" +msgstr "" + +#: src/view/com/notifications/FeedItem.tsx:350 msgid "Show users" msgstr "Afficher les utilisateurs" +#: src/view/com/profile/ProfileHeader.tsx:501 +msgid "Shows a list of users similar to this user." +msgstr "" + +#: src/view/com/profile/ProfileHeader.tsx:545 +msgid "Shows posts from {0} in your feed" +msgstr "" + #: src/view/com/auth/HomeLoggedOutCTA.tsx:70 #: src/view/com/auth/login/Login.tsx:98 #: src/view/com/auth/SplashScreen.tsx:54 @@ -2065,7 +3191,9 @@ msgid "Sign into" msgstr "Se connecter à" #: src/view/com/modals/SwitchAccount.tsx:64 -#: src/view/com/modals/SwitchAccount.tsx:67 +#: src/view/com/modals/SwitchAccount.tsx:69 +#: src/view/screens/Settings.tsx:102 +#: src/view/screens/Settings.tsx:105 msgid "Sign out" msgstr "Déconnexion" @@ -2089,14 +3217,34 @@ msgstr "S’inscrire ou se connecter pour participer à la conversation" msgid "Sign-in Required" msgstr "Connexion requise" -#: src/view/screens/Settings.tsx:327 +#: src/view/screens/Settings.tsx:342 msgid "Signed in as" msgstr "Connecté en tant que" +#: src/view/com/auth/login/ChooseAccountForm.tsx:103 +msgid "Signed in as @{0}" +msgstr "" + +#: src/view/com/modals/SwitchAccount.tsx:66 +msgid "Signs {0} out of Bluesky" +msgstr "" + #: src/view/com/auth/onboarding/WelcomeMobile.tsx:33 msgid "Skip" msgstr "Ignorer" +#: 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 "" + +#: src/App.native.tsx:57 +msgid "Sorry! Your session expired. Please log in again." +msgstr "" + #: src/view/screens/PreferencesThreads.tsx:69 msgid "Sort Replies" msgstr "Trier les réponses" @@ -2114,11 +3262,19 @@ msgstr "Carré" msgid "Staging" msgstr "Mise en scène" -#: src/view/screens/Settings.tsx:763 +#: src/view/screens/Settings.tsx:780 msgid "Status page" msgstr "Page de statut" -#: src/view/screens/Settings.tsx:699 +#: src/view/com/auth/create/StepHeader.tsx:15 +msgid "Step {step} of 3" +msgstr "" + +#: src/view/screens/Settings.tsx:269 +msgid "Storage cleared, you need to restart the app now." +msgstr "" + +#: src/view/screens/Settings.tsx:716 msgid "Storybook" msgstr "Historique" @@ -2126,28 +3282,59 @@ msgstr "Historique" msgid "Submit" msgstr "Envoyer" -#: src/view/screens/ProfileList.tsx:575 +#: src/view/screens/ProfileList.tsx:586 msgid "Subscribe" msgstr "S’abonner" -#: src/view/screens/ProfileList.tsx:571 +#: src/view/screens/ProfileList.tsx:582 msgid "Subscribe to this list" msgstr "S’abonner à cette liste" +#: src/view/com/lists/ListCard.tsx:101 +msgid "Subscribed" +msgstr "" + #: src/view/screens/Search/Search.tsx:362 msgid "Suggested Follows" msgstr "Suivis suggérés" +#: src/view/com/profile/ProfileHeaderSuggestedFollows.tsx:64 +msgid "Suggested for you" +msgstr "" + +#: src/view/com/modals/SelfLabel.tsx:95 +msgid "Suggestive" +msgstr "" + +#: src/Navigation.tsx:214 #: src/view/screens/Support.tsx:30 #: src/view/screens/Support.tsx:33 msgid "Support" msgstr "Soutien" -#: src/view/com/modals/SwitchAccount.tsx:115 +#: 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 "Changer de compte" -#: src/view/screens/Settings.tsx:679 +#: src/view/com/modals/SwitchAccount.tsx:97 +#: src/view/screens/Settings.tsx:132 +msgid "Switch to {0}" +msgstr "" + +#: src/view/com/modals/SwitchAccount.tsx:98 +#: src/view/screens/Settings.tsx:133 +msgid "Switches the account you are logged in to" +msgstr "" + +#: src/view/screens/Settings.tsx:453 +msgid "System" +msgstr "" + +#: src/view/screens/Settings.tsx:696 msgid "System log" msgstr "Journal système" @@ -2155,11 +3342,16 @@ msgstr "Journal système" msgid "Tall" msgstr "Grand" +#: src/view/com/util/images/AutoSizedImage.tsx:70 +msgid "Tap to view fully" +msgstr "" + #: src/view/shell/desktop/RightNav.tsx:93 msgid "Terms" msgstr "Conditions générales" -#: src/view/screens/Settings.tsx:777 +#: src/Navigation.tsx:224 +#: src/view/screens/Settings.tsx:794 #: src/view/screens/TermsOfService.tsx:29 #: src/view/shell/Drawer.tsx:256 msgid "Terms of Service" @@ -2170,7 +3362,7 @@ msgstr "Conditions d’utilisation" msgid "Text input field" msgstr "Champ de saisie de texte" -#: src/view/com/profile/ProfileHeader.tsx:306 +#: src/view/com/profile/ProfileHeader.tsx:310 msgid "The account will be able to interact with you after unblocking." msgstr "Ce compte pourra interagir avec vous après le déblocage." @@ -2182,7 +3374,7 @@ msgstr "Les lignes directrices communautaires ont été déplacées vers <0/>" msgid "The Copyright Policy has been moved to <0/>" msgstr "Notre politique de droits d’auteur a été déplacée vers <0/>" -#: src/view/com/post-thread/PostThread.tsx:433 +#: src/view/com/post-thread/PostThread.tsx:437 msgid "The post may have been deleted." msgstr "Ce post a peut-être été supprimé." @@ -2191,13 +3383,86 @@ msgid "The Privacy Policy has been moved to <0/>" msgstr "Notre politique de confidentialité a été déplacée vers <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 "Le formulaire d’assistance a été déplacé. Si vous avez besoin d’aide, veuillez <0/> ou rendez-vous sur {HELP_DESK_URL} pour nous contacter." +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 "Le formulaire d’assistance a été déplacé. Si vous avez besoin d’aide, veuillez <0/> ou rendez-vous sur {HELP_DESK_URL} pour nous contacter." #: src/view/screens/TermsOfService.tsx:33 msgid "The Terms of Service have been moved to" msgstr "Nos conditions d’utilisation ont été déplacées vers" +#: src/view/screens/ProfileFeed.tsx:558 +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 +msgid "There was an an issue removing this feed. Please check your internet connection and try again." +msgstr "" + +#: src/view/screens/ProfileFeed.tsx:218 +msgid "There was an an issue updating your feeds, please check your internet connection and try again." +msgstr "" + +#: src/view/screens/ProfileFeed.tsx:245 +#: src/view/screens/ProfileList.tsx:266 +#: src/view/screens/SavedFeeds.tsx:209 +#: src/view/screens/SavedFeeds.tsx:231 +#: src/view/screens/SavedFeeds.tsx:252 +msgid "There was an issue contacting the server" +msgstr "" + +#: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:57 +#: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:66 +#: src/view/com/feeds/FeedSourceCard.tsx:113 +#: src/view/com/feeds/FeedSourceCard.tsx:127 +#: src/view/com/feeds/FeedSourceCard.tsx:181 +msgid "There was an issue contacting your server" +msgstr "" + +#: src/view/com/notifications/Feed.tsx:115 +msgid "There was an issue fetching notifications. Tap here to try again." +msgstr "" + +#: src/view/com/posts/Feed.tsx:261 +msgid "There was an issue fetching posts. Tap here to try again." +msgstr "" + +#: src/view/com/lists/ListMembers.tsx:172 +msgid "There was an issue fetching the list. Tap here to try again." +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 "" + +#: src/view/com/modals/ContentFilteringSettings.tsx:126 +msgid "There was an issue syncing your preferences with the server" +msgstr "" + +#: src/view/screens/AppPasswords.tsx:66 +msgid "There was an issue with fetching your app passwords" +msgstr "" + +#: src/view/com/profile/ProfileHeader.tsx:204 +#: src/view/com/profile/ProfileHeader.tsx:225 +#: src/view/com/profile/ProfileHeader.tsx:264 +#: src/view/com/profile/ProfileHeader.tsx:277 +#: src/view/com/profile/ProfileHeader.tsx:297 +#: src/view/com/profile/ProfileHeader.tsx:319 +msgid "There was an issue! {0}" +msgstr "" + +#: src/view/screens/ProfileList.tsx:287 +#: src/view/screens/ProfileList.tsx:306 +#: src/view/screens/ProfileList.tsx:328 +#: src/view/screens/ProfileList.tsx:347 +msgid "There was an issue. Please check your internet connection and try again." +msgstr "" + #: src/view/com/util/ErrorBoundary.tsx:35 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é !" @@ -2217,19 +3482,33 @@ msgstr "Ce compte a demandé aux utilisateurs de s’identifier pour voir son pr msgid "This content is hosted by {0}. Do you want to enable external media?" msgstr "" -#: src/view/com/posts/FeedErrorMessage.tsx:107 +#: src/view/com/modals/ModerationDetails.tsx:67 +msgid "This content is not available because one of the users involved has blocked the other." +msgstr "" + +#: src/view/com/posts/FeedErrorMessage.tsx:108 msgid "This content is not viewable without a Bluesky account." msgstr "Ce contenu n’est pas visible sans un compte Bluesky." -#: src/view/com/posts/FeedErrorMessage.tsx:113 +#: src/view/com/posts/FeedErrorMessage.tsx:114 msgid "This feed is currently receiving high traffic and is temporarily unavailable. Please try again later." msgstr "Ce fil d’actu reçoit actuellement un trafic important, il est temporairement indisponible. Veuillez réessayer plus tard." +#: src/view/screens/Profile.tsx:392 +#: src/view/screens/ProfileFeed.tsx:484 +#: src/view/screens/ProfileList.tsx:639 +msgid "This feed is empty!" +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 "" + #: src/view/com/modals/BirthDateSettings.tsx:61 msgid "This information is not shared with other users." msgstr "Ces informations ne sont pas partagées avec d’autres utilisateurs." -#: src/view/com/modals/VerifyEmail.tsx:113 +#: 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 "Ceci est important au cas où vous auriez besoin de changer d’e-mail ou de réinitialiser votre mot de passe." @@ -2241,20 +3520,40 @@ msgstr "C’est le service qui vous permet de rester en ligne." msgid "This link is taking you to the following website:" msgstr "Ce lien vous conduit au site Web suivant :" +#: src/view/screens/ProfileList.tsx:813 +msgid "This list is empty!" +msgstr "" + +#: src/view/com/modals/AddAppPasswords.tsx:105 +msgid "This name is already in use" +msgstr "" + #: src/view/com/post-thread/PostThreadItem.tsx:123 msgid "This post has been deleted." msgstr "Ce post a été supprimé." +#: src/view/com/modals/ModerationDetails.tsx:62 +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 "" + +#: 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 "Cet avertissement n’est disponible que pour les messages contenant des médias." -#: src/view/com/util/forms/PostDropdownBtn.tsx:178 +#: src/view/com/util/forms/PostDropdownBtn.tsx:190 msgid "This will hide this post from your feeds." msgstr "Cela va masquer ce post de vos fils d’actu." #: src/view/screens/PreferencesThreads.tsx:53 -#: src/view/screens/Settings.tsx:503 +#: src/view/screens/Settings.tsx:518 msgid "Thread Preferences" msgstr "Préférences des fils de discussion" @@ -2262,7 +3561,11 @@ msgstr "Préférences des fils de discussion" msgid "Threaded Mode" msgstr "Mode arborescent" -#: src/view/com/util/forms/DropdownButton.tsx:230 +#: src/Navigation.tsx:254 +msgid "Threads Preferences" +msgstr "" + +#: src/view/com/util/forms/DropdownButton.tsx:234 msgid "Toggle dropdown" msgstr "Activer le menu déroulant" @@ -2270,60 +3573,100 @@ msgstr "Activer le menu déroulant" msgid "Transformations" msgstr "Transformations" -#: src/view/com/post-thread/PostThreadItem.tsx:705 -#: src/view/com/post-thread/PostThreadItem.tsx:707 -#: src/view/com/util/forms/PostDropdownBtn.tsx:111 +#: src/view/com/post-thread/PostThreadItem.tsx:710 +#: src/view/com/post-thread/PostThreadItem.tsx:712 +#: src/view/com/util/forms/PostDropdownBtn.tsx:123 msgid "Translate" msgstr "Traduire" -#: src/view/com/util/error/ErrorScreen.tsx:73 +#: src/view/com/util/error/ErrorScreen.tsx:75 +msgctxt "action" msgid "Try again" -msgstr "Réessayer" +msgstr "" -#: src/view/screens/ProfileList.tsx:473 +#: src/view/com/util/error/ErrorScreen.tsx:73 +#~ msgid "Try again" +#~ msgstr "Réessayer" + +#: src/view/screens/ProfileList.tsx:484 msgid "Un-block list" msgstr "Débloquer la liste" -#: src/view/screens/ProfileList.tsx:458 +#: src/view/screens/ProfileList.tsx:469 msgid "Un-mute list" msgstr "Réafficher cette liste" #: src/view/com/auth/create/CreateAccount.tsx:65 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:87 #: src/view/com/auth/login/Login.tsx:76 #: src/view/com/auth/login/LoginForm.tsx:120 msgid "Unable to contact your service. Please check your Internet connection." msgstr "Impossible de contacter votre service. Veuillez vérifier votre connexion Internet." -#: src/view/com/profile/ProfileHeader.tsx:466 -#: src/view/com/profile/ProfileHeader.tsx:469 +#: src/view/com/profile/ProfileHeader.tsx:475 +msgctxt "action" +msgid "Unblock" +msgstr "" + +#: src/view/com/profile/ProfileHeader.tsx:472 +#: src/view/screens/ProfileList.tsx:568 msgid "Unblock" msgstr "Débloquer" -#: src/view/com/profile/ProfileHeader.tsx:304 -#: src/view/com/profile/ProfileHeader.tsx:388 +#: src/view/com/profile/ProfileHeader.tsx:308 +#: src/view/com/profile/ProfileHeader.tsx:392 msgid "Unblock Account" msgstr "Débloquer le compte" +#: 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 "Annuler le repost" +#: src/view/com/profile/FollowButton.tsx:55 +msgctxt "action" +msgid "Unfollow" +msgstr "" + +#: src/view/com/profile/ProfileHeader.tsx:524 +msgid "Unfollow {0}" +msgstr "" + #: src/view/com/auth/create/state.ts:216 msgid "Unfortunately, you do not meet the requirements to create an account." msgstr "Malheureusement, vous ne remplissez pas les conditions requises pour créer un compte." -#: src/view/com/profile/ProfileHeader.tsx:369 +#: src/view/com/util/post-ctrls/PostCtrls.tsx:189 +msgid "Unlike" +msgstr "" + +#: src/view/screens/ProfileList.tsx:575 +msgid "Unmute" +msgstr "" + +#: src/view/com/profile/ProfileHeader.tsx:373 msgid "Unmute Account" msgstr "Réafficher ce compte" -#: src/view/com/util/forms/PostDropdownBtn.tsx:157 +#: src/view/com/util/forms/PostDropdownBtn.tsx:169 msgid "Unmute thread" msgstr "Réafficher ce fil de discussion" -#: src/view/screens/ProfileList.tsx:441 +#: src/view/screens/ProfileFeed.tsx:362 +#: src/view/screens/ProfileList.tsx:559 +msgid "Unpin" +msgstr "" + +#: src/view/screens/ProfileList.tsx:452 msgid "Unpin moderation list" msgstr "Supprimer la liste de modération" +#: src/view/screens/ProfileFeed.tsx:354 +msgid "Unsave" +msgstr "" + #: src/view/com/modals/UserAddRemoveLists.tsx:54 msgid "Update {displayName} in Lists" msgstr "Mise à jour de {displayName} dans les listes" @@ -2332,34 +3675,73 @@ msgstr "Mise à jour de {displayName} dans les listes" msgid "Update Available" msgstr "Mise à jour disponible" -#: src/view/com/auth/login/SetNewPasswordForm.tsx:172 +#: src/view/com/auth/login/SetNewPasswordForm.tsx:174 msgid "Updating..." msgstr "Mise à jour…" -#: src/view/com/modals/ChangeHandle.tsx:453 +#: src/view/com/modals/ChangeHandle.tsx:455 msgid "Upload a text file to:" msgstr "Télécharger un fichier texte vers :" -#: src/view/screens/AppPasswords.tsx:194 +#: 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 "Utiliser les mots de passe de l’appli pour se connecter à d’autres clients Bluesky sans donner un accès complet à votre compte ou à votre mot de passe." -#: src/view/com/modals/ChangeHandle.tsx:513 +#: src/view/com/modals/ChangeHandle.tsx:515 msgid "Use default provider" msgstr "Utiliser le fournisseur par défaut" -#: src/view/com/modals/AddAppPasswords.tsx:150 +#: src/view/com/modals/AddAppPasswords.tsx:154 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/InviteCodes.tsx:197 +#: 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 "Utilisé par :" +#: src/view/com/modals/ModerationDetails.tsx:54 +msgid "User Blocked" +msgstr "" + +#: src/view/com/modals/ModerationDetails.tsx:40 +msgid "User Blocked by List" +msgstr "" + +#: src/view/com/modals/ModerationDetails.tsx:60 +msgid "User Blocks You" +msgstr "" + #: src/view/com/auth/create/Step3.tsx:38 msgid "User handle" msgstr "Pseudo utilisateur" +#: src/view/com/lists/ListCard.tsx:84 +#: src/view/com/modals/UserAddRemoveLists.tsx:182 +msgid "User list by {0}" +msgstr "" + +#: src/view/screens/ProfileList.tsx:741 +msgid "User list by <0/>" +msgstr "" + +#: src/view/com/lists/ListCard.tsx:82 +#: src/view/com/modals/UserAddRemoveLists.tsx:180 +#: src/view/screens/ProfileList.tsx:739 +msgid "User list by you" +msgstr "" + +#: src/view/com/modals/CreateOrEditList.tsx:138 +msgid "User list created" +msgstr "" + +#: src/view/com/modals/CreateOrEditList.tsx:125 +msgid "User list updated" +msgstr "" + #: src/view/screens/Lists.tsx:58 msgid "User Lists" msgstr "Listes d’utilisateurs" @@ -2369,7 +3751,7 @@ msgstr "Listes d’utilisateurs" msgid "Username or email address" msgstr "Nom d’utilisateur ou e-mail" -#: src/view/screens/ProfileList.tsx:747 +#: src/view/screens/ProfileList.tsx:775 msgid "Users" msgstr "Utilisateurs" @@ -2381,15 +3763,15 @@ msgstr "utilisateurs suivis par <0/>" msgid "Users in \"{0}\"" msgstr "Utilisateurs dans « {0} »" -#: src/view/screens/Settings.tsx:802 +#: src/view/screens/Settings.tsx:819 msgid "Verify email" msgstr "Confirmer l’e-mail" -#: src/view/screens/Settings.tsx:827 +#: src/view/screens/Settings.tsx:844 msgid "Verify my email" msgstr "Confirmer mon e-mail" -#: src/view/screens/Settings.tsx:836 +#: src/view/screens/Settings.tsx:853 msgid "Verify My Email" msgstr "Confirmer mon e-mail" @@ -2398,10 +3780,26 @@ msgstr "Confirmer mon e-mail" msgid "Verify New Email" msgstr "Confirmer le nouvel e-mail" +#: src/view/com/modals/VerifyEmail.tsx:103 +msgid "Verify Your Email" +msgstr "" + +#: src/view/com/profile/ProfileHeader.tsx:701 +msgid "View {0}'s avatar" +msgstr "" + #: src/view/screens/Log.tsx:52 msgid "View debug entry" msgstr "Afficher l’entrée de débogage" +#: src/view/com/posts/FeedSlice.tsx:103 +msgid "View full thread" +msgstr "" + +#: src/view/com/posts/FeedErrorMessage.tsx:172 +msgid "View profile" +msgstr "" + #: src/view/com/profile/ProfileSubpageHeader.tsx:128 msgid "View the avatar" msgstr "Afficher l’avatar" @@ -2410,10 +3808,22 @@ msgstr "Afficher l’avatar" msgid "Visit Site" msgstr "Visiter le site" +#: src/view/com/modals/ContentFilteringSettings.tsx:254 +msgid "Warn" +msgstr "" + +#: src/view/com/modals/AppealLabel.tsx:48 +msgid "We'll look into your appeal promptly." +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:122 msgid "We're so excited to have you join us!" msgstr "Nous sommes ravis de vous accueillir !" +#: src/view/screens/ProfileList.tsx:83 +msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." +msgstr "" + #: src/view/screens/Search/Search.tsx:243 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "Nous sommes désolés, mais votre recherche a été annulée. Veuillez réessayer dans quelques minutes." @@ -2431,6 +3841,7 @@ msgid "What is the issue with this {collectionName}?" msgstr "Quel est le problème avec cette {collectionName} ?" #: src/view/com/auth/SplashScreen.tsx:34 +#: src/view/com/composer/Composer.tsx:278 msgid "What's up?" msgstr "Quoi de neuf ?" @@ -2451,23 +3862,29 @@ msgstr "Qui peut répondre ?" msgid "Wide" msgstr "Large" -#: src/view/com/composer/Composer.tsx:418 +#: src/view/com/composer/Composer.tsx:414 msgid "Write post" msgstr "Rédiger un post" +#: src/view/com/composer/Composer.tsx:277 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "Rédigez votre réponse" -#: src/view/screens/PreferencesHomeFeed.tsx:126 -#: src/view/screens/PreferencesHomeFeed.tsx:198 -#: src/view/screens/PreferencesHomeFeed.tsx:233 -#: src/view/screens/PreferencesHomeFeed.tsx:268 +#: src/view/screens/PreferencesHomeFeed.tsx:129 +#: src/view/screens/PreferencesHomeFeed.tsx:201 +#: src/view/screens/PreferencesHomeFeed.tsx:236 +#: src/view/screens/PreferencesHomeFeed.tsx:271 #: src/view/screens/PreferencesThreads.tsx:106 #: src/view/screens/PreferencesThreads.tsx:129 msgid "Yes" msgstr "Oui" +#: 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/view/com/auth/create/Step1.tsx:106 msgid "You can change hosting providers at any time." msgstr "Vous pouvez changer d’hébergeur à tout moment." @@ -2477,7 +3894,7 @@ msgstr "Vous pouvez changer d’hébergeur à tout moment." msgid "You can now sign in with your new password." msgstr "Vous pouvez maintenant vous connecter avec votre nouveau mot de passe." -#: src/view/com/modals/InviteCodes.tsx:64 +#: 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." @@ -2485,7 +3902,7 @@ msgstr "Vous n’avez encore aucun code d’invitation ! Nous vous en enverrons msgid "You don't have any pinned feeds." msgstr "Vous n’avez encore aucun fil épinglé." -#: src/view/screens/Feeds.tsx:383 +#: src/view/screens/Feeds.tsx:387 msgid "You don't have any saved feeds!" msgstr "Vous n’avez encore aucun fil enregistré !" @@ -2493,16 +3910,24 @@ msgstr "Vous n’avez encore aucun fil enregistré !" msgid "You don't have any saved feeds." msgstr "Vous n’avez encore aucun fil enregistré." -#: src/view/com/post-thread/PostThread.tsx:381 +#: src/view/com/post-thread/PostThread.tsx:385 msgid "You have blocked the author or you have been blocked by the author." msgstr "Vous avez bloqué cet auteur ou vous avez été bloqué par celui-ci." -#: src/view/com/feeds/ProfileFeedgens.tsx:134 +#: src/view/com/modals/ModerationDetails.tsx:56 +msgid "You have blocked this user. You cannot view their content." +msgstr "" + +#: src/view/com/modals/ModerationDetails.tsx:87 +msgid "You have muted this user." +msgstr "" + +#: src/view/com/feeds/ProfileFeedgens.tsx:136 msgid "You have no feeds." msgstr "Vous n’avez aucun fil." #: src/view/com/lists/MyLists.tsx:89 -#: src/view/com/lists/ProfileLists.tsx:138 +#: src/view/com/lists/ProfileLists.tsx:140 msgid "You have no lists." msgstr "Vous n’avez aucune liste." @@ -2510,7 +3935,7 @@ msgstr "Vous n’avez aucune liste." 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." -#: src/view/screens/AppPasswords.tsx:86 +#: 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 "Vous n’avez encore créé aucun mot de passe pour l’appli. Vous pouvez en créer un en cliquant sur le bouton suivant." @@ -2518,23 +3943,44 @@ msgstr "Vous n’avez encore créé aucun mot de passe pour l’appli. Vous pouv 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." +#: src/view/com/modals/ContentFilteringSettings.tsx:170 +msgid "You must be 18 or older to enable adult content." +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:96 +msgid "You will no longer receive notifications for this thread" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:99 +msgid "You will now receive notifications for this thread" +msgstr "" + #: src/view/com/auth/login/SetNewPasswordForm.tsx:81 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." +#: src/view/com/posts/FollowingEndOfFeed.tsx:48 +msgid "You've reached the end of your feed! Find some more accounts to follow." +msgstr "" + #: src/view/com/auth/create/Step2.tsx:58 msgid "Your account" msgstr "Votre compte" +#: src/view/com/modals/DeleteAccount.tsx:65 +msgid "Your account has been deleted" +msgstr "" + #: src/view/com/auth/create/Step2.tsx:146 msgid "Your birth date" msgstr "Votre date de naissance" #: src/view/com/auth/create/state.ts:102 +#: src/view/com/auth/login/ForgotPasswordForm.tsx:70 msgid "Your email appears to be invalid." msgstr "Votre e-mail semble être invalide." -#: src/view/com/modals/Waitlist.tsx:107 +#: 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." @@ -2542,33 +3988,50 @@ msgstr "Votre e-mail a été enregistré ! Nous vous contacterons bientôt." 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." -#: src/view/com/modals/VerifyEmail.tsx:108 +#: 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 "Votre e-mail n’a pas encore été vérifié. Il s’agit d’une mesure de sécurité importante que nous recommandons." +#: src/view/com/posts/FollowingEmptyState.tsx:47 +msgid "Your following feed is empty! Follow more users to see what's happening." +msgstr "" + #: src/view/com/auth/create/Step3.tsx:42 -#: src/view/com/modals/ChangeHandle.tsx:270 msgid "Your full handle will be" msgstr "Votre nom complet sera" +#: 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 "Votre fournisseur d’hébergement" -#: src/view/screens/Settings.tsx:402 +#: src/view/screens/Settings.tsx:417 #: src/view/shell/desktop/RightNav.tsx:137 -#: src/view/shell/Drawer.tsx:655 +#: src/view/shell/Drawer.tsx:657 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/view/com/composer/Composer.tsx:266 +msgid "Your post has been published" +msgstr "" + +#: 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 "Vos posts, les mentions « J’aime » et les blocages sont publics. Les silences (comptes masqués) sont privés." -#: src/view/com/modals/SwitchAccount.tsx:82 +#: src/view/com/modals/SwitchAccount.tsx:84 +#: src/view/screens/Settings.tsx:120 msgid "Your profile" msgstr "Votre profil" +#: src/view/com/composer/Composer.tsx:265 +msgid "Your reply has been published" +msgstr "" + #: src/view/com/auth/create/Step3.tsx:28 msgid "Your user handle" msgstr "Votre pseudo" From 6734bc325d18f1c3e15a2cdc6aa7e8911682dc7b Mon Sep 17 00:00:00 2001 From: "Stanislas Signoud (Signez)" Date: Fri, 12 Jan 2024 19:48:32 +0100 Subject: [PATCH 02/28] Translate more strings in French --- src/locale/locales/fr/messages.po | 859 ++++++++++++++---------------- 1 file changed, 402 insertions(+), 457 deletions(-) diff --git a/src/locale/locales/fr/messages.po b/src/locale/locales/fr/messages.po index 11bc8f2511..c02b8ac819 100644 --- a/src/locale/locales/fr/messages.po +++ b/src/locale/locales/fr/messages.po @@ -9,34 +9,30 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: \n" -"Last-Translator: \n" +"Last-Translator: Stanislas Signoud (@signez.fr)\n" "Language-Team: \n" "Plural-Forms: \n" #: src/view/com/modals/VerifyEmail.tsx:142 msgid "(no email)" -msgstr "" +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 {# invite code available} other {# invite codes available}}" +msgstr "{0, plural, one {# code d’invitation disponible} other {# codes d’invitations disponibles}}" #: src/view/com/modals/CreateOrEditList.tsx:185 #: src/view/screens/Settings.tsx:287 msgid "{0}" msgstr "{0}" -#: src/view/com/modals/CreateOrEditList.tsx:176 -#~ msgid "{0} {purposeLabel} List" -#~ msgstr "{0} {purposeLabel} Liste" - #: src/view/com/profile/ProfileHeader.tsx:632 msgid "{following} following" -msgstr "" +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 {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:422 #: src/view/shell/Drawer.tsx:661 @@ -54,11 +50,11 @@ msgstr "{message}" #: src/view/shell/Drawer.tsx:440 msgid "{numUnreadNotifications} unread" -msgstr "" +msgstr "{numUnreadNotifications} non lus" #: src/Navigation.tsx:147 msgid "@{0}" -msgstr "" +msgstr "@{0}" #: src/view/com/threadgate/WhoCanReply.tsx:158 msgid "<0/> members" @@ -66,7 +62,7 @@ msgstr "<0/> membres" #: src/view/com/profile/ProfileHeader.tsx:634 msgid "<0>{following} <1>following" -msgstr "" +msgstr "<0>{following} <1>abonné·e·s" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:30 msgid "<0>Choose your<1>Recommended<2>Feeds" @@ -74,15 +70,15 @@ msgstr "<0>Choisissez vos<1>fils d’actualité<2>recommandés" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:37 msgid "<0>Follow some<1>Recommended<2>Users" -msgstr "<0>Suivre certains<1>utilisateurs<2>recommandés" +msgstr "<0>Suivre certains<1>comptes<2>recommandés" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:21 msgid "<0>Welcome to<1>Bluesky" -msgstr "" +msgstr "<0>Bienvenue sur<1>Bluesky" #: src/view/com/profile/ProfileHeader.tsx:597 msgid "⚠Invalid Handle" -msgstr "" +msgstr "⚠Pseudo invalide" #: src/view/com/util/moderation/LabelInfo.tsx:45 msgid "A content warning has been applied to this {0}." @@ -95,11 +91,11 @@ msgstr "Une nouvelle version de l’application est disponible. Veuillez faire l #: src/view/com/util/ViewHeader.tsx:83 #: src/view/screens/Search/Search.tsx:538 msgid "Access navigation links and settings" -msgstr "" +msgstr "Accède aux liens de navigation et aux paramètres" #: src/view/com/pager/FeedsTabBarMobile.tsx:78 msgid "Access profile and other navigation links" -msgstr "" +msgstr "Accède au profil et aux autres liens de navigation" #: src/view/com/modals/EditImage.tsx:299 #: src/view/screens/Settings.tsx:432 @@ -113,19 +109,19 @@ msgstr "Compte" #: src/view/com/profile/ProfileHeader.tsx:293 msgid "Account blocked" -msgstr "" +msgstr "Compte bloqué" #: src/view/com/profile/ProfileHeader.tsx:260 msgid "Account muted" -msgstr "" +msgstr "Compte masqué" #: src/view/com/modals/ModerationDetails.tsx:86 msgid "Account Muted" -msgstr "" +msgstr "Compte masqué" #: src/view/com/modals/ModerationDetails.tsx:72 msgid "Account Muted by List" -msgstr "" +msgstr "Compte masqué par list" #: src/view/com/util/AccountDropdownBtn.tsx:41 msgid "Account options" @@ -133,15 +129,15 @@ msgstr "Options de compte" #: src/view/com/util/AccountDropdownBtn.tsx:25 msgid "Account removed from quick access" -msgstr "" +msgstr "Compte supprimé de l’accès rapide" #: src/view/com/profile/ProfileHeader.tsx:315 msgid "Account unblocked" -msgstr "" +msgstr "Compte débloqué" #: src/view/com/profile/ProfileHeader.tsx:273 msgid "Account unmuted" -msgstr "" +msgstr "Compte démasqué" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 @@ -156,7 +152,7 @@ msgstr "Ajouter un avertissement sur le contenu" #: src/view/screens/ProfileList.tsx:781 msgid "Add a user to this list" -msgstr "Ajouter un utilisateur à cette liste" +msgstr "Ajouter un compte à cette liste" #: src/view/screens/Settings.tsx:370 #: src/view/screens/Settings.tsx:379 @@ -173,7 +169,7 @@ msgstr "Ajouter un texte alt" #: src/view/screens/AppPasswords.tsx:143 #: src/view/screens/AppPasswords.tsx:156 msgid "Add App Password" -msgstr "" +msgstr "Ajouter un mot de passe d’application" #: src/view/com/modals/report/InputIssueDetails.tsx:41 #: src/view/com/modals/report/Modal.tsx:191 @@ -207,7 +203,7 @@ msgstr "Ajouter à mes fils d’actu" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:139 msgid "Added" -msgstr "" +msgstr "Ajouté" #: src/view/com/modals/ListAddRemoveUsers.tsx:191 #: src/view/com/modals/UserAddRemoveLists.tsx:128 @@ -216,7 +212,7 @@ msgstr "Ajouté à la liste" #: src/view/com/feeds/FeedSourceCard.tsx:125 msgid "Added to my feeds" -msgstr "" +msgstr "Ajouté à mes fils d’actu" #: src/view/screens/PreferencesHomeFeed.tsx:173 msgid "Adjust the number of likes a reply must have to be shown in your feed." @@ -228,7 +224,7 @@ msgstr "Contenu pour adultes" #: src/view/com/modals/ContentFilteringSettings.tsx:137 msgid "Adult content can only be enabled via the Web at <0/>." -msgstr "" +msgstr "Le contenu pour adultes ne peut être activé que via le Web à <0/>." #: src/view/screens/Settings.tsx:617 msgid "Advanced" @@ -236,7 +232,7 @@ msgstr "Avancé" #: src/view/com/auth/login/ChooseAccountForm.tsx:98 msgid "Already signed in as @{0}" -msgstr "" +msgstr "Déjà connecté·e en tant que @{0}" #: src/view/com/composer/photos/Gallery.tsx:130 msgid "ALT" @@ -248,7 +244,7 @@ msgstr "Texte Alt" #: 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 "Le texte Alt décrit les images pour les utilisateurs aveugles et malvoyants, et aide à donner un contexte à tout le monde." +msgstr "Le texte Alt décrit les images pour les personnes aveugles et malvoyantes, et aide à donner un contexte à tout le monde." #: 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." @@ -261,7 +257,7 @@ msgstr "Un courriel a été envoyé à votre ancienne adresse, {0}. Il comprend #: src/view/com/profile/FollowButton.tsx:30 #: src/view/com/profile/FollowButton.tsx:40 msgid "An issue occurred, please try again." -msgstr "" +msgstr "Un problème est survenu, veuillez réessayer." #: src/view/com/notifications/FeedItem.tsx:240 #: src/view/com/threadgate/WhoCanReply.tsx:178 @@ -274,19 +270,19 @@ msgstr "Langue de l’application" #: src/view/screens/AppPasswords.tsx:228 msgid "App password deleted" -msgstr "" +msgstr "Mot de passe d’application supprimé" #: src/view/com/modals/AddAppPasswords.tsx:133 msgid "App Password names can only contain letters, numbers, spaces, dashes, and underscores." -msgstr "" +msgstr "Les noms de mots de passe d’application ne peuvent contenir que des lettres, des chiffres, des espaces, des tirets et des tirets bas." #: src/view/com/modals/AddAppPasswords.tsx:98 msgid "App Password names must be at least 4 characters long." -msgstr "" +msgstr "Les noms de mots de passe d’application doivent comporter au moins 4 caractères." #: src/view/screens/Settings.tsx:628 msgid "App password settings" -msgstr "" +msgstr "Paramètres de mot de passe d’application" #: src/view/screens/Settings.tsx:637 msgid "App passwords" @@ -305,9 +301,6 @@ msgstr "Faire appel de l’avertissement sur le contenu" msgid "Appeal Content Warning" msgstr "Appel de l’avertissement sur le contenu" -#~ msgid "Appeal Decision" -#~ msgstr "Appel de la décision" - #: src/view/com/util/moderation/LabelInfo.tsx:52 msgid "Appeal this decision" msgstr "Faire appel de cette décision" @@ -343,7 +336,7 @@ msgstr "Nudité artistique ou non érotique." #: src/view/com/post-thread/PostThread.tsx:400 msgctxt "action" msgid "Back" -msgstr "" +msgstr "Retour" #: src/view/com/auth/create/CreateAccount.tsx:141 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 @@ -391,11 +384,11 @@ msgstr "Bloquer ces comptes ?" #: src/view/screens/ProfileList.tsx:319 msgid "Block this List" -msgstr "" +msgstr "Bloquer cette liste" #: src/view/com/util/post-embeds/QuoteEmbed.tsx:57 msgid "Blocked" -msgstr "" +msgstr "Bloqué" #: src/view/screens/Moderation.tsx:123 msgid "Blocked accounts" @@ -451,7 +444,7 @@ msgstr "Bluesky distribue des invitations pour construire une communauté plus s #: src/view/screens/Moderation.tsx:225 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 utilisateurs non connectés. Il est possible que d’autres applications n’honorent pas cette demande. Cela ne privatise pas votre compte." +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" @@ -467,23 +460,23 @@ msgstr "Affaires" #: src/view/com/modals/ServerInput.tsx:115 msgid "Button disabled. Input custom domain to proceed." -msgstr "" +msgstr "Bouton désactivé. Saisissez un domaine personnalisé pour continuer." #: src/view/com/profile/ProfileSubpageHeader.tsx:157 msgid "by —" -msgstr "" +msgstr "par —" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:100 msgid "by {0}" -msgstr "" +msgstr "par {0}" #: src/view/com/profile/ProfileSubpageHeader.tsx:161 msgid "by <0/>" -msgstr "" +msgstr "par <0/>" #: src/view/com/profile/ProfileSubpageHeader.tsx:159 msgid "by you" -msgstr "" +msgstr "par vous" #: src/view/com/composer/photos/OpenCameraBtn.tsx:60 #: src/view/com/util/UserAvatar.tsx:221 @@ -502,7 +495,7 @@ msgstr "Ne peut contenir que des lettres, des chiffres, des espaces, des tirets #: src/view/com/modals/DeleteAccount.tsx:227 msgctxt "action" msgid "Cancel" -msgstr "" +msgstr "Annuler" #: src/view/com/composer/Composer.tsx:299 #: src/view/com/composer/Composer.tsx:304 @@ -526,10 +519,6 @@ msgstr "Annuler" msgid "Cancel account deletion" msgstr "Annuler la suppression de compte" -#: src/view/com/modals/AltImage.tsx:123 -#~ msgid "Cancel add image alt text" -#~ msgstr "Annuler l’ajout d’un texte alt à l’image" - #: src/view/com/modals/ChangeHandle.tsx:149 msgid "Cancel change handle" msgstr "Annuler le changement de pseudo" @@ -558,20 +547,16 @@ msgstr "Annuler l’inscription sur la liste d’attente" #: src/view/screens/Settings.tsx:321 msgctxt "action" msgid "Change" -msgstr "" - -#: src/view/screens/Settings.tsx:306 -#~ msgid "Change" -#~ msgstr "Changer" +msgstr "Modifier" #: src/view/screens/Settings.tsx:649 #: src/view/screens/Settings.tsx:658 msgid "Change handle" -msgstr "Changer le pseudo" +msgstr "Modifier le pseudo" #: src/view/com/modals/ChangeHandle.tsx:161 msgid "Change Handle" -msgstr "Changer le pseudo" +msgstr "Modifier le pseudo" #: src/view/com/modals/VerifyEmail.tsx:147 msgid "Change my email" @@ -579,7 +564,7 @@ msgstr "Modifier mon e-mail" #: src/view/com/modals/ChangeEmail.tsx:109 msgid "Change Your Email" -msgstr "Modifiez votre e-mail" +msgstr "Modifier votre e-mail" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:121 msgid "Check out some recommended feeds. Tap + to add them to your list of pinned feeds." @@ -587,7 +572,7 @@ msgstr "Consultez quelques fils d’actu recommandés. Appuyez sur + pour les aj #: src/view/com/auth/onboarding/RecommendedFollows.tsx:185 msgid "Check out some recommended users. Follow them to see similar users." -msgstr "Consultez quelques utilisateurs recommandés. Suivez-les pour voir des utilisateurs similaires." +msgstr "Consultez quelques comptes recommandés. Suivez-les pour voir des personnes similaires." #: src/view/com/modals/DeleteAccount.tsx:165 msgid "Check your inbox for an email with the confirmation code to enter below:" @@ -599,7 +584,7 @@ msgstr "Choisir « Tout le monde » ou « Personne »" #: src/view/screens/Settings.tsx:650 msgid "Choose a new Bluesky username or create" -msgstr "" +msgstr "Choisir un nouveau pseudo Bluesky ou en créer un" #: src/view/com/modals/ServerInput.tsx:38 msgid "Choose Service" @@ -639,7 +624,7 @@ msgstr "Effacer la recherche" #: src/view/screens/Support.tsx:40 msgid "click here" -msgstr "" +msgstr "cliquez ici" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:38 msgid "Close alert" @@ -663,23 +648,23 @@ msgstr "Fermer le pied de page de navigation" #: src/view/shell/index.web.tsx:50 msgid "Closes bottom navigation bar" -msgstr "" +msgstr "Ferme la barre de navigation du bas" #: src/view/com/auth/login/PasswordUpdatedForm.tsx:39 msgid "Closes password update alert" -msgstr "" +msgstr "Ferme la notification de mise à jour du mot de passe" #: src/view/com/composer/Composer.tsx:301 msgid "Closes post composer and discards post draft" -msgstr "" +msgstr "Ferme la fenêtre de rédaction et supprime le brouillon" #: src/view/com/lightbox/ImageViewing/components/ImageDefaultHeader.tsx:27 msgid "Closes viewer for header image" -msgstr "" +msgstr "Ferme la visionneuse pour l’image d’en-tête" #: src/view/com/notifications/FeedItem.tsx:321 msgid "Collapses list of users for a given notification" -msgstr "" +msgstr "Réduit la liste des comptes pour une notification donnée" #: src/Navigation.tsx:229 #: src/view/screens/CommunityGuidelines.tsx:32 @@ -688,7 +673,7 @@ msgstr "Directives communautaires" #: src/view/com/composer/Composer.tsx:416 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" -msgstr "" +msgstr "Permet d’écrire des messages de {MAX_GRAPHEME_LENGTH} caractères maximum" #: src/view/com/composer/Prompt.tsx:24 msgid "Compose reply" @@ -698,7 +683,7 @@ msgstr "Rédiger une réponse" #: src/view/com/modals/Confirm.tsx:78 msgctxt "action" msgid "Confirm" -msgstr "" +msgstr "Confirmer" #: src/view/com/modals/AppealLabel.tsx:98 #: src/view/com/modals/SelfLabel.tsx:154 @@ -724,7 +709,7 @@ msgstr "Confirmer la suppression du compte" #: src/view/com/modals/ContentFilteringSettings.tsx:151 msgid "Confirm your age to enable adult content." -msgstr "" +msgstr "Confirmez votre âge pour activer le contenu pour adultes." #: src/view/com/modals/ChangeEmail.tsx:157 #: src/view/com/modals/DeleteAccount.tsx:178 @@ -734,7 +719,7 @@ msgstr "Code de confirmation" #: src/view/com/modals/Waitlist.tsx:120 msgid "Confirms signing up {email} to the waitlist" -msgstr "" +msgstr "Confirme l’inscription de {email} sur la liste d’attente" #: src/view/com/auth/create/CreateAccount.tsx:174 #: src/view/com/auth/login/LoginForm.tsx:275 @@ -756,7 +741,7 @@ msgstr "Langues du contenu" #: src/view/com/modals/ModerationDetails.tsx:65 msgid "Content Not Available" -msgstr "" +msgstr "Contenu non disponible" #: src/view/com/modals/ModerationDetails.tsx:33 #: src/view/com/util/moderation/ScreenHider.tsx:78 @@ -779,17 +764,17 @@ msgstr "Copié" #: src/view/screens/Settings.tsx:236 msgid "Copied build version to clipboard" -msgstr "" +msgstr "Version de build copiée dans le presse-papier" #: src/view/com/modals/AddAppPasswords.tsx:75 #: src/view/com/modals/InviteCodes.tsx:152 #: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Copied to clipboard" -msgstr "" +msgstr "Copié dans le presse-papier" #: src/view/com/modals/AddAppPasswords.tsx:191 msgid "Copies app password" -msgstr "" +msgstr "Copie le mot de passe d’application" #: src/view/com/modals/AddAppPasswords.tsx:190 msgid "Copy" @@ -797,7 +782,7 @@ msgstr "Copie" #: src/view/screens/ProfileList.tsx:396 msgid "Copy link to list" -msgstr "Copier le lien dans la liste" +msgstr "Copier le lien vers la liste" #: src/view/com/util/forms/PostDropdownBtn.tsx:151 msgid "Copy link to post" @@ -805,7 +790,7 @@ msgstr "Copier le lien vers le post" #: src/view/com/profile/ProfileHeader.tsx:342 msgid "Copy link to profile" -msgstr "Copier le lien sur le profil" +msgstr "Copier le lien vers le profil" #: src/view/com/util/forms/PostDropdownBtn.tsx:137 msgid "Copy post text" @@ -832,7 +817,7 @@ msgstr "Créer un nouveau compte" #: src/view/screens/Settings.tsx:371 msgid "Create a new Bluesky account" -msgstr "" +msgstr "Créer un compte Bluesky" #: src/view/com/auth/create/CreateAccount.tsx:121 msgid "Create Account" @@ -840,7 +825,7 @@ msgstr "Créer un compte" #: src/view/com/modals/AddAppPasswords.tsx:228 msgid "Create App Password" -msgstr "" +msgstr "Créer un mot de passe d’application" #: src/view/com/auth/HomeLoggedOutCTA.tsx:54 #: src/view/com/auth/SplashScreen.tsx:43 @@ -853,15 +838,15 @@ msgstr "{0} créé" #: src/view/screens/ProfileFeed.tsx:625 msgid "Created by <0/>" -msgstr "" +msgstr "Créée par <0/>" #: src/view/screens/ProfileFeed.tsx:623 msgid "Created by you" -msgstr "" +msgstr "Créée par vous" #: src/view/com/composer/Composer.tsx:447 msgid "Creates a card with a thumbnail. The card links to {url}" -msgstr "" +msgstr "Crée une carte avec une miniature. La carte pointe vers {url}" #: src/view/com/modals/ChangeHandle.tsx:389 #: src/view/com/modals/ServerInput.tsx:102 @@ -870,7 +855,7 @@ msgstr "Domaine personnalisé" #: src/view/screens/PreferencesExternalEmbeds.tsx:55 msgid "Customize media from external sites." -msgstr "" +msgstr "Personnaliser les médias provenant de sites externes." #: src/view/screens/Settings.tsx:663 msgid "Danger Zone" @@ -878,19 +863,19 @@ msgstr "Zone de danger" #: src/view/screens/Settings.tsx:466 msgid "Dark" -msgstr "" +msgstr "Sombre" #: src/view/screens/Debug.tsx:63 msgid "Dark mode" -msgstr "" +msgstr "Mode sombre" #: src/Navigation.tsx:204 msgid "Debug" -msgstr "" +msgstr "Débug" #: src/view/screens/Debug.tsx:83 msgid "Debug panel" -msgstr "" +msgstr "Panneau de débug" #: src/view/screens/Settings.tsx:670 msgid "Delete account" @@ -928,7 +913,7 @@ msgstr "Supprimer ce post ?" #: src/view/com/util/post-embeds/QuoteEmbed.tsx:66 msgid "Deleted" -msgstr "" +msgstr "Supprimé" #: src/view/com/post-thread/PostThread.tsx:246 msgid "Deleted post." @@ -963,12 +948,12 @@ msgstr "Ignorer le brouillon" #: src/view/screens/Moderation.tsx:207 msgid "Discourage apps from showing my account to logged-out users" -msgstr "Empêcher les applis de montrer mon compte aux utilisateurs déconnectés" +msgstr "Empêcher les applis de montrer mon compte aux personnes déconnectées" #: src/view/com/posts/FollowingEmptyState.tsx:74 #: src/view/com/posts/FollowingEndOfFeed.tsx:75 msgid "Discover new custom feeds" -msgstr "" +msgstr "Découvrir des fils d’actu personnalisés" #: src/view/screens/Feeds.tsx:409 msgid "Discover new feeds" @@ -988,7 +973,7 @@ msgstr "Domaine vérifié !" #: src/view/com/auth/create/Step2.tsx:83 msgid "Don't have an invite code?" -msgstr "" +msgstr "Pas de code d’invitation ?" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:86 #: src/view/com/modals/EditImage.tsx:333 @@ -1001,7 +986,7 @@ msgstr "" #: src/view/screens/PreferencesThreads.tsx:162 msgctxt "action" msgid "Done" -msgstr "" +msgstr "Terminer" #: src/view/com/modals/AddAppPasswords.tsx:228 #: src/view/com/modals/AltImage.tsx:115 @@ -1021,31 +1006,31 @@ msgstr "Terminé{extraText}" #: src/view/com/auth/login/ChooseAccountForm.tsx:45 msgid "Double tap to sign in" -msgstr "" +msgstr "Tapotez deux fois pour vous connecter" #: src/view/com/modals/EditProfile.tsx:185 msgid "e.g. Alice Roberts" -msgstr "" +msgstr "ex. Alice Dupont" #: src/view/com/modals/EditProfile.tsx:203 msgid "e.g. Artist, dog-lover, and avid reader." -msgstr "" +msgstr "ex. Artiste, amoureuse des chiens et lectrice passionnée." #: src/view/com/modals/CreateOrEditList.tsx:225 msgid "e.g. Great Posters" -msgstr "" +msgstr "ex. Les meilleurs comptes" #: src/view/com/modals/CreateOrEditList.tsx:226 msgid "e.g. Spammers" -msgstr "" +msgstr "ex. Spammeurs" #: src/view/com/modals/CreateOrEditList.tsx:246 msgid "e.g. The posters who never miss." -msgstr "" +msgstr "ex. Ces comptes qui ne ratent jamais leur coup." #: src/view/com/modals/CreateOrEditList.tsx:247 msgid "e.g. Users that repeatedly reply with ads." -msgstr "" +msgstr "ex. Les comptes qui répondent toujours avec des pubs." #: src/view/com/modals/InviteCodes.tsx:96 msgid "Each code works once. You'll receive more invite codes periodically." @@ -1054,7 +1039,7 @@ msgstr "Chaque code ne fonctionne qu’une seule fois. Vous recevrez régulière #: src/view/com/lists/ListMembers.tsx:149 msgctxt "action" msgid "Edit" -msgstr "" +msgstr "Modifier" #: src/view/com/composer/photos/Gallery.tsx:144 #: src/view/com/modals/EditImage.tsx:207 @@ -1067,7 +1052,7 @@ msgstr "Modifier les infos de la liste" #: src/view/com/modals/CreateOrEditList.tsx:193 msgid "Edit Moderation List" -msgstr "" +msgstr "Modifier la liste de modération" #: src/Navigation.tsx:244 #: src/view/screens/Feeds.tsx:371 @@ -1093,15 +1078,15 @@ msgstr "Modifier les fils d’actu enregistrés" #: src/view/com/modals/CreateOrEditList.tsx:188 msgid "Edit User List" -msgstr "" +msgstr "Modifier la liste de compte" #: src/view/com/modals/EditProfile.tsx:193 msgid "Edit your display name" -msgstr "" +msgstr "Modifier votre nom d’affichage" #: src/view/com/modals/EditProfile.tsx:211 msgid "Edit your profile description" -msgstr "" +msgstr "Modifier votre description de profil" #: src/view/com/auth/create/Step2.tsx:108 #: src/view/com/auth/login/ForgotPasswordForm.tsx:152 @@ -1118,7 +1103,7 @@ msgstr "Adresse e-mail" #: src/view/com/modals/ChangeEmail.tsx:56 #: src/view/com/modals/ChangeEmail.tsx:88 msgid "Email updated" -msgstr "" +msgstr "Adresse e-mail mise à jour" #: src/view/com/modals/ChangeEmail.tsx:111 msgid "Email Updated" @@ -1126,7 +1111,7 @@ msgstr "E-mail mis à jour" #: src/view/com/modals/VerifyEmail.tsx:78 msgid "Email verified" -msgstr "" +msgstr "Adresse e-mail vérifiée" #: src/view/screens/Settings.tsx:305 msgid "Email:" @@ -1134,19 +1119,19 @@ msgstr "E-mail :" #: src/view/com/modals/EmbedConsent.tsx:113 msgid "Enable {0} only" -msgstr "" +msgstr "Activer {0} uniquement" #: src/view/com/modals/ContentFilteringSettings.tsx:162 msgid "Enable Adult Content" -msgstr "" +msgstr "Activer le contenu pour adultes" #: src/view/com/modals/EmbedConsent.tsx:97 msgid "Enable External Media" -msgstr "" +msgstr "Activer les médias externes" #: src/view/screens/PreferencesExternalEmbeds.tsx:75 msgid "Enable media players for" -msgstr "" +msgstr "Activer les lecteurs médias pour" #: src/view/screens/PreferencesHomeFeed.tsx:147 msgid "Enable this setting to only see replies between people you follow." @@ -1158,15 +1143,15 @@ msgstr "Fin du fil d’actu" #: src/view/com/modals/AddAppPasswords.tsx:165 msgid "Enter a name for this App Password" -msgstr "" +msgstr "Entrer un nom pour ce mot de passe d’application" #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" -msgstr "" +msgstr "Entrer un code de confirmation" #: src/view/com/auth/create/Step1.tsx:71 msgid "Enter the address of your provider:" -msgstr "Saisissez l’adresse de votre fournisseur :" +msgstr "Saisissez l’adresse de votre hébergeur :" #: src/view/com/modals/ChangeHandle.tsx:371 msgid "Enter the domain you want to use" @@ -1179,11 +1164,11 @@ msgstr "Saisissez l’e-mail que vous avez utilisé pour créer votre compte. No #: src/view/com/auth/create/Step2.tsx:157 #: src/view/com/modals/BirthDateSettings.tsx:74 msgid "Enter your birth date" -msgstr "" +msgstr "Saisissez votre date de naissance" #: src/view/com/modals/Waitlist.tsx:78 msgid "Enter your email" -msgstr "" +msgstr "Entrez votre e-mail" #: src/view/com/auth/create/Step2.tsx:104 msgid "Enter your email address" @@ -1191,7 +1176,7 @@ msgstr "Entrez votre e-mail" #: src/view/com/modals/ChangeEmail.tsx:41 msgid "Enter your new email above" -msgstr "" +msgstr "Entrez votre nouvel e-mail ci-dessus" #: src/view/com/modals/ChangeEmail.tsx:117 msgid "Enter your new email address below." @@ -1199,7 +1184,7 @@ msgstr "Entrez votre nouvelle e-mail ci-dessous." #: src/view/com/auth/login/Login.tsx:99 msgid "Enter your username and password" -msgstr "Entrez votre nom d’utilisateur et votre mot de passe" +msgstr "Entrez votre pseudo et votre mot de passe" #: src/view/screens/Search/Search.tsx:105 msgid "Error:" @@ -1211,20 +1196,20 @@ msgstr "Tout le monde" #: src/view/com/modals/ChangeHandle.tsx:150 msgid "Exits handle change process" -msgstr "" +msgstr "Sors du processus de changement de pseudo" #: src/view/com/lightbox/Lightbox.web.tsx:113 msgid "Exits image view" -msgstr "" +msgstr "Sors de la vue de l’image" #: src/view/com/modals/ListAddRemoveUsers.tsx:88 #: src/view/shell/desktop/Search.tsx:182 msgid "Exits inputting search query" -msgstr "" +msgstr "Sors de la saisie de la recherche" #: src/view/com/modals/Waitlist.tsx:138 msgid "Exits signing up for waitlist with {email}" -msgstr "" +msgstr "Sors de l’inscription sur la liste d’attente avec {email}" #: src/view/com/lightbox/Lightbox.web.tsx:156 msgid "Expand alt text" @@ -1233,39 +1218,39 @@ msgstr "Développer le texte alt" #: 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 "Étend ou rétrécit le post complet auquel vous répondez" #: src/view/com/modals/EmbedConsent.tsx:64 msgid "External Media" -msgstr "" +msgstr "Média externe" #: 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 "Les médias externes peuvent permettre à des sites web de collecter des informations sur vous et votre appareil. Aucune information n’est envoyée ou demandée tant que vous n’appuyez pas sur le bouton de lecture." #: src/Navigation.tsx:260 #: src/view/screens/PreferencesExternalEmbeds.tsx:52 #: src/view/screens/Settings.tsx:610 msgid "External Media Preferences" -msgstr "" +msgstr "Préférences sur les médias externes" #: src/view/screens/Settings.tsx:601 msgid "External media settings" -msgstr "" +msgstr "Préférences sur les médias externes" #: src/view/com/modals/AddAppPasswords.tsx:114 #: src/view/com/modals/AddAppPasswords.tsx:118 msgid "Failed to create app password." -msgstr "" +msgstr "Échec de la création du mot de passe d’application." #: src/view/com/modals/CreateOrEditList.tsx:148 msgid "Failed to create the list. Check your internet connection and try again." -msgstr "" +msgstr "Échec de la création de la liste. Vérifiez votre connexion Internet et réessayez." #: src/view/com/util/forms/PostDropdownBtn.tsx:86 msgid "Failed to delete post, please try again" -msgstr "" +msgstr "Échec de la suppression du post, veuillez réessayer" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:109 #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:141 @@ -1274,11 +1259,11 @@ msgstr "Échec du chargement des fils d’actu recommandés" #: src/Navigation.tsx:194 msgid "Feed" -msgstr "" +msgstr "Fil d’actu" #: src/view/com/feeds/FeedSourceCard.tsx:229 msgid "Feed by {0}" -msgstr "" +msgstr "Fil d’actu par {0}" #: src/view/screens/Feeds.tsx:560 msgid "Feed offline" @@ -1305,25 +1290,25 @@ msgstr "Fil 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." -msgstr "Les fils d’actu sont créés par les utilisateurs pour rassembler du contenu. Choisissez des fils d’actu qui vous intéressent." +msgstr "Les fils d’actu sont créés par d’autres personnes pour rassembler du contenu. Choisissez des fils d’actu qui vous intéressent." #: src/view/screens/SavedFeeds.tsx:156 msgid "Feeds are custom algorithms that users build with a little coding expertise. <0/> for more information." -msgstr "Les fils d’actu sont des algorithmes personnalisés que les utilisateurs construisent avec un peu d’expertise en codage. <0/> pour obtenir de plus amples informations." +msgstr "Les fils d’actu sont des algorithmes personnalisés qui se construisent avec un peu d’expertise en codage. <0/> pour plus d’informations." #: 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 "Trouver des comptes à suivre" #: src/view/screens/Search/Search.tsx:427 msgid "Find users on Bluesky" -msgstr "Trouver des utilisateurs sur Bluesky" +msgstr "Trouver des comptes sur Bluesky" #: src/view/screens/Search/Search.tsx:425 msgid "Find users with the search tool on the right" -msgstr "Trouvez des utilisateurs à l’aide de l’outil de recherche, à droite" +msgstr "Trouvez des comptes à l’aide de l’outil de recherche, à droite" #: src/view/com/auth/onboarding/RecommendedFollowsItem.tsx:150 msgid "Finding similar accounts..." @@ -1331,25 +1316,25 @@ msgstr "Recherche de comptes similaires…" #: src/view/screens/PreferencesHomeFeed.tsx:111 msgid "Fine-tune the content you see on your home screen." -msgstr "Affinez le contenu de votre écran d’accueil." +msgstr "Affine le contenu affiché sur votre écran d’accueil." #: src/view/screens/PreferencesThreads.tsx:60 msgid "Fine-tune the discussion threads." -msgstr "Affiner les fils de discussion." +msgstr "Affine les fils de discussion." #: src/view/com/modals/EditImage.tsx:115 msgid "Flip horizontal" -msgstr "" +msgstr "Miroir horizontal" #: src/view/com/modals/EditImage.tsx:120 #: src/view/com/modals/EditImage.tsx:287 msgid "Flip vertically" -msgstr "" +msgstr "Miroir vertical" #: src/view/com/profile/FollowButton.tsx:64 msgctxt "action" msgid "Follow" -msgstr "" +msgstr "Suivre" #: src/view/com/profile/ProfileHeader.tsx:552 msgid "Follow" @@ -1357,35 +1342,31 @@ msgstr "Suivre" #: src/view/com/profile/ProfileHeader.tsx:543 msgid "Follow {0}" -msgstr "" +msgstr "Suivre {0}" #: 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 "Suivez quelques utilisateurs pour commencer. Nous pouvons vous recommander d’autres utilisateurs en fonction des personnes qui vous intéressent." +msgstr "Suivez quelques comptes pour commencer. Nous pouvons vous recommander d’autres comptes en fonction des personnes qui vous intéressent." #: src/view/com/profile/ProfileCard.tsx:194 msgid "Followed by {0}" -msgstr "" +msgstr "Suivi par {0}" #: src/view/com/modals/Threadgate.tsx:98 msgid "Followed users" -msgstr "Utilisateurs suivis" +msgstr "Comptes suivis" #: src/view/screens/PreferencesHomeFeed.tsx:154 msgid "Followed users only" -msgstr "Utilisateurs suivis uniquement" +msgstr "Comptes suivis uniquement" #: src/view/com/notifications/FeedItem.tsx:166 msgid "followed you" -msgstr "" +msgstr "vous suit" #: src/view/screens/ProfileFollowers.tsx:25 msgid "Followers" -msgstr "Followers" - -#: src/view/com/profile/ProfileHeader.tsx:624 -#~ msgid "following" -#~ msgstr "suivi" +msgstr "Abonné·e·s" #: src/view/com/profile/ProfileHeader.tsx:534 #: src/view/screens/ProfileFollows.tsx:25 @@ -1394,7 +1375,7 @@ msgstr "Suivi" #: src/view/com/profile/ProfileHeader.tsx:196 msgid "Following {0}" -msgstr "" +msgstr "Suit {0}" #: src/view/com/profile/ProfileHeader.tsx:585 msgid "Follows you" @@ -1402,7 +1383,7 @@ msgstr "Vous suit" #: src/view/com/profile/ProfileCard.tsx:141 msgid "Follows You" -msgstr "" +msgstr "Vous suit" #: src/view/com/modals/DeleteAccount.tsx:107 msgid "For security reasons, we'll need to send a confirmation code to your email address." @@ -1428,7 +1409,7 @@ msgstr "Mot de passe oublié" #: src/view/com/posts/FeedItem.tsx:188 msgctxt "from-feed" msgid "From <0/>" -msgstr "" +msgstr "Tiré de <0/>" #: src/view/com/composer/photos/SelectPhotoBtn.tsx:43 msgid "Gallery" @@ -1476,7 +1457,7 @@ msgstr "Voici le mot de passe de votre appli." #: src/view/com/notifications/FeedItem.tsx:329 msgctxt "action" msgid "Hide" -msgstr "" +msgstr "Cacher" #: src/view/com/modals/ContentFilteringSettings.tsx:246 #: src/view/com/util/moderation/ContentHider.tsx:105 @@ -1491,7 +1472,7 @@ msgstr "Cacher ce post" #: src/view/com/util/moderation/ContentHider.tsx:67 #: src/view/com/util/moderation/PostHider.tsx:61 msgid "Hide the content" -msgstr "" +msgstr "Cacher ce contenu" #: src/view/com/util/forms/PostDropdownBtn.tsx:189 msgid "Hide this post?" @@ -1499,31 +1480,31 @@ msgstr "Cacher ce post ?" #: src/view/com/notifications/FeedItem.tsx:319 msgid "Hide user list" -msgstr "Cacher la liste des utilisateurs" +msgstr "Cacher la liste des comptes" #: src/view/com/profile/ProfileHeader.tsx:526 msgid "Hides posts from {0} in your feed" -msgstr "" +msgstr "Masque les posts de {0} dans votre fil d’actu" #: 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, un problème s’est produit avec le serveur de fils d’actu. Veuillez informer le propriétaire du fil d’actu de ce problème." +msgstr "Hmm, un problème s’est produit avec le serveur de fils d’actu. Veuillez informer la personne à l’origine du fil d’actu de ce problème." #: 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, le serveur du fils d’actu semble être mal configuré. Veuillez informer le propriétaire du fil d’actu de ce problème." +msgstr "Hmm, le serveur du fils d’actu semble être mal configuré. Veuillez informer la personne à l’origine du fil d’actu de ce problème." #: 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 "Mmm… le serveur de fils d’actu semble être hors ligne. Veuillez informer le propriétaire du fil d’actu de ce problème." +msgstr "Mmm… le serveur de fils d’actu semble être hors ligne. Veuillez informer la personne à l’origine du fil d’actu de ce problème." #: 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 "Mmm… le serveur de fils d’actu ne répond pas. Veuillez informer le propriétaire du fil d’actu de ce problème." +msgstr "Mmm… le serveur de fils d’actu ne répond pas. Veuillez informer la personne à l’origine du fil d’actu de ce problème." #: src/view/com/posts/FeedErrorMessage.tsx:96 msgid "Hmm, we're having trouble finding this feed. It may have been deleted." -msgstr "Hmm, nous n’arrivons pas à trouver ce fils d’actu. Il a peut-être été supprimé." +msgstr "Hmm, nous n’arrivons pas à trouver ce fil d’actu. Il a peut-être été supprimé." #: src/Navigation.tsx:432 #: src/view/shell/bottom-bar/BottomBar.tsx:137 @@ -1542,7 +1523,7 @@ msgstr "Préférences de fils d’actu de l’accueil" #: src/view/com/auth/login/ForgotPasswordForm.tsx:116 msgid "Hosting provider" -msgstr "Fournisseur d’hébergement" +msgstr "Hébergeur" #: src/view/com/auth/create/Step1.tsx:76 #: src/view/com/auth/create/Step1.tsx:81 @@ -1555,7 +1536,7 @@ msgstr "J’ai un code" #: src/view/com/modals/VerifyEmail.tsx:216 msgid "I have a confirmation code" -msgstr "" +msgstr "J’ai un code de confirmation" #: src/view/com/modals/ChangeHandle.tsx:283 msgid "I have my own domain" @@ -1563,7 +1544,7 @@ msgstr "J’ai mon propre domaine" #: src/view/com/lightbox/Lightbox.web.tsx:158 msgid "If alt text is long, toggles alt text expanded state" -msgstr "" +msgstr "Si le texte alternatif est trop long, affiche le texte alternatif complet" #: src/view/com/modals/SelfLabel.tsx:127 msgid "If none are selected, suitable for all ages." @@ -1571,7 +1552,7 @@ msgstr "Si rien n’est sélectionné, il n’y a pas de restriction d’âge." #: src/view/com/util/images/Gallery.tsx:37 msgid "Image" -msgstr "" +msgstr "Image" #: src/view/com/modals/AltImage.tsx:97 msgid "Image alt text" @@ -1584,63 +1565,63 @@ msgstr "Options d’images" #: src/view/com/auth/login/SetNewPasswordForm.tsx:110 msgid "Input code sent to your email for password reset" -msgstr "" +msgstr "Entrez le code envoyé à votre e-mail pour réinitialiser le mot de passe" #: src/view/com/modals/DeleteAccount.tsx:180 msgid "Input confirmation code for account deletion" -msgstr "" +msgstr "Entrez le code de confirmation pour supprimer le compte" #: src/view/com/auth/create/Step2.tsx:109 msgid "Input email for Bluesky waitlist" -msgstr "" +msgstr "Entrez l’e-mail pour la liste d’attente de Bluesky" #: src/view/com/auth/create/Step1.tsx:80 msgid "Input hosting provider address" -msgstr "" +msgstr "Entrez l’adresse de l’hébergeur" #: src/view/com/auth/create/Step2.tsx:73 msgid "Input invite code to proceed" -msgstr "" +msgstr "Entrez le code d’invitation pour continuer" #: src/view/com/modals/AddAppPasswords.tsx:182 msgid "Input name for app password" -msgstr "" +msgstr "Entrez le nom du mot de passe de l’appli" #: src/view/com/auth/login/SetNewPasswordForm.tsx:133 msgid "Input new password" -msgstr "" +msgstr "Entrez le nouveau mot de passe" #: src/view/com/modals/DeleteAccount.tsx:196 msgid "Input password for account deletion" -msgstr "" +msgstr "Entrez le mot de passe pour la suppression du compte" #: src/view/com/auth/login/LoginForm.tsx:227 msgid "Input the password tied to {identifier}" -msgstr "" +msgstr "Entrez le mot de passe associé à {identifier}" #: src/view/com/auth/login/LoginForm.tsx:194 msgid "Input the username or email address you used at signup" -msgstr "" +msgstr "Entrez le pseudo ou l’adresse e-mail que vous avez utilisé lors de l’inscription" #: src/view/com/modals/Waitlist.tsx:90 msgid "Input your email to get on the Bluesky waitlist" -msgstr "" +msgstr "Entrez votre e-mail pour vous inscrire sur la liste d’attente de Bluesky" #: src/view/com/auth/login/LoginForm.tsx:226 msgid "Input your password" -msgstr "" +msgstr "Entrez votre mot de passe" #: src/view/com/auth/create/Step3.tsx:39 msgid "Input your user handle" -msgstr "" +msgstr "Entrez votre pseudo" #: src/view/com/post-thread/PostThreadItem.tsx:229 msgid "Invalid or unsupported post record" -msgstr "" +msgstr "Enregistrement de post invalide ou non pris en charge" #: src/view/com/auth/login/LoginForm.tsx:115 msgid "Invalid username or password" -msgstr "Nom d’utilisateur ou mot de passe incorrect" +msgstr "Pseudo ou mot de passe incorrect" #: src/view/screens/Settings.tsx:398 msgid "Invite" @@ -1662,15 +1643,15 @@ 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 "" +msgstr "Code d’invitation : {0} disponible" #: src/view/shell/Drawer.tsx:642 msgid "Invite codes: {invitesAvailable} available" -msgstr "Codes d’invitation : {invitesAvailable} disponible" +msgstr "Invitations : {invitesAvailable} codes dispo" #: src/view/com/modals/InviteCodes.tsx:169 msgid "Invite codes: 1 available" -msgstr "" +msgstr "Invitations : 1 code dispo" #: src/view/com/auth/HomeLoggedOutCTA.tsx:99 msgid "Jobs" @@ -1695,7 +1676,7 @@ msgstr "Sélection de la langue" #: src/view/screens/Settings.tsx:547 msgid "Language settings" -msgstr "" +msgstr "Préférences de langue" #: src/Navigation.tsx:141 #: src/view/screens/LanguageSettings.tsx:89 @@ -1708,7 +1689,7 @@ msgstr "Langues" #: src/view/com/auth/create/StepHeader.tsx:13 msgid "Last step!" -msgstr "" +msgstr "Dernière étape !" #: src/view/com/util/moderation/ContentHider.tsx:103 msgid "Learn more" @@ -1742,7 +1723,7 @@ msgstr "Quitter Bluesky" #: src/view/screens/Settings.tsx:273 msgid "Legacy storage cleared, you need to restart the app now." -msgstr "" +msgstr "Stockage ancien effacé, vous devez redémarrer l’application maintenant." #: src/view/com/auth/login/Login.tsx:128 #: src/view/com/auth/login/Login.tsx:144 @@ -1756,11 +1737,11 @@ msgstr "Bibliothèque" #: src/view/screens/Settings.tsx:460 msgid "Light" -msgstr "" +msgstr "Clair" #: src/view/com/util/post-ctrls/PostCtrls.tsx:189 msgid "Like" -msgstr "" +msgstr "Aimer" #: src/view/screens/ProfileFeed.tsx:600 msgid "Like this feed" @@ -1774,19 +1755,19 @@ msgstr "Liké par" #: src/view/com/feeds/FeedSourceCard.tsx:277 msgid "Liked by {0} {1}" -msgstr "" +msgstr "Liké par {0} {1}" #: src/view/screens/ProfileFeed.tsx:615 msgid "Liked by {likeCount} {0}" -msgstr "" +msgstr "Liké par {likeCount} {0}" #: src/view/com/notifications/FeedItem.tsx:171 msgid "liked your custom feed{0}" -msgstr "" +msgstr "liké votre fil d’actu personnalisé{0}" #: src/view/com/notifications/FeedItem.tsx:155 msgid "liked your post" -msgstr "" +msgstr "liké votre post" #: src/view/screens/Profile.tsx:164 msgid "Likes" @@ -1794,11 +1775,11 @@ msgstr "Likes" #: src/view/com/post-thread/PostThreadItem.tsx:184 msgid "Likes on this post" -msgstr "" +msgstr "Likes sur ce post" #: src/Navigation.tsx:168 msgid "List" -msgstr "" +msgstr "Liste" #: src/view/com/modals/CreateOrEditList.tsx:205 msgid "List Avatar" @@ -1806,19 +1787,19 @@ msgstr "Liste des avatars" #: src/view/screens/ProfileList.tsx:323 msgid "List blocked" -msgstr "" +msgstr "Liste bloquée" #: src/view/com/feeds/FeedSourceCard.tsx:231 msgid "List by {0}" -msgstr "" +msgstr "Liste par {0}" #: src/view/screens/ProfileList.tsx:367 msgid "List deleted" -msgstr "" +msgstr "Liste supprimée" #: src/view/screens/ProfileList.tsx:282 msgid "List muted" -msgstr "" +msgstr "Liste masquée" #: src/view/com/modals/CreateOrEditList.tsx:218 msgid "List Name" @@ -1826,11 +1807,11 @@ msgstr "Nom de liste" #: src/view/screens/ProfileList.tsx:342 msgid "List unblocked" -msgstr "" +msgstr "Liste débloquée" #: src/view/screens/ProfileList.tsx:301 msgid "List unmuted" -msgstr "" +msgstr "Liste démasquée" #: src/Navigation.tsx:111 #: src/view/screens/Profile.tsx:166 @@ -1866,7 +1847,7 @@ msgstr "Serveur de dév local" #: src/Navigation.tsx:209 msgid "Log" -msgstr "" +msgstr "Journaux" #: src/view/screens/Moderation.tsx:136 msgid "Logged-out visibility" @@ -1886,24 +1867,20 @@ msgstr "Média" #: src/view/com/threadgate/WhoCanReply.tsx:139 msgid "mentioned users" -msgstr "utilisateurs mentionnés" +msgstr "comptes mentionnés" #: src/view/com/modals/Threadgate.tsx:93 msgid "Mentioned users" -msgstr "Utilisateurs mentionnés" +msgstr "Comptes mentionnés" #: src/view/com/util/ViewHeader.tsx:81 #: src/view/screens/Search/Search.tsx:537 msgid "Menu" msgstr "Menu" -#: src/view/com/posts/FeedErrorMessage.tsx:194 -#~ msgid "Message from server" -#~ msgstr "Message du serveur" - #: src/view/com/posts/FeedErrorMessage.tsx:197 msgid "Message from server: {0}" -msgstr "" +msgstr "Message du serveur : {0}" #: src/Navigation.tsx:116 #: src/view/screens/Moderation.tsx:64 @@ -1917,25 +1894,25 @@ msgstr "Modération" #: src/view/com/lists/ListCard.tsx:92 #: src/view/com/modals/UserAddRemoveLists.tsx:190 msgid "Moderation list by {0}" -msgstr "" +msgstr "Liste de modération par {0}" #: src/view/screens/ProfileList.tsx:753 msgid "Moderation list by <0/>" -msgstr "" +msgstr "Liste de modération par <0/>" #: src/view/com/lists/ListCard.tsx:90 #: src/view/com/modals/UserAddRemoveLists.tsx:188 #: src/view/screens/ProfileList.tsx:751 msgid "Moderation list by you" -msgstr "" +msgstr "Liste de modération par vous" #: src/view/com/modals/CreateOrEditList.tsx:139 msgid "Moderation list created" -msgstr "" +msgstr "Liste de modération créée" #: src/view/com/modals/CreateOrEditList.tsx:126 msgid "Moderation list updated" -msgstr "" +msgstr "Liste de modération mise à jour" #: src/view/screens/Moderation.tsx:95 msgid "Moderation lists" @@ -1948,11 +1925,11 @@ msgstr "Listes de modération" #: src/view/screens/Settings.tsx:572 msgid "Moderation settings" -msgstr "" +msgstr "Paramètres de modération" #: src/view/com/modals/ModerationDetails.tsx:35 msgid "Moderator has chosen to set a general warning on the content." -msgstr "" +msgstr "La modération a choisi d’ajouter un avertissement général sur le contenu." #: src/view/shell/desktop/Feeds.tsx:53 msgid "More feeds" @@ -1966,7 +1943,7 @@ msgstr "Plus d’options" #: src/view/com/util/forms/PostDropdownBtn.tsx:268 msgid "More post options" -msgstr "" +msgstr "Plus d’options de post" #: src/view/screens/PreferencesThreads.tsx:82 msgid "Most-liked replies first" @@ -1990,7 +1967,7 @@ msgstr "Masquer ces comptes ?" #: src/view/screens/ProfileList.tsx:278 msgid "Mute this List" -msgstr "" +msgstr "Masquer cette liste" #: src/view/com/util/forms/PostDropdownBtn.tsx:169 msgid "Mute thread" @@ -2036,22 +2013,22 @@ msgstr "Nom" #: src/view/com/modals/CreateOrEditList.tsx:108 msgid "Name is required" -msgstr "" +msgstr "Le nom est requis" #: src/view/com/auth/login/ForgotPasswordForm.tsx:186 #: src/view/com/auth/login/LoginForm.tsx:286 #: src/view/com/auth/login/SetNewPasswordForm.tsx:166 msgid "Navigates to the next screen" -msgstr "" +msgstr "Navigue vers le prochain écran" #: src/view/shell/Drawer.tsx:71 msgid "Navigates to your profile" -msgstr "" +msgstr "Navigue vers votre profil" #: src/view/com/modals/EmbedConsent.tsx:107 #: src/view/com/modals/EmbedConsent.tsx:123 msgid "Never load embeds from {0}" -msgstr "" +msgstr "Ne jamais charger les contenus intégrés de {0}" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:72 #: src/view/com/auth/onboarding/WelcomeMobile.tsx:72 @@ -2061,7 +2038,7 @@ msgstr "Ne perdez jamais l’accès à vos followers et à vos données." #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" -msgstr "" +msgstr "Nouveau" #: src/view/screens/ModerationModlists.tsx:78 msgid "New" @@ -2069,16 +2046,16 @@ msgstr "Nouveau" #: src/view/com/modals/CreateOrEditList.tsx:195 msgid "New Moderation List" -msgstr "" +msgstr "Nouvelle liste de modération" #: src/view/com/auth/login/SetNewPasswordForm.tsx:122 msgid "New password" -msgstr "" +msgstr "Nouveau mot de passe" #: src/view/com/feeds/FeedPage.tsx:201 msgctxt "action" msgid "New post" -msgstr "" +msgstr "Nouveau post" #: src/view/screens/Feeds.tsx:511 #: src/view/screens/Profile.tsx:354 @@ -2092,24 +2069,20 @@ msgstr "Nouveau post" #: src/view/shell/desktop/LeftNav.tsx:258 msgctxt "action" msgid "New Post" -msgstr "" - -#: src/view/shell/desktop/LeftNav.tsx:258 -#~ msgid "New Post" -#~ msgstr "Nouveau post" +msgstr "Nouveau post" #: src/view/com/modals/CreateOrEditList.tsx:190 msgid "New User List" -msgstr "" +msgstr "Nouvelle liste de comptes" #: src/view/screens/PreferencesThreads.tsx:79 msgid "Newest replies first" -msgstr "" +msgstr "Réponses les plus récentes en premier" #: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 msgctxt "action" msgid "Next" -msgstr "" +msgstr "Suivant" #: src/view/com/auth/create/CreateAccount.tsx:154 #: src/view/com/auth/login/ForgotPasswordForm.tsx:178 @@ -2141,11 +2114,11 @@ msgstr "Aucune description" #: src/view/com/profile/ProfileHeader.tsx:217 msgid "No longer following {0}" -msgstr "" +msgstr "Ne suit plus {0}" #: src/view/com/notifications/Feed.tsx:107 msgid "No notifications yet!" -msgstr "" +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 @@ -2166,7 +2139,7 @@ msgstr "Aucun résultat trouvé pour {query}" #: src/view/com/modals/EmbedConsent.tsx:129 msgid "No thanks" -msgstr "" +msgstr "Non merci" #: src/view/com/modals/Threadgate.tsx:82 msgid "Nobody" @@ -2178,16 +2151,16 @@ msgstr "Sans objet." #: src/Navigation.tsx:106 msgid "Not Found" -msgstr "" +msgstr "Introuvable" #: src/view/com/modals/VerifyEmail.tsx:246 #: src/view/com/modals/VerifyEmail.tsx:252 msgid "Not right now" -msgstr "" +msgstr "Pas maintenant" #: src/view/screens/Moderation.tsx:232 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 utilisateurs déconnectés 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 déconnectées par d’autres applications et sites Web." #: src/Navigation.tsx:447 #: src/view/screens/Notifications.tsx:113 @@ -2201,7 +2174,7 @@ msgstr "Notifications" #: src/view/com/modals/SelfLabel.tsx:103 msgid "Nudity" -msgstr "" +msgstr "Nudité" #: src/view/com/util/ErrorBoundary.tsx:34 msgid "Oh no!" @@ -2217,7 +2190,7 @@ msgstr "Plus anciennes réponses en premier" #: src/view/screens/Settings.tsx:229 msgid "Onboarding reset" -msgstr "" +msgstr "Réinitialiser le didacticiel" #: src/view/com/composer/Composer.tsx:374 msgid "One or more images is missing alt text." @@ -2231,7 +2204,7 @@ msgstr "Seul {0} peut répondre." #: src/view/com/modals/ProfilePreview.tsx:61 #: src/view/screens/AppPasswords.tsx:65 msgid "Oops!" -msgstr "" +msgstr "Oups !" #: src/view/com/composer/Composer.tsx:468 #: src/view/com/composer/Composer.tsx:469 @@ -2244,27 +2217,27 @@ msgstr "Navigation ouverte" #: src/view/screens/Settings.tsx:713 msgid "Open storybook page" -msgstr "" +msgstr "Ouvrir la page Storybook" #: src/view/com/util/forms/DropdownButton.tsx:147 msgid "Opens {numItems} options" -msgstr "" +msgstr "Ouvre {numItems} options" #: src/view/screens/Log.tsx:54 msgid "Opens additional details for a debug entry" -msgstr "" +msgstr "Ouvre des détails supplémentaires pour une entrée de débug" #: src/view/com/notifications/FeedItem.tsx:352 msgid "Opens an expanded list of users in this notification" -msgstr "" +msgstr "Ouvre une liste étendue des comptes dans cette notification" #: src/view/com/composer/photos/OpenCameraBtn.tsx:61 msgid "Opens camera on device" -msgstr "" +msgstr "Ouvre l’appareil photo de l’appareil" #: src/view/com/composer/Prompt.tsx:25 msgid "Opens composer" -msgstr "" +msgstr "Ouvre le rédacteur" #: src/view/screens/Settings.tsx:548 msgid "Opens configurable language settings" @@ -2272,27 +2245,27 @@ msgstr "Ouvre les paramètres linguistiques configurables" #: src/view/com/composer/photos/SelectPhotoBtn.tsx:44 msgid "Opens device photo gallery" -msgstr "" +msgstr "Ouvre la galerie de photos de l’appareil" #: src/view/com/profile/ProfileHeader.tsx:459 msgid "Opens editor for profile display name, avatar, background image, and description" -msgstr "" +msgstr "Ouvre l’éditeur pour le nom d’affichage du profil, l’avatar, l’image d’arrière-plan et la description" #: src/view/screens/Settings.tsx:602 msgid "Opens external embeds settings" -msgstr "" +msgstr "Ouvre les paramètres d’intégration externe" #: src/view/com/profile/ProfileHeader.tsx:614 msgid "Opens followers list" -msgstr "" +msgstr "Ouvre la liste des comptes abonnés" #: src/view/com/profile/ProfileHeader.tsx:633 msgid "Opens following list" -msgstr "" +msgstr "Ouvre la liste des abonnements" #: src/view/screens/Settings.tsx:399 msgid "Opens invite code list" -msgstr "" +msgstr "Ouvre la liste des codes d’invitation" #: src/view/com/modals/InviteCodes.tsx:172 #: src/view/shell/desktop/RightNav.tsx:156 @@ -2302,7 +2275,7 @@ msgstr "Ouvre la liste des codes d’invitation" #: src/view/screens/Settings.tsx:672 msgid "Opens modal for account deletion confirmation. Requires email code." -msgstr "" +msgstr "Ouvre la fenêtre modale pour confirmer la suppression du compte. Requiert un code e-mail." #: src/view/com/modals/ChangeHandle.tsx:281 msgid "Opens modal for using custom domain" @@ -2314,11 +2287,11 @@ msgstr "Ouvre les paramètres de modération" #: src/view/com/auth/login/LoginForm.tsx:236 msgid "Opens password reset form" -msgstr "" +msgstr "Ouvre le formulaire de réinitialisation du mot de passe" #: src/view/screens/Feeds.tsx:335 msgid "Opens screen to edit Saved Feeds" -msgstr "" +msgstr "Ouvre l’écran pour modifier les fils d’actu enregistrés" #: src/view/screens/Settings.tsx:529 msgid "Opens screen with all saved feeds" @@ -2346,7 +2319,7 @@ msgstr "Ouvre les préférences relatives aux fils de discussion" #: src/view/com/util/forms/DropdownButton.tsx:254 msgid "Option {0} of {numItems}" -msgstr "" +msgstr "Option {0} sur {numItems}" #: src/view/com/modals/Threadgate.tsx:89 msgid "Or combine these options:" @@ -2387,19 +2360,19 @@ msgstr "Mot de passe mis à jour !" #: src/Navigation.tsx:162 msgid "People followed by @{0}" -msgstr "" +msgstr "Personnes suivies par @{0}" #: src/Navigation.tsx:155 msgid "People following @{0}" -msgstr "" +msgstr "Personnes qui suivent @{0}" #: src/view/com/lightbox/Lightbox.tsx:66 msgid "Permission to access camera roll is required." -msgstr "" +msgstr "Permission d’accès à la pellicule requise." #: src/view/com/lightbox/Lightbox.tsx:72 msgid "Permission to access camera roll was denied. Please enable it in your system settings." -msgstr "" +msgstr "Permission d’accès à la pellicule refusée. Veuillez l’activer dans les paramètres de votre système." #: src/view/com/modals/SelfLabel.tsx:121 msgid "Pictures meant for adults." @@ -2408,7 +2381,7 @@ msgstr "Images destinées aux adultes." #: src/view/screens/ProfileFeed.tsx:362 #: src/view/screens/ProfileList.tsx:559 msgid "Pin to home" -msgstr "" +msgstr "Ajouter à l’accueil" #: src/view/screens/SavedFeeds.tsx:88 msgid "Pinned Feeds" @@ -2416,16 +2389,16 @@ msgstr "Fils épinglés" #: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:111 msgid "Play {0}" -msgstr "" +msgstr "Lire {0}" #: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:54 #: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:55 msgid "Play Video" -msgstr "" +msgstr "Lire la vidéo" #: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:110 msgid "Plays the GIF" -msgstr "" +msgstr "Lis le GIF" #: src/view/com/auth/create/state.ts:116 msgid "Please choose your handle." @@ -2441,7 +2414,7 @@ msgstr "Veuillez confirmer votre e-mail avant de le modifier. Ceci est temporair #: src/view/com/modals/AddAppPasswords.tsx:89 msgid "Please enter a name for your app password. All spaces is not allowed." -msgstr "" +msgstr "Veuillez entrer un nom pour votre mot de passe d’application. Les espaces ne sont pas autorisés." #: src/view/com/modals/AddAppPasswords.tsx:144 msgid "Please enter a unique name for this App Password or use our randomly generated one." @@ -2460,12 +2433,9 @@ msgstr "Veuillez également entrer votre mot de passe :" 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 !" -#~ msgid "Please tell us why you think this decision was incorrect." -#~ msgstr "Dites-nous pourquoi vous pensez que cette décision était incorrecte." - #: src/view/com/modals/VerifyEmail.tsx:101 msgid "Please Verify Your Email" -msgstr "" +msgstr "Veuillez vérifier votre e-mail" #: src/view/com/composer/Composer.tsx:214 msgid "Please wait for your link card to finish loading" @@ -2473,43 +2443,37 @@ msgstr "Veuillez patienter le temps que votre carte de lien soit chargée" #: src/view/com/modals/SelfLabel.tsx:111 msgid "Porn" -msgstr "" +msgstr "Porno" #: src/view/com/composer/Composer.tsx:349 #: src/view/com/composer/Composer.tsx:357 msgctxt "action" msgid "Post" -msgstr "" +msgstr "Poster" #: src/view/com/post-thread/PostThread.tsx:227 #: src/view/screens/PostThread.tsx:82 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 "Post" +msgstr "Post" #: src/view/com/post-thread/PostThreadItem.tsx:176 msgid "Post by {0}" -msgstr "" +msgstr "Post de {0}" #: src/Navigation.tsx:174 #: src/Navigation.tsx:181 #: src/Navigation.tsx:188 msgid "Post by @{0}" -msgstr "" +msgstr "Post de @{0}" #: src/view/com/util/forms/PostDropdownBtn.tsx:82 msgid "Post deleted" -msgstr "" +msgstr "Post supprimé" #: src/view/com/post-thread/PostThread.tsx:382 msgid "Post hidden" -msgstr "Posts cachés" +msgstr "Post caché" #: src/view/com/composer/select-language/SelectLangBtn.tsx:87 msgid "Post language" @@ -2529,7 +2493,7 @@ msgstr "Posts" #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" -msgstr "" +msgstr "Posts cachés" #: src/view/com/modals/LinkWarning.tsx:44 msgid "Potentially Misleading Link" @@ -2573,7 +2537,7 @@ msgstr "Profil" #: src/view/com/modals/EditProfile.tsx:128 msgid "Profile updated" -msgstr "" +msgstr "Profil mis à jour" #: src/view/screens/Settings.tsx:858 msgid "Protect your account by verifying your email." @@ -2581,7 +2545,7 @@ msgstr "Protégez votre compte en vérifiant votre e-mail." #: src/view/screens/ModerationModlists.tsx:61 msgid "Public, shareable lists of users to mute or block in bulk." -msgstr "Listes publiques et partageables d’utilisateurs à masquer ou à bloquer." +msgstr "Listes publiques et partageables de comptes à masquer ou à bloquer." #: src/view/screens/Lists.tsx:61 msgid "Public, shareable lists which can drive feeds." @@ -2589,16 +2553,16 @@ msgstr "Les listes publiques et partageables qui peuvent alimenter les fils d’ #: src/view/com/composer/Composer.tsx:334 msgid "Publish post" -msgstr "" +msgstr "Publier le post" #: src/view/com/composer/Composer.tsx:334 msgid "Publish reply" -msgstr "" +msgstr "Publier la réponse" #: src/view/com/modals/Repost.tsx:65 msgctxt "action" msgid "Quote post" -msgstr "" +msgstr "Citer le post" #: src/view/com/util/post-ctrls/RepostButton.web.tsx:58 msgid "Quote post" @@ -2607,15 +2571,11 @@ msgstr "Citer le post" #: src/view/com/modals/Repost.tsx:70 msgctxt "action" msgid "Quote Post" -msgstr "" - -#: src/view/com/modals/Repost.tsx:56 -#~ msgid "Quote Post" -#~ msgstr "Citer un post" +msgstr "Citer le post" #: src/view/screens/PreferencesThreads.tsx:86 msgid "Random (aka \"Poster's Roulette\")" -msgstr "" +msgstr "Aléatoire" #: src/view/com/modals/EditImage.tsx:236 msgid "Ratios" @@ -2627,7 +2587,7 @@ msgstr "Fils d’actu recommandés" #: src/view/com/auth/onboarding/RecommendedFollows.tsx:180 msgid "Recommended Users" -msgstr "Utilisateurs recommandés" +msgstr "Comptes recommandés" #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 @@ -2668,7 +2628,7 @@ msgstr "Supprimer l’aperçu d’image" #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" -msgstr "" +msgstr "Supprimer le reposts" #: src/view/com/feeds/FeedSourceCard.tsx:173 msgid "Remove this feed from my feeds?" @@ -2686,11 +2646,11 @@ msgstr "Supprimé de la liste" #: src/view/com/feeds/FeedSourceCard.tsx:111 #: src/view/com/feeds/FeedSourceCard.tsx:178 msgid "Removed from my feeds" -msgstr "" +msgstr "Supprimé de mes fils d’actu" #: src/view/com/composer/ExternalEmbed.tsx:71 msgid "Removes default thumbnail from {0}" -msgstr "" +msgstr "Supprime la miniature par défaut de {0}" #: src/view/screens/Profile.tsx:162 msgid "Replies" @@ -2703,7 +2663,7 @@ msgstr "Les réponses à ce fil de discussion sont désactivées" #: src/view/com/composer/Composer.tsx:347 msgctxt "action" msgid "Reply" -msgstr "" +msgstr "Répondre" #: src/view/screens/PreferencesHomeFeed.tsx:144 msgid "Reply Filters" @@ -2713,7 +2673,7 @@ msgstr "Filtres de réponse" #: src/view/com/posts/FeedItem.tsx:286 msgctxt "description" msgid "Reply to <0/>" -msgstr "" +msgstr "Réponse à <0/>" #: src/view/com/modals/report/Modal.tsx:166 msgid "Report {collectionName}" @@ -2742,7 +2702,7 @@ msgstr "Signaler le post" #: src/view/com/util/post-ctrls/RepostButton.tsx:61 msgctxt "action" msgid "Repost" -msgstr "" +msgstr "Republier" #: src/view/com/util/post-ctrls/RepostButton.web.tsx:48 msgid "Repost" @@ -2759,19 +2719,19 @@ msgstr "Republié par" #: src/view/com/posts/FeedItem.tsx:206 msgid "Reposted by {0})" -msgstr "" +msgstr "Republié par {0})" #: src/view/com/posts/FeedItem.tsx:223 msgid "Reposted by <0/>" -msgstr "" +msgstr "Republié par <0/>" #: src/view/com/notifications/FeedItem.tsx:162 msgid "reposted your post" -msgstr "" +msgstr "a republié votre post" #: src/view/com/post-thread/PostThreadItem.tsx:189 msgid "Reposts of this post" -msgstr "" +msgstr "Reposts de ce post" #: src/view/com/modals/ChangeEmail.tsx:181 #: src/view/com/modals/ChangeEmail.tsx:183 @@ -2784,7 +2744,7 @@ msgstr "Nécessiter un texte alt avant de publier" #: src/view/com/auth/create/Step2.tsx:68 msgid "Required for this provider" -msgstr "Obligatoire pour ce fournisseur" +msgstr "Obligatoire pour cet hébergeur" #: src/view/com/auth/login/SetNewPasswordForm.tsx:98 #: src/view/com/auth/login/SetNewPasswordForm.tsx:108 @@ -2793,11 +2753,11 @@ msgstr "Réinitialiser le code" #: src/view/screens/Settings.tsx:733 msgid "Reset onboarding" -msgstr "" +msgstr "Réinitialiser le didacticiel" #: src/view/screens/Settings.tsx:736 msgid "Reset onboarding state" -msgstr "Réinitialisation de l’état d’accueil" +msgstr "Réinitialisation du didacticiel" #: src/view/com/auth/login/ForgotPasswordForm.tsx:100 msgid "Reset password" @@ -2805,7 +2765,7 @@ msgstr "Réinitialiser mot de passe" #: src/view/screens/Settings.tsx:723 msgid "Reset preferences" -msgstr "" +msgstr "Réinitialiser les préférences" #: src/view/screens/Settings.tsx:726 msgid "Reset preferences state" @@ -2821,12 +2781,12 @@ msgstr "Réinitialise l’état des préférences" #: src/view/com/auth/login/LoginForm.tsx:266 msgid "Retries login" -msgstr "" +msgstr "Réessaye la connection" #: src/view/com/util/error/ErrorMessage.tsx:57 #: src/view/com/util/error/ErrorScreen.tsx:67 msgid "Retries the last action, which errored out" -msgstr "" +msgstr "Réessaye la dernière action, qui a échoué" #: src/view/com/auth/create/CreateAccount.tsx:163 #: src/view/com/auth/create/CreateAccount.tsx:167 @@ -2839,17 +2799,17 @@ msgstr "Réessayer" #: src/view/screens/ProfileList.tsx:877 msgid "Return to previous page" -msgstr "" +msgstr "Retourne à la page précédente" #: src/view/shell/desktop/RightNav.tsx:59 msgid "SANDBOX. Posts and accounts are not permanent." -msgstr "" +msgstr "SANDBOX. Les posts et les comptes ne sont pas permanents." #: src/view/com/lightbox/Lightbox.tsx:125 #: src/view/com/modals/CreateOrEditList.tsx:278 msgctxt "action" msgid "Save" -msgstr "" +msgstr "Enregistrer" #: src/view/com/modals/BirthDateSettings.tsx:94 #: src/view/com/modals/BirthDateSettings.tsx:97 @@ -2882,15 +2842,15 @@ msgstr "Fils d’actu enregistrés" #: src/view/com/modals/EditProfile.tsx:225 msgid "Saves any changes to your profile" -msgstr "" +msgstr "Enregistre toutes les modifications apportées à votre profil" #: src/view/com/modals/ChangeHandle.tsx:171 msgid "Saves handle change to {handle}" -msgstr "" +msgstr "Enregistre le changement de pseudo en {handle}" #: src/view/screens/ProfileList.tsx:833 msgid "Scroll to top" -msgstr "" +msgstr "Remonter en haut" #: src/Navigation.tsx:437 #: src/view/com/auth/LoggedOut.tsx:122 @@ -2913,7 +2873,7 @@ msgstr "Recherche" #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 msgid "Search for users" -msgstr "Rechercher des utilisateurs" +msgstr "Rechercher des personnes" #: src/view/com/modals/ChangeEmail.tsx:110 msgid "Security Step Required" @@ -2921,7 +2881,7 @@ msgstr "Étape de sécurité requise" #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" -msgstr "" +msgstr "Voir ce guide" #: src/view/com/auth/HomeLoggedOutCTA.tsx:39 msgid "See what's next" @@ -2929,7 +2889,7 @@ msgstr "Voir la suite" #: src/view/com/util/Selector.tsx:106 msgid "Select {item}" -msgstr "" +msgstr "Sélectionner {item}" #: src/view/com/modals/ServerInput.tsx:75 msgid "Select Bluesky Social" @@ -2941,7 +2901,7 @@ msgstr "Sélectionner un compte existant" #: src/view/com/util/Selector.tsx:107 msgid "Select option {i} of {numItems}" -msgstr "" +msgstr "Sélectionne l’option {i} sur {numItems}" #: src/view/com/auth/login/LoginForm.tsx:147 msgid "Select service" @@ -2949,7 +2909,7 @@ msgstr "Sélectionner un service" #: 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 "Sélectionnez les langues que vous souhaitez voir figurer dans les fils d’actu auxquels vous êtes abonné. Si aucune langue n’est sélectionnée, toutes les langues seront affichées." +msgstr "Sélectionnez les langues que vous souhaitez voir figurer dans les fils d’actu que vous suivez. Si aucune langue n’est sélectionnée, toutes les langues seront affichées." #: src/view/screens/LanguageSettings.tsx:98 msgid "Select your app language for the default text to display in the app" @@ -2971,11 +2931,7 @@ msgstr "Envoyer e-mail" #: src/view/com/modals/DeleteAccount.tsx:140 msgctxt "action" msgid "Send Email" -msgstr "" - -#: src/view/com/modals/DeleteAccount.tsx:138 -#~ msgid "Send Email" -#~ msgstr "Envoyer e-mail" +msgstr "Envoyer l’e-mail" #: src/view/shell/Drawer.tsx:295 #: src/view/shell/Drawer.tsx:316 @@ -2988,29 +2944,29 @@ msgstr "Envoyer le rapport" #: src/view/com/modals/DeleteAccount.tsx:129 msgid "Sends email with confirmation code for account deletion" -msgstr "" +msgstr "Envoie un e-mail avec le code de confirmation pour la suppression du compte" #: src/view/com/modals/ContentFilteringSettings.tsx:306 msgid "Set {value} for {labelGroup} content moderation policy" -msgstr "" +msgstr "Choisis {value} pour la politique de modération de contenu {labelGroup}" #: src/view/com/modals/ContentFilteringSettings.tsx:155 #: src/view/com/modals/ContentFilteringSettings.tsx:174 msgctxt "action" msgid "Set Age" -msgstr "" +msgstr "Enregistrer l’âge" #: src/view/screens/Settings.tsx:469 msgid "Set color theme to dark" -msgstr "" +msgstr "Change le thème de couleur en sombre" #: src/view/screens/Settings.tsx:462 msgid "Set color theme to light" -msgstr "" +msgstr "Change le thème de couleur en clair" #: src/view/screens/Settings.tsx:456 msgid "Set color theme to system setting" -msgstr "" +msgstr "Change le thème de couleur en fonction du paramètre système" #: src/view/com/auth/login/SetNewPasswordForm.tsx:78 msgid "Set new password" @@ -3018,7 +2974,7 @@ msgstr "Définir un nouveau mot de passe" #: src/view/com/auth/create/Step2.tsx:133 msgid "Set password" -msgstr "" +msgstr "Définis le mot de passe" #: src/view/screens/PreferencesHomeFeed.tsx:225 msgid "Set this setting to \"No\" to hide all quote posts from your feed. Reposts will still be visible." @@ -3042,23 +2998,23 @@ msgstr "Choisissez « Oui » pour afficher des échantillons de vos fils d’a #: src/view/com/modals/ChangeHandle.tsx:266 msgid "Sets Bluesky username" -msgstr "" +msgstr "Définis le pseudo Bluesky" #: src/view/com/auth/login/ForgotPasswordForm.tsx:153 msgid "Sets email for password reset" -msgstr "" +msgstr "Définis l’e-mail pour la réinitialisation du mot de passe" #: src/view/com/auth/login/ForgotPasswordForm.tsx:118 msgid "Sets hosting provider for password reset" -msgstr "" +msgstr "Définis l’hébergeur pour la réinitialisation du mot de passe" #: src/view/com/auth/create/Step1.tsx:143 msgid "Sets hosting provider to {label}" -msgstr "" +msgstr "Définis l’hébergeur à {label}" #: src/view/com/auth/login/LoginForm.tsx:148 msgid "Sets server for the Bluesky client" -msgstr "" +msgstr "Définis le serveur pour le client Bluesky" #: src/Navigation.tsx:136 #: src/view/screens/Settings.tsx:287 @@ -3075,7 +3031,7 @@ msgstr "Activité sexuelle ou nudité érotique." #: src/view/com/lightbox/Lightbox.tsx:134 msgctxt "action" msgid "Share" -msgstr "" +msgstr "Partager" #: src/view/com/profile/ProfileHeader.tsx:342 #: src/view/com/util/forms/PostDropdownBtn.tsx:151 @@ -3096,7 +3052,7 @@ msgstr "Afficher" #: src/view/screens/PreferencesHomeFeed.tsx:68 msgid "Show all replies" -msgstr "" +msgstr "Afficher toutes les réponses" #: src/view/com/util/moderation/ScreenHider.tsx:132 msgid "Show anyway" @@ -3104,17 +3060,17 @@ msgstr "Afficher quand même" #: src/view/com/modals/EmbedConsent.tsx:87 msgid "Show embeds from {0}" -msgstr "" +msgstr "Afficher les intégrations de {0}" #: src/view/com/profile/ProfileHeader.tsx:498 msgid "Show follows similar to {0}" -msgstr "" +msgstr "Afficher les suivis similaires à {0}" #: src/view/com/post-thread/PostThreadItem.tsx:569 #: src/view/com/post/Post.tsx:196 #: src/view/com/posts/FeedItem.tsx:362 msgid "Show More" -msgstr "" +msgstr "Voir plus" #: src/view/screens/PreferencesHomeFeed.tsx:258 msgid "Show Posts from My Feeds" @@ -3122,7 +3078,7 @@ msgstr "Afficher les posts de mes fils d’actu" #: src/view/screens/PreferencesHomeFeed.tsx:222 msgid "Show Quote Posts" -msgstr "Afficher les posts de citation" +msgstr "Afficher les citations" #: src/view/screens/PreferencesHomeFeed.tsx:119 msgid "Show Replies" @@ -3134,7 +3090,7 @@ msgstr "Afficher les réponses des personnes que vous suivez avant toutes les au #: src/view/screens/PreferencesHomeFeed.tsx:70 msgid "Show replies with at least {value} {0}" -msgstr "" +msgstr "Afficher les réponses avec au moins {value} {0}" #: src/view/screens/PreferencesHomeFeed.tsx:188 msgid "Show Reposts" @@ -3143,19 +3099,19 @@ msgstr "Afficher les reposts" #: src/view/com/util/moderation/ContentHider.tsx:67 #: src/view/com/util/moderation/PostHider.tsx:61 msgid "Show the content" -msgstr "" +msgstr "Afficher le contenu" #: src/view/com/notifications/FeedItem.tsx:350 msgid "Show users" -msgstr "Afficher les utilisateurs" +msgstr "Afficher les comptes" #: src/view/com/profile/ProfileHeader.tsx:501 msgid "Shows a list of users similar to this user." -msgstr "" +msgstr "Affiche une liste de comptes similaires à ce compte." #: src/view/com/profile/ProfileHeader.tsx:545 msgid "Shows posts from {0} in your feed" -msgstr "" +msgstr "Affiche les posts de {0} dans votre fil d’actu" #: src/view/com/auth/HomeLoggedOutCTA.tsx:70 #: src/view/com/auth/login/Login.tsx:98 @@ -3223,11 +3179,11 @@ msgstr "Connecté en tant que" #: src/view/com/auth/login/ChooseAccountForm.tsx:103 msgid "Signed in as @{0}" -msgstr "" +msgstr "Connecté comme @{0}" #: src/view/com/modals/SwitchAccount.tsx:66 msgid "Signs {0} out of Bluesky" -msgstr "" +msgstr "Déconnecte {0} de Bluesky" #: src/view/com/auth/onboarding/WelcomeMobile.tsx:33 msgid "Skip" @@ -3235,15 +3191,15 @@ msgstr "Ignorer" #: src/view/com/modals/ProfilePreview.tsx:62 msgid "Something went wrong and we're not sure what." -msgstr "" +msgstr "Quelque chose a échoué et on ne sait pas trop quoi." #: src/view/com/modals/Waitlist.tsx:51 msgid "Something went wrong. Check your email and try again." -msgstr "" +msgstr "Quelque chose a échoué. Vérifiez vos e-mails et réessayez." #: src/App.native.tsx:57 msgid "Sorry! Your session expired. Please log in again." -msgstr "" +msgstr "Désolé ! Votre session a expiré. Essayez de vous reconnecter." #: src/view/screens/PreferencesThreads.tsx:69 msgid "Sort Replies" @@ -3260,19 +3216,19 @@ msgstr "Carré" #: src/view/com/auth/create/Step1.tsx:90 #: src/view/com/modals/ServerInput.tsx:62 msgid "Staging" -msgstr "Mise en scène" +msgstr "Serveur de test" #: src/view/screens/Settings.tsx:780 msgid "Status page" -msgstr "Page de statut" +msgstr "État du service" #: src/view/com/auth/create/StepHeader.tsx:15 msgid "Step {step} of 3" -msgstr "" +msgstr "Étape {step} sur 3" #: src/view/screens/Settings.tsx:269 msgid "Storage cleared, you need to restart the app now." -msgstr "" +msgstr "Stockage effacé, vous devez redémarrer l’application maintenant." #: src/view/screens/Settings.tsx:716 msgid "Storybook" @@ -3292,7 +3248,7 @@ msgstr "S’abonner à cette liste" #: src/view/com/lists/ListCard.tsx:101 msgid "Subscribed" -msgstr "" +msgstr "Abonné·e" #: src/view/screens/Search/Search.tsx:362 msgid "Suggested Follows" @@ -3300,11 +3256,11 @@ msgstr "Suivis suggérés" #: src/view/com/profile/ProfileHeaderSuggestedFollows.tsx:64 msgid "Suggested for you" -msgstr "" +msgstr "Suggérés pour vous" #: src/view/com/modals/SelfLabel.tsx:95 msgid "Suggestive" -msgstr "" +msgstr "Suggestif" #: src/Navigation.tsx:214 #: src/view/screens/Support.tsx:30 @@ -3314,7 +3270,7 @@ msgstr "Soutien" #: src/view/com/modals/ProfilePreview.tsx:110 msgid "Swipe up to see more" -msgstr "" +msgstr "Glisser vers le haut pour en voir plus" #: src/view/com/modals/SwitchAccount.tsx:117 msgid "Switch Account" @@ -3323,16 +3279,16 @@ msgstr "Changer de compte" #: src/view/com/modals/SwitchAccount.tsx:97 #: src/view/screens/Settings.tsx:132 msgid "Switch to {0}" -msgstr "" +msgstr "Basculer sur {0}" #: src/view/com/modals/SwitchAccount.tsx:98 #: src/view/screens/Settings.tsx:133 msgid "Switches the account you are logged in to" -msgstr "" +msgstr "Bascule le compte auquel vous êtes connectés vers" #: src/view/screens/Settings.tsx:453 msgid "System" -msgstr "" +msgstr "Système" #: src/view/screens/Settings.tsx:696 msgid "System log" @@ -3344,7 +3300,7 @@ msgstr "Grand" #: src/view/com/util/images/AutoSizedImage.tsx:70 msgid "Tap to view fully" -msgstr "" +msgstr "Tapper pour voir en entier" #: src/view/shell/desktop/RightNav.tsx:93 msgid "Terms" @@ -3384,11 +3340,7 @@ msgstr "Notre politique de confidentialité a été déplacée vers <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 "" - -#: 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 "Le formulaire d’assistance a été déplacé. Si vous avez besoin d’aide, veuillez <0/> ou rendez-vous sur {HELP_DESK_URL} pour nous contacter." +msgstr "Le formulaire d’assistance a été déplacé. Si vous avez besoin d’aide, veuillez <0/> ou rendez-vous sur {HELP_DESK_URL} pour nous contacter." #: src/view/screens/TermsOfService.tsx:33 msgid "The Terms of Service have been moved to" @@ -3396,15 +3348,15 @@ msgstr "Nos conditions d’utilisation ont été déplacées vers" #: src/view/screens/ProfileFeed.tsx:558 msgid "There was an an issue contacting the server, please check your internet connection and try again." -msgstr "" +msgstr "Il y a eu un problème de connexion au serveur, veuillez vérifier votre connexion Internet et réessayez." #: 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 "Il y a eu un problème lors de la suppression du fil, veuillez vérifier votre connexion Internet et réessayez." #: src/view/screens/ProfileFeed.tsx:218 msgid "There was an an issue updating your feeds, please check your internet connection and try again." -msgstr "" +msgstr "Il y a eu un problème lors de la mise à jour de vos fils d’actu, veuillez vérifier votre connexion Internet et réessayez." #: src/view/screens/ProfileFeed.tsx:245 #: src/view/screens/ProfileList.tsx:266 @@ -3412,7 +3364,7 @@ msgstr "" #: src/view/screens/SavedFeeds.tsx:231 #: src/view/screens/SavedFeeds.tsx:252 msgid "There was an issue contacting the server" -msgstr "" +msgstr "Il y a eu un problème de connexion au serveur" #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:57 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:66 @@ -3420,32 +3372,32 @@ msgstr "" #: src/view/com/feeds/FeedSourceCard.tsx:127 #: src/view/com/feeds/FeedSourceCard.tsx:181 msgid "There was an issue contacting your server" -msgstr "" +msgstr "Il y a eu un problème de connexion à votre serveur" #: src/view/com/notifications/Feed.tsx:115 msgid "There was an issue fetching notifications. Tap here to try again." -msgstr "" +msgstr "Il y a eu un problème lors de la récupération des notifications. Appuyez ici pour réessayer." #: src/view/com/posts/Feed.tsx:261 msgid "There was an issue fetching posts. Tap here to try again." -msgstr "" +msgstr "Il y a eu un problème lors de la récupération des posts. Appuyez ici pour réessayer." #: src/view/com/lists/ListMembers.tsx:172 msgid "There was an issue fetching the list. Tap here to try again." -msgstr "" +msgstr "Il y a eu un problème lors de la récupération de la liste. Appuyez ici pour réessayer." #: 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 "Il y a eu un problème lors de la récupération de vos listes. Appuyez ici pour réessayer." #: src/view/com/modals/ContentFilteringSettings.tsx:126 msgid "There was an issue syncing your preferences with the server" -msgstr "" +msgstr "Il y a eu un problème de synchronisation de vos préférences avec le serveur" #: src/view/screens/AppPasswords.tsx:66 msgid "There was an issue with fetching your app passwords" -msgstr "" +msgstr "Il y a eu un problème lors de la récupération de vos mots de passe d’application" #: src/view/com/profile/ProfileHeader.tsx:204 #: src/view/com/profile/ProfileHeader.tsx:225 @@ -3454,37 +3406,34 @@ msgstr "" #: src/view/com/profile/ProfileHeader.tsx:297 #: src/view/com/profile/ProfileHeader.tsx:319 msgid "There was an issue! {0}" -msgstr "" +msgstr "Il y a eu un problème ! {0}" #: src/view/screens/ProfileList.tsx:287 #: src/view/screens/ProfileList.tsx:306 #: src/view/screens/ProfileList.tsx:328 #: src/view/screens/ProfileList.tsx:347 msgid "There was an issue. Please check your internet connection and try again." -msgstr "" +msgstr "Il y a eu un problème. Veuillez vérifier votre connexion Internet et réessayez." #: src/view/com/util/ErrorBoundary.tsx:35 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é !" -#~ msgid "This {0} has been labeled." -#~ msgstr "Ce {0} a été classé." - #: src/view/com/util/moderation/ScreenHider.tsx:88 msgid "This {screenDescription} has been flagged:" 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." -msgstr "Ce compte a demandé aux utilisateurs de s’identifier pour voir son profil." +msgstr "Ce compte a demandé aux personnes de s’identifier 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 "" +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." -msgstr "" +msgstr "Ce contenu n’est pas disponible car l’un des comptes impliqués a bloqué l’autre." #: src/view/com/posts/FeedErrorMessage.tsx:108 msgid "This content is not viewable without a Bluesky account." @@ -3498,15 +3447,15 @@ msgstr "Ce fil d’actu reçoit actuellement un trafic important, il est tempora #: src/view/screens/ProfileFeed.tsx:484 #: src/view/screens/ProfileList.tsx:639 msgid "This feed is empty!" -msgstr "" +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 "" +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." -msgstr "Ces informations ne sont pas partagées avec d’autres utilisateurs." +msgstr "Ces informations ne sont pas partagées avec d’autres personnes." #: src/view/com/modals/VerifyEmail.tsx:119 msgid "This is important in case you ever need to change your email or reset your password." @@ -3522,11 +3471,11 @@ msgstr "Ce lien vous conduit au site Web suivant :" #: src/view/screens/ProfileList.tsx:813 msgid "This list is empty!" -msgstr "" +msgstr "Cette liste est vide !" #: src/view/com/modals/AddAppPasswords.tsx:105 msgid "This name is already in use" -msgstr "" +msgstr "Ce nom est déjà utilisé" #: src/view/com/post-thread/PostThreadItem.tsx:123 msgid "This post has been deleted." @@ -3534,15 +3483,15 @@ msgstr "Ce post a été supprimé." #: src/view/com/modals/ModerationDetails.tsx:62 msgid "This user has blocked you. You cannot view their content." -msgstr "" +msgstr "Ce compte vous a bloqué. Vous ne pouvez pas voir son contenu." #: src/view/com/modals/ModerationDetails.tsx:42 msgid "This user is included in the <0/> list which you have blocked." -msgstr "" +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 the <0/> list which you have muted." -msgstr "" +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." @@ -3563,7 +3512,7 @@ msgstr "Mode arborescent" #: src/Navigation.tsx:254 msgid "Threads Preferences" -msgstr "" +msgstr "Préférences de fils de discussion" #: src/view/com/util/forms/DropdownButton.tsx:234 msgid "Toggle dropdown" @@ -3582,11 +3531,7 @@ msgstr "Traduire" #: src/view/com/util/error/ErrorScreen.tsx:75 msgctxt "action" msgid "Try again" -msgstr "" - -#: src/view/com/util/error/ErrorScreen.tsx:73 -#~ msgid "Try again" -#~ msgstr "Réessayer" +msgstr "Réessayer" #: src/view/screens/ProfileList.tsx:484 msgid "Un-block list" @@ -3606,7 +3551,7 @@ msgstr "Impossible de contacter votre service. Veuillez vérifier votre connexio #: src/view/com/profile/ProfileHeader.tsx:475 msgctxt "action" msgid "Unblock" -msgstr "" +msgstr "Débloquer" #: src/view/com/profile/ProfileHeader.tsx:472 #: src/view/screens/ProfileList.tsx:568 @@ -3628,11 +3573,11 @@ msgstr "Annuler le repost" #: src/view/com/profile/FollowButton.tsx:55 msgctxt "action" msgid "Unfollow" -msgstr "" +msgstr "Se désabonner" #: src/view/com/profile/ProfileHeader.tsx:524 msgid "Unfollow {0}" -msgstr "" +msgstr "Se désabonner de {0}" #: src/view/com/auth/create/state.ts:216 msgid "Unfortunately, you do not meet the requirements to create an account." @@ -3640,11 +3585,11 @@ msgstr "Malheureusement, vous ne remplissez pas les conditions requises pour cr #: src/view/com/util/post-ctrls/PostCtrls.tsx:189 msgid "Unlike" -msgstr "" +msgstr "Déliker" #: src/view/screens/ProfileList.tsx:575 msgid "Unmute" -msgstr "" +msgstr "Réafficher" #: src/view/com/profile/ProfileHeader.tsx:373 msgid "Unmute Account" @@ -3657,7 +3602,7 @@ msgstr "Réafficher ce fil de discussion" #: src/view/screens/ProfileFeed.tsx:362 #: src/view/screens/ProfileList.tsx:559 msgid "Unpin" -msgstr "" +msgstr "Désépingler" #: src/view/screens/ProfileList.tsx:452 msgid "Unpin moderation list" @@ -3665,7 +3610,7 @@ msgstr "Supprimer la liste de modération" #: src/view/screens/ProfileFeed.tsx:354 msgid "Unsave" -msgstr "" +msgstr "Supprimer" #: src/view/com/modals/UserAddRemoveLists.tsx:54 msgid "Update {displayName} in Lists" @@ -3681,11 +3626,11 @@ msgstr "Mise à jour…" #: src/view/com/modals/ChangeHandle.tsx:455 msgid "Upload a text file to:" -msgstr "Télécharger 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." -msgstr "Utiliser les mots de passe de l’appli pour se connecter à d’autres clients Bluesky sans donner un accès complet à votre compte ou à votre mot de passe." +msgstr "Utilisez les mots de passe de l’appli pour se connecter à d’autres clients Bluesky sans donner un accès complet à votre compte ou à votre mot de passe." #: src/view/com/modals/ChangeHandle.tsx:515 msgid "Use default provider" @@ -3697,7 +3642,7 @@ msgstr "Utilisez-le pour vous connecter à l’autre application avec votre iden #: src/view/com/modals/ServerInput.tsx:105 msgid "Use your domain as your Bluesky client service provider" -msgstr "" +msgstr "Utilise votre domaine comme un fournisseur de client Bluesky" #: src/view/com/modals/InviteCodes.tsx:200 msgid "Used by:" @@ -3705,63 +3650,63 @@ msgstr "Utilisé par :" #: src/view/com/modals/ModerationDetails.tsx:54 msgid "User Blocked" -msgstr "" +msgstr "Compte bloqué" #: src/view/com/modals/ModerationDetails.tsx:40 msgid "User Blocked by List" -msgstr "" +msgstr "Compte bloqué par liste" #: src/view/com/modals/ModerationDetails.tsx:60 msgid "User Blocks You" -msgstr "" +msgstr "Compte qui vous bloque" #: src/view/com/auth/create/Step3.tsx:38 msgid "User handle" -msgstr "Pseudo utilisateur" +msgstr "Pseudo" #: src/view/com/lists/ListCard.tsx:84 #: src/view/com/modals/UserAddRemoveLists.tsx:182 msgid "User list by {0}" -msgstr "" +msgstr "Liste de compte de {0}" #: src/view/screens/ProfileList.tsx:741 msgid "User list by <0/>" -msgstr "" +msgstr "Liste de compte par <0/>" #: src/view/com/lists/ListCard.tsx:82 #: src/view/com/modals/UserAddRemoveLists.tsx:180 #: src/view/screens/ProfileList.tsx:739 msgid "User list by you" -msgstr "" +msgstr "Liste de compte par vous" #: src/view/com/modals/CreateOrEditList.tsx:138 msgid "User list created" -msgstr "" +msgstr "Liste de compte créée" #: src/view/com/modals/CreateOrEditList.tsx:125 msgid "User list updated" -msgstr "" +msgstr "Liste de compte mise à jour" #: src/view/screens/Lists.tsx:58 msgid "User Lists" -msgstr "Listes d’utilisateurs" +msgstr "Listes de comptes" #: src/view/com/auth/login/LoginForm.tsx:174 #: src/view/com/auth/login/LoginForm.tsx:192 msgid "Username or email address" -msgstr "Nom d’utilisateur ou e-mail" +msgstr "Pseudo ou e-mail" #: src/view/screens/ProfileList.tsx:775 msgid "Users" -msgstr "Utilisateurs" +msgstr "Comptes" #: src/view/com/threadgate/WhoCanReply.tsx:143 msgid "users followed by <0/>" -msgstr "utilisateurs suivis par <0/>" +msgstr "comptes suivis par <0/>" #: src/view/com/modals/Threadgate.tsx:106 msgid "Users in \"{0}\"" -msgstr "Utilisateurs dans « {0} »" +msgstr "Comptes dans « {0} »" #: src/view/screens/Settings.tsx:819 msgid "Verify email" @@ -3782,11 +3727,11 @@ msgstr "Confirmer le nouvel e-mail" #: src/view/com/modals/VerifyEmail.tsx:103 msgid "Verify Your Email" -msgstr "" +msgstr "Vérifiez votre e-mail" #: src/view/com/profile/ProfileHeader.tsx:701 msgid "View {0}'s avatar" -msgstr "" +msgstr "Voir l’avatar de {0}" #: src/view/screens/Log.tsx:52 msgid "View debug entry" @@ -3794,11 +3739,11 @@ msgstr "Afficher l’entrée de débogage" #: src/view/com/posts/FeedSlice.tsx:103 msgid "View full thread" -msgstr "" +msgstr "Voir le fil de discussion entier" #: src/view/com/posts/FeedErrorMessage.tsx:172 msgid "View profile" -msgstr "" +msgstr "Voir le profil" #: src/view/com/profile/ProfileSubpageHeader.tsx:128 msgid "View the avatar" @@ -3810,11 +3755,11 @@ msgstr "Visiter le site" #: src/view/com/modals/ContentFilteringSettings.tsx:254 msgid "Warn" -msgstr "" +msgstr "Avertir" #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." -msgstr "" +msgstr "Nous examinerons votre appel rapidement." #: src/view/com/auth/create/CreateAccount.tsx:122 msgid "We're so excited to have you join us!" @@ -3822,7 +3767,7 @@ msgstr "Nous sommes ravis de vous accueillir !" #: src/view/screens/ProfileList.tsx:83 msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." -msgstr "" +msgstr "Nous sommes désolés, mais nous n’avons pas pu résoudre cette liste. Si cela persiste, veuillez contacter l’origine de la liste, @{handleOrDid}." #: src/view/screens/Search/Search.tsx:243 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." @@ -3883,7 +3828,7 @@ msgstr "Oui" #: 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 "Vous pouvez aussi découvrir de nouveaux fils d’actu personnalisés à suivre." #: src/view/com/auth/create/Step1.tsx:106 msgid "You can change hosting providers at any time." @@ -3916,11 +3861,11 @@ msgstr "Vous avez bloqué cet auteur ou vous avez été bloqué par celui-ci." #: src/view/com/modals/ModerationDetails.tsx:56 msgid "You have blocked this user. You cannot view their content." -msgstr "" +msgstr "Vous avez bloqué ce compte. Vous ne pouvez pas voir son contenu." #: src/view/com/modals/ModerationDetails.tsx:87 msgid "You have muted this user." -msgstr "" +msgstr "Vous avez masqué ce compte." #: src/view/com/feeds/ProfileFeedgens.tsx:136 msgid "You have no feeds." @@ -3945,15 +3890,15 @@ msgstr "Vous n’avez encore masqué aucun compte. Pour désactiver un compte, a #: src/view/com/modals/ContentFilteringSettings.tsx:170 msgid "You must be 18 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:96 msgid "You will no longer receive notifications for this thread" -msgstr "" +msgstr "Vous ne recevrez plus de notifications pour ce fil de discussion" #: src/view/com/util/forms/PostDropdownBtn.tsx:99 msgid "You will now receive notifications for this thread" -msgstr "" +msgstr "Vous recevrez désormais des notifications pour ce fil de discussion" #: src/view/com/auth/login/SetNewPasswordForm.tsx:81 msgid "You will receive an email with a \"reset code.\" Enter that code here, then enter your new password." @@ -3961,7 +3906,7 @@ msgstr "Vous recevrez un e-mail contenant un « code de réinitialisation » S #: src/view/com/posts/FollowingEndOfFeed.tsx:48 msgid "You've reached the end of your feed! Find some more accounts to follow." -msgstr "" +msgstr "Vous avez atteint la fin de votre fil d’actu ! Trouvez d’autres comptes à suivre." #: src/view/com/auth/create/Step2.tsx:58 msgid "Your account" @@ -3969,7 +3914,7 @@ msgstr "Votre compte" #: src/view/com/modals/DeleteAccount.tsx:65 msgid "Your account has been deleted" -msgstr "" +msgstr "Votre compte a été supprimé" #: src/view/com/auth/create/Step2.tsx:146 msgid "Your birth date" @@ -3994,7 +3939,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 "" +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/Step3.tsx:42 msgid "Your full handle will be" @@ -4002,11 +3947,11 @@ msgstr "Votre nom complet sera" #: src/view/com/modals/ChangeHandle.tsx:270 msgid "Your full handle will be <0>@{0}" -msgstr "" +msgstr "Votre pseudo complet sera <0>@{0}" #: src/view/com/auth/create/Step1.tsx:53 msgid "Your hosting provider" -msgstr "Votre fournisseur d’hébergement" +msgstr "Votre hébergeur" #: src/view/screens/Settings.tsx:417 #: src/view/shell/desktop/RightNav.tsx:137 @@ -4016,12 +3961,12 @@ msgstr "Vos codes d’invitation sont cachés lorsque vous êtes connecté à l #: src/view/com/composer/Composer.tsx:266 msgid "Your post has been published" -msgstr "" +msgstr "Votre post a été publié" #: 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 "Vos posts, les mentions « J’aime » et les blocages sont publics. Les silences (comptes masqués) sont privés." +msgstr "Vos posts, les likes et les blocages sont publics. Les silences (comptes masqués) sont privés." #: src/view/com/modals/SwitchAccount.tsx:84 #: src/view/screens/Settings.tsx:120 @@ -4030,7 +3975,7 @@ msgstr "Votre profil" #: src/view/com/composer/Composer.tsx:265 msgid "Your reply has been published" -msgstr "" +msgstr "Votre réponse a été publiée" #: src/view/com/auth/create/Step3.tsx:28 msgid "Your user handle" From 46d0d911e15bed008ec03bbbd7dbd04b54881e2e Mon Sep 17 00:00:00 2001 From: "Stanislas Signoud (Signez)" Date: Fri, 12 Jan 2024 23:04:35 +0100 Subject: [PATCH 03/28] Improve French localization thanks to reviews Thanks to @fenarinarsa for all the review work! --- src/locale/locales/fr/messages.po | 64 +++++++++++++++---------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/locale/locales/fr/messages.po b/src/locale/locales/fr/messages.po index c02b8ac819..4671b6e88d 100644 --- a/src/locale/locales/fr/messages.po +++ b/src/locale/locales/fr/messages.po @@ -62,7 +62,7 @@ msgstr "<0/> membres" #: src/view/com/profile/ProfileHeader.tsx:634 msgid "<0>{following} <1>following" -msgstr "<0>{following} <1>abonné·e·s" +msgstr "<0>{following} <1>abonnements" #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:30 msgid "<0>Choose your<1>Recommended<2>Feeds" @@ -121,7 +121,7 @@ msgstr "Compte masqué" #: src/view/com/modals/ModerationDetails.tsx:72 msgid "Account Muted by List" -msgstr "Compte masqué par list" +msgstr "Compte masqué par liste" #: src/view/com/util/AccountDropdownBtn.tsx:41 msgid "Account options" @@ -948,7 +948,7 @@ msgstr "Ignorer le brouillon" #: src/view/screens/Moderation.tsx:207 msgid "Discourage apps from showing my account to logged-out users" -msgstr "Empêcher les applis de montrer mon compte aux personnes déconnectées" +msgstr "Empêcher les applis de montrer mon compte aux personnes non connectées" #: src/view/com/posts/FollowingEmptyState.tsx:74 #: src/view/com/posts/FollowingEndOfFeed.tsx:75 @@ -1078,7 +1078,7 @@ msgstr "Modifier les fils d’actu enregistrés" #: src/view/com/modals/CreateOrEditList.tsx:188 msgid "Edit User List" -msgstr "Modifier la liste de compte" +msgstr "Modifier la liste de comptes" #: src/view/com/modals/EditProfile.tsx:193 msgid "Edit your display name" @@ -1196,20 +1196,20 @@ msgstr "Tout le monde" #: src/view/com/modals/ChangeHandle.tsx:150 msgid "Exits handle change process" -msgstr "Sors du processus de changement de pseudo" +msgstr "Sort du processus de changement de pseudo" #: src/view/com/lightbox/Lightbox.web.tsx:113 msgid "Exits image view" -msgstr "Sors de la vue de l’image" +msgstr "Sort de la vue de l’image" #: src/view/com/modals/ListAddRemoveUsers.tsx:88 #: src/view/shell/desktop/Search.tsx:182 msgid "Exits inputting search query" -msgstr "Sors de la saisie de la recherche" +msgstr "Sort de la saisie de la recherche" #: src/view/com/modals/Waitlist.tsx:138 msgid "Exits signing up for waitlist with {email}" -msgstr "Sors de l’inscription sur la liste d’attente avec {email}" +msgstr "Sort de l’inscription sur la liste d’attente avec {email}" #: src/view/com/lightbox/Lightbox.web.tsx:156 msgid "Expand alt text" @@ -1218,7 +1218,7 @@ msgstr "Développer le texte alt" #: 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 "Étend ou rétrécit le post complet auquel vous répondez" +msgstr "Développe ou réduit le post complet auquel vous répondez" #: src/view/com/modals/EmbedConsent.tsx:64 msgid "External Media" @@ -1294,7 +1294,7 @@ msgstr "Les fils d’actu sont créés par d’autres personnes pour rassembler #: src/view/screens/SavedFeeds.tsx:156 msgid "Feeds are custom algorithms that users build with a little coding expertise. <0/> for more information." -msgstr "Les fils d’actu sont des algorithmes personnalisés qui se construisent avec un peu d’expertise en codage. <0/> pour plus d’informations." +msgstr "Les fils d’actu sont des algorithmes personnalisés qui se construisent avec un peu d’expertise en programmation. <0/> pour plus d’informations." #: src/view/com/posts/CustomFeedEmptyState.tsx:47 #: src/view/com/posts/FollowingEmptyState.tsx:57 @@ -1488,19 +1488,19 @@ msgstr "Masque les posts de {0} dans votre fil d’actu" #: 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, un problème s’est produit avec le serveur de fils d’actu. Veuillez informer la personne à l’origine du fil d’actu de ce problème." +msgstr "Hmm, un problème s’est produit avec le serveur de fils d’actu. Veuillez informer la personne propriétaire du fil d’actu de ce problème." #: 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, le serveur du fils d’actu semble être mal configuré. Veuillez informer la personne à l’origine du fil d’actu de ce problème." +msgstr "Hmm, le serveur du fils d’actu semble être mal configuré. Veuillez informer la personne propriétaire du fil d’actu de ce problème." #: 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 "Mmm… le serveur de fils d’actu semble être hors ligne. Veuillez informer la personne à l’origine du fil d’actu de ce problème." +msgstr "Mmm… le serveur de fils d’actu semble être hors ligne. Veuillez informer la personne propriétaire du fil d’actu de ce problème." #: 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 "Mmm… le serveur de fils d’actu ne répond pas. Veuillez informer la personne à l’origine du fil d’actu de ce problème." +msgstr "Mmm… le serveur de fils d’actu ne répond pas. Veuillez informer la personne propriétaire du fil d’actu de ce problème." #: src/view/com/posts/FeedErrorMessage.tsx:96 msgid "Hmm, we're having trouble finding this feed. It may have been deleted." @@ -1544,7 +1544,7 @@ msgstr "J’ai mon propre domaine" #: src/view/com/lightbox/Lightbox.web.tsx:158 msgid "If alt text is long, toggles alt text expanded state" -msgstr "Si le texte alternatif est trop long, affiche le texte alternatif complet" +msgstr "Si le texte alternatif est trop long, change son mode d’affichage" #: src/view/com/modals/SelfLabel.tsx:127 msgid "If none are selected, suitable for all ages." @@ -1741,7 +1741,7 @@ msgstr "Clair" #: src/view/com/util/post-ctrls/PostCtrls.tsx:189 msgid "Like" -msgstr "Aimer" +msgstr "Liker" #: src/view/screens/ProfileFeed.tsx:600 msgid "Like this feed" @@ -2160,7 +2160,7 @@ msgstr "Pas maintenant" #: src/view/screens/Moderation.tsx:232 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 dé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:447 #: src/view/screens/Notifications.tsx:113 @@ -2398,7 +2398,7 @@ msgstr "Lire la vidéo" #: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:110 msgid "Plays the GIF" -msgstr "Lis le GIF" +msgstr "Lit le GIF" #: src/view/com/auth/create/state.ts:116 msgid "Please choose your handle." @@ -2628,7 +2628,7 @@ msgstr "Supprimer l’aperçu d’image" #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" -msgstr "Supprimer le reposts" +msgstr "Supprimer le repost" #: src/view/com/feeds/FeedSourceCard.tsx:173 msgid "Remove this feed from my feeds?" @@ -2873,7 +2873,7 @@ msgstr "Recherche" #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 msgid "Search for users" -msgstr "Rechercher des personnes" +msgstr "Rechercher des comptes" #: src/view/com/modals/ChangeEmail.tsx:110 msgid "Security Step Required" @@ -2974,7 +2974,7 @@ msgstr "Définir un nouveau mot de passe" #: src/view/com/auth/create/Step2.tsx:133 msgid "Set password" -msgstr "Définis le mot de passe" +msgstr "Définit le mot de passe" #: src/view/screens/PreferencesHomeFeed.tsx:225 msgid "Set this setting to \"No\" to hide all quote posts from your feed. Reposts will still be visible." @@ -2998,23 +2998,23 @@ msgstr "Choisissez « Oui » pour afficher des échantillons de vos fils d’a #: src/view/com/modals/ChangeHandle.tsx:266 msgid "Sets Bluesky username" -msgstr "Définis le pseudo Bluesky" +msgstr "Définit le pseudo Bluesky" #: src/view/com/auth/login/ForgotPasswordForm.tsx:153 msgid "Sets email for password reset" -msgstr "Définis l’e-mail pour la réinitialisation du mot de passe" +msgstr "Définit l’e-mail pour la réinitialisation du mot de passe" #: src/view/com/auth/login/ForgotPasswordForm.tsx:118 msgid "Sets hosting provider for password reset" -msgstr "Définis l’hébergeur pour la réinitialisation du mot de passe" +msgstr "Définit l’hébergeur pour la réinitialisation du mot de passe" #: src/view/com/auth/create/Step1.tsx:143 msgid "Sets hosting provider to {label}" -msgstr "Définis l’hébergeur à {label}" +msgstr "Définit l’hébergeur à {label}" #: src/view/com/auth/login/LoginForm.tsx:148 msgid "Sets server for the Bluesky client" -msgstr "Définis le serveur pour le client Bluesky" +msgstr "Définit le serveur pour le client Bluesky" #: src/Navigation.tsx:136 #: src/view/screens/Settings.tsx:287 @@ -3179,7 +3179,7 @@ msgstr "Connecté en tant que" #: src/view/com/auth/login/ChooseAccountForm.tsx:103 msgid "Signed in as @{0}" -msgstr "Connecté comme @{0}" +msgstr "Connecté en tant que @{0}" #: src/view/com/modals/SwitchAccount.tsx:66 msgid "Signs {0} out of Bluesky" @@ -3191,11 +3191,11 @@ msgstr "Ignorer" #: src/view/com/modals/ProfilePreview.tsx:62 msgid "Something went wrong and we're not sure what." -msgstr "Quelque chose a échoué et on ne sait pas trop quoi." +msgstr "Quelque chose n’a pas marché, mais on ne sait pas trop quoi." #: src/view/com/modals/Waitlist.tsx:51 msgid "Something went wrong. Check your email and try again." -msgstr "Quelque chose a échoué. Vérifiez vos e-mails et réessayez." +msgstr "Quelque chose n’a pas marché. Vérifiez vos e-mails et réessayez." #: src/App.native.tsx:57 msgid "Sorry! Your session expired. Please log in again." @@ -3425,7 +3425,7 @@ 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." -msgstr "Ce compte a demandé aux personnes de s’identifier pour voir son profil." +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?" @@ -3642,7 +3642,7 @@ msgstr "Utilisez-le pour vous connecter à l’autre application avec votre iden #: src/view/com/modals/ServerInput.tsx:105 msgid "Use your domain as your Bluesky client service provider" -msgstr "Utilise votre domaine comme un fournisseur de client Bluesky" +msgstr "Utilise votre domaine comme votre fournisseur de client Bluesky" #: src/view/com/modals/InviteCodes.tsx:200 msgid "Used by:" @@ -3767,7 +3767,7 @@ msgstr "Nous sommes ravis de vous accueillir !" #: src/view/screens/ProfileList.tsx:83 msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." -msgstr "Nous sommes désolés, mais nous n’avons pas pu résoudre cette liste. Si cela persiste, veuillez contacter l’origine de la liste, @{handleOrDid}." +msgstr "Nous sommes désolés, mais nous n’avons pas pu charger cette liste. Si cela persiste, veuillez contacter l’origine de la liste, @{handleOrDid}." #: src/view/screens/Search/Search.tsx:243 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." From 921b57d1b7b0dab48ed2627725460748fd1a6ff3 Mon Sep 17 00:00:00 2001 From: Mary <148872143+mary-ext@users.noreply.github.com> Date: Tue, 16 Jan 2024 04:11:48 +0700 Subject: [PATCH 04/28] feat: show muted/blocked status on list card (#2523) --- src/view/com/lists/ListCard.tsx | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/view/com/lists/ListCard.tsx b/src/view/com/lists/ListCard.tsx index 28e98144a4..5750faec19 100644 --- a/src/view/com/lists/ListCard.tsx +++ b/src/view/com/lists/ListCard.tsx @@ -94,15 +94,23 @@ export const ListCard = ({ ))} - {!!list.viewer?.muted && ( - + + {list.viewer?.muted ? ( - Subscribed + Muted - - )} + ) : null} + + {list.viewer?.blocked ? ( + + + Blocked + + + ) : null} + {renderButton ? ( {renderButton()} From 1d3e20220d7ed18480e5c852d032aae882efacb3 Mon Sep 17 00:00:00 2001 From: bnewbold Date: Mon, 15 Jan 2024 13:13:15 -0800 Subject: [PATCH 05/28] rss: filter out replies server-side (#2518) --- bskyweb/cmd/bskyweb/rss.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bskyweb/cmd/bskyweb/rss.go b/bskyweb/cmd/bskyweb/rss.go index 64e67fd228..b756b90e6a 100644 --- a/bskyweb/cmd/bskyweb/rss.go +++ b/bskyweb/cmd/bskyweb/rss.go @@ -80,7 +80,7 @@ func (srv *Server) WebProfileRSS(c echo.Context) error { } } - af, err := appbsky.FeedGetAuthorFeed(ctx, srv.xrpcc, did.String(), "", "", 30) + af, err := appbsky.FeedGetAuthorFeed(ctx, srv.xrpcc, did.String(), "", "posts_no_replies", 30) if err != nil { log.Warn("failed to fetch author feed", "did", did, "err", err) return err From 7df0b7ade14cc8015996cb23f052066b7ae3131b Mon Sep 17 00:00:00 2001 From: Cooper Edmunds Date: Mon, 15 Jan 2024 16:19:47 -0500 Subject: [PATCH 06/28] Add accept-language header (#2457) --- src/lib/api/feed/custom.ts | 27 ++++++++++++++++++--------- src/lib/api/feed/merge.ts | 15 ++++++++++----- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/lib/api/feed/custom.ts b/src/lib/api/feed/custom.ts index 94cbff1305..41c5367e57 100644 --- a/src/lib/api/feed/custom.ts +++ b/src/lib/api/feed/custom.ts @@ -4,15 +4,20 @@ import { } from '@atproto/api' import {FeedAPI, FeedAPIResponse} from './types' import {getAgent} from '#/state/session' +import {getContentLanguages} from '#/state/preferences/languages' export class CustomFeedAPI implements FeedAPI { constructor(public params: GetCustomFeed.QueryParams) {} async peekLatest(): Promise { - const res = await getAgent().app.bsky.feed.getFeed({ - ...this.params, - limit: 1, - }) + const contentLangs = getContentLanguages().join(',') + const res = await getAgent().app.bsky.feed.getFeed( + { + ...this.params, + limit: 1, + }, + {headers: {'Accept-Language': contentLangs}}, + ) return res.data.feed[0] } @@ -23,11 +28,15 @@ export class CustomFeedAPI implements FeedAPI { cursor: string | undefined limit: number }): Promise { - const res = await getAgent().app.bsky.feed.getFeed({ - ...this.params, - cursor, - limit, - }) + const contentLangs = getContentLanguages().join(',') + const res = await getAgent().app.bsky.feed.getFeed( + { + ...this.params, + cursor, + limit, + }, + {headers: {'Accept-Language': contentLangs}}, + ) if (res.success) { // NOTE // some custom feeds fail to enforce the pagination limit diff --git a/src/lib/api/feed/merge.ts b/src/lib/api/feed/merge.ts index 2314e2b954..2fef9db87c 100644 --- a/src/lib/api/feed/merge.ts +++ b/src/lib/api/feed/merge.ts @@ -8,6 +8,7 @@ import {FeedAPI, FeedAPIResponse, ReasonFeedSource} from './types' import {FeedParams} from '#/state/queries/post-feed' import {FeedTunerFn} from '../feed-manip' import {getAgent} from '#/state/session' +import {getContentLanguages} from '#/state/preferences/languages' const REQUEST_WAIT_MS = 500 // 500ms const POST_AGE_CUTOFF = 60e3 * 60 * 24 // 24hours @@ -231,11 +232,15 @@ class MergeFeedSource_Custom extends MergeFeedSource { limit: number, ): Promise { try { - const res = await getAgent().app.bsky.feed.getFeed({ - cursor, - limit, - feed: this.feedUri, - }) + const contentLangs = getContentLanguages().join(',') + const res = await getAgent().app.bsky.feed.getFeed( + { + cursor, + limit, + feed: this.feedUri, + }, + {headers: {'Accept-Language': contentLangs}}, + ) // NOTE // some custom feeds fail to enforce the pagination limit // so we manually truncate here From a7d617c7a616b6f6a8e0db41f02e052d6bd077e8 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Mon, 15 Jan 2024 15:03:54 -0800 Subject: [PATCH 07/28] Add a new home feed-api wrapper and give a header indicating the fallback behavior (#2534) * Add a new home feed-api wrapper and give a header indicating the fallback behavior * Sneak in a quick fix: use the correct text color in the delete modal * Use imported constant --- src/lib/api/feed/home.ts | 88 +++++++++++++++++++ src/lib/api/feed/merge.ts | 2 +- src/state/queries/post-feed.ts | 7 +- src/view/com/modals/DeleteAccount.tsx | 7 +- src/view/com/posts/DiscoverFallbackHeader.tsx | 43 +++++++++ src/view/com/posts/Feed.tsx | 8 ++ src/view/screens/Home.tsx | 3 +- 7 files changed, 152 insertions(+), 6 deletions(-) create mode 100644 src/lib/api/feed/home.ts create mode 100644 src/view/com/posts/DiscoverFallbackHeader.tsx diff --git a/src/lib/api/feed/home.ts b/src/lib/api/feed/home.ts new file mode 100644 index 0000000000..91634927ab --- /dev/null +++ b/src/lib/api/feed/home.ts @@ -0,0 +1,88 @@ +import {AppBskyFeedDefs} from '@atproto/api' +import {FeedAPI, FeedAPIResponse} from './types' +import {FollowingFeedAPI} from './following' +import {CustomFeedAPI} from './custom' +import {PROD_DEFAULT_FEED} from '#/lib/constants' + +// HACK +// the feed API does not include any facilities for passing down +// non-post elements. adding that is a bit of a heavy lift, and we +// have just one temporary usecase for it: flagging when the home feed +// falls back to discover. +// we use this fallback marker post to drive this instead. see Feed.tsx +// for the usage. +// -prf +export const FALLBACK_MARKER_POST: AppBskyFeedDefs.FeedViewPost = { + post: { + uri: 'fallback-marker-post', + cid: 'fake', + record: {}, + author: { + did: 'did:fake', + handle: 'fake.com', + }, + indexedAt: new Date().toISOString(), + }, +} + +export class HomeFeedAPI implements FeedAPI { + following: FollowingFeedAPI + discover: CustomFeedAPI + usingDiscover = false + itemCursor = 0 + + constructor() { + this.following = new FollowingFeedAPI() + this.discover = new CustomFeedAPI({feed: PROD_DEFAULT_FEED('whats-hot')}) + } + + reset() { + this.following = new FollowingFeedAPI() + this.discover = new CustomFeedAPI({feed: PROD_DEFAULT_FEED('whats-hot')}) + this.usingDiscover = false + this.itemCursor = 0 + } + + async peekLatest(): Promise { + if (this.usingDiscover) { + return this.discover.peekLatest() + } + return this.following.peekLatest() + } + + async fetch({ + cursor, + limit, + }: { + cursor: string | undefined + limit: number + }): Promise { + if (!cursor) { + this.reset() + } + + let returnCursor + let posts: AppBskyFeedDefs.FeedViewPost[] = [] + + if (!this.usingDiscover) { + const res = await this.following.fetch({cursor, limit}) + returnCursor = res.cursor + posts = posts.concat(res.feed) + if (res.feed.length === 0 || !cursor) { + posts.push(FALLBACK_MARKER_POST) + this.usingDiscover = true + } + } + + if (this.usingDiscover) { + const res = await this.discover.fetch({cursor, limit}) + returnCursor = res.cursor + posts = posts.concat(res.feed) + } + + return { + cursor: returnCursor, + feed: posts, + } + } +} diff --git a/src/lib/api/feed/merge.ts b/src/lib/api/feed/merge.ts index 2fef9db87c..28bf143cbb 100644 --- a/src/lib/api/feed/merge.ts +++ b/src/lib/api/feed/merge.ts @@ -26,7 +26,7 @@ export class MergeFeedAPI implements FeedAPI { reset() { this.following = new MergeFeedSource_Following(this.feedTuners) - this.customFeeds = [] // just empty the array, they will be captured in _fetchNext() + this.customFeeds = [] this.feedCursor = 0 this.itemCursor = 0 this.sampleCursor = 0 diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts index dbb729133d..82acf39743 100644 --- a/src/state/queries/post-feed.ts +++ b/src/state/queries/post-feed.ts @@ -18,6 +18,7 @@ import {LikesFeedAPI} from 'lib/api/feed/likes' import {CustomFeedAPI} from 'lib/api/feed/custom' import {ListFeedAPI} from 'lib/api/feed/list' import {MergeFeedAPI} from 'lib/api/feed/merge' +import {HomeFeedAPI} from '#/lib/api/feed/home' import {logger} from '#/logger' import {STALE} from '#/state/queries' import {precacheFeedPosts as precacheResolvedUris} from './resolve-uri' @@ -338,7 +339,11 @@ function createApi( feedTuners: FeedTunerFn[], ) { if (feedDesc === 'home') { - return new MergeFeedAPI(params, feedTuners) + if (params.mergeFeedEnabled) { + return new MergeFeedAPI(params, feedTuners) + } else { + return new HomeFeedAPI() + } } else if (feedDesc === 'following') { return new FollowingFeedAPI() } else if (feedDesc.startsWith('author')) { diff --git a/src/view/com/modals/DeleteAccount.tsx b/src/view/com/modals/DeleteAccount.tsx index 0cfc098d44..945d7bc891 100644 --- a/src/view/com/modals/DeleteAccount.tsx +++ b/src/view/com/modals/DeleteAccount.tsx @@ -160,7 +160,7 @@ export function Component({}: {}) { {/* TODO: Update this label to be more concise */} Check your inbox for an email with the confirmation code to @@ -180,7 +180,10 @@ export function Component({}: {}) { msg`Input confirmation code for account deletion`, )} /> - + Please enter your password as well: + + + + + + + We ran out of posts from your follows. Here's the latest from + {' '} + + . + + + + ) +} diff --git a/src/view/com/posts/Feed.tsx b/src/view/com/posts/Feed.tsx index cd9f264635..04753fe6c2 100644 --- a/src/view/com/posts/Feed.tsx +++ b/src/view/com/posts/Feed.tsx @@ -30,6 +30,8 @@ import {useSession} from '#/state/session' import {STALE} from '#/state/queries' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {DiscoverFallbackHeader} from './DiscoverFallbackHeader' +import {FALLBACK_MARKER_POST} from '#/lib/api/feed/home' const LOADING_ITEM = {_reactKey: '__loading__'} const EMPTY_FEED_ITEM = {_reactKey: '__empty__'} @@ -265,6 +267,12 @@ let Feed = ({ ) } else if (item === LOADING_ITEM) { return + } else if (item.rootUri === FALLBACK_MARKER_POST.post.uri) { + // HACK + // tell the user we fell back to discover + // see home.ts (feed api) for more info + // -prf + return } return }, diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx index 0e20a9cf77..7d6a40f022 100644 --- a/src/view/screens/Home.tsx +++ b/src/view/screens/Home.tsx @@ -19,7 +19,6 @@ import {useSession} from '#/state/session' import {loadString, saveString} from '#/lib/storage' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {clamp} from '#/lib/numbers' -import {PROD_DEFAULT_FEED} from '#/lib/constants' type Props = NativeStackScreenProps export function HomeScreen(props: Props) { @@ -112,7 +111,7 @@ function HomeScreenReady({ mergeFeedEnabled: Boolean(preferences.feedViewPrefs.lab_mergeFeedEnabled), mergeFeedSources: preferences.feedViewPrefs.lab_mergeFeedEnabled ? preferences.feeds.saved - : [PROD_DEFAULT_FEED('whats-hot')], + : [], } }, [preferences]) From 8c4e5b5f0b953faf4e09caabb2170cc6da3df76b Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Mon, 15 Jan 2024 15:19:05 -0800 Subject: [PATCH 08/28] Bump ios build number --- app.config.js | 2 +- src/locale/locales/de/messages.po | 87 +++++++++++++++------------- src/locale/locales/en/messages.po | 85 +++++++++++++++------------ src/locale/locales/es/messages.po | 87 +++++++++++++++------------- src/locale/locales/fr/messages.po | 87 +++++++++++++++------------- src/locale/locales/hi/messages.po | 87 +++++++++++++++------------- src/locale/locales/id/messages.po | 87 +++++++++++++++------------- src/locale/locales/ja/messages.po | 87 +++++++++++++++------------- src/locale/locales/ko/messages.po | 87 +++++++++++++++------------- src/locale/locales/pt-BR/messages.po | 87 +++++++++++++++------------- src/locale/locales/uk/messages.po | 87 +++++++++++++++------------- 11 files changed, 480 insertions(+), 390 deletions(-) diff --git a/app.config.js b/app.config.js index afd6677ef1..bf1c4fa0ad 100644 --- a/app.config.js +++ b/app.config.js @@ -20,7 +20,7 @@ module.exports = function () { /** * iOS build number. Must be incremented for each TestFlight version. */ - const IOS_BUILD_NUMBER = '1' + const IOS_BUILD_NUMBER = '2' /** * Android build number. Must be incremented for each release. diff --git a/src/locale/locales/de/messages.po b/src/locale/locales/de/messages.po index 8c8ed45788..e9dce63bc5 100644 --- a/src/locale/locales/de/messages.po +++ b/src/locale/locales/de/messages.po @@ -345,11 +345,6 @@ msgstr "" msgid "Artistic or non-erotic nudity." msgstr "Künstlerische oder nicht-erotische Nacktheit." -#: src/view/com/post-thread/PostThread.tsx:400 -msgctxt "action" -msgid "Back" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:141 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 #: src/view/com/auth/login/ForgotPasswordForm.tsx:170 @@ -364,6 +359,11 @@ msgstr "" msgid "Back" msgstr "Zurück" +#: src/view/com/post-thread/PostThread.tsx:400 +msgctxt "action" +msgid "Back" +msgstr "" + #: src/view/screens/Settings.tsx:489 msgid "Basics" msgstr "Grundlagen" @@ -398,6 +398,7 @@ msgstr "Diese Kontos sperren?" msgid "Block this List" msgstr "" +#: src/view/com/lists/ListCard.tsx:109 #: src/view/com/util/post-embeds/QuoteEmbed.tsx:57 msgid "Blocked" msgstr "" @@ -500,15 +501,6 @@ msgstr "Kamera" 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 "Darf nur Buchstaben, Zahlen, Leerzeichen, Bindestriche und Unterstriche enthalten. Muss mindestens 4 Zeichen lang sein, darf aber nicht länger als 32 Zeichen sein." -#: src/view/com/modals/Confirm.tsx:88 -#: src/view/com/modals/Confirm.tsx:91 -#: src/view/com/modals/CreateOrEditList.tsx:293 -#: src/view/com/modals/DeleteAccount.tsx:152 -#: src/view/com/modals/DeleteAccount.tsx:227 -msgctxt "action" -msgid "Cancel" -msgstr "" - #: src/view/com/composer/Composer.tsx:300 #: src/view/com/composer/Composer.tsx:305 #: src/view/com/modals/ChangeEmail.tsx:218 @@ -527,8 +519,17 @@ msgstr "" msgid "Cancel" msgstr "Abbrechen" +#: src/view/com/modals/Confirm.tsx:88 +#: src/view/com/modals/Confirm.tsx:91 +#: src/view/com/modals/CreateOrEditList.tsx:293 +#: src/view/com/modals/DeleteAccount.tsx:152 +#: src/view/com/modals/DeleteAccount.tsx:230 +msgctxt "action" +msgid "Cancel" +msgstr "" + #: src/view/com/modals/DeleteAccount.tsx:148 -#: src/view/com/modals/DeleteAccount.tsx:223 +#: src/view/com/modals/DeleteAccount.tsx:226 msgid "Cancel account deletion" msgstr "Kontolöschung abbrechen" @@ -704,12 +705,6 @@ msgstr "" msgid "Compose reply" msgstr "Antwort zusammenstellen" -#: src/view/com/modals/Confirm.tsx:75 -#: src/view/com/modals/Confirm.tsx:78 -msgctxt "action" -msgid "Confirm" -msgstr "" - #: src/view/com/modals/AppealLabel.tsx:98 #: src/view/com/modals/SelfLabel.tsx:154 #: src/view/com/modals/VerifyEmail.tsx:231 @@ -719,6 +714,12 @@ msgstr "" msgid "Confirm" msgstr "Bestätigen" +#: 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" @@ -728,7 +729,7 @@ msgstr "Änderung bestätigen" msgid "Confirm content language settings" msgstr "Bestätigen Sie die Spracheinstellungen für den Inhalt" -#: src/view/com/modals/DeleteAccount.tsx:213 +#: src/view/com/modals/DeleteAccount.tsx:216 msgid "Confirm delete account" msgstr "Bestätigen Sie Konto löschen" @@ -920,7 +921,7 @@ msgstr "App-Passwort löschen" msgid "Delete List" msgstr "Liste löschen" -#: src/view/com/modals/DeleteAccount.tsx:216 +#: src/view/com/modals/DeleteAccount.tsx:219 msgid "Delete my account" msgstr "Mein Konto löschen" @@ -1624,7 +1625,7 @@ msgstr "" msgid "Input new password" msgstr "" -#: src/view/com/modals/DeleteAccount.tsx:196 +#: src/view/com/modals/DeleteAccount.tsx:199 msgid "Input password for account deletion" msgstr "" @@ -2014,6 +2015,10 @@ msgstr "" msgid "Mute thread" msgstr "Thema stummschalten" +#: src/view/com/lists/ListCard.tsx:101 +msgid "Muted" +msgstr "" + #: src/view/screens/Moderation.tsx:109 msgid "Muted accounts" msgstr "Stumme Kontos" @@ -2124,11 +2129,6 @@ msgstr "" msgid "Newest replies first" msgstr "" -#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 -msgctxt "action" -msgid "Next" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:154 #: src/view/com/auth/login/ForgotPasswordForm.tsx:178 #: src/view/com/auth/login/ForgotPasswordForm.tsx:188 @@ -2139,6 +2139,11 @@ msgstr "" msgid "Next" msgstr "Nächster" +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 +msgctxt "action" +msgid "Next" +msgstr "" + #: src/view/com/lightbox/Lightbox.web.tsx:142 msgid "Next image" msgstr "Nächstes Bild " @@ -2395,7 +2400,7 @@ msgstr "Seite nicht gefunden" #: src/view/com/auth/create/Step2.tsx:132 #: src/view/com/auth/login/LoginForm.tsx:223 #: src/view/com/auth/login/SetNewPasswordForm.tsx:132 -#: src/view/com/modals/DeleteAccount.tsx:195 +#: src/view/com/modals/DeleteAccount.tsx:198 msgid "Password" msgstr "Passwort" @@ -2473,7 +2478,7 @@ msgstr "Bitte geben Sie einen eindeutigen Namen für dieses App-Passwort ein ode msgid "Please enter your email." msgstr "Bitte geben Sie Ihre E-Mail-Adresse ein." -#: src/view/com/modals/DeleteAccount.tsx:184 +#: src/view/com/modals/DeleteAccount.tsx:187 msgid "Please enter your password as well:" msgstr "Bitte geben Sie auch Ihr Passwort ein:" @@ -3315,8 +3320,8 @@ msgid "Subscribe to this list" msgstr "Abonnieren Sie diese Liste" #: src/view/com/lists/ListCard.tsx:101 -msgid "Subscribed" -msgstr "" +#~ msgid "Subscribed" +#~ msgstr "" #: src/view/screens/Search/Search.tsx:362 msgid "Suggested Follows" @@ -3450,7 +3455,7 @@ msgstr "" msgid "There was an issue fetching notifications. Tap here to try again." msgstr "" -#: src/view/com/posts/Feed.tsx:261 +#: src/view/com/posts/Feed.tsx:263 msgid "There was an issue fetching posts. Tap here to try again." msgstr "" @@ -3628,16 +3633,16 @@ msgstr "Stummschaltliste aufheben" msgid "Unable to contact your service. Please check your Internet connection." msgstr "Sie können Ihren Dienst nicht kontaktieren. Bitte überprüfen Sie Ihre Internetverbindung." -#: src/view/com/profile/ProfileHeader.tsx:475 -msgctxt "action" -msgid "Unblock" -msgstr "" - #: src/view/com/profile/ProfileHeader.tsx:472 #: src/view/screens/ProfileList.tsx:568 msgid "Unblock" msgstr "Freischalten" +#: src/view/com/profile/ProfileHeader.tsx:475 +msgctxt "action" +msgid "Unblock" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:308 #: src/view/com/profile/ProfileHeader.tsx:392 msgid "Unblock Account" @@ -3847,6 +3852,10 @@ msgstr "Seite besuchen" msgid "Warn" msgstr "" +#: src/view/com/posts/DiscoverFallbackHeader.tsx:29 +msgid "We ran out of posts from your follows. Here's the latest from" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." msgstr "" diff --git a/src/locale/locales/en/messages.po b/src/locale/locales/en/messages.po index c53a2c67e6..cb967bcaaa 100644 --- a/src/locale/locales/en/messages.po +++ b/src/locale/locales/en/messages.po @@ -373,11 +373,6 @@ msgstr "" #~ msgid "Ask apps to limit the visibility of my account" #~ msgstr "" -#: src/view/com/post-thread/PostThread.tsx:400 -msgctxt "action" -msgid "Back" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:141 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 #: src/view/com/auth/login/ForgotPasswordForm.tsx:170 @@ -392,6 +387,11 @@ msgstr "" msgid "Back" msgstr "" +#: src/view/com/post-thread/PostThread.tsx:400 +msgctxt "action" +msgid "Back" +msgstr "" + #: src/view/screens/Settings.tsx:489 msgid "Basics" msgstr "" @@ -426,6 +426,7 @@ msgstr "" msgid "Block this List" msgstr "" +#: src/view/com/lists/ListCard.tsx:109 #: src/view/com/util/post-embeds/QuoteEmbed.tsx:57 msgid "Blocked" msgstr "" @@ -528,15 +529,6 @@ 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 "" -#: src/view/com/modals/Confirm.tsx:88 -#: src/view/com/modals/Confirm.tsx:91 -#: src/view/com/modals/CreateOrEditList.tsx:293 -#: src/view/com/modals/DeleteAccount.tsx:152 -#: src/view/com/modals/DeleteAccount.tsx:227 -msgctxt "action" -msgid "Cancel" -msgstr "" - #: src/view/com/composer/Composer.tsx:300 #: src/view/com/composer/Composer.tsx:305 #: src/view/com/modals/ChangeEmail.tsx:218 @@ -555,8 +547,17 @@ msgstr "" msgid "Cancel" msgstr "" +#: src/view/com/modals/Confirm.tsx:88 +#: src/view/com/modals/Confirm.tsx:91 +#: src/view/com/modals/CreateOrEditList.tsx:293 +#: src/view/com/modals/DeleteAccount.tsx:152 +#: src/view/com/modals/DeleteAccount.tsx:230 +msgctxt "action" +msgid "Cancel" +msgstr "" + #: src/view/com/modals/DeleteAccount.tsx:148 -#: src/view/com/modals/DeleteAccount.tsx:223 +#: src/view/com/modals/DeleteAccount.tsx:226 msgid "Cancel account deletion" msgstr "" @@ -736,12 +737,6 @@ msgstr "" msgid "Compose reply" msgstr "" -#: src/view/com/modals/Confirm.tsx:75 -#: src/view/com/modals/Confirm.tsx:78 -msgctxt "action" -msgid "Confirm" -msgstr "" - #: src/view/com/modals/AppealLabel.tsx:98 #: src/view/com/modals/SelfLabel.tsx:154 #: src/view/com/modals/VerifyEmail.tsx:231 @@ -751,6 +746,12 @@ msgstr "" 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" @@ -760,7 +761,7 @@ msgstr "" msgid "Confirm content language settings" msgstr "" -#: src/view/com/modals/DeleteAccount.tsx:213 +#: src/view/com/modals/DeleteAccount.tsx:216 msgid "Confirm delete account" msgstr "" @@ -952,7 +953,7 @@ msgstr "" msgid "Delete List" msgstr "" -#: src/view/com/modals/DeleteAccount.tsx:216 +#: src/view/com/modals/DeleteAccount.tsx:219 msgid "Delete my account" msgstr "" @@ -1673,7 +1674,7 @@ msgstr "" msgid "Input new password" msgstr "" -#: src/view/com/modals/DeleteAccount.tsx:196 +#: src/view/com/modals/DeleteAccount.tsx:199 msgid "Input password for account deletion" msgstr "" @@ -2075,6 +2076,10 @@ msgstr "" msgid "Mute thread" msgstr "" +#: src/view/com/lists/ListCard.tsx:101 +msgid "Muted" +msgstr "" + #: src/view/screens/Moderation.tsx:109 msgid "Muted accounts" msgstr "" @@ -2189,11 +2194,6 @@ msgstr "" msgid "Newest replies first" msgstr "" -#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 -msgctxt "action" -msgid "Next" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:154 #: src/view/com/auth/login/ForgotPasswordForm.tsx:178 #: src/view/com/auth/login/ForgotPasswordForm.tsx:188 @@ -2204,6 +2204,11 @@ msgstr "" msgid "Next" msgstr "" +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 +msgctxt "action" +msgid "Next" +msgstr "" + #: src/view/com/lightbox/Lightbox.web.tsx:142 msgid "Next image" msgstr "" @@ -2477,7 +2482,7 @@ msgstr "" #: src/view/com/auth/create/Step2.tsx:132 #: src/view/com/auth/login/LoginForm.tsx:223 #: src/view/com/auth/login/SetNewPasswordForm.tsx:132 -#: src/view/com/modals/DeleteAccount.tsx:195 +#: src/view/com/modals/DeleteAccount.tsx:198 msgid "Password" msgstr "" @@ -2555,7 +2560,7 @@ msgstr "" msgid "Please enter your email." msgstr "" -#: src/view/com/modals/DeleteAccount.tsx:184 +#: src/view/com/modals/DeleteAccount.tsx:187 msgid "Please enter your password as well:" msgstr "" @@ -3422,8 +3427,8 @@ msgid "Subscribe to this list" msgstr "" #: src/view/com/lists/ListCard.tsx:101 -msgid "Subscribed" -msgstr "" +#~ msgid "Subscribed" +#~ msgstr "" #: src/view/screens/Search/Search.tsx:362 msgid "Suggested Follows" @@ -3557,7 +3562,7 @@ msgstr "" msgid "There was an issue fetching notifications. Tap here to try again." msgstr "" -#: src/view/com/posts/Feed.tsx:261 +#: src/view/com/posts/Feed.tsx:263 msgid "There was an issue fetching posts. Tap here to try again." msgstr "" @@ -3735,13 +3740,13 @@ msgstr "" msgid "Unable to contact your service. Please check your Internet connection." msgstr "" -#: src/view/com/profile/ProfileHeader.tsx:475 -msgctxt "action" +#: src/view/com/profile/ProfileHeader.tsx:472 +#: src/view/screens/ProfileList.tsx:568 msgid "Unblock" msgstr "" -#: src/view/com/profile/ProfileHeader.tsx:472 -#: src/view/screens/ProfileList.tsx:568 +#: src/view/com/profile/ProfileHeader.tsx:475 +msgctxt "action" msgid "Unblock" msgstr "" @@ -3958,6 +3963,10 @@ msgstr "" msgid "Warn" msgstr "" +#: src/view/com/posts/DiscoverFallbackHeader.tsx:29 +msgid "We ran out of posts from your follows. Here's the latest from" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." msgstr "" diff --git a/src/locale/locales/es/messages.po b/src/locale/locales/es/messages.po index 25616816bf..7f4d5b73e4 100644 --- a/src/locale/locales/es/messages.po +++ b/src/locale/locales/es/messages.po @@ -341,11 +341,6 @@ msgstr "" msgid "Artistic or non-erotic nudity." msgstr "Desnudez artística o no erótica." -#: src/view/com/post-thread/PostThread.tsx:400 -msgctxt "action" -msgid "Back" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:141 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 #: src/view/com/auth/login/ForgotPasswordForm.tsx:170 @@ -360,6 +355,11 @@ msgstr "" msgid "Back" msgstr "Regresar" +#: src/view/com/post-thread/PostThread.tsx:400 +msgctxt "action" +msgid "Back" +msgstr "" + #: src/view/screens/Settings.tsx:489 msgid "Basics" msgstr "Conceptos básicos" @@ -394,6 +394,7 @@ msgstr "¿Bloquear estas cuentas?" msgid "Block this List" msgstr "" +#: src/view/com/lists/ListCard.tsx:109 #: src/view/com/util/post-embeds/QuoteEmbed.tsx:57 msgid "Blocked" msgstr "" @@ -496,15 +497,6 @@ msgstr "Cámara" 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 "Sólo puede contener letras, números, espacios, guiones y guiones bajos. Debe tener al menos 4 caracteres, pero no más de 32." -#: src/view/com/modals/Confirm.tsx:88 -#: src/view/com/modals/Confirm.tsx:91 -#: src/view/com/modals/CreateOrEditList.tsx:293 -#: src/view/com/modals/DeleteAccount.tsx:152 -#: src/view/com/modals/DeleteAccount.tsx:227 -msgctxt "action" -msgid "Cancel" -msgstr "" - #: src/view/com/composer/Composer.tsx:300 #: src/view/com/composer/Composer.tsx:305 #: src/view/com/modals/ChangeEmail.tsx:218 @@ -523,8 +515,17 @@ msgstr "" msgid "Cancel" msgstr "Cancelar" +#: src/view/com/modals/Confirm.tsx:88 +#: src/view/com/modals/Confirm.tsx:91 +#: src/view/com/modals/CreateOrEditList.tsx:293 +#: src/view/com/modals/DeleteAccount.tsx:152 +#: src/view/com/modals/DeleteAccount.tsx:230 +msgctxt "action" +msgid "Cancel" +msgstr "" + #: src/view/com/modals/DeleteAccount.tsx:148 -#: src/view/com/modals/DeleteAccount.tsx:223 +#: src/view/com/modals/DeleteAccount.tsx:226 msgid "Cancel account deletion" msgstr "Cancelar la eliminación de la cuenta" @@ -700,12 +701,6 @@ msgstr "" msgid "Compose reply" msgstr "Redactar la respuesta" -#: src/view/com/modals/Confirm.tsx:75 -#: src/view/com/modals/Confirm.tsx:78 -msgctxt "action" -msgid "Confirm" -msgstr "" - #: src/view/com/modals/AppealLabel.tsx:98 #: src/view/com/modals/SelfLabel.tsx:154 #: src/view/com/modals/VerifyEmail.tsx:231 @@ -715,6 +710,12 @@ msgstr "" msgid "Confirm" msgstr "Confirmar" +#: 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" @@ -724,7 +725,7 @@ msgstr "Confirmar el cambio" msgid "Confirm content language settings" msgstr "Confirmar la configuración del idioma del contenido" -#: src/view/com/modals/DeleteAccount.tsx:213 +#: src/view/com/modals/DeleteAccount.tsx:216 msgid "Confirm delete account" msgstr "Confirmar eliminación de cuenta" @@ -916,7 +917,7 @@ msgstr "Borrar la contraseña de la app" msgid "Delete List" msgstr "Borrar la lista" -#: src/view/com/modals/DeleteAccount.tsx:216 +#: src/view/com/modals/DeleteAccount.tsx:219 msgid "Delete my account" msgstr "Borrar mi cuenta" @@ -1620,7 +1621,7 @@ msgstr "" msgid "Input new password" msgstr "" -#: src/view/com/modals/DeleteAccount.tsx:196 +#: src/view/com/modals/DeleteAccount.tsx:199 msgid "Input password for account deletion" msgstr "" @@ -2006,6 +2007,10 @@ msgstr "" msgid "Mute thread" msgstr "Silenciar el hilo" +#: src/view/com/lists/ListCard.tsx:101 +msgid "Muted" +msgstr "" + #: src/view/screens/Moderation.tsx:109 msgid "Muted accounts" msgstr "Cuentas silenciadas" @@ -2116,11 +2121,6 @@ msgstr "" msgid "Newest replies first" msgstr "" -#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 -msgctxt "action" -msgid "Next" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:154 #: src/view/com/auth/login/ForgotPasswordForm.tsx:178 #: src/view/com/auth/login/ForgotPasswordForm.tsx:188 @@ -2131,6 +2131,11 @@ msgstr "" msgid "Next" msgstr "Siguiente" +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 +msgctxt "action" +msgid "Next" +msgstr "" + #: src/view/com/lightbox/Lightbox.web.tsx:142 msgid "Next image" msgstr "Imagen nueva" @@ -2387,7 +2392,7 @@ msgstr "Página no encontrada" #: src/view/com/auth/create/Step2.tsx:132 #: src/view/com/auth/login/LoginForm.tsx:223 #: src/view/com/auth/login/SetNewPasswordForm.tsx:132 -#: src/view/com/modals/DeleteAccount.tsx:195 +#: src/view/com/modals/DeleteAccount.tsx:198 msgid "Password" msgstr "Contraseña" @@ -2465,7 +2470,7 @@ msgstr "Introduce un nombre único para la contraseña de esta app o utiliza una msgid "Please enter your email." msgstr "Introduce tu correo electrónico." -#: src/view/com/modals/DeleteAccount.tsx:184 +#: src/view/com/modals/DeleteAccount.tsx:187 msgid "Please enter your password as well:" msgstr "Introduce tu contraseña, también:" @@ -3302,8 +3307,8 @@ msgid "Subscribe to this list" msgstr "Suscribirse a esta lista" #: src/view/com/lists/ListCard.tsx:101 -msgid "Subscribed" -msgstr "" +#~ msgid "Subscribed" +#~ msgstr "" #: src/view/screens/Search/Search.tsx:362 msgid "Suggested Follows" @@ -3437,7 +3442,7 @@ msgstr "" msgid "There was an issue fetching notifications. Tap here to try again." msgstr "" -#: src/view/com/posts/Feed.tsx:261 +#: src/view/com/posts/Feed.tsx:263 msgid "There was an issue fetching posts. Tap here to try again." msgstr "" @@ -3611,16 +3616,16 @@ msgstr "Desactivar la opción de silenciar la lista" msgid "Unable to contact your service. Please check your Internet connection." msgstr "No se puede contactar con tu servicio. Comprueba tu conexión a Internet." -#: src/view/com/profile/ProfileHeader.tsx:475 -msgctxt "action" -msgid "Unblock" -msgstr "" - #: src/view/com/profile/ProfileHeader.tsx:472 #: src/view/screens/ProfileList.tsx:568 msgid "Unblock" msgstr "Desbloquear" +#: src/view/com/profile/ProfileHeader.tsx:475 +msgctxt "action" +msgid "Unblock" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:308 #: src/view/com/profile/ProfileHeader.tsx:392 msgid "Unblock Account" @@ -3830,6 +3835,10 @@ msgstr "Visitar el sitio" msgid "Warn" msgstr "" +#: src/view/com/posts/DiscoverFallbackHeader.tsx:29 +msgid "We ran out of posts from your follows. Here's the latest from" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." msgstr "" diff --git a/src/locale/locales/fr/messages.po b/src/locale/locales/fr/messages.po index db3a584b67..dea80a1a94 100644 --- a/src/locale/locales/fr/messages.po +++ b/src/locale/locales/fr/messages.po @@ -344,11 +344,6 @@ msgstr "" msgid "Artistic or non-erotic nudity." msgstr "Nudité artistique ou non érotique." -#: src/view/com/post-thread/PostThread.tsx:400 -msgctxt "action" -msgid "Back" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:141 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 #: src/view/com/auth/login/ForgotPasswordForm.tsx:170 @@ -363,6 +358,11 @@ msgstr "" msgid "Back" msgstr "Arrière" +#: src/view/com/post-thread/PostThread.tsx:400 +msgctxt "action" +msgid "Back" +msgstr "" + #: src/view/screens/Settings.tsx:489 msgid "Basics" msgstr "Principes de base" @@ -397,6 +397,7 @@ msgstr "Bloquer ces comptes ?" msgid "Block this List" msgstr "" +#: src/view/com/lists/ListCard.tsx:109 #: src/view/com/util/post-embeds/QuoteEmbed.tsx:57 msgid "Blocked" msgstr "" @@ -499,15 +500,6 @@ msgstr "Caméra" 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 "Ne peut contenir que des lettres, des chiffres, des espaces, des tirets et des tirets bas. La longueur doit être d’au moins 4 caractères, mais pas plus de 32." -#: src/view/com/modals/Confirm.tsx:88 -#: src/view/com/modals/Confirm.tsx:91 -#: src/view/com/modals/CreateOrEditList.tsx:293 -#: src/view/com/modals/DeleteAccount.tsx:152 -#: src/view/com/modals/DeleteAccount.tsx:227 -msgctxt "action" -msgid "Cancel" -msgstr "" - #: src/view/com/composer/Composer.tsx:300 #: src/view/com/composer/Composer.tsx:305 #: src/view/com/modals/ChangeEmail.tsx:218 @@ -526,8 +518,17 @@ msgstr "" msgid "Cancel" msgstr "Annuler" +#: src/view/com/modals/Confirm.tsx:88 +#: src/view/com/modals/Confirm.tsx:91 +#: src/view/com/modals/CreateOrEditList.tsx:293 +#: src/view/com/modals/DeleteAccount.tsx:152 +#: src/view/com/modals/DeleteAccount.tsx:230 +msgctxt "action" +msgid "Cancel" +msgstr "" + #: src/view/com/modals/DeleteAccount.tsx:148 -#: src/view/com/modals/DeleteAccount.tsx:223 +#: src/view/com/modals/DeleteAccount.tsx:226 msgid "Cancel account deletion" msgstr "Annuler la suppression de compte" @@ -703,12 +704,6 @@ msgstr "" msgid "Compose reply" msgstr "Rédiger une réponse" -#: src/view/com/modals/Confirm.tsx:75 -#: src/view/com/modals/Confirm.tsx:78 -msgctxt "action" -msgid "Confirm" -msgstr "" - #: src/view/com/modals/AppealLabel.tsx:98 #: src/view/com/modals/SelfLabel.tsx:154 #: src/view/com/modals/VerifyEmail.tsx:231 @@ -718,6 +713,12 @@ msgstr "" msgid "Confirm" msgstr "Confirmer" +#: 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" @@ -727,7 +728,7 @@ msgstr "Confirmer le changement" msgid "Confirm content language settings" msgstr "Confirmer les paramètres de langue" -#: src/view/com/modals/DeleteAccount.tsx:213 +#: src/view/com/modals/DeleteAccount.tsx:216 msgid "Confirm delete account" msgstr "Confirmer la suppression du compte" @@ -919,7 +920,7 @@ msgstr "Supprimer le mot de passe de l’appli" msgid "Delete List" msgstr "Supprimer la liste" -#: src/view/com/modals/DeleteAccount.tsx:216 +#: src/view/com/modals/DeleteAccount.tsx:219 msgid "Delete my account" msgstr "Supprimer mon compte" @@ -1623,7 +1624,7 @@ msgstr "" msgid "Input new password" msgstr "" -#: src/view/com/modals/DeleteAccount.tsx:196 +#: src/view/com/modals/DeleteAccount.tsx:199 msgid "Input password for account deletion" msgstr "" @@ -2009,6 +2010,10 @@ msgstr "" msgid "Mute thread" msgstr "Masquer ce fil de discussion" +#: src/view/com/lists/ListCard.tsx:101 +msgid "Muted" +msgstr "" + #: src/view/screens/Moderation.tsx:109 msgid "Muted accounts" msgstr "Comptes masqués" @@ -2119,11 +2124,6 @@ msgstr "" msgid "Newest replies first" msgstr "" -#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 -msgctxt "action" -msgid "Next" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:154 #: src/view/com/auth/login/ForgotPasswordForm.tsx:178 #: src/view/com/auth/login/ForgotPasswordForm.tsx:188 @@ -2134,6 +2134,11 @@ msgstr "" msgid "Next" msgstr "Suivant" +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 +msgctxt "action" +msgid "Next" +msgstr "" + #: src/view/com/lightbox/Lightbox.web.tsx:142 msgid "Next image" msgstr "Image suivante" @@ -2390,7 +2395,7 @@ msgstr "Page introuvable" #: src/view/com/auth/create/Step2.tsx:132 #: src/view/com/auth/login/LoginForm.tsx:223 #: src/view/com/auth/login/SetNewPasswordForm.tsx:132 -#: src/view/com/modals/DeleteAccount.tsx:195 +#: src/view/com/modals/DeleteAccount.tsx:198 msgid "Password" msgstr "Mot de passe" @@ -2468,7 +2473,7 @@ msgstr "Veuillez saisir un nom unique pour le mot de passe de l’application ou msgid "Please enter your email." msgstr "Veuillez entrer votre e-mail." -#: src/view/com/modals/DeleteAccount.tsx:184 +#: src/view/com/modals/DeleteAccount.tsx:187 msgid "Please enter your password as well:" msgstr "Veuillez également entrer votre mot de passe :" @@ -3308,8 +3313,8 @@ msgid "Subscribe to this list" msgstr "S’abonner à cette liste" #: src/view/com/lists/ListCard.tsx:101 -msgid "Subscribed" -msgstr "" +#~ msgid "Subscribed" +#~ msgstr "" #: src/view/screens/Search/Search.tsx:362 msgid "Suggested Follows" @@ -3443,7 +3448,7 @@ msgstr "" msgid "There was an issue fetching notifications. Tap here to try again." msgstr "" -#: src/view/com/posts/Feed.tsx:261 +#: src/view/com/posts/Feed.tsx:263 msgid "There was an issue fetching posts. Tap here to try again." msgstr "" @@ -3620,16 +3625,16 @@ msgstr "Réafficher cette liste" msgid "Unable to contact your service. Please check your Internet connection." msgstr "Impossible de contacter votre service. Veuillez vérifier votre connexion Internet." -#: src/view/com/profile/ProfileHeader.tsx:475 -msgctxt "action" -msgid "Unblock" -msgstr "" - #: src/view/com/profile/ProfileHeader.tsx:472 #: src/view/screens/ProfileList.tsx:568 msgid "Unblock" msgstr "Débloquer" +#: src/view/com/profile/ProfileHeader.tsx:475 +msgctxt "action" +msgid "Unblock" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:308 #: src/view/com/profile/ProfileHeader.tsx:392 msgid "Unblock Account" @@ -3839,6 +3844,10 @@ msgstr "Visiter le site" msgid "Warn" msgstr "" +#: src/view/com/posts/DiscoverFallbackHeader.tsx:29 +msgid "We ran out of posts from your follows. Here's the latest from" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." msgstr "" diff --git a/src/locale/locales/hi/messages.po b/src/locale/locales/hi/messages.po index 1240c1cc08..b0f6f984bf 100644 --- a/src/locale/locales/hi/messages.po +++ b/src/locale/locales/hi/messages.po @@ -373,11 +373,6 @@ msgstr "कलात्मक या गैर-कामुक नग्नत #~ msgid "Ask apps to limit the visibility of my account" #~ msgstr "" -#: src/view/com/post-thread/PostThread.tsx:400 -msgctxt "action" -msgid "Back" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:141 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 #: src/view/com/auth/login/ForgotPasswordForm.tsx:170 @@ -392,6 +387,11 @@ msgstr "" msgid "Back" msgstr "वापस" +#: src/view/com/post-thread/PostThread.tsx:400 +msgctxt "action" +msgid "Back" +msgstr "" + #: src/view/screens/Settings.tsx:489 msgid "Basics" msgstr "मूल बातें" @@ -426,6 +426,7 @@ msgstr "खाता ब्लॉक करें?" msgid "Block this List" msgstr "" +#: src/view/com/lists/ListCard.tsx:109 #: src/view/com/util/post-embeds/QuoteEmbed.tsx:57 msgid "Blocked" msgstr "" @@ -528,15 +529,6 @@ 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/view/com/modals/Confirm.tsx:88 -#: src/view/com/modals/Confirm.tsx:91 -#: src/view/com/modals/CreateOrEditList.tsx:293 -#: src/view/com/modals/DeleteAccount.tsx:152 -#: src/view/com/modals/DeleteAccount.tsx:227 -msgctxt "action" -msgid "Cancel" -msgstr "" - #: src/view/com/composer/Composer.tsx:300 #: src/view/com/composer/Composer.tsx:305 #: src/view/com/modals/ChangeEmail.tsx:218 @@ -555,8 +547,17 @@ msgstr "" msgid "Cancel" msgstr "कैंसिल" +#: src/view/com/modals/Confirm.tsx:88 +#: src/view/com/modals/Confirm.tsx:91 +#: src/view/com/modals/CreateOrEditList.tsx:293 +#: src/view/com/modals/DeleteAccount.tsx:152 +#: src/view/com/modals/DeleteAccount.tsx:230 +msgctxt "action" +msgid "Cancel" +msgstr "" + #: src/view/com/modals/DeleteAccount.tsx:148 -#: src/view/com/modals/DeleteAccount.tsx:223 +#: src/view/com/modals/DeleteAccount.tsx:226 msgid "Cancel account deletion" msgstr "अकाउंट बंद मत करो" @@ -732,12 +733,6 @@ msgstr "" msgid "Compose reply" msgstr "जवाब लिखो" -#: src/view/com/modals/Confirm.tsx:75 -#: src/view/com/modals/Confirm.tsx:78 -msgctxt "action" -msgid "Confirm" -msgstr "" - #: src/view/com/modals/AppealLabel.tsx:98 #: src/view/com/modals/SelfLabel.tsx:154 #: src/view/com/modals/VerifyEmail.tsx:231 @@ -747,6 +742,12 @@ msgstr "" 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" @@ -756,7 +757,7 @@ msgstr "बदलाव की पुष्टि करें" msgid "Confirm content language settings" msgstr "सामग्री भाषा सेटिंग्स की पुष्टि करें" -#: src/view/com/modals/DeleteAccount.tsx:213 +#: src/view/com/modals/DeleteAccount.tsx:216 msgid "Confirm delete account" msgstr "खाते को हटा दें" @@ -948,7 +949,7 @@ msgstr "अप्प पासवर्ड हटाएं" msgid "Delete List" msgstr "सूची हटाएँ" -#: src/view/com/modals/DeleteAccount.tsx:216 +#: src/view/com/modals/DeleteAccount.tsx:219 msgid "Delete my account" msgstr "मेरा खाता हटाएं" @@ -1665,7 +1666,7 @@ msgstr "" msgid "Input new password" msgstr "" -#: src/view/com/modals/DeleteAccount.tsx:196 +#: src/view/com/modals/DeleteAccount.tsx:199 msgid "Input password for account deletion" msgstr "" @@ -2067,6 +2068,10 @@ msgstr "" msgid "Mute thread" msgstr "थ्रेड म्यूट करें" +#: src/view/com/lists/ListCard.tsx:101 +msgid "Muted" +msgstr "" + #: src/view/screens/Moderation.tsx:109 msgid "Muted accounts" msgstr "म्यूट किए गए खाते" @@ -2181,11 +2186,6 @@ msgstr "" msgid "Newest replies first" msgstr "" -#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 -msgctxt "action" -msgid "Next" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:154 #: src/view/com/auth/login/ForgotPasswordForm.tsx:178 #: src/view/com/auth/login/ForgotPasswordForm.tsx:188 @@ -2196,6 +2196,11 @@ msgstr "" msgid "Next" msgstr "अगला" +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 +msgctxt "action" +msgid "Next" +msgstr "" + #: src/view/com/lightbox/Lightbox.web.tsx:142 msgid "Next image" msgstr "अगली फोटो" @@ -2469,7 +2474,7 @@ msgstr "पृष्ठ नहीं मिला" #: src/view/com/auth/create/Step2.tsx:132 #: src/view/com/auth/login/LoginForm.tsx:223 #: src/view/com/auth/login/SetNewPasswordForm.tsx:132 -#: src/view/com/modals/DeleteAccount.tsx:195 +#: src/view/com/modals/DeleteAccount.tsx:198 msgid "Password" msgstr "पासवर्ड" @@ -2547,7 +2552,7 @@ msgstr "कृपया इस ऐप पासवर्ड के लिए ए msgid "Please enter your email." msgstr "" -#: src/view/com/modals/DeleteAccount.tsx:184 +#: src/view/com/modals/DeleteAccount.tsx:187 msgid "Please enter your password as well:" msgstr "कृपया अपना पासवर्ड भी दर्ज करें:" @@ -3414,8 +3419,8 @@ msgid "Subscribe to this list" msgstr "इस सूची को सब्सक्राइब करें" #: src/view/com/lists/ListCard.tsx:101 -msgid "Subscribed" -msgstr "" +#~ msgid "Subscribed" +#~ msgstr "" #: src/view/screens/Search/Search.tsx:362 msgid "Suggested Follows" @@ -3549,7 +3554,7 @@ msgstr "" msgid "There was an issue fetching notifications. Tap here to try again." msgstr "" -#: src/view/com/posts/Feed.tsx:261 +#: src/view/com/posts/Feed.tsx:263 msgid "There was an issue fetching posts. Tap here to try again." msgstr "" @@ -3727,16 +3732,16 @@ msgstr "" msgid "Unable to contact your service. Please check your Internet connection." msgstr "आपकी सेवा से संपर्क करने में असमर्थ। कृपया अपने इंटरनेट कनेक्शन की जांच करें।।" -#: src/view/com/profile/ProfileHeader.tsx:475 -msgctxt "action" -msgid "Unblock" -msgstr "" - #: src/view/com/profile/ProfileHeader.tsx:472 #: src/view/screens/ProfileList.tsx:568 msgid "Unblock" msgstr "अनब्लॉक" +#: src/view/com/profile/ProfileHeader.tsx:475 +msgctxt "action" +msgid "Unblock" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:308 #: src/view/com/profile/ProfileHeader.tsx:392 msgid "Unblock Account" @@ -3950,6 +3955,10 @@ msgstr "साइट पर जाएं" msgid "Warn" msgstr "" +#: src/view/com/posts/DiscoverFallbackHeader.tsx:29 +msgid "We ran out of posts from your follows. Here's the latest from" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." msgstr "" diff --git a/src/locale/locales/id/messages.po b/src/locale/locales/id/messages.po index ba6a4c4be0..f32a00eff1 100644 --- a/src/locale/locales/id/messages.po +++ b/src/locale/locales/id/messages.po @@ -345,11 +345,6 @@ msgstr "" msgid "Artistic or non-erotic nudity." msgstr "Ketelanjangan artistik atau non-erotis." -#: src/view/com/post-thread/PostThread.tsx:400 -msgctxt "action" -msgid "Back" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:141 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 #: src/view/com/auth/login/ForgotPasswordForm.tsx:170 @@ -364,6 +359,11 @@ msgstr "" msgid "Back" msgstr "Kembali" +#: src/view/com/post-thread/PostThread.tsx:400 +msgctxt "action" +msgid "Back" +msgstr "" + #: src/view/screens/Settings.tsx:489 msgid "Basics" msgstr "Dasar" @@ -398,6 +398,7 @@ msgstr "Blokir akun ini?" msgid "Block this List" msgstr "" +#: src/view/com/lists/ListCard.tsx:109 #: src/view/com/util/post-embeds/QuoteEmbed.tsx:57 msgid "Blocked" msgstr "" @@ -500,15 +501,6 @@ msgstr "Kamera" 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 "Hanya dapat terdiri dari huruf, angka, spasi, tanda hubung dan garis bawah. Minimal 4 karakter, namun tidak boleh lebih dari 32 karakter." -#: src/view/com/modals/Confirm.tsx:88 -#: src/view/com/modals/Confirm.tsx:91 -#: src/view/com/modals/CreateOrEditList.tsx:293 -#: src/view/com/modals/DeleteAccount.tsx:152 -#: src/view/com/modals/DeleteAccount.tsx:227 -msgctxt "action" -msgid "Cancel" -msgstr "" - #: src/view/com/composer/Composer.tsx:300 #: src/view/com/composer/Composer.tsx:305 #: src/view/com/modals/ChangeEmail.tsx:218 @@ -527,8 +519,17 @@ msgstr "" msgid "Cancel" msgstr "Batal" +#: src/view/com/modals/Confirm.tsx:88 +#: src/view/com/modals/Confirm.tsx:91 +#: src/view/com/modals/CreateOrEditList.tsx:293 +#: src/view/com/modals/DeleteAccount.tsx:152 +#: src/view/com/modals/DeleteAccount.tsx:230 +msgctxt "action" +msgid "Cancel" +msgstr "" + #: src/view/com/modals/DeleteAccount.tsx:148 -#: src/view/com/modals/DeleteAccount.tsx:223 +#: src/view/com/modals/DeleteAccount.tsx:226 msgid "Cancel account deletion" msgstr "Batal menghapus akun" @@ -704,12 +705,6 @@ msgstr "" msgid "Compose reply" msgstr "Tulis balasan" -#: src/view/com/modals/Confirm.tsx:75 -#: src/view/com/modals/Confirm.tsx:78 -msgctxt "action" -msgid "Confirm" -msgstr "" - #: src/view/com/modals/AppealLabel.tsx:98 #: src/view/com/modals/SelfLabel.tsx:154 #: src/view/com/modals/VerifyEmail.tsx:231 @@ -719,6 +714,12 @@ msgstr "" msgid "Confirm" msgstr "Konfirmasi" +#: 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" @@ -728,7 +729,7 @@ msgstr "Konfirmasi Perubahan" msgid "Confirm content language settings" msgstr "Konfirmasi pengaturan bahasa konten" -#: src/view/com/modals/DeleteAccount.tsx:213 +#: src/view/com/modals/DeleteAccount.tsx:216 msgid "Confirm delete account" msgstr "Konfirmasi hapus akun" @@ -920,7 +921,7 @@ msgstr "Hapus kata sandi aplikasi" msgid "Delete List" msgstr "Hapus Daftar " -#: src/view/com/modals/DeleteAccount.tsx:216 +#: src/view/com/modals/DeleteAccount.tsx:219 msgid "Delete my account" msgstr "Hapus akun saya" @@ -1624,7 +1625,7 @@ msgstr "" msgid "Input new password" msgstr "" -#: src/view/com/modals/DeleteAccount.tsx:196 +#: src/view/com/modals/DeleteAccount.tsx:199 msgid "Input password for account deletion" msgstr "" @@ -2014,6 +2015,10 @@ msgstr "" msgid "Mute thread" msgstr "Bisukan utasan" +#: src/view/com/lists/ListCard.tsx:101 +msgid "Muted" +msgstr "" + #: src/view/screens/Moderation.tsx:109 msgid "Muted accounts" msgstr "Akun yang dibisukan" @@ -2124,11 +2129,6 @@ msgstr "" msgid "Newest replies first" msgstr "" -#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 -msgctxt "action" -msgid "Next" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:154 #: src/view/com/auth/login/ForgotPasswordForm.tsx:178 #: src/view/com/auth/login/ForgotPasswordForm.tsx:188 @@ -2139,6 +2139,11 @@ msgstr "" msgid "Next" msgstr "Berikutnya" +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 +msgctxt "action" +msgid "Next" +msgstr "" + #: src/view/com/lightbox/Lightbox.web.tsx:142 msgid "Next image" msgstr "Gambar berikutnya" @@ -2395,7 +2400,7 @@ msgstr "Halaman tidak ditemukan" #: src/view/com/auth/create/Step2.tsx:132 #: src/view/com/auth/login/LoginForm.tsx:223 #: src/view/com/auth/login/SetNewPasswordForm.tsx:132 -#: src/view/com/modals/DeleteAccount.tsx:195 +#: src/view/com/modals/DeleteAccount.tsx:198 msgid "Password" msgstr "Kata sandi" @@ -2473,7 +2478,7 @@ msgstr "Mohon masukkan nama unik untuk Kata Sandi Aplikasi ini atau gunakan nama msgid "Please enter your email." msgstr "Masukkan email Anda." -#: src/view/com/modals/DeleteAccount.tsx:184 +#: src/view/com/modals/DeleteAccount.tsx:187 msgid "Please enter your password as well:" msgstr "Masukkan juga kata sandi Anda:" @@ -3315,8 +3320,8 @@ msgid "Subscribe to this list" msgstr "Langganan ke daftar ini" #: src/view/com/lists/ListCard.tsx:101 -msgid "Subscribed" -msgstr "" +#~ msgid "Subscribed" +#~ msgstr "" #: src/view/screens/Search/Search.tsx:362 msgid "Suggested Follows" @@ -3450,7 +3455,7 @@ msgstr "" msgid "There was an issue fetching notifications. Tap here to try again." msgstr "" -#: src/view/com/posts/Feed.tsx:261 +#: src/view/com/posts/Feed.tsx:263 msgid "There was an issue fetching posts. Tap here to try again." msgstr "" @@ -3628,16 +3633,16 @@ msgstr "Bunyikan daftar" msgid "Unable to contact your service. Please check your Internet connection." msgstr "Tidak dapat terhubung ke layanan. Mohon periksa koneksi internet Anda." -#: src/view/com/profile/ProfileHeader.tsx:475 -msgctxt "action" -msgid "Unblock" -msgstr "" - #: src/view/com/profile/ProfileHeader.tsx:472 #: src/view/screens/ProfileList.tsx:568 msgid "Unblock" msgstr "Buka blokir" +#: src/view/com/profile/ProfileHeader.tsx:475 +msgctxt "action" +msgid "Unblock" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:308 #: src/view/com/profile/ProfileHeader.tsx:392 msgid "Unblock Account" @@ -3847,6 +3852,10 @@ msgstr "Kunjungi Halaman" msgid "Warn" msgstr "" +#: src/view/com/posts/DiscoverFallbackHeader.tsx:29 +msgid "We ran out of posts from your follows. Here's the latest from" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." msgstr "" diff --git a/src/locale/locales/ja/messages.po b/src/locale/locales/ja/messages.po index 7ffca0abcd..1727ded83b 100644 --- a/src/locale/locales/ja/messages.po +++ b/src/locale/locales/ja/messages.po @@ -345,11 +345,6 @@ msgstr "" msgid "Artistic or non-erotic nudity." msgstr "芸術的または性的ではないヌード。" -#: src/view/com/post-thread/PostThread.tsx:400 -msgctxt "action" -msgid "Back" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:141 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 #: src/view/com/auth/login/ForgotPasswordForm.tsx:170 @@ -364,6 +359,11 @@ msgstr "" msgid "Back" msgstr "戻る" +#: src/view/com/post-thread/PostThread.tsx:400 +msgctxt "action" +msgid "Back" +msgstr "" + #: src/view/screens/Settings.tsx:489 msgid "Basics" msgstr "基本" @@ -398,6 +398,7 @@ msgstr "これらのアカウントをブロックしますか?" msgid "Block this List" msgstr "" +#: src/view/com/lists/ListCard.tsx:109 #: src/view/com/util/post-embeds/QuoteEmbed.tsx:57 msgid "Blocked" msgstr "" @@ -500,15 +501,6 @@ 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/view/com/modals/Confirm.tsx:88 -#: src/view/com/modals/Confirm.tsx:91 -#: src/view/com/modals/CreateOrEditList.tsx:293 -#: src/view/com/modals/DeleteAccount.tsx:152 -#: src/view/com/modals/DeleteAccount.tsx:227 -msgctxt "action" -msgid "Cancel" -msgstr "" - #: src/view/com/composer/Composer.tsx:300 #: src/view/com/composer/Composer.tsx:305 #: src/view/com/modals/ChangeEmail.tsx:218 @@ -527,8 +519,17 @@ msgstr "" msgid "Cancel" msgstr "キャンセル" +#: src/view/com/modals/Confirm.tsx:88 +#: src/view/com/modals/Confirm.tsx:91 +#: src/view/com/modals/CreateOrEditList.tsx:293 +#: src/view/com/modals/DeleteAccount.tsx:152 +#: src/view/com/modals/DeleteAccount.tsx:230 +msgctxt "action" +msgid "Cancel" +msgstr "" + #: src/view/com/modals/DeleteAccount.tsx:148 -#: src/view/com/modals/DeleteAccount.tsx:223 +#: src/view/com/modals/DeleteAccount.tsx:226 msgid "Cancel account deletion" msgstr "アカウントの削除をキャンセル" @@ -704,12 +705,6 @@ msgstr "" msgid "Compose reply" msgstr "返信を作成" -#: src/view/com/modals/Confirm.tsx:75 -#: src/view/com/modals/Confirm.tsx:78 -msgctxt "action" -msgid "Confirm" -msgstr "" - #: src/view/com/modals/AppealLabel.tsx:98 #: src/view/com/modals/SelfLabel.tsx:154 #: src/view/com/modals/VerifyEmail.tsx:231 @@ -719,6 +714,12 @@ msgstr "" 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" @@ -728,7 +729,7 @@ msgstr "変更を確認" msgid "Confirm content language settings" msgstr "コンテンツの言語設定を確認" -#: src/view/com/modals/DeleteAccount.tsx:213 +#: src/view/com/modals/DeleteAccount.tsx:216 msgid "Confirm delete account" msgstr "アカウントの削除を確認" @@ -920,7 +921,7 @@ msgstr "アプリパスワードを削除" msgid "Delete List" msgstr "リストを削除" -#: src/view/com/modals/DeleteAccount.tsx:216 +#: src/view/com/modals/DeleteAccount.tsx:219 msgid "Delete my account" msgstr "マイアカウントを削除" @@ -1624,7 +1625,7 @@ msgstr "" msgid "Input new password" msgstr "" -#: src/view/com/modals/DeleteAccount.tsx:196 +#: src/view/com/modals/DeleteAccount.tsx:199 msgid "Input password for account deletion" msgstr "" @@ -2022,6 +2023,10 @@ msgstr "" msgid "Mute thread" msgstr "スレッドをミュート" +#: src/view/com/lists/ListCard.tsx:101 +msgid "Muted" +msgstr "" + #: src/view/screens/Moderation.tsx:109 msgid "Muted accounts" msgstr "ミュート中のアカウント" @@ -2132,11 +2137,6 @@ msgstr "" msgid "Newest replies first" msgstr "新しい順に返信を表示" -#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 -msgctxt "action" -msgid "Next" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:154 #: src/view/com/auth/login/ForgotPasswordForm.tsx:178 #: src/view/com/auth/login/ForgotPasswordForm.tsx:188 @@ -2147,6 +2147,11 @@ msgstr "" msgid "Next" msgstr "次へ" +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 +msgctxt "action" +msgid "Next" +msgstr "" + #: src/view/com/lightbox/Lightbox.web.tsx:142 msgid "Next image" msgstr "次の画像" @@ -2407,7 +2412,7 @@ msgstr "ページが見つかりません" #: src/view/com/auth/create/Step2.tsx:132 #: src/view/com/auth/login/LoginForm.tsx:223 #: src/view/com/auth/login/SetNewPasswordForm.tsx:132 -#: src/view/com/modals/DeleteAccount.tsx:195 +#: src/view/com/modals/DeleteAccount.tsx:198 msgid "Password" msgstr "パスワード" @@ -2485,7 +2490,7 @@ msgstr "このアプリパスワードに固有の名前を入力するか、ラ msgid "Please enter your email." msgstr "メールアドレスを入力してください。" -#: src/view/com/modals/DeleteAccount.tsx:184 +#: src/view/com/modals/DeleteAccount.tsx:187 msgid "Please enter your password as well:" msgstr "パスワードも入力してください:" @@ -3331,8 +3336,8 @@ msgid "Subscribe to this list" msgstr "このリストに登録" #: src/view/com/lists/ListCard.tsx:101 -msgid "Subscribed" -msgstr "" +#~ msgid "Subscribed" +#~ msgstr "" #: src/view/screens/Search/Search.tsx:362 msgid "Suggested Follows" @@ -3466,7 +3471,7 @@ msgstr "" msgid "There was an issue fetching notifications. Tap here to try again." msgstr "" -#: src/view/com/posts/Feed.tsx:261 +#: src/view/com/posts/Feed.tsx:263 msgid "There was an issue fetching posts. Tap here to try again." msgstr "" @@ -3644,16 +3649,16 @@ msgstr "リストでのミュートを解除" msgid "Unable to contact your service. Please check your Internet connection." msgstr "あなたのサービスに接続できません。インターネットの接続を確認してください。" -#: src/view/com/profile/ProfileHeader.tsx:475 -msgctxt "action" -msgid "Unblock" -msgstr "" - #: src/view/com/profile/ProfileHeader.tsx:472 #: src/view/screens/ProfileList.tsx:568 msgid "Unblock" msgstr "ブロックを解除" +#: src/view/com/profile/ProfileHeader.tsx:475 +msgctxt "action" +msgid "Unblock" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:308 #: src/view/com/profile/ProfileHeader.tsx:392 msgid "Unblock Account" @@ -3863,6 +3868,10 @@ msgstr "サイトへアクセス" msgid "Warn" msgstr "" +#: src/view/com/posts/DiscoverFallbackHeader.tsx:29 +msgid "We ran out of posts from your follows. Here's the latest from" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." msgstr "" diff --git a/src/locale/locales/ko/messages.po b/src/locale/locales/ko/messages.po index a0ba65b1ea..277b97e225 100644 --- a/src/locale/locales/ko/messages.po +++ b/src/locale/locales/ko/messages.po @@ -421,11 +421,6 @@ msgstr "선정적이지 않거나 예술적인 노출." #~ msgid "Ask apps to limit the visibility of my account" #~ msgstr "내 계정의 공개 범위를 제한하도록 앱에 요청하기" -#: src/view/com/post-thread/PostThread.tsx:400 -msgctxt "action" -msgid "Back" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:141 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 #: src/view/com/auth/login/ForgotPasswordForm.tsx:170 @@ -440,6 +435,11 @@ msgstr "" msgid "Back" msgstr "뒤로" +#: src/view/com/post-thread/PostThread.tsx:400 +msgctxt "action" +msgid "Back" +msgstr "" + #: src/view/screens/Settings.tsx:489 msgid "Basics" msgstr "기본" @@ -474,6 +474,7 @@ msgstr "이 계정들을 차단하시겠습니까?" msgid "Block this List" msgstr "" +#: src/view/com/lists/ListCard.tsx:109 #: src/view/com/util/post-embeds/QuoteEmbed.tsx:57 msgid "Blocked" msgstr "" @@ -580,15 +581,6 @@ 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/view/com/modals/Confirm.tsx:88 -#: src/view/com/modals/Confirm.tsx:91 -#: src/view/com/modals/CreateOrEditList.tsx:293 -#: src/view/com/modals/DeleteAccount.tsx:152 -#: src/view/com/modals/DeleteAccount.tsx:227 -msgctxt "action" -msgid "Cancel" -msgstr "" - #: src/view/com/composer/Composer.tsx:300 #: src/view/com/composer/Composer.tsx:305 #: src/view/com/modals/ChangeEmail.tsx:218 @@ -607,8 +599,17 @@ msgstr "" msgid "Cancel" msgstr "취소" +#: src/view/com/modals/Confirm.tsx:88 +#: src/view/com/modals/Confirm.tsx:91 +#: src/view/com/modals/CreateOrEditList.tsx:293 +#: src/view/com/modals/DeleteAccount.tsx:152 +#: src/view/com/modals/DeleteAccount.tsx:230 +msgctxt "action" +msgid "Cancel" +msgstr "" + #: src/view/com/modals/DeleteAccount.tsx:148 -#: src/view/com/modals/DeleteAccount.tsx:223 +#: src/view/com/modals/DeleteAccount.tsx:226 msgid "Cancel account deletion" msgstr "계정 삭제 취소" @@ -788,12 +789,6 @@ msgstr "" msgid "Compose reply" msgstr "답글 작성하기" -#: src/view/com/modals/Confirm.tsx:75 -#: src/view/com/modals/Confirm.tsx:78 -msgctxt "action" -msgid "Confirm" -msgstr "" - #: src/view/com/modals/AppealLabel.tsx:98 #: src/view/com/modals/SelfLabel.tsx:154 #: src/view/com/modals/VerifyEmail.tsx:231 @@ -803,6 +798,12 @@ msgstr "" 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" @@ -812,7 +813,7 @@ msgstr "변경 확인" msgid "Confirm content language settings" msgstr "콘텐츠 언어 설정 확인" -#: src/view/com/modals/DeleteAccount.tsx:213 +#: src/view/com/modals/DeleteAccount.tsx:216 msgid "Confirm delete account" msgstr "계정 삭제 확인" @@ -1020,7 +1021,7 @@ msgstr "앱 비밀번호 삭제" msgid "Delete List" msgstr "리스트 삭제" -#: src/view/com/modals/DeleteAccount.tsx:216 +#: src/view/com/modals/DeleteAccount.tsx:219 msgid "Delete my account" msgstr "내 계정 삭제" @@ -1850,7 +1851,7 @@ msgstr "" msgid "Input new password" msgstr "" -#: src/view/com/modals/DeleteAccount.tsx:196 +#: src/view/com/modals/DeleteAccount.tsx:199 msgid "Input password for account deletion" msgstr "" @@ -2256,6 +2257,10 @@ msgstr "" msgid "Mute thread" msgstr "스레드 뮤트" +#: src/view/com/lists/ListCard.tsx:101 +msgid "Muted" +msgstr "" + #: src/view/screens/Moderation.tsx:109 msgid "Muted accounts" msgstr "뮤트한 계정" @@ -2379,11 +2384,6 @@ msgstr "" msgid "Newest replies first" msgstr "새로운 순" -#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 -msgctxt "action" -msgid "Next" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:154 #: src/view/com/auth/login/ForgotPasswordForm.tsx:178 #: src/view/com/auth/login/ForgotPasswordForm.tsx:188 @@ -2394,6 +2394,11 @@ msgstr "" msgid "Next" msgstr "다음" +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 +msgctxt "action" +msgid "Next" +msgstr "" + #: src/view/com/lightbox/Lightbox.web.tsx:142 msgid "Next image" msgstr "다음 이미지" @@ -2688,7 +2693,7 @@ msgstr "페이지를 찾을 수 없음" #: src/view/com/auth/create/Step2.tsx:132 #: src/view/com/auth/login/LoginForm.tsx:223 #: src/view/com/auth/login/SetNewPasswordForm.tsx:132 -#: src/view/com/modals/DeleteAccount.tsx:195 +#: src/view/com/modals/DeleteAccount.tsx:198 msgid "Password" msgstr "비밀번호" @@ -2766,7 +2771,7 @@ msgstr "이 앱 비밀번호에 대해 고유한 이름을 입력하거나 무 msgid "Please enter your email." msgstr "이메일을 입력하세요." -#: src/view/com/modals/DeleteAccount.tsx:184 +#: src/view/com/modals/DeleteAccount.tsx:187 msgid "Please enter your password as well:" msgstr "비밀번호도 입력해 주세요:" @@ -3683,8 +3688,8 @@ msgid "Subscribe to this list" msgstr "이 리스트로 구독" #: src/view/com/lists/ListCard.tsx:101 -msgid "Subscribed" -msgstr "" +#~ msgid "Subscribed" +#~ msgstr "" #: src/view/screens/Search/Search.tsx:362 msgid "Suggested Follows" @@ -3839,7 +3844,7 @@ msgstr "서버에 연결하는 동안 문제가 발생했습니다." msgid "There was an issue fetching notifications. Tap here to try again." msgstr "" -#: src/view/com/posts/Feed.tsx:261 +#: src/view/com/posts/Feed.tsx:263 msgid "There was an issue fetching posts. Tap here to try again." msgstr "" @@ -4029,16 +4034,16 @@ msgstr "리스트 언뮤트" msgid "Unable to contact your service. Please check your Internet connection." msgstr "서비스에 연결할 수 없습니다. 인터넷 연결을 확인하세요." -#: src/view/com/profile/ProfileHeader.tsx:475 -msgctxt "action" -msgid "Unblock" -msgstr "" - #: src/view/com/profile/ProfileHeader.tsx:472 #: src/view/screens/ProfileList.tsx:568 msgid "Unblock" msgstr "차단 해제" +#: src/view/com/profile/ProfileHeader.tsx:475 +msgctxt "action" +msgid "Unblock" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:308 #: src/view/com/profile/ProfileHeader.tsx:392 msgid "Unblock Account" @@ -4290,6 +4295,10 @@ msgstr "사이트 방문" msgid "Warn" msgstr "경고" +#: src/view/com/posts/DiscoverFallbackHeader.tsx:29 +msgid "We ran out of posts from your follows. Here's the latest from" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." msgstr "이의신청을 즉시 검토하겠습니다." diff --git a/src/locale/locales/pt-BR/messages.po b/src/locale/locales/pt-BR/messages.po index aa2cbee685..d7083ff37b 100644 --- a/src/locale/locales/pt-BR/messages.po +++ b/src/locale/locales/pt-BR/messages.po @@ -373,11 +373,6 @@ msgstr "Nudez artística ou não erótica." #~ msgid "Ask apps to limit the visibility of my account" #~ msgstr "" -#: src/view/com/post-thread/PostThread.tsx:400 -msgctxt "action" -msgid "Back" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:141 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 #: src/view/com/auth/login/ForgotPasswordForm.tsx:170 @@ -392,6 +387,11 @@ msgstr "" msgid "Back" msgstr "Voltar" +#: src/view/com/post-thread/PostThread.tsx:400 +msgctxt "action" +msgid "Back" +msgstr "" + #: src/view/screens/Settings.tsx:489 msgid "Basics" msgstr "Básicos" @@ -426,6 +426,7 @@ msgstr "Bloquear esta conta?" msgid "Block this List" msgstr "" +#: src/view/com/lists/ListCard.tsx:109 #: src/view/com/util/post-embeds/QuoteEmbed.tsx:57 msgid "Blocked" msgstr "" @@ -528,15 +529,6 @@ msgstr "Câmera" 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 "Só pode conter letras, números, espaços, traços e sublinhados. Deve ter pelo menos 4 caracteres, mas não mais de 32 caracteres." -#: src/view/com/modals/Confirm.tsx:88 -#: src/view/com/modals/Confirm.tsx:91 -#: src/view/com/modals/CreateOrEditList.tsx:293 -#: src/view/com/modals/DeleteAccount.tsx:152 -#: src/view/com/modals/DeleteAccount.tsx:227 -msgctxt "action" -msgid "Cancel" -msgstr "" - #: src/view/com/composer/Composer.tsx:300 #: src/view/com/composer/Composer.tsx:305 #: src/view/com/modals/ChangeEmail.tsx:218 @@ -555,8 +547,17 @@ msgstr "" msgid "Cancel" msgstr "Cancelar" +#: src/view/com/modals/Confirm.tsx:88 +#: src/view/com/modals/Confirm.tsx:91 +#: src/view/com/modals/CreateOrEditList.tsx:293 +#: src/view/com/modals/DeleteAccount.tsx:152 +#: src/view/com/modals/DeleteAccount.tsx:230 +msgctxt "action" +msgid "Cancel" +msgstr "" + #: src/view/com/modals/DeleteAccount.tsx:148 -#: src/view/com/modals/DeleteAccount.tsx:223 +#: src/view/com/modals/DeleteAccount.tsx:226 msgid "Cancel account deletion" msgstr "Cancelar exclusão da conta" @@ -736,12 +737,6 @@ msgstr "" msgid "Compose reply" msgstr "Escrever resposta" -#: src/view/com/modals/Confirm.tsx:75 -#: src/view/com/modals/Confirm.tsx:78 -msgctxt "action" -msgid "Confirm" -msgstr "" - #: src/view/com/modals/AppealLabel.tsx:98 #: src/view/com/modals/SelfLabel.tsx:154 #: src/view/com/modals/VerifyEmail.tsx:231 @@ -751,6 +746,12 @@ msgstr "" msgid "Confirm" msgstr "Confirme" +#: 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" @@ -760,7 +761,7 @@ msgstr "Confirmar Alterações" msgid "Confirm content language settings" msgstr "Confirmar configurações de idioma de conteúdo" -#: src/view/com/modals/DeleteAccount.tsx:213 +#: src/view/com/modals/DeleteAccount.tsx:216 msgid "Confirm delete account" msgstr "Confirmar a exclusão da conta" @@ -952,7 +953,7 @@ msgstr "Excluir senha do aplicativo" msgid "Delete List" msgstr "Excluir Lista" -#: src/view/com/modals/DeleteAccount.tsx:216 +#: src/view/com/modals/DeleteAccount.tsx:219 msgid "Delete my account" msgstr "Excluir minha conta" @@ -1673,7 +1674,7 @@ msgstr "" msgid "Input new password" msgstr "" -#: src/view/com/modals/DeleteAccount.tsx:196 +#: src/view/com/modals/DeleteAccount.tsx:199 msgid "Input password for account deletion" msgstr "" @@ -2075,6 +2076,10 @@ msgstr "" msgid "Mute thread" msgstr "Silenciar tópico" +#: src/view/com/lists/ListCard.tsx:101 +msgid "Muted" +msgstr "" + #: src/view/screens/Moderation.tsx:109 msgid "Muted accounts" msgstr "Contas silenciadas" @@ -2189,11 +2194,6 @@ msgstr "" msgid "Newest replies first" msgstr "Respostas mais recentes primeiro" -#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 -msgctxt "action" -msgid "Next" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:154 #: src/view/com/auth/login/ForgotPasswordForm.tsx:178 #: src/view/com/auth/login/ForgotPasswordForm.tsx:188 @@ -2204,6 +2204,11 @@ msgstr "" msgid "Next" msgstr "Próximo" +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 +msgctxt "action" +msgid "Next" +msgstr "" + #: src/view/com/lightbox/Lightbox.web.tsx:142 msgid "Next image" msgstr "Próxima imagem" @@ -2477,7 +2482,7 @@ msgstr "Página não encontrada" #: src/view/com/auth/create/Step2.tsx:132 #: src/view/com/auth/login/LoginForm.tsx:223 #: src/view/com/auth/login/SetNewPasswordForm.tsx:132 -#: src/view/com/modals/DeleteAccount.tsx:195 +#: src/view/com/modals/DeleteAccount.tsx:198 msgid "Password" msgstr "Senha" @@ -2555,7 +2560,7 @@ msgstr "Por favor, insira um nome único para esta Senha do Aplicativo ou use no msgid "Please enter your email." msgstr "Por favor, digite o seu email." -#: src/view/com/modals/DeleteAccount.tsx:184 +#: src/view/com/modals/DeleteAccount.tsx:187 msgid "Please enter your password as well:" msgstr "Por favor, digite sua senha também:" @@ -3422,8 +3427,8 @@ msgid "Subscribe to this list" msgstr "Assinar esta lista" #: src/view/com/lists/ListCard.tsx:101 -msgid "Subscribed" -msgstr "" +#~ msgid "Subscribed" +#~ msgstr "" #: src/view/screens/Search/Search.tsx:362 msgid "Suggested Follows" @@ -3557,7 +3562,7 @@ msgstr "" msgid "There was an issue fetching notifications. Tap here to try again." msgstr "" -#: src/view/com/posts/Feed.tsx:261 +#: src/view/com/posts/Feed.tsx:263 msgid "There was an issue fetching posts. Tap here to try again." msgstr "" @@ -3735,16 +3740,16 @@ msgstr "Lista de não silenciados" msgid "Unable to contact your service. Please check your Internet connection." msgstr "Não foi possível entrar em contato com seu serviço. Por favor, verifique sua conexão à internet." -#: src/view/com/profile/ProfileHeader.tsx:475 -msgctxt "action" -msgid "Unblock" -msgstr "" - #: src/view/com/profile/ProfileHeader.tsx:472 #: src/view/screens/ProfileList.tsx:568 msgid "Unblock" msgstr "Desbloquear" +#: src/view/com/profile/ProfileHeader.tsx:475 +msgctxt "action" +msgid "Unblock" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:308 #: src/view/com/profile/ProfileHeader.tsx:392 msgid "Unblock Account" @@ -3958,6 +3963,10 @@ msgstr "Visitar Site" msgid "Warn" msgstr "" +#: src/view/com/posts/DiscoverFallbackHeader.tsx:29 +msgid "We ran out of posts from your follows. Here's the latest from" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." msgstr "" diff --git a/src/locale/locales/uk/messages.po b/src/locale/locales/uk/messages.po index ce366a0b38..016e206233 100644 --- a/src/locale/locales/uk/messages.po +++ b/src/locale/locales/uk/messages.po @@ -378,11 +378,6 @@ msgstr "Художня або нееротична оголеність." #~ msgid "Ask apps to limit the visibility of my account" #~ msgstr "" -#: src/view/com/post-thread/PostThread.tsx:400 -msgctxt "action" -msgid "Back" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:141 #: src/view/com/auth/login/ChooseAccountForm.tsx:151 #: src/view/com/auth/login/ForgotPasswordForm.tsx:170 @@ -397,6 +392,11 @@ msgstr "" msgid "Back" msgstr "Назад" +#: src/view/com/post-thread/PostThread.tsx:400 +msgctxt "action" +msgid "Back" +msgstr "" + #: src/view/screens/Settings.tsx:489 msgid "Basics" msgstr "Основні" @@ -431,6 +431,7 @@ msgstr "Заблокувати ці облікові записи?" msgid "Block this List" msgstr "" +#: src/view/com/lists/ListCard.tsx:109 #: src/view/com/util/post-embeds/QuoteEmbed.tsx:57 msgid "Blocked" msgstr "" @@ -533,15 +534,6 @@ 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/view/com/modals/Confirm.tsx:88 -#: src/view/com/modals/Confirm.tsx:91 -#: src/view/com/modals/CreateOrEditList.tsx:293 -#: src/view/com/modals/DeleteAccount.tsx:152 -#: src/view/com/modals/DeleteAccount.tsx:227 -msgctxt "action" -msgid "Cancel" -msgstr "" - #: src/view/com/composer/Composer.tsx:300 #: src/view/com/composer/Composer.tsx:305 #: src/view/com/modals/ChangeEmail.tsx:218 @@ -560,8 +552,17 @@ msgstr "" msgid "Cancel" msgstr "Скасувати" +#: src/view/com/modals/Confirm.tsx:88 +#: src/view/com/modals/Confirm.tsx:91 +#: src/view/com/modals/CreateOrEditList.tsx:293 +#: src/view/com/modals/DeleteAccount.tsx:152 +#: src/view/com/modals/DeleteAccount.tsx:230 +msgctxt "action" +msgid "Cancel" +msgstr "" + #: src/view/com/modals/DeleteAccount.tsx:148 -#: src/view/com/modals/DeleteAccount.tsx:223 +#: src/view/com/modals/DeleteAccount.tsx:226 msgid "Cancel account deletion" msgstr "Скасувати видалення облікового запису" @@ -741,12 +742,6 @@ msgstr "" msgid "Compose reply" msgstr "Відповісти" -#: src/view/com/modals/Confirm.tsx:75 -#: src/view/com/modals/Confirm.tsx:78 -msgctxt "action" -msgid "Confirm" -msgstr "" - #: src/view/com/modals/AppealLabel.tsx:98 #: src/view/com/modals/SelfLabel.tsx:154 #: src/view/com/modals/VerifyEmail.tsx:231 @@ -756,6 +751,12 @@ msgstr "" 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" @@ -765,7 +766,7 @@ msgstr "Підтвердити" msgid "Confirm content language settings" msgstr "Підтвердити перелік мов" -#: src/view/com/modals/DeleteAccount.tsx:213 +#: src/view/com/modals/DeleteAccount.tsx:216 msgid "Confirm delete account" msgstr "Підтвердити видалення облікового запису" @@ -957,7 +958,7 @@ msgstr "Видалити пароль для застосунку" msgid "Delete List" msgstr "Видалити список" -#: src/view/com/modals/DeleteAccount.tsx:216 +#: src/view/com/modals/DeleteAccount.tsx:219 msgid "Delete my account" msgstr "Видалити мій обліковий запис" @@ -1678,7 +1679,7 @@ msgstr "" msgid "Input new password" msgstr "" -#: src/view/com/modals/DeleteAccount.tsx:196 +#: src/view/com/modals/DeleteAccount.tsx:199 msgid "Input password for account deletion" msgstr "" @@ -2080,6 +2081,10 @@ msgstr "" msgid "Mute thread" msgstr "Ігнорувати пост" +#: src/view/com/lists/ListCard.tsx:101 +msgid "Muted" +msgstr "" + #: src/view/screens/Moderation.tsx:109 msgid "Muted accounts" msgstr "Ігноровані облікові записи" @@ -2194,11 +2199,6 @@ msgstr "" msgid "Newest replies first" msgstr "Спочатку найновіші" -#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 -msgctxt "action" -msgid "Next" -msgstr "" - #: src/view/com/auth/create/CreateAccount.tsx:154 #: src/view/com/auth/login/ForgotPasswordForm.tsx:178 #: src/view/com/auth/login/ForgotPasswordForm.tsx:188 @@ -2209,6 +2209,11 @@ msgstr "" msgid "Next" msgstr "Далі" +#: src/view/com/auth/onboarding/WelcomeDesktop.tsx:103 +msgctxt "action" +msgid "Next" +msgstr "" + #: src/view/com/lightbox/Lightbox.web.tsx:142 msgid "Next image" msgstr "Наступне зображення" @@ -2482,7 +2487,7 @@ msgstr "Сторінку не знайдено" #: src/view/com/auth/create/Step2.tsx:132 #: src/view/com/auth/login/LoginForm.tsx:223 #: src/view/com/auth/login/SetNewPasswordForm.tsx:132 -#: src/view/com/modals/DeleteAccount.tsx:195 +#: src/view/com/modals/DeleteAccount.tsx:198 msgid "Password" msgstr "Пароль" @@ -2560,7 +2565,7 @@ msgstr "Будь ласка, введіть унікальну назву для msgid "Please enter your email." msgstr "Будь ласка, введіть адресу ел. пошти." -#: src/view/com/modals/DeleteAccount.tsx:184 +#: src/view/com/modals/DeleteAccount.tsx:187 msgid "Please enter your password as well:" msgstr "Будь ласка, також введіть ваш пароль:" @@ -3427,8 +3432,8 @@ msgid "Subscribe to this list" msgstr "Підписатися на цей список" #: src/view/com/lists/ListCard.tsx:101 -msgid "Subscribed" -msgstr "" +#~ msgid "Subscribed" +#~ msgstr "" #: src/view/screens/Search/Search.tsx:362 msgid "Suggested Follows" @@ -3562,7 +3567,7 @@ msgstr "" msgid "There was an issue fetching notifications. Tap here to try again." msgstr "" -#: src/view/com/posts/Feed.tsx:261 +#: src/view/com/posts/Feed.tsx:263 msgid "There was an issue fetching posts. Tap here to try again." msgstr "" @@ -3740,16 +3745,16 @@ msgstr "Перестати ігнорувати" msgid "Unable to contact your service. Please check your Internet connection." msgstr "Не вдалося зв'язатися з вашим хостинг-провайдером. Перевірте ваше підключення до Інтернету." -#: src/view/com/profile/ProfileHeader.tsx:475 -msgctxt "action" -msgid "Unblock" -msgstr "" - #: src/view/com/profile/ProfileHeader.tsx:472 #: src/view/screens/ProfileList.tsx:568 msgid "Unblock" msgstr "Розблокувати" +#: src/view/com/profile/ProfileHeader.tsx:475 +msgctxt "action" +msgid "Unblock" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:308 #: src/view/com/profile/ProfileHeader.tsx:392 msgid "Unblock Account" @@ -3963,6 +3968,10 @@ msgstr "Відвідати сайт" msgid "Warn" msgstr "" +#: src/view/com/posts/DiscoverFallbackHeader.tsx:29 +msgid "We ran out of posts from your follows. Here's the latest from" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:48 msgid "We'll look into your appeal promptly." msgstr "" From d35be77a116772eb13c1c1165b0ed4628f0ac657 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Mon, 15 Jan 2024 15:31:56 -0800 Subject: [PATCH 09/28] Bump android version code --- app.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.config.js b/app.config.js index bf1c4fa0ad..c05787428a 100644 --- a/app.config.js +++ b/app.config.js @@ -25,7 +25,7 @@ module.exports = function () { /** * Android build number. Must be incremented for each release. */ - const ANDROID_VERSION_CODE = 55 + const ANDROID_VERSION_CODE = 56 /** * Uses built-in Expo env vars From 6d0557c959ed250ff0061605454324cc88775005 Mon Sep 17 00:00:00 2001 From: Mary Date: Tue, 16 Jan 2024 07:31:01 +0700 Subject: [PATCH 10/28] feat: better autocomplete view --- src/view/screens/Search/Search.tsx | 43 ++++++++++++----- src/view/shell/desktop/Search.tsx | 77 ++++++++++++++++++++++-------- 2 files changed, 86 insertions(+), 34 deletions(-) diff --git a/src/view/screens/Search/Search.tsx b/src/view/screens/Search/Search.tsx index 8e7e204ad2..02a631fa0d 100644 --- a/src/view/screens/Search/Search.tsx +++ b/src/view/screens/Search/Search.tsx @@ -42,7 +42,11 @@ import {useSetDrawerOpen} from '#/state/shell' import {useAnalytics} from '#/lib/analytics/analytics' import {MagnifyingGlassIcon} from '#/lib/icons' import {useModerationOpts} from '#/state/queries/preferences' -import {SearchResultCard} from '#/view/shell/desktop/Search' +import { + MATCH_HANDLE, + SearchLinkCard, + SearchProfileCard, +} from '#/view/shell/desktop/Search' import {useSetMinimalShellMode, useSetDrawerSwipeDisabled} from '#/state/shell' import {isWeb} from '#/platform/detection' import {listenSoftReset} from '#/state/events' @@ -511,6 +515,11 @@ export function SearchScreen( onPressCancelSearch() }, [onPressCancelSearch]) + const queryMaybeHandle = React.useMemo(() => { + const match = MATCH_HANDLE.exec(query) + return match && match[1] + }, [query]) + useFocusEffect( React.useCallback(() => { setMinimalShellMode(false) @@ -617,18 +626,26 @@ export function SearchScreen( dataSet={{stableGutters: '1'}} keyboardShouldPersistTaps="handled" keyboardDismissMode="on-drag"> - {searchResults.length ? ( - searchResults.map((item, i) => ( - - )) - ) : ( - - )} + + + {queryMaybeHandle ? ( + + ) : null} + + {searchResults.map(item => ( + + ))} diff --git a/src/view/shell/desktop/Search.tsx b/src/view/shell/desktop/Search.tsx index df49da55b0..c24940b522 100644 --- a/src/view/shell/desktop/Search.tsx +++ b/src/view/shell/desktop/Search.tsx @@ -29,13 +29,41 @@ import {UserAvatar} from '#/view/com/util/UserAvatar' import {useActorAutocompleteFn} from '#/state/queries/actor-autocomplete' import {useModerationOpts} from '#/state/queries/preferences' -export function SearchResultCard({ - profile, +export const MATCH_HANDLE = + /@?([a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*(?:\.[a-zA-Z]{2,}))/ + +export function SearchLinkCard({ + label, + to, style, +}: { + label: string + to: string + style?: ViewStyle +}) { + const pal = usePalette('default') + + return ( + + + + {label} + + + + ) +} + +export function SearchProfileCard({ + profile, moderation, }: { profile: AppBskyActorDefs.ProfileViewBasic - style: ViewStyle moderation: ProfileModeration }) { const pal = usePalette('default') @@ -50,9 +78,7 @@ export function SearchResultCard({ { + const match = MATCH_HANDLE.exec(query) + return match && match[1] + }, [query]) + return ( ) : ( <> - {searchResults.length ? ( - searchResults.map((item, i) => ( - - )) - ) : ( - - - No results found for {query} - - - )} + + + {queryMaybeHandle ? ( + + ) : null} + + {searchResults.map(item => ( + + ))} )} From 8372c0c261143e9a4cb5c244f15c966f865e282d Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Tue, 16 Jan 2024 10:01:41 -0800 Subject: [PATCH 11/28] Fix the fallback to discover behavior on the home feed (#2546) --- src/lib/api/feed/home.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/api/feed/home.ts b/src/lib/api/feed/home.ts index 91634927ab..436a66d076 100644 --- a/src/lib/api/feed/home.ts +++ b/src/lib/api/feed/home.ts @@ -68,7 +68,8 @@ export class HomeFeedAPI implements FeedAPI { const res = await this.following.fetch({cursor, limit}) returnCursor = res.cursor posts = posts.concat(res.feed) - if (res.feed.length === 0 || !cursor) { + if (!returnCursor) { + cursor = '' posts.push(FALLBACK_MARKER_POST) this.usingDiscover = true } From f1e58626fbfc9cd474677c7fe48daf755a3470cf Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Tue, 16 Jan 2024 10:05:11 -0800 Subject: [PATCH 12/28] 1.65 --- app.config.js | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app.config.js b/app.config.js index c05787428a..4adeb03b79 100644 --- a/app.config.js +++ b/app.config.js @@ -20,12 +20,12 @@ module.exports = function () { /** * iOS build number. Must be incremented for each TestFlight version. */ - const IOS_BUILD_NUMBER = '2' + const IOS_BUILD_NUMBER = '1' /** * Android build number. Must be incremented for each release. */ - const ANDROID_VERSION_CODE = 56 + const ANDROID_VERSION_CODE = 57 /** * Uses built-in Expo env vars diff --git a/package.json b/package.json index 71410feabf..517c328c10 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bsky.app", - "version": "1.64.0", + "version": "1.65.0", "private": true, "engines": { "node": ">=18" From 64f7800bed3ac72f1742f96e94e72334fcb65283 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 16 Jan 2024 16:35:08 -0600 Subject: [PATCH 13/28] Patch `@lingui/core` to fix `unraw` import resolution error (#2548) --- patches/@lingui+core+4.5.0.patch | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 patches/@lingui+core+4.5.0.patch diff --git a/patches/@lingui+core+4.5.0.patch b/patches/@lingui+core+4.5.0.patch new file mode 100644 index 0000000000..8ace93a744 --- /dev/null +++ b/patches/@lingui+core+4.5.0.patch @@ -0,0 +1,10 @@ +diff --git a/node_modules/@lingui/core/dist/index.mjs b/node_modules/@lingui/core/dist/index.mjs +index 9759736..881f67b 100644 +--- a/node_modules/@lingui/core/dist/index.mjs ++++ b/node_modules/@lingui/core/dist/index.mjs +@@ -1,4 +1,4 @@ +-import unraw from 'unraw'; ++import { unraw } from 'unraw'; + import { compileMessage } from '@lingui/message-utils/compileMessage'; + + const isString = (s) => typeof s === "string"; From 9cbd3c0937d22e8dccbd9c086d3a3a24dbd27b3a Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 16 Jan 2024 17:48:35 -0600 Subject: [PATCH 14/28] Reduce some Sentry logs (#2549) * Reduce some Sentry logs * Update tests --- src/state/persisted/__tests__/migrate.test.ts | 6 +++--- src/state/persisted/legacy.ts | 4 ++-- src/state/queries/feed.ts | 3 ++- src/state/queries/notifications/unread.tsx | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/state/persisted/__tests__/migrate.test.ts b/src/state/persisted/__tests__/migrate.test.ts index d42580efdf..2435ed24fb 100644 --- a/src/state/persisted/__tests__/migrate.test.ts +++ b/src/state/persisted/__tests__/migrate.test.ts @@ -26,7 +26,7 @@ test('migrate: fresh install', async () => { expect(AsyncStorage.getItem).toHaveBeenCalledWith('root') expect(read).toHaveBeenCalledTimes(1) - expect(logger.log).toHaveBeenCalledWith( + expect(logger.info).toHaveBeenCalledWith( 'persisted state: no migration needed', ) }) @@ -38,7 +38,7 @@ test('migrate: fresh install, existing new storage', async () => { expect(AsyncStorage.getItem).toHaveBeenCalledWith('root') expect(read).toHaveBeenCalledTimes(1) - expect(logger.log).toHaveBeenCalledWith( + expect(logger.info).toHaveBeenCalledWith( 'persisted state: no migration needed', ) }) @@ -68,7 +68,7 @@ test('migrate: has legacy data', async () => { await migrate() expect(write).toHaveBeenCalledWith(transform(fixtures.LEGACY_DATA_DUMP)) - expect(logger.log).toHaveBeenCalledWith( + expect(logger.info).toHaveBeenCalledWith( 'persisted state: migrated legacy storage', ) }) diff --git a/src/state/persisted/legacy.ts b/src/state/persisted/legacy.ts index 334ef1d92a..097d6bc5c7 100644 --- a/src/state/persisted/legacy.ts +++ b/src/state/persisted/legacy.ts @@ -164,14 +164,14 @@ export async function migrate() { if (validate.success) { await write(newData) - logger.log('persisted state: migrated legacy storage') + logger.info('persisted state: migrated legacy storage') } else { logger.error('persisted state: legacy data failed validation', { error: validate.error, }) } } else { - logger.log('persisted state: no migration needed') + logger.info('persisted state: no migration needed') } } catch (e: any) { logger.error(e, { diff --git a/src/state/queries/feed.ts b/src/state/queries/feed.ts index 7a55b4e186..4acc7179a7 100644 --- a/src/state/queries/feed.ts +++ b/src/state/queries/feed.ts @@ -272,7 +272,8 @@ export function usePinnedFeedsInfos(): { }, }) } catch (e) { - logger.warn(`usePinnedFeedsInfos: failed to fetch ${uri}`, { + // expected failure + logger.info(`usePinnedFeedsInfos: failed to fetch ${uri}`, { error: e, }) } diff --git a/src/state/queries/notifications/unread.tsx b/src/state/queries/notifications/unread.tsx index 49bb5a29d3..a96b562258 100644 --- a/src/state/queries/notifications/unread.tsx +++ b/src/state/queries/notifications/unread.tsx @@ -167,7 +167,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } broadcast.postMessage({event: unreadCountStr}) } catch (e) { - logger.error('Failed to check unread notifications', {error: e}) + logger.warn('Failed to check unread notifications', {error: e}) } }, From 66b8774ecb9c5d465987909577ddad3dd4a3ab8e Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Thu, 18 Jan 2024 20:28:04 -0600 Subject: [PATCH 15/28] New component library based on ALF (#2459) * Install on native as well * Add button and link components * Comments * Use new prop * Add some form elements * Add labels to input * Fix line height, add suffix * Date inputs * Autofill styles * Clean up InputDate types * Improve types for InputText, value handling * Enforce a11y props on buttons * Add Dialog, Portal * Dialog contents * Native dialog * Clean up * Fix animations * Improvements to web modal, exiting still broken * Clean up dialog types * Add Prompt, Dialog refinement, mobile refinement * Integrate new design tokens, reorg storybook * Button colors * Dim mode * Reorg * Some styles * Toggles * Improve a11y * Autosize dialog, handle max height, Dialog.ScrolLView not working * Try to use BottomSheet's own APIs * Scrollable dialogs * Add web shadow * Handle overscroll * Styles * Dialog text input * Shadows * Button focus states * Button pressed states * Gradient poc * Gradient colors and hovers * Add hrefAttrs to Link * Some more a11y * Toggle invalid states * Update dialog descriptions for demo * Icons * WIP Toggle cleanup * Refactor toggle to not rely on immediate children * Make Toggle controlled * Clean up Toggles storybook * ToggleButton styles * Improve a11y labels * ToggleButton hover darkmode * Some i18n * Refactor input * Allow extension of input * Remove old input * Improve icons, add CalendarDays * Refactor DateField, web done * Add label example * Clean up old InputDate, DateField android, text area example * Consistent imports * Button context, icons * Add todo * Add closeAllDialogs control * Alignment * Expand color palette * Hitslops, add shortcut to Storybook in dev * Fix multiline on ios * Mark dialog close button as unused --- .../arrowTopRight_stoke2_corner0_rounded.svg | 1 + .../calendarDays_stroke2_corner0_rounded.svg | 1 + .../colorPalette_stroke2_corner0_rounded.svg | 1 + .../icons/globe_stroke2_corner0_rounded.svg | 1 + bskyweb/templates/base.html | 19 + package.json | 1 + src/App.native.tsx | 59 +- src/App.web.tsx | 18 +- src/Navigation.tsx | 6 +- src/alf/atoms.ts | 344 ++++++++--- src/alf/index.tsx | 1 + src/alf/themes.ts | 306 ++++++++-- src/alf/tokens.ts | 174 ++++-- src/alf/util/flatten.ts | 3 + src/components/Button.tsx | 507 ++++++++++++++++ src/components/Dialog/context.ts | 35 ++ src/components/Dialog/index.tsx | 162 ++++++ src/components/Dialog/index.web.tsx | 194 +++++++ src/components/Dialog/types.ts | 43 ++ src/components/Link.tsx | 191 +++++++ src/components/Portal.tsx | 56 ++ src/components/Prompt.tsx | 119 ++++ src/{view/com => components}/Typography.tsx | 34 +- .../forms/DateField/index.android.tsx | 108 ++++ src/components/forms/DateField/index.tsx | 56 ++ src/components/forms/DateField/index.web.tsx | 64 +++ src/components/forms/DateField/types.ts | 7 + src/components/forms/DateField/utils.ts | 16 + src/components/forms/InputGroup.tsx | 43 ++ src/components/forms/TextField.tsx | 334 +++++++++++ src/components/forms/Toggle.tsx | 473 +++++++++++++++ src/components/forms/ToggleButton.tsx | 124 ++++ src/components/hooks/useInteractionState.ts | 21 + src/components/icons/ArrowTopRight.tsx | 5 + src/components/icons/CalendarDays.tsx | 5 + src/components/icons/ColorPalette.tsx | 5 + src/components/icons/Globe.tsx | 5 + src/components/icons/TEMPLATE.tsx | 48 ++ src/components/icons/common.ts | 32 ++ src/state/dialogs/index.tsx | 44 ++ src/view/com/Button.tsx | 204 ------- src/view/com/pager/FeedsTabBarMobile.tsx | 23 +- src/view/icons/Logo.tsx | 9 +- src/view/screens/DebugNew.tsx | 541 ------------------ src/view/screens/Storybook/Breakpoints.tsx | 25 + src/view/screens/Storybook/Buttons.tsx | 124 ++++ src/view/screens/Storybook/Dialogs.tsx | 90 +++ src/view/screens/Storybook/Forms.tsx | 215 +++++++ src/view/screens/Storybook/Icons.tsx | 41 ++ src/view/screens/Storybook/Links.tsx | 48 ++ src/view/screens/Storybook/Palette.tsx | 336 +++++++++++ src/view/screens/Storybook/Shadows.tsx | 53 ++ src/view/screens/Storybook/Spacing.tsx | 64 +++ src/view/screens/Storybook/Theming.tsx | 56 ++ src/view/screens/Storybook/Typography.tsx | 30 + src/view/screens/Storybook/index.tsx | 78 +++ src/view/shell/index.tsx | 2 + src/view/shell/index.web.tsx | 2 + web/index.html | 19 + yarn.lock | 25 + 60 files changed, 4683 insertions(+), 968 deletions(-) create mode 100644 assets/icons/arrowTopRight_stoke2_corner0_rounded.svg create mode 100644 assets/icons/calendarDays_stroke2_corner0_rounded.svg create mode 100644 assets/icons/colorPalette_stroke2_corner0_rounded.svg create mode 100644 assets/icons/globe_stroke2_corner0_rounded.svg create mode 100644 src/alf/util/flatten.ts create mode 100644 src/components/Button.tsx create mode 100644 src/components/Dialog/context.ts create mode 100644 src/components/Dialog/index.tsx create mode 100644 src/components/Dialog/index.web.tsx create mode 100644 src/components/Dialog/types.ts create mode 100644 src/components/Link.tsx create mode 100644 src/components/Portal.tsx create mode 100644 src/components/Prompt.tsx rename src/{view/com => components}/Typography.tsx (63%) create mode 100644 src/components/forms/DateField/index.android.tsx create mode 100644 src/components/forms/DateField/index.tsx create mode 100644 src/components/forms/DateField/index.web.tsx create mode 100644 src/components/forms/DateField/types.ts create mode 100644 src/components/forms/DateField/utils.ts create mode 100644 src/components/forms/InputGroup.tsx create mode 100644 src/components/forms/TextField.tsx create mode 100644 src/components/forms/Toggle.tsx create mode 100644 src/components/forms/ToggleButton.tsx create mode 100644 src/components/hooks/useInteractionState.ts create mode 100644 src/components/icons/ArrowTopRight.tsx create mode 100644 src/components/icons/CalendarDays.tsx create mode 100644 src/components/icons/ColorPalette.tsx create mode 100644 src/components/icons/Globe.tsx create mode 100644 src/components/icons/TEMPLATE.tsx create mode 100644 src/components/icons/common.ts create mode 100644 src/state/dialogs/index.tsx delete mode 100644 src/view/com/Button.tsx delete mode 100644 src/view/screens/DebugNew.tsx create mode 100644 src/view/screens/Storybook/Breakpoints.tsx create mode 100644 src/view/screens/Storybook/Buttons.tsx create mode 100644 src/view/screens/Storybook/Dialogs.tsx create mode 100644 src/view/screens/Storybook/Forms.tsx create mode 100644 src/view/screens/Storybook/Icons.tsx create mode 100644 src/view/screens/Storybook/Links.tsx create mode 100644 src/view/screens/Storybook/Palette.tsx create mode 100644 src/view/screens/Storybook/Shadows.tsx create mode 100644 src/view/screens/Storybook/Spacing.tsx create mode 100644 src/view/screens/Storybook/Theming.tsx create mode 100644 src/view/screens/Storybook/Typography.tsx create mode 100644 src/view/screens/Storybook/index.tsx diff --git a/assets/icons/arrowTopRight_stoke2_corner0_rounded.svg b/assets/icons/arrowTopRight_stoke2_corner0_rounded.svg new file mode 100644 index 0000000000..554a7374ec --- /dev/null +++ b/assets/icons/arrowTopRight_stoke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/calendarDays_stroke2_corner0_rounded.svg b/assets/icons/calendarDays_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..09d9c0f490 --- /dev/null +++ b/assets/icons/calendarDays_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/colorPalette_stroke2_corner0_rounded.svg b/assets/icons/colorPalette_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..b1056e1a96 --- /dev/null +++ b/assets/icons/colorPalette_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/globe_stroke2_corner0_rounded.svg b/assets/icons/globe_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..83cb88d136 --- /dev/null +++ b/assets/icons/globe_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/bskyweb/templates/base.html b/bskyweb/templates/base.html index 57ad064f8c..942e18fccd 100644 --- a/bskyweb/templates/base.html +++ b/bskyweb/templates/base.html @@ -39,6 +39,25 @@ height: calc(100% + env(safe-area-inset-top)); } + /* Remove autofill styles on Webkit */ + input:-webkit-autofill, + input:-webkit-autofill:hover, + input:-webkit-autofill:focus, + textarea:-webkit-autofill, + textarea:-webkit-autofill:hover, + textarea:-webkit-autofill:focus, + select:-webkit-autofill, + select:-webkit-autofill:hover, + select:-webkit-autofill:focus { + border: 0; + -webkit-text-fill-color: transparent; + -webkit-box-shadow: none; + } + /* Force left-align date/time inputs on iOS mobile */ + input::-webkit-date-and-time-value { + text-align: left; + } + /* Color theming */ :root { --text: black; diff --git a/package.json b/package.json index 517c328c10..ff0ddd3e9b 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "@segment/analytics-react-native": "^2.10.1", "@segment/sovran-react-native": "^0.4.5", "@sentry/react-native": "5.5.0", + "@tamagui/focus-scope": "^1.84.1", "@tanstack/react-query": "^5.8.1", "@tiptap/core": "^2.0.0-beta.220", "@tiptap/extension-document": "^2.0.0-beta.220", diff --git a/src/App.native.tsx b/src/App.native.tsx index 9de901767a..41b78fc98a 100644 --- a/src/App.native.tsx +++ b/src/App.native.tsx @@ -13,6 +13,8 @@ import { import 'view/icons' +import {ThemeProvider as Alf} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {init as initPersistedState} from '#/state/persisted' import {listenSessionDropped} from './state/events' import {useColorMode} from 'state/shell' @@ -25,6 +27,7 @@ import {queryClient} 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' +import {Provider as DialogStateProvider} from 'state/dialogs' import {Provider as LightboxStateProvider} from 'state/lightbox' import {Provider as MutedThreadsProvider} from 'state/muted-threads' import {Provider as InvitesStateProvider} from 'state/invites' @@ -39,6 +42,7 @@ import { import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unread' import * as persisted from '#/state/persisted' import {Splash} from '#/Splash' +import {Provider as PortalProvider} from '#/components/Portal' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' @@ -48,6 +52,7 @@ function InnerApp() { const colorMode = useColorMode() const {isInitialLoad, currentAccount} = useSession() const {resumeSession} = useSessionApi() + const theme = useColorModeTheme(colorMode) const {_} = useLingui() // init @@ -63,25 +68,27 @@ function InnerApp() { return ( - - - - - - {/* All components should be within this provider */} - - - - - - - - - - - + + + + + + + {/* All components should be within this provider */} + + + + + + + + + + + + ) } @@ -109,11 +116,15 @@ function App() { - - - - - + + + + + + + + + diff --git a/src/App.web.tsx b/src/App.web.tsx index 1bdb3c208c..1efa0567c7 100644 --- a/src/App.web.tsx +++ b/src/App.web.tsx @@ -8,6 +8,7 @@ import {RootSiblingParent} from 'react-native-root-siblings' import 'view/icons' import {ThemeProvider as Alf} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {init as initPersistedState} from '#/state/persisted' import {useColorMode} from 'state/shell' import {Shell} from 'view/shell/index' @@ -16,6 +17,7 @@ import {ThemeProvider} from 'lib/ThemeContext' import {queryClient} 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' import {Provider as LightboxStateProvider} from 'state/lightbox' import {Provider as MutedThreadsProvider} from 'state/muted-threads' import {Provider as InvitesStateProvider} from 'state/invites' @@ -29,7 +31,7 @@ import { } from 'state/session' import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unread' import * as persisted from '#/state/persisted' -import {useColorModeTheme} from '#/alf/util/useColorModeTheme' +import {Provider as PortalProvider} from '#/components/Portal' function InnerApp() { const {isInitialLoad, currentAccount} = useSession() @@ -92,11 +94,15 @@ function App() { - - - - - + + + + + + + + + diff --git a/src/Navigation.tsx b/src/Navigation.tsx index c68cb05807..ea0cd384e8 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -61,7 +61,7 @@ import {ProfileListScreen} from './view/screens/ProfileList' import {PostThreadScreen} from './view/screens/PostThread' import {PostLikedByScreen} from './view/screens/PostLikedBy' import {PostRepostedByScreen} from './view/screens/PostRepostedBy' -import {DebugScreen} from './view/screens/DebugNew' +import {Storybook} from './view/screens/Storybook' import {LogScreen} from './view/screens/Log' import {SupportScreen} from './view/screens/Support' import {PrivacyPolicyScreen} from './view/screens/PrivacyPolicy' @@ -200,8 +200,8 @@ function commonScreens(Stack: typeof HomeTab, unreadCountLabel?: string) { /> DebugScreen} - options={{title: title(msg`Debug`), requireAuth: true}} + getComponent={() => Storybook} + options={{title: title(msg`Storybook`), requireAuth: true}} /> +export type ReadonlyPalette = typeof lightPalette +export type Palette = Mutable -export type Palette = { - primary: string - positive: string - negative: string -} +export const lightPalette = { + white: tokens.color.gray_0, + black: tokens.color.gray_1000, -export const lightPalette: Palette = { - primary: tokens.color.blue_500, - positive: tokens.color.green_500, - negative: tokens.color.red_500, + contrast_25: tokens.color.gray_25, + contrast_50: tokens.color.gray_50, + contrast_100: tokens.color.gray_100, + contrast_200: tokens.color.gray_200, + contrast_300: tokens.color.gray_300, + contrast_400: tokens.color.gray_400, + contrast_500: tokens.color.gray_500, + contrast_600: tokens.color.gray_600, + contrast_700: tokens.color.gray_700, + contrast_800: tokens.color.gray_800, + contrast_900: tokens.color.gray_900, + contrast_950: tokens.color.gray_950, + contrast_975: tokens.color.gray_975, + + primary_25: tokens.color.blue_25, + primary_50: tokens.color.blue_50, + primary_100: tokens.color.blue_100, + primary_200: tokens.color.blue_200, + primary_300: tokens.color.blue_300, + primary_400: tokens.color.blue_400, + primary_500: tokens.color.blue_500, + primary_600: tokens.color.blue_600, + primary_700: tokens.color.blue_700, + primary_800: tokens.color.blue_800, + primary_900: tokens.color.blue_900, + primary_950: tokens.color.blue_950, + primary_975: tokens.color.blue_975, + + positive_25: tokens.color.green_25, + positive_50: tokens.color.green_50, + positive_100: tokens.color.green_100, + positive_200: tokens.color.green_200, + positive_300: tokens.color.green_300, + positive_400: tokens.color.green_400, + positive_500: tokens.color.green_500, + positive_600: tokens.color.green_600, + positive_700: tokens.color.green_700, + positive_800: tokens.color.green_800, + positive_900: tokens.color.green_900, + positive_950: tokens.color.green_950, + positive_975: tokens.color.green_975, + + negative_25: tokens.color.red_25, + negative_50: tokens.color.red_50, + negative_100: tokens.color.red_100, + negative_200: tokens.color.red_200, + negative_300: tokens.color.red_300, + negative_400: tokens.color.red_400, + negative_500: tokens.color.red_500, + negative_600: tokens.color.red_600, + negative_700: tokens.color.red_700, + negative_800: tokens.color.red_800, + negative_900: tokens.color.red_900, + negative_950: tokens.color.red_950, + negative_975: tokens.color.red_975, } as const export const darkPalette: Palette = { - primary: tokens.color.blue_500, - positive: tokens.color.green_400, - negative: tokens.color.red_400, + white: tokens.color.gray_0, + black: tokens.color.gray_1000, + + contrast_25: tokens.color.gray_975, + contrast_50: tokens.color.gray_950, + contrast_100: tokens.color.gray_900, + contrast_200: tokens.color.gray_800, + contrast_300: tokens.color.gray_700, + contrast_400: tokens.color.gray_600, + contrast_500: tokens.color.gray_500, + contrast_600: tokens.color.gray_400, + contrast_700: tokens.color.gray_300, + contrast_800: tokens.color.gray_200, + contrast_900: tokens.color.gray_100, + contrast_950: tokens.color.gray_50, + contrast_975: tokens.color.gray_25, + + primary_25: tokens.color.blue_25, + primary_50: tokens.color.blue_50, + primary_100: tokens.color.blue_100, + primary_200: tokens.color.blue_200, + primary_300: tokens.color.blue_300, + primary_400: tokens.color.blue_400, + primary_500: tokens.color.blue_500, + primary_600: tokens.color.blue_600, + primary_700: tokens.color.blue_700, + primary_800: tokens.color.blue_800, + primary_900: tokens.color.blue_900, + primary_950: tokens.color.blue_950, + primary_975: tokens.color.blue_975, + + positive_25: tokens.color.green_25, + positive_50: tokens.color.green_50, + positive_100: tokens.color.green_100, + positive_200: tokens.color.green_200, + positive_300: tokens.color.green_300, + positive_400: tokens.color.green_400, + positive_500: tokens.color.green_500, + positive_600: tokens.color.green_600, + positive_700: tokens.color.green_700, + positive_800: tokens.color.green_800, + positive_900: tokens.color.green_900, + positive_950: tokens.color.green_950, + positive_975: tokens.color.green_975, + + negative_25: tokens.color.red_25, + negative_50: tokens.color.red_50, + negative_100: tokens.color.red_100, + negative_200: tokens.color.red_200, + negative_300: tokens.color.red_300, + negative_400: tokens.color.red_400, + negative_500: tokens.color.red_500, + negative_600: tokens.color.red_600, + negative_700: tokens.color.red_700, + negative_800: tokens.color.red_800, + negative_900: tokens.color.red_900, + negative_950: tokens.color.red_950, + negative_975: tokens.color.red_975, } as const export const light = { + name: 'light', palette: lightPalette, atoms: { text: { - color: tokens.color.gray_1000, + color: lightPalette.black, }, text_contrast_700: { - color: tokens.color.gray_700, + color: lightPalette.contrast_700, + }, + text_contrast_600: { + color: lightPalette.contrast_600, }, text_contrast_500: { - color: tokens.color.gray_500, + color: lightPalette.contrast_500, + }, + text_contrast_400: { + color: lightPalette.contrast_400, }, text_inverted: { - color: tokens.color.white, + color: lightPalette.white, }, bg: { - backgroundColor: tokens.color.white, + backgroundColor: lightPalette.white, + }, + bg_contrast_25: { + backgroundColor: lightPalette.contrast_25, + }, + bg_contrast_50: { + backgroundColor: lightPalette.contrast_50, }, bg_contrast_100: { - backgroundColor: tokens.color.gray_100, + backgroundColor: lightPalette.contrast_100, }, bg_contrast_200: { - backgroundColor: tokens.color.gray_200, + backgroundColor: lightPalette.contrast_200, }, bg_contrast_300: { - backgroundColor: tokens.color.gray_300, - }, - bg_positive: { - backgroundColor: tokens.color.green_500, - }, - bg_negative: { - backgroundColor: tokens.color.red_400, + backgroundColor: lightPalette.contrast_300, }, border: { - borderColor: tokens.color.gray_200, + borderColor: lightPalette.contrast_200, }, - border_contrast_500: { - borderColor: tokens.color.gray_500, + border_contrast: { + borderColor: lightPalette.contrast_400, + }, + shadow_sm: { + ...atoms.shadow_sm, + shadowColor: lightPalette.black, + }, + shadow_md: { + ...atoms.shadow_md, + shadowColor: lightPalette.black, + }, + shadow_lg: { + ...atoms.shadow_lg, + shadowColor: lightPalette.black, + }, + }, +} + +export const dim: Theme = { + name: 'dim', + palette: darkPalette, + atoms: { + text: { + color: darkPalette.white, + }, + text_contrast_700: { + color: darkPalette.contrast_800, + }, + text_contrast_600: { + color: darkPalette.contrast_700, + }, + text_contrast_500: { + color: darkPalette.contrast_600, + }, + text_contrast_400: { + color: darkPalette.contrast_500, + }, + text_inverted: { + color: darkPalette.black, + }, + bg: { + backgroundColor: darkPalette.contrast_50, + }, + bg_contrast_25: { + backgroundColor: darkPalette.contrast_100, + }, + bg_contrast_50: { + backgroundColor: darkPalette.contrast_200, + }, + bg_contrast_100: { + backgroundColor: darkPalette.contrast_300, + }, + bg_contrast_200: { + backgroundColor: darkPalette.contrast_400, + }, + bg_contrast_300: { + backgroundColor: darkPalette.contrast_500, + }, + border: { + borderColor: darkPalette.contrast_200, + }, + border_contrast: { + borderColor: darkPalette.contrast_400, + }, + shadow_sm: { + ...atoms.shadow_sm, + shadowOpacity: 0.7, + shadowColor: tokens.color.trueBlack, + }, + shadow_md: { + ...atoms.shadow_md, + shadowOpacity: 0.7, + shadowColor: tokens.color.trueBlack, + }, + shadow_lg: { + ...atoms.shadow_lg, + shadowOpacity: 0.7, + shadowColor: tokens.color.trueBlack, }, }, } export const dark: Theme = { + name: 'dark', palette: darkPalette, atoms: { text: { - color: tokens.color.white, + color: darkPalette.white, }, text_contrast_700: { - color: tokens.color.gray_300, + color: darkPalette.contrast_700, + }, + text_contrast_600: { + color: darkPalette.contrast_600, }, text_contrast_500: { - color: tokens.color.gray_500, + color: darkPalette.contrast_500, + }, + text_contrast_400: { + color: darkPalette.contrast_400, }, text_inverted: { - color: tokens.color.gray_1000, + color: darkPalette.black, }, bg: { - backgroundColor: tokens.color.gray_1000, + backgroundColor: darkPalette.contrast_25, + }, + bg_contrast_25: { + backgroundColor: darkPalette.contrast_50, + }, + bg_contrast_50: { + backgroundColor: darkPalette.contrast_100, }, bg_contrast_100: { - backgroundColor: tokens.color.gray_900, + backgroundColor: darkPalette.contrast_200, }, bg_contrast_200: { - backgroundColor: tokens.color.gray_800, + backgroundColor: darkPalette.contrast_300, }, bg_contrast_300: { - backgroundColor: tokens.color.gray_700, - }, - bg_positive: { - backgroundColor: tokens.color.green_400, - }, - bg_negative: { - backgroundColor: tokens.color.red_400, + backgroundColor: darkPalette.contrast_400, }, border: { - borderColor: tokens.color.gray_800, + borderColor: darkPalette.contrast_100, }, - border_contrast_500: { - borderColor: tokens.color.gray_500, + border_contrast: { + borderColor: darkPalette.contrast_300, + }, + shadow_sm: { + ...atoms.shadow_sm, + shadowOpacity: 0.7, + shadowColor: tokens.color.trueBlack, + }, + shadow_md: { + ...atoms.shadow_md, + shadowOpacity: 0.7, + shadowColor: tokens.color.trueBlack, + }, + shadow_lg: { + ...atoms.shadow_lg, + shadowOpacity: 0.7, + shadowColor: tokens.color.trueBlack, }, }, } diff --git a/src/alf/tokens.ts b/src/alf/tokens.ts index 4034e0deb4..0e370cdc17 100644 --- a/src/alf/tokens.ts +++ b/src/alf/tokens.ts @@ -1,79 +1,95 @@ const BLUE_HUE = 211 -const GRAYSCALE_SATURATION = 22 +const RED_HUE = 346 +const GREEN_HUE = 152 export const color = { - white: '#FFFFFF', + trueBlack: '#000000', - gray_0: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 100%)`, - gray_100: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 95%)`, - gray_200: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 85%)`, - gray_300: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 75%)`, - gray_400: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 65%)`, - gray_500: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 55%)`, - gray_600: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 45%)`, - gray_700: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 35%)`, - gray_800: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 25%)`, - gray_900: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 15%)`, - gray_1000: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 5%)`, + gray_0: `hsl(${BLUE_HUE}, 20%, 100%)`, + gray_25: `hsl(${BLUE_HUE}, 20%, 97%)`, + gray_50: `hsl(${BLUE_HUE}, 20%, 95%)`, + gray_100: `hsl(${BLUE_HUE}, 20%, 90%)`, + gray_200: `hsl(${BLUE_HUE}, 20%, 80%)`, + gray_300: `hsl(${BLUE_HUE}, 20%, 70%)`, + gray_400: `hsl(${BLUE_HUE}, 20%, 60%)`, + gray_500: `hsl(${BLUE_HUE}, 20%, 50%)`, + gray_600: `hsl(${BLUE_HUE}, 20%, 42%)`, + gray_700: `hsl(${BLUE_HUE}, 20%, 34%)`, + gray_800: `hsl(${BLUE_HUE}, 20%, 26%)`, + gray_900: `hsl(${BLUE_HUE}, 20%, 18%)`, + gray_950: `hsl(${BLUE_HUE}, 20%, 10%)`, + gray_975: `hsl(${BLUE_HUE}, 20%, 7%)`, + gray_1000: `hsl(${BLUE_HUE}, 20%, 4%)`, - blue_0: `hsl(${BLUE_HUE}, 99%, 100%)`, - blue_100: `hsl(${BLUE_HUE}, 99%, 93%)`, - blue_200: `hsl(${BLUE_HUE}, 99%, 83%)`, - blue_300: `hsl(${BLUE_HUE}, 99%, 73%)`, - blue_400: `hsl(${BLUE_HUE}, 99%, 63%)`, + blue_25: `hsl(${BLUE_HUE}, 99%, 97%)`, + blue_50: `hsl(${BLUE_HUE}, 99%, 95%)`, + blue_100: `hsl(${BLUE_HUE}, 99%, 90%)`, + blue_200: `hsl(${BLUE_HUE}, 99%, 80%)`, + blue_300: `hsl(${BLUE_HUE}, 99%, 70%)`, + blue_400: `hsl(${BLUE_HUE}, 99%, 60%)`, blue_500: `hsl(${BLUE_HUE}, 99%, 53%)`, - blue_600: `hsl(${BLUE_HUE}, 99%, 43%)`, - blue_700: `hsl(${BLUE_HUE}, 99%, 33%)`, - blue_800: `hsl(${BLUE_HUE}, 99%, 23%)`, - blue_900: `hsl(${BLUE_HUE}, 99%, 13%)`, - blue_1000: `hsl(${BLUE_HUE}, 99%, 8%)`, + blue_600: `hsl(${BLUE_HUE}, 99%, 42%)`, + blue_700: `hsl(${BLUE_HUE}, 99%, 34%)`, + blue_800: `hsl(${BLUE_HUE}, 99%, 26%)`, + blue_900: `hsl(${BLUE_HUE}, 99%, 18%)`, + blue_950: `hsl(${BLUE_HUE}, 99%, 10%)`, + blue_975: `hsl(${BLUE_HUE}, 99%, 7%)`, - green_0: `hsl(130, 60%, 100%)`, - green_100: `hsl(130, 60%, 95%)`, - green_200: `hsl(130, 60%, 85%)`, - green_300: `hsl(130, 60%, 75%)`, - green_400: `hsl(130, 60%, 65%)`, - green_500: `hsl(130, 60%, 55%)`, - green_600: `hsl(130, 60%, 45%)`, - green_700: `hsl(130, 60%, 35%)`, - green_800: `hsl(130, 60%, 25%)`, - green_900: `hsl(130, 60%, 15%)`, - green_1000: `hsl(130, 60%, 5%)`, + green_25: `hsl(${GREEN_HUE}, 82%, 97%)`, + green_50: `hsl(${GREEN_HUE}, 82%, 95%)`, + green_100: `hsl(${GREEN_HUE}, 82%, 90%)`, + green_200: `hsl(${GREEN_HUE}, 82%, 80%)`, + green_300: `hsl(${GREEN_HUE}, 82%, 70%)`, + green_400: `hsl(${GREEN_HUE}, 82%, 60%)`, + green_500: `hsl(${GREEN_HUE}, 82%, 50%)`, + green_600: `hsl(${GREEN_HUE}, 82%, 42%)`, + green_700: `hsl(${GREEN_HUE}, 82%, 34%)`, + green_800: `hsl(${GREEN_HUE}, 82%, 26%)`, + green_900: `hsl(${GREEN_HUE}, 82%, 18%)`, + green_950: `hsl(${GREEN_HUE}, 82%, 10%)`, + green_975: `hsl(${GREEN_HUE}, 82%, 7%)`, - red_0: `hsl(349, 96%, 100%)`, - red_100: `hsl(349, 96%, 95%)`, - red_200: `hsl(349, 96%, 85%)`, - red_300: `hsl(349, 96%, 75%)`, - red_400: `hsl(349, 96%, 65%)`, - red_500: `hsl(349, 96%, 55%)`, - red_600: `hsl(349, 96%, 45%)`, - red_700: `hsl(349, 96%, 35%)`, - red_800: `hsl(349, 96%, 25%)`, - red_900: `hsl(349, 96%, 15%)`, - red_1000: `hsl(349, 96%, 5%)`, + red_25: `hsl(${RED_HUE}, 91%, 97%)`, + red_50: `hsl(${RED_HUE}, 91%, 95%)`, + red_100: `hsl(${RED_HUE}, 91%, 90%)`, + red_200: `hsl(${RED_HUE}, 91%, 80%)`, + red_300: `hsl(${RED_HUE}, 91%, 70%)`, + red_400: `hsl(${RED_HUE}, 91%, 60%)`, + red_500: `hsl(${RED_HUE}, 91%, 50%)`, + red_600: `hsl(${RED_HUE}, 91%, 42%)`, + red_700: `hsl(${RED_HUE}, 91%, 34%)`, + red_800: `hsl(${RED_HUE}, 91%, 26%)`, + red_900: `hsl(${RED_HUE}, 91%, 18%)`, + red_950: `hsl(${RED_HUE}, 91%, 10%)`, + red_975: `hsl(${RED_HUE}, 91%, 7%)`, } as const export const space = { - xxs: 2, + _2xs: 2, xs: 4, sm: 8, md: 12, - lg: 18, - xl: 24, - xxl: 32, + lg: 16, + xl: 20, + _2xl: 24, + _3xl: 28, + _4xl: 32, + _5xl: 40, } as const export const fontSize = { - xxs: 10, + _2xs: 10, xs: 12, sm: 14, md: 16, lg: 18, - xl: 22, - xxl: 26, + xl: 20, + _2xl: 22, + _3xl: 26, + _4xl: 32, + _5xl: 40, } as const -// TODO test export const lineHeight = { none: 1, normal: 1.5, @@ -81,6 +97,8 @@ export const lineHeight = { } as const export const borderRadius = { + _2xs: 2, + xs: 4, sm: 8, md: 12, full: 999, @@ -92,6 +110,56 @@ export const fontWeight = { bold: '900', } as const +export const gradients = { + sky: { + values: [ + [0, '#0A7AFF'], + [1, '#59B9FF'], + ], + hover_value: '#0A7AFF', + }, + midnight: { + values: [ + [0, '#022C5E'], + [1, '#4079BC'], + ], + hover_value: '#022C5E', + }, + sunrise: { + values: [ + [0, '#4E90AE'], + [0.4, '#AEA3AB'], + [0.8, '#E6A98F'], + [1, '#F3A84C'], + ], + hover_value: '#AEA3AB', + }, + sunset: { + values: [ + [0, '#6772AF'], + [0.6, '#B88BB6'], + [1, '#FFA6AC'], + ], + hover_value: '#B88BB6', + }, + nordic: { + values: [ + [0, '#083367'], + [1, '#9EE8C1'], + ], + hover_value: '#3A7085', + }, + bonfire: { + values: [ + [0, '#203E4E'], + [0.4, '#755B62'], + [0.8, '#CD7765'], + [1, '#EF956E'], + ], + hover_value: '#755B62', + }, +} as const + export type Color = keyof typeof color export type Space = keyof typeof space export type FontSize = keyof typeof fontSize diff --git a/src/alf/util/flatten.ts b/src/alf/util/flatten.ts new file mode 100644 index 0000000000..448716a082 --- /dev/null +++ b/src/alf/util/flatten.ts @@ -0,0 +1,3 @@ +import {StyleSheet} from 'react-native' + +export const flatten = StyleSheet.flatten diff --git a/src/components/Button.tsx b/src/components/Button.tsx new file mode 100644 index 0000000000..d2100f0b42 --- /dev/null +++ b/src/components/Button.tsx @@ -0,0 +1,507 @@ +import React from 'react' +import { + Pressable, + Text, + PressableProps, + TextProps, + ViewStyle, + AccessibilityProps, + View, + TextStyle, + StyleSheet, +} from 'react-native' +import LinearGradient from 'react-native-linear-gradient' + +import {useTheme, atoms as a, tokens, web, native} from '#/alf' +import {Props as SVGIconProps} from '#/components/icons/common' + +export type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'gradient' +export type ButtonColor = + | 'primary' + | 'secondary' + | 'negative' + | 'gradient_sky' + | 'gradient_midnight' + | 'gradient_sunrise' + | 'gradient_sunset' + | 'gradient_nordic' + | 'gradient_bonfire' +export type ButtonSize = 'small' | 'large' +export type VariantProps = { + /** + * The style variation of the button + */ + variant?: ButtonVariant + /** + * The color of the button + */ + color?: ButtonColor + /** + * The size of the button + */ + size?: ButtonSize +} + +export type ButtonProps = React.PropsWithChildren< + Pick & + AccessibilityProps & + VariantProps & { + label: string + } +> +export type ButtonTextProps = TextProps & VariantProps & {disabled?: boolean} + +const Context = React.createContext< + VariantProps & { + hovered: boolean + focused: boolean + pressed: boolean + disabled: boolean + } +>({ + hovered: false, + focused: false, + pressed: false, + disabled: false, +}) + +export function useButtonContext() { + return React.useContext(Context) +} + +export function Button({ + children, + variant, + color, + size, + label, + disabled = false, + ...rest +}: ButtonProps) { + const t = useTheme() + const [state, setState] = React.useState({ + pressed: false, + hovered: false, + focused: false, + }) + + const onPressIn = React.useCallback(() => { + setState(s => ({ + ...s, + pressed: true, + })) + }, [setState]) + const onPressOut = React.useCallback(() => { + setState(s => ({ + ...s, + pressed: false, + })) + }, [setState]) + const onHoverIn = React.useCallback(() => { + setState(s => ({ + ...s, + hovered: true, + })) + }, [setState]) + const onHoverOut = React.useCallback(() => { + setState(s => ({ + ...s, + hovered: false, + })) + }, [setState]) + const onFocus = React.useCallback(() => { + setState(s => ({ + ...s, + focused: true, + })) + }, [setState]) + const onBlur = React.useCallback(() => { + setState(s => ({ + ...s, + focused: false, + })) + }, [setState]) + + const {baseStyles, hoverStyles, focusStyles} = React.useMemo(() => { + const baseStyles: ViewStyle[] = [] + const hoverStyles: ViewStyle[] = [] + const light = t.name === 'light' + + if (color === 'primary') { + if (variant === 'solid') { + if (!disabled) { + baseStyles.push({ + backgroundColor: t.palette.primary_500, + }) + hoverStyles.push({ + backgroundColor: t.palette.primary_600, + }) + } else { + baseStyles.push({ + backgroundColor: t.palette.primary_700, + }) + } + } else if (variant === 'outline') { + baseStyles.push(a.border, t.atoms.bg, { + borderWidth: 1, + }) + + if (!disabled) { + baseStyles.push(a.border, { + borderColor: tokens.color.blue_500, + }) + hoverStyles.push(a.border, { + backgroundColor: light + ? t.palette.primary_50 + : t.palette.primary_950, + }) + } else { + baseStyles.push(a.border, { + borderColor: light ? tokens.color.blue_200 : tokens.color.blue_900, + }) + } + } else if (variant === 'ghost') { + if (!disabled) { + baseStyles.push(t.atoms.bg) + hoverStyles.push({ + backgroundColor: light + ? t.palette.primary_100 + : t.palette.primary_900, + }) + } + } + } else if (color === 'secondary') { + if (variant === 'solid') { + if (!disabled) { + baseStyles.push({ + backgroundColor: light + ? tokens.color.gray_100 + : tokens.color.gray_900, + }) + hoverStyles.push({ + backgroundColor: light + ? tokens.color.gray_200 + : tokens.color.gray_950, + }) + } else { + baseStyles.push({ + backgroundColor: light + ? tokens.color.gray_300 + : tokens.color.gray_950, + }) + } + } else if (variant === 'outline') { + baseStyles.push(a.border, t.atoms.bg, { + borderWidth: 1, + }) + + if (!disabled) { + baseStyles.push(a.border, { + borderColor: light ? tokens.color.gray_500 : tokens.color.gray_500, + }) + hoverStyles.push(a.border, t.atoms.bg_contrast_50) + } else { + baseStyles.push(a.border, { + borderColor: light ? tokens.color.gray_200 : tokens.color.gray_800, + }) + } + } else if (variant === 'ghost') { + if (!disabled) { + baseStyles.push(t.atoms.bg) + hoverStyles.push({ + backgroundColor: light + ? tokens.color.gray_100 + : tokens.color.gray_900, + }) + } + } + } else if (color === 'negative') { + if (variant === 'solid') { + if (!disabled) { + baseStyles.push({ + backgroundColor: t.palette.negative_400, + }) + hoverStyles.push({ + backgroundColor: t.palette.negative_500, + }) + } else { + baseStyles.push({ + backgroundColor: t.palette.negative_600, + }) + } + } else if (variant === 'outline') { + baseStyles.push(a.border, t.atoms.bg, { + borderWidth: 1, + }) + + if (!disabled) { + baseStyles.push(a.border, { + borderColor: t.palette.negative_400, + }) + hoverStyles.push(a.border, { + backgroundColor: light + ? t.palette.negative_50 + : t.palette.negative_975, + }) + } else { + baseStyles.push(a.border, { + borderColor: light + ? t.palette.negative_200 + : t.palette.negative_900, + }) + } + } else if (variant === 'ghost') { + if (!disabled) { + baseStyles.push(t.atoms.bg) + hoverStyles.push({ + backgroundColor: light + ? t.palette.negative_100 + : t.palette.negative_950, + }) + } + } + } + + if (size === 'large') { + baseStyles.push({paddingVertical: 15}, a.px_2xl, a.rounded_sm, a.gap_sm) + } else if (size === 'small') { + baseStyles.push({paddingVertical: 9}, a.px_md, a.rounded_sm, a.gap_sm) + } + + return { + baseStyles, + hoverStyles, + focusStyles: [ + ...hoverStyles, + { + outline: 0, + } as ViewStyle, + ], + } + }, [t, variant, color, size, disabled]) + + const {gradientColors, gradientHoverColors, gradientLocations} = + React.useMemo(() => { + const colors: string[] = [] + const hoverColors: string[] = [] + const locations: number[] = [] + const gradient = { + primary: tokens.gradients.sky, + secondary: tokens.gradients.sky, + negative: tokens.gradients.sky, + gradient_sky: tokens.gradients.sky, + gradient_midnight: tokens.gradients.midnight, + gradient_sunrise: tokens.gradients.sunrise, + gradient_sunset: tokens.gradients.sunset, + gradient_nordic: tokens.gradients.nordic, + gradient_bonfire: tokens.gradients.bonfire, + }[color || 'primary'] + + if (variant === 'gradient') { + colors.push(...gradient.values.map(([_, color]) => color)) + hoverColors.push(...gradient.values.map(_ => gradient.hover_value)) + locations.push(...gradient.values.map(([location, _]) => location)) + } + + return { + gradientColors: colors, + gradientHoverColors: hoverColors, + gradientLocations: locations, + } + }, [variant, color]) + + const context = React.useMemo( + () => ({ + ...state, + variant, + color, + size, + disabled: disabled || false, + }), + [state, variant, color, size, disabled], + ) + + return ( + + {variant === 'gradient' && ( + + )} + + {typeof children === 'string' ? ( + {children} + ) : ( + children + )} + + + ) +} + +export function useSharedButtonTextStyles() { + const t = useTheme() + const {color, variant, disabled, size} = useButtonContext() + return React.useMemo(() => { + const baseStyles: TextStyle[] = [] + const light = t.name === 'light' + + if (color === 'primary') { + if (variant === 'solid') { + if (!disabled) { + baseStyles.push({color: t.palette.white}) + } else { + baseStyles.push({color: t.palette.white, opacity: 0.5}) + } + } else if (variant === 'outline') { + if (!disabled) { + baseStyles.push({ + color: light ? t.palette.primary_600 : t.palette.primary_500, + }) + } else { + baseStyles.push({color: t.palette.primary_600, opacity: 0.5}) + } + } else if (variant === 'ghost') { + if (!disabled) { + baseStyles.push({color: t.palette.primary_600}) + } else { + baseStyles.push({color: t.palette.primary_600, opacity: 0.5}) + } + } + } else if (color === 'secondary') { + if (variant === 'solid' || variant === 'gradient') { + if (!disabled) { + baseStyles.push({ + color: light ? tokens.color.gray_700 : tokens.color.gray_100, + }) + } else { + baseStyles.push({ + color: light ? tokens.color.gray_400 : tokens.color.gray_700, + }) + } + } else if (variant === 'outline') { + if (!disabled) { + baseStyles.push({ + color: light ? tokens.color.gray_600 : tokens.color.gray_300, + }) + } else { + baseStyles.push({ + color: light ? tokens.color.gray_400 : tokens.color.gray_700, + }) + } + } else if (variant === 'ghost') { + if (!disabled) { + baseStyles.push({ + color: light ? tokens.color.gray_600 : tokens.color.gray_300, + }) + } else { + baseStyles.push({ + color: light ? tokens.color.gray_400 : tokens.color.gray_600, + }) + } + } + } else if (color === 'negative') { + if (variant === 'solid' || variant === 'gradient') { + if (!disabled) { + baseStyles.push({color: t.palette.white}) + } else { + baseStyles.push({color: t.palette.white, opacity: 0.5}) + } + } else if (variant === 'outline') { + if (!disabled) { + baseStyles.push({color: t.palette.negative_400}) + } else { + baseStyles.push({color: t.palette.negative_400, opacity: 0.5}) + } + } else if (variant === 'ghost') { + if (!disabled) { + baseStyles.push({color: t.palette.negative_400}) + } else { + baseStyles.push({color: t.palette.negative_400, opacity: 0.5}) + } + } + } else { + if (!disabled) { + baseStyles.push({color: t.palette.white}) + } else { + baseStyles.push({color: t.palette.white, opacity: 0.5}) + } + } + + if (size === 'large') { + baseStyles.push( + a.text_md, + web({paddingBottom: 1}), + native({marginTop: 2}), + ) + } else { + baseStyles.push( + a.text_md, + web({paddingBottom: 1}), + native({marginTop: 2}), + ) + } + + return StyleSheet.flatten(baseStyles) + }, [t, variant, color, size, disabled]) +} + +export function ButtonText({children, style, ...rest}: ButtonTextProps) { + const textStyles = useSharedButtonTextStyles() + + return ( + + {children} + + ) +} + +export function ButtonIcon({ + icon: Comp, +}: { + icon: React.ComponentType +}) { + const {size} = useButtonContext() + const textStyles = useSharedButtonTextStyles() + + return ( + + + + ) +} diff --git a/src/components/Dialog/context.ts b/src/components/Dialog/context.ts new file mode 100644 index 0000000000..b28b9f5a25 --- /dev/null +++ b/src/components/Dialog/context.ts @@ -0,0 +1,35 @@ +import React from 'react' + +import {useDialogStateContext} from '#/state/dialogs' +import {DialogContextProps, DialogControlProps} from '#/components/Dialog/types' + +export const Context = React.createContext({ + close: () => {}, +}) + +export function useDialogContext() { + return React.useContext(Context) +} + +export function useDialogControl() { + const id = React.useId() + const control = React.useRef({ + open: () => {}, + close: () => {}, + }) + const {activeDialogs} = useDialogStateContext() + + React.useEffect(() => { + activeDialogs.current.set(id, control) + return () => { + // eslint-disable-next-line react-hooks/exhaustive-deps + activeDialogs.current.delete(id) + } + }, [id, activeDialogs]) + + return { + ref: control, + open: () => control.current.open(), + close: () => control.current.close(), + } +} diff --git a/src/components/Dialog/index.tsx b/src/components/Dialog/index.tsx new file mode 100644 index 0000000000..44e4dc8a70 --- /dev/null +++ b/src/components/Dialog/index.tsx @@ -0,0 +1,162 @@ +import React, {useImperativeHandle} from 'react' +import {View, Dimensions} from 'react-native' +import BottomSheet, { + BottomSheetBackdrop, + BottomSheetScrollView, + BottomSheetTextInput, + BottomSheetView, +} from '@gorhom/bottom-sheet' +import {useSafeAreaInsets} from 'react-native-safe-area-context' + +import {useTheme, atoms as a} from '#/alf' +import {Portal} from '#/components/Portal' +import {createInput} from '#/components/forms/TextField' + +import { + DialogOuterProps, + DialogControlProps, + DialogInnerProps, +} from '#/components/Dialog/types' +import {Context} from '#/components/Dialog/context' + +export {useDialogControl, useDialogContext} from '#/components/Dialog/context' +export * from '#/components/Dialog/types' +// @ts-ignore +export const Input = createInput(BottomSheetTextInput) + +export function Outer({ + children, + control, + onClose, + nativeOptions, +}: React.PropsWithChildren) { + const t = useTheme() + const sheet = React.useRef(null) + const sheetOptions = nativeOptions?.sheet || {} + const hasSnapPoints = !!sheetOptions.snapPoints + + const open = React.useCallback((i = 0) => { + sheet.current?.snapToIndex(i) + }, []) + + const close = React.useCallback(() => { + sheet.current?.close() + onClose?.() + }, [onClose]) + + useImperativeHandle( + control.ref, + () => ({ + open, + close, + }), + [open, close], + ) + + const context = React.useMemo(() => ({close}), [close]) + + return ( + + ( + + )} + handleIndicatorStyle={{backgroundColor: t.palette.primary_500}} + handleStyle={{display: 'none'}} + onClose={onClose}> + + + {children} + + + + ) +} + +// TODO a11y props here, or is that handled by the sheet? +export function Inner(props: DialogInnerProps) { + const insets = useSafeAreaInsets() + return ( + + {props.children} + + ) +} + +export function ScrollableInner(props: DialogInnerProps) { + const insets = useSafeAreaInsets() + return ( + + {props.children} + + + ) +} + +export function Handle() { + const t = useTheme() + return ( + + ) +} + +export function Close() { + return null +} diff --git a/src/components/Dialog/index.web.tsx b/src/components/Dialog/index.web.tsx new file mode 100644 index 0000000000..305c00e97a --- /dev/null +++ b/src/components/Dialog/index.web.tsx @@ -0,0 +1,194 @@ +import React, {useImperativeHandle} from 'react' +import {View, TouchableWithoutFeedback} from 'react-native' +import {FocusScope} from '@tamagui/focus-scope' +import Animated, {FadeInDown, FadeIn} from 'react-native-reanimated' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {useTheme, atoms as a, useBreakpoints, web} from '#/alf' +import {Portal} from '#/components/Portal' + +import {DialogOuterProps, DialogInnerProps} from '#/components/Dialog/types' +import {Context} from '#/components/Dialog/context' + +export {useDialogControl, useDialogContext} from '#/components/Dialog/context' +export * from '#/components/Dialog/types' +export {Input} from '#/components/forms/TextField' + +const stopPropagation = (e: any) => e.stopPropagation() + +export function Outer({ + control, + onClose, + children, +}: React.PropsWithChildren) { + const {_} = useLingui() + const t = useTheme() + const {gtMobile} = useBreakpoints() + const [isOpen, setIsOpen] = React.useState(false) + const [isVisible, setIsVisible] = React.useState(true) + + const open = React.useCallback(() => { + setIsOpen(true) + }, [setIsOpen]) + + const close = React.useCallback(async () => { + setIsVisible(false) + await new Promise(resolve => setTimeout(resolve, 150)) + setIsOpen(false) + setIsVisible(true) + onClose?.() + }, [onClose, setIsOpen]) + + useImperativeHandle( + control.ref, + () => ({ + open, + close, + }), + [open, close], + ) + + React.useEffect(() => { + if (!isOpen) return + + function handler(e: KeyboardEvent) { + if (e.key === 'Escape') close() + } + + document.addEventListener('keydown', handler) + + return () => document.removeEventListener('keydown', handler) + }, [isOpen, close]) + + const context = React.useMemo( + () => ({ + close, + }), + [close], + ) + + return ( + <> + {isOpen && ( + + + + + {isVisible && ( + + )} + + + {isVisible ? children : null} + + + + + + )} + + ) +} + +export function Inner({ + children, + style, + label, + accessibilityLabelledBy, + accessibilityDescribedBy, +}: DialogInnerProps) { + const t = useTheme() + const {gtMobile} = useBreakpoints() + return ( + + true} + onTouchEnd={stopPropagation} + entering={FadeInDown.duration(100)} + // exiting={FadeOut.duration(100)} + style={[ + a.relative, + a.rounded_md, + a.w_full, + a.border, + gtMobile ? a.p_xl : a.p_lg, + t.atoms.bg, + { + maxWidth: 600, + borderColor: t.palette.contrast_200, + shadowColor: t.palette.black, + shadowOpacity: t.name === 'light' ? 0.1 : 0.4, + shadowRadius: 30, + }, + ...(Array.isArray(style) ? style : [style || {}]), + ]}> + {children} + + + ) +} + +export const ScrollableInner = Inner + +export function Handle() { + return null +} + +/** + * TODO(eric) unused rn + */ +// export function Close() { +// const {_} = useLingui() +// const t = useTheme() +// const {close} = useDialogContext() +// return ( +// +// +// +// ) +// } diff --git a/src/components/Dialog/types.ts b/src/components/Dialog/types.ts new file mode 100644 index 0000000000..d36784183c --- /dev/null +++ b/src/components/Dialog/types.ts @@ -0,0 +1,43 @@ +import React from 'react' +import type {ViewStyle, AccessibilityProps} from 'react-native' +import {BottomSheetProps} from '@gorhom/bottom-sheet' + +type A11yProps = Required + +export type DialogContextProps = { + close: () => void +} + +export type DialogControlProps = { + open: (index?: number) => void + close: () => void +} + +export type DialogOuterProps = { + control: { + ref: React.RefObject + open: (index?: number) => void + close: () => void + } + onClose?: () => void + nativeOptions?: { + sheet?: Omit + } + webOptions?: {} +} + +type DialogInnerPropsBase = React.PropsWithChildren<{ + style?: ViewStyle +}> & + T +export type DialogInnerProps = + | DialogInnerPropsBase<{ + label?: undefined + accessibilityLabelledBy: A11yProps['aria-labelledby'] + accessibilityDescribedBy: string + }> + | DialogInnerPropsBase<{ + label: string + accessibilityLabelledBy?: undefined + accessibilityDescribedBy?: undefined + }> diff --git a/src/components/Link.tsx b/src/components/Link.tsx new file mode 100644 index 0000000000..8f686f3c4c --- /dev/null +++ b/src/components/Link.tsx @@ -0,0 +1,191 @@ +import React from 'react' +import { + Text, + TextStyle, + StyleProp, + GestureResponderEvent, + Linking, +} from 'react-native' +import { + useLinkProps, + useNavigation, + StackActions, +} from '@react-navigation/native' +import {sanitizeUrl} from '@braintree/sanitize-url' + +import {isWeb} from '#/platform/detection' +import {useTheme, web, flatten} from '#/alf' +import {Button, ButtonProps, useButtonContext} from '#/components/Button' +import {AllNavigatorParams, NavigationProp} from '#/lib/routes/types' +import { + convertBskyAppUrlIfNeeded, + isExternalUrl, + linkRequiresWarning, +} from '#/lib/strings/url-helpers' +import {useModalControls} from '#/state/modals' +import {router} from '#/routes' + +export type LinkProps = Omit< + ButtonProps, + 'style' | 'onPress' | 'disabled' | 'label' +> & { + /** + * `TextStyle` to apply to the anchor element itself. Does not apply to any children. + */ + style?: StyleProp + /** + * The React Navigation `StackAction` to perform when the link is pressed. + */ + action?: 'push' | 'replace' | 'navigate' + /** + * If true, will warn the user if the link text does not match the href. Only + * works for Links with children that are strings i.e. text links. + */ + warnOnMismatchingTextChild?: boolean + label?: ButtonProps['label'] +} & Pick>[0], 'to'> + +/** + * A interactive element that renders as a `` tag on the web. On mobile it + * will translate the `href` to navigator screens and params and dispatch a + * navigation action. + * + * Intended to behave as a web anchor tag. For more complex routing, use a + * `Button`. + */ +export function Link({ + children, + to, + action = 'push', + warnOnMismatchingTextChild, + style, + ...rest +}: LinkProps) { + const navigation = useNavigation() + const {href} = useLinkProps({ + to: + typeof to === 'string' ? convertBskyAppUrlIfNeeded(sanitizeUrl(to)) : to, + }) + const isExternal = isExternalUrl(href) + const {openModal, closeModal} = useModalControls() + const onPress = React.useCallback( + (e: GestureResponderEvent) => { + const stringChildren = typeof children === 'string' ? children : '' + const requiresWarning = Boolean( + warnOnMismatchingTextChild && + stringChildren && + isExternal && + linkRequiresWarning(href, stringChildren), + ) + + if (requiresWarning) { + e.preventDefault() + + openModal({ + name: 'link-warning', + text: stringChildren, + href: href, + }) + } else { + e.preventDefault() + + if (isExternal) { + Linking.openURL(href) + } else { + /** + * A `GestureResponderEvent`, but cast to `any` to avoid using a bunch + * of @ts-ignore below. + */ + const event = e as any + const isMiddleClick = isWeb && event.button === 1 + const isMetaKey = + isWeb && + (event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) + const shouldOpenInNewTab = isMetaKey || isMiddleClick + + if ( + shouldOpenInNewTab || + href.startsWith('http') || + href.startsWith('mailto') + ) { + Linking.openURL(href) + } else { + closeModal() // close any active modals + + if (action === 'push') { + navigation.dispatch(StackActions.push(...router.matchPath(href))) + } else if (action === 'replace') { + navigation.dispatch( + StackActions.replace(...router.matchPath(href)), + ) + } else if (action === 'navigate') { + // @ts-ignore + navigation.navigate(...router.matchPath(href)) + } else { + throw Error('Unsupported navigator action.') + } + } + } + } + }, + [ + href, + isExternal, + warnOnMismatchingTextChild, + navigation, + action, + children, + closeModal, + openModal, + ], + ) + + return ( + + ) +} + +function LinkText({ + children, + style, +}: React.PropsWithChildren<{ + style?: StyleProp +}>) { + const t = useTheme() + const {hovered} = useButtonContext() + return ( + + {children as string} + + ) +} diff --git a/src/components/Portal.tsx b/src/components/Portal.tsx new file mode 100644 index 0000000000..1813d9e05e --- /dev/null +++ b/src/components/Portal.tsx @@ -0,0 +1,56 @@ +import React from 'react' + +type Component = React.ReactElement + +type ContextType = { + outlet: Component | null + append(id: string, component: Component): void + remove(id: string): void +} + +type ComponentMap = { + [id: string]: Component +} + +export const Context = React.createContext({ + outlet: null, + append: () => {}, + remove: () => {}, +}) + +export function Provider(props: React.PropsWithChildren<{}>) { + const map = React.useRef({}) + const [outlet, setOutlet] = React.useState(null) + + const append = React.useCallback((id, component) => { + if (map.current[id]) return + map.current[id] = {component} + setOutlet(<>{Object.values(map.current)}) + }, []) + + const remove = React.useCallback(id => { + delete map.current[id] + setOutlet(<>{Object.values(map.current)}) + }, []) + + return ( + + {props.children} + + ) +} + +export function Outlet() { + const ctx = React.useContext(Context) + return ctx.outlet +} + +export function Portal({children}: React.PropsWithChildren<{}>) { + const {append, remove} = React.useContext(Context) + const id = React.useId() + React.useEffect(() => { + append(id, children as Component) + return () => remove(id) + }, [id, children, append, remove]) + return null +} diff --git a/src/components/Prompt.tsx b/src/components/Prompt.tsx new file mode 100644 index 0000000000..7115f61901 --- /dev/null +++ b/src/components/Prompt.tsx @@ -0,0 +1,119 @@ +import React from 'react' +import {View, PressableProps} from 'react-native' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {useTheme, atoms as a} from '#/alf' +import {H4, P} from '#/components/Typography' +import {Button} from '#/components/Button' + +import * as Dialog from '#/components/Dialog' + +export {useDialogControl as usePromptControl} from '#/components/Dialog' + +const Context = React.createContext<{ + titleId: string + descriptionId: string +}>({ + titleId: '', + descriptionId: '', +}) + +export function Outer({ + children, + control, +}: React.PropsWithChildren<{ + control: Dialog.DialogOuterProps['control'] +}>) { + const titleId = React.useId() + const descriptionId = React.useId() + + const context = React.useMemo( + () => ({titleId, descriptionId}), + [titleId, descriptionId], + ) + + return ( + + + + + + {children} + + + + ) +} + +export function Title({children}: React.PropsWithChildren<{}>) { + const t = useTheme() + const {titleId} = React.useContext(Context) + return ( +

+ {children} +

+ ) +} + +export function Description({children}: React.PropsWithChildren<{}>) { + const t = useTheme() + const {descriptionId} = React.useContext(Context) + return ( +

+ {children} +

+ ) +} + +export function Actions({children}: React.PropsWithChildren<{}>) { + return ( + + {children} + + ) +} + +export function Cancel({ + children, +}: React.PropsWithChildren<{onPress?: PressableProps['onPress']}>) { + const {_} = useLingui() + const {close} = Dialog.useDialogContext() + return ( + + ) +} + +export function Action({ + children, + onPress, +}: React.PropsWithChildren<{onPress?: () => void}>) { + const {_} = useLingui() + const {close} = Dialog.useDialogContext() + const handleOnPress = React.useCallback(() => { + close() + onPress?.() + }, [close, onPress]) + return ( + + ) +} diff --git a/src/view/com/Typography.tsx b/src/components/Typography.tsx similarity index 63% rename from src/view/com/Typography.tsx rename to src/components/Typography.tsx index 6579c2e511..66cf0720de 100644 --- a/src/view/com/Typography.tsx +++ b/src/components/Typography.tsx @@ -1,6 +1,7 @@ import React from 'react' import {Text as RNText, TextProps} from 'react-native' -import {useTheme, atoms, web} from '#/alf' + +import {useTheme, atoms, web, flatten} from '#/alf' export function Text({style, ...rest}: TextProps) { const t = useTheme() @@ -18,7 +19,7 @@ export function H1({style, ...rest}: TextProps) { ) } @@ -34,7 +35,7 @@ export function H2({style, ...rest}: TextProps) { ) } @@ -50,7 +51,7 @@ export function H3({style, ...rest}: TextProps) { ) } @@ -66,7 +67,7 @@ export function H4({style, ...rest}: TextProps) { ) } @@ -82,7 +83,7 @@ export function H5({style, ...rest}: TextProps) { ) } @@ -98,7 +99,26 @@ export function H6({style, ...rest}: TextProps) { + ) +} + +export function P({style, ...rest}: TextProps) { + const t = useTheme() + const attr = + web({ + role: 'paragraph', + }) || {} + const _style = flatten(style) + const lineHeight = + (_style?.lineHeight || atoms.text_md.lineHeight) * + atoms.leading_normal.lineHeight + return ( + ) } diff --git a/src/components/forms/DateField/index.android.tsx b/src/components/forms/DateField/index.android.tsx new file mode 100644 index 0000000000..83fa285f5f --- /dev/null +++ b/src/components/forms/DateField/index.android.tsx @@ -0,0 +1,108 @@ +import React from 'react' +import {View, Pressable} from 'react-native' +import DateTimePicker, { + BaseProps as DateTimePickerProps, +} from '@react-native-community/datetimepicker' + +import {useTheme, atoms} from '#/alf' +import {Text} from '#/components/Typography' +import {useInteractionState} from '#/components/hooks/useInteractionState' +import * as TextField from '#/components/forms/TextField' +import {CalendarDays_Stroke2_Corner0_Rounded as CalendarDays} from '#/components/icons/CalendarDays' + +import {DateFieldProps} from '#/components/forms/DateField/types' +import { + localizeDate, + toSimpleDateString, +} from '#/components/forms/DateField/utils' + +export * as utils from '#/components/forms/DateField/utils' +export const Label = TextField.Label + +export function DateField({ + value, + onChangeDate, + label, + isInvalid, + testID, +}: DateFieldProps) { + const t = useTheme() + const [open, setOpen] = React.useState(false) + const { + state: pressed, + onIn: onPressIn, + onOut: onPressOut, + } = useInteractionState() + const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState() + + const {chromeFocus, chromeError, chromeErrorHover} = + TextField.useSharedInputStyles() + + const onChangeInternal = React.useCallback< + Required['onChange'] + >( + (_event, date) => { + setOpen(false) + + if (date) { + const formatted = toSimpleDateString(date) + onChangeDate(formatted) + } + }, + [onChangeDate, setOpen], + ) + + return ( + + setOpen(true)} + onPressIn={onPressIn} + onPressOut={onPressOut} + onFocus={onFocus} + onBlur={onBlur} + style={[ + { + paddingTop: 16, + paddingBottom: 16, + borderColor: 'transparent', + borderWidth: 2, + }, + atoms.flex_row, + atoms.flex_1, + atoms.w_full, + atoms.px_lg, + atoms.rounded_sm, + t.atoms.bg_contrast_50, + focused || pressed ? chromeFocus : {}, + isInvalid ? chromeError : {}, + isInvalid && (focused || pressed) ? chromeErrorHover : {}, + ]}> + + + + {localizeDate(value)} + + + + {open && ( + + )} + + ) +} diff --git a/src/components/forms/DateField/index.tsx b/src/components/forms/DateField/index.tsx new file mode 100644 index 0000000000..c359a9d460 --- /dev/null +++ b/src/components/forms/DateField/index.tsx @@ -0,0 +1,56 @@ +import React from 'react' +import {View} from 'react-native' +import DateTimePicker, { + DateTimePickerEvent, +} from '@react-native-community/datetimepicker' + +import {useTheme, atoms} from '#/alf' +import * as TextField from '#/components/forms/TextField' +import {toSimpleDateString} from '#/components/forms/DateField/utils' +import {DateFieldProps} from '#/components/forms/DateField/types' + +export * as utils from '#/components/forms/DateField/utils' +export const Label = TextField.Label + +/** + * Date-only input. Accepts a date in the format YYYY-MM-DD, and reports date + * changes in the same format. + * + * For dates of unknown format, convert with the + * `utils.toSimpleDateString(Date)` export of this file. + */ +export function DateField({ + value, + onChangeDate, + testID, + label, +}: DateFieldProps) { + const t = useTheme() + + const onChangeInternal = React.useCallback( + (event: DateTimePickerEvent, date: Date | undefined) => { + if (date) { + const formatted = toSimpleDateString(date) + onChangeDate(formatted) + } + }, + [onChangeDate], + ) + + return ( + + + + ) +} diff --git a/src/components/forms/DateField/index.web.tsx b/src/components/forms/DateField/index.web.tsx new file mode 100644 index 0000000000..32f38a5d16 --- /dev/null +++ b/src/components/forms/DateField/index.web.tsx @@ -0,0 +1,64 @@ +import React from 'react' +import {TextInput, TextInputProps, StyleSheet} from 'react-native' +// @ts-ignore +import {unstable_createElement} from 'react-native-web' + +import * as TextField from '#/components/forms/TextField' +import {toSimpleDateString} from '#/components/forms/DateField/utils' +import {DateFieldProps} from '#/components/forms/DateField/types' + +export * as utils from '#/components/forms/DateField/utils' +export const Label = TextField.Label + +const InputBase = React.forwardRef( + ({style, ...props}, ref) => { + return unstable_createElement('input', { + ...props, + ref, + type: 'date', + style: [ + StyleSheet.flatten(style), + { + background: 'transparent', + border: 0, + }, + ], + }) + }, +) + +InputBase.displayName = 'InputBase' + +const Input = TextField.createInput(InputBase as unknown as typeof TextInput) + +export function DateField({ + value, + onChangeDate, + label, + isInvalid, + testID, +}: DateFieldProps) { + const handleOnChange = React.useCallback( + (e: any) => { + const date = e.target.valueAsDate || e.target.value + + if (date) { + const formatted = toSimpleDateString(date) + onChangeDate(formatted) + } + }, + [onChangeDate], + ) + + return ( + + {}} + testID={testID} + /> + + ) +} diff --git a/src/components/forms/DateField/types.ts b/src/components/forms/DateField/types.ts new file mode 100644 index 0000000000..129f5672d4 --- /dev/null +++ b/src/components/forms/DateField/types.ts @@ -0,0 +1,7 @@ +export type DateFieldProps = { + value: string + onChangeDate: (date: string) => void + label: string + isInvalid?: boolean + testID?: string +} diff --git a/src/components/forms/DateField/utils.ts b/src/components/forms/DateField/utils.ts new file mode 100644 index 0000000000..c787272fe8 --- /dev/null +++ b/src/components/forms/DateField/utils.ts @@ -0,0 +1,16 @@ +import {getLocales} from 'expo-localization' + +const LOCALE = getLocales()[0] + +// we need the date in the form yyyy-MM-dd to pass to the input +export function toSimpleDateString(date: Date | string): string { + const _date = typeof date === 'string' ? new Date(date) : date + return _date.toISOString().split('T')[0] +} + +export function localizeDate(date: Date | string): string { + const _date = typeof date === 'string' ? new Date(date) : date + return new Intl.DateTimeFormat(LOCALE.languageTag, { + timeZone: 'UTC', + }).format(_date) +} diff --git a/src/components/forms/InputGroup.tsx b/src/components/forms/InputGroup.tsx new file mode 100644 index 0000000000..6908d4df8e --- /dev/null +++ b/src/components/forms/InputGroup.tsx @@ -0,0 +1,43 @@ +import React from 'react' +import {View} from 'react-native' + +import {atoms, useTheme} from '#/alf' + +/** + * NOT FINISHED, just here as a reference + */ +export function InputGroup(props: React.PropsWithChildren<{}>) { + const t = useTheme() + const children = React.Children.toArray(props.children) + const total = children.length + return ( + + {children.map((child, i) => { + return React.isValidElement(child) ? ( + + {i > 0 ? ( + + ) : null} + {React.cloneElement(child, { + // @ts-ignore + style: [ + ...(Array.isArray(child.props?.style) + ? child.props.style + : [child.props.style || {}]), + { + borderTopLeftRadius: i > 0 ? 0 : undefined, + borderTopRightRadius: i > 0 ? 0 : undefined, + borderBottomLeftRadius: i < total - 1 ? 0 : undefined, + borderBottomRightRadius: i < total - 1 ? 0 : undefined, + borderBottomWidth: i < total - 1 ? 0 : undefined, + }, + ], + })} + + ) : null + })} + + ) +} diff --git a/src/components/forms/TextField.tsx b/src/components/forms/TextField.tsx new file mode 100644 index 0000000000..1ee58303ae --- /dev/null +++ b/src/components/forms/TextField.tsx @@ -0,0 +1,334 @@ +import React from 'react' +import { + View, + TextInput, + TextInputProps, + TextStyle, + ViewStyle, + Pressable, + StyleSheet, + AccessibilityProps, +} from 'react-native' + +import {HITSLOP_20} from 'lib/constants' +import {isWeb} from '#/platform/detection' +import {useTheme, atoms as a, web, tokens, android} from '#/alf' +import {Text} from '#/components/Typography' +import {useInteractionState} from '#/components/hooks/useInteractionState' +import {Props as SVGIconProps} from '#/components/icons/common' + +const Context = React.createContext<{ + inputRef: React.RefObject | null + isInvalid: boolean + hovered: boolean + onHoverIn: () => void + onHoverOut: () => void + focused: boolean + onFocus: () => void + onBlur: () => void +}>({ + inputRef: null, + isInvalid: false, + hovered: false, + onHoverIn: () => {}, + onHoverOut: () => {}, + focused: false, + onFocus: () => {}, + onBlur: () => {}, +}) + +export type RootProps = React.PropsWithChildren<{isInvalid?: boolean}> + +export function Root({children, isInvalid = false}: RootProps) { + const inputRef = React.useRef(null) + const rootRef = React.useRef(null) + const { + state: hovered, + onIn: onHoverIn, + onOut: onHoverOut, + } = useInteractionState() + const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState() + + const context = React.useMemo( + () => ({ + inputRef, + hovered, + onHoverIn, + onHoverOut, + focused, + onFocus, + onBlur, + isInvalid, + }), + [ + inputRef, + hovered, + onHoverIn, + onHoverOut, + focused, + onFocus, + onBlur, + isInvalid, + ], + ) + + React.useLayoutEffect(() => { + const root = rootRef.current + if (!root || !isWeb) return + // @ts-ignore web only + root.tabIndex = -1 + }, []) + + return ( + + inputRef.current?.focus()} + onHoverIn={onHoverIn} + onHoverOut={onHoverOut}> + {children} + + + ) +} + +export function useSharedInputStyles() { + const t = useTheme() + return React.useMemo(() => { + const hover: ViewStyle[] = [ + { + borderColor: t.palette.contrast_100, + }, + ] + const focus: ViewStyle[] = [ + { + backgroundColor: t.palette.contrast_50, + borderColor: t.palette.primary_500, + }, + ] + const error: ViewStyle[] = [ + { + backgroundColor: + t.name === 'light' ? t.palette.negative_25 : t.palette.negative_900, + borderColor: + t.name === 'light' ? t.palette.negative_300 : t.palette.negative_800, + }, + ] + const errorHover: ViewStyle[] = [ + { + backgroundColor: + t.name === 'light' ? t.palette.negative_25 : t.palette.negative_900, + borderColor: tokens.color.red_500, + }, + ] + + return { + chromeHover: StyleSheet.flatten(hover), + chromeFocus: StyleSheet.flatten(focus), + chromeError: StyleSheet.flatten(error), + chromeErrorHover: StyleSheet.flatten(errorHover), + } + }, [t]) +} + +export type InputProps = Omit & { + label: string + value: string + onChangeText: (value: string) => void + isInvalid?: boolean +} + +export function createInput(Component: typeof TextInput) { + return function Input({ + label, + placeholder, + value, + onChangeText, + isInvalid, + ...rest + }: InputProps) { + const t = useTheme() + const ctx = React.useContext(Context) + const withinRoot = Boolean(ctx.inputRef) + + const {chromeHover, chromeFocus, chromeError, chromeErrorHover} = + useSharedInputStyles() + + if (!withinRoot) { + return ( + + + + ) + } + + return ( + <> + + + + + ) + } +} + +export const Input = createInput(TextInput) + +export function Label({children}: React.PropsWithChildren<{}>) { + const t = useTheme() + return ( + + {children} + + ) +} + +export function Icon({icon: Comp}: {icon: React.ComponentType}) { + const t = useTheme() + const ctx = React.useContext(Context) + const {hover, focus, errorHover, errorFocus} = React.useMemo(() => { + const hover: TextStyle[] = [ + { + color: t.palette.contrast_800, + }, + ] + const focus: TextStyle[] = [ + { + color: t.palette.primary_500, + }, + ] + const errorHover: TextStyle[] = [ + { + color: t.palette.negative_500, + }, + ] + const errorFocus: TextStyle[] = [ + { + color: t.palette.negative_500, + }, + ] + + return { + hover, + focus, + errorHover, + errorFocus, + } + }, [t]) + + return ( + + + + ) +} + +export function Suffix({ + children, + label, + accessibilityHint, +}: React.PropsWithChildren<{ + label: string + accessibilityHint?: AccessibilityProps['accessibilityHint'] +}>) { + const t = useTheme() + const ctx = React.useContext(Context) + return ( + + {children} + + ) +} diff --git a/src/components/forms/Toggle.tsx b/src/components/forms/Toggle.tsx new file mode 100644 index 0000000000..ad82bdff5f --- /dev/null +++ b/src/components/forms/Toggle.tsx @@ -0,0 +1,473 @@ +import React from 'react' +import {Pressable, View, ViewStyle} from 'react-native' + +import {HITSLOP_10} from 'lib/constants' +import {useTheme, atoms as a, web, native} from '#/alf' +import {Text} from '#/components/Typography' +import {useInteractionState} from '#/components/hooks/useInteractionState' + +export type ItemState = { + name: string + selected: boolean + disabled: boolean + isInvalid: boolean + hovered: boolean + pressed: boolean + focused: boolean +} + +const ItemContext = React.createContext({ + name: '', + selected: false, + disabled: false, + isInvalid: false, + hovered: false, + pressed: false, + focused: false, +}) + +const GroupContext = React.createContext<{ + values: string[] + disabled: boolean + type: 'radio' | 'checkbox' + maxSelectionsReached: boolean + setFieldValue: (props: {name: string; value: boolean}) => void +}>({ + type: 'checkbox', + values: [], + disabled: false, + maxSelectionsReached: false, + setFieldValue: () => {}, +}) + +export type GroupProps = React.PropsWithChildren<{ + type?: 'radio' | 'checkbox' + values: string[] + maxSelections?: number + disabled?: boolean + onChange: (value: string[]) => void + label: string +}> + +export type ItemProps = { + type?: 'radio' | 'checkbox' + name: string + label: string + value?: boolean + disabled?: boolean + onChange?: (selected: boolean) => void + isInvalid?: boolean + style?: (state: ItemState) => ViewStyle + children: ((props: ItemState) => React.ReactNode) | React.ReactNode +} + +export function useItemContext() { + return React.useContext(ItemContext) +} + +export function Group({ + children, + values: providedValues, + onChange, + disabled = false, + type = 'checkbox', + maxSelections, + label, +}: GroupProps) { + const groupRole = type === 'radio' ? 'radiogroup' : undefined + const values = type === 'radio' ? providedValues.slice(0, 1) : providedValues + const [maxReached, setMaxReached] = React.useState(false) + + const setFieldValue = React.useCallback< + (props: {name: string; value: boolean}) => void + >( + ({name, value}) => { + if (type === 'checkbox') { + const pruned = values.filter(v => v !== name) + const next = value ? pruned.concat(name) : pruned + onChange(next) + } else { + onChange([name]) + } + }, + [type, onChange, values], + ) + + React.useEffect(() => { + if (type === 'checkbox') { + if ( + maxSelections && + values.length >= maxSelections && + maxReached === false + ) { + setMaxReached(true) + } else if ( + maxSelections && + values.length < maxSelections && + maxReached === true + ) { + setMaxReached(false) + } + } + }, [type, values.length, maxSelections, maxReached, setMaxReached]) + + const context = React.useMemo( + () => ({ + values, + type, + disabled, + maxSelectionsReached: maxReached, + setFieldValue, + }), + [values, disabled, type, maxReached, setFieldValue], + ) + + return ( + + + {children} + + + ) +} + +export function Item({ + children, + name, + value = false, + disabled: itemDisabled = false, + onChange, + isInvalid, + style, + type = 'checkbox', + label, + ...rest +}: ItemProps) { + const { + values: selectedValues, + type: groupType, + disabled: groupDisabled, + setFieldValue, + maxSelectionsReached, + } = React.useContext(GroupContext) + const { + state: hovered, + onIn: onHoverIn, + onOut: onHoverOut, + } = useInteractionState() + const { + state: pressed, + onIn: onPressIn, + onOut: onPressOut, + } = useInteractionState() + const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState() + + const role = groupType === 'radio' ? 'radio' : type + const selected = selectedValues.includes(name) || !!value + const disabled = + groupDisabled || itemDisabled || (!selected && maxSelectionsReached) + + const onPress = React.useCallback(() => { + const next = !selected + setFieldValue({name, value: next}) + onChange?.(next) + }, [name, selected, onChange, setFieldValue]) + + const state = React.useMemo( + () => ({ + name, + selected, + disabled: disabled ?? false, + isInvalid: isInvalid ?? false, + hovered, + pressed, + focused, + }), + [name, selected, disabled, hovered, pressed, focused, isInvalid], + ) + + return ( + + + {typeof children === 'function' ? children(state) : children} + + + ) +} + +export function Label({children}: React.PropsWithChildren<{}>) { + const t = useTheme() + const {disabled} = useItemContext() + return ( + + {children} + + ) +} + +// TODO(eric) refactor to memoize styles without knowledge of state +export function createSharedToggleStyles({ + theme: t, + hovered, + focused, + selected, + disabled, + isInvalid, +}: { + theme: ReturnType + selected: boolean + hovered: boolean + focused: boolean + disabled: boolean + isInvalid: boolean +}) { + const base: ViewStyle[] = [] + const baseHover: ViewStyle[] = [] + const indicator: ViewStyle[] = [] + + if (selected) { + base.push({ + backgroundColor: + t.name === 'light' ? t.palette.primary_25 : t.palette.primary_900, + borderColor: t.palette.primary_500, + }) + + if (hovered || focused) { + baseHover.push({ + backgroundColor: + t.name === 'light' ? t.palette.primary_100 : t.palette.primary_800, + borderColor: + t.name === 'light' ? t.palette.primary_600 : t.palette.primary_400, + }) + } + } else { + if (hovered || focused) { + baseHover.push({ + backgroundColor: + t.name === 'light' ? t.palette.contrast_50 : t.palette.contrast_100, + borderColor: t.palette.contrast_500, + }) + } + } + + if (isInvalid) { + base.push({ + backgroundColor: + t.name === 'light' ? t.palette.negative_25 : t.palette.negative_900, + borderColor: + t.name === 'light' ? t.palette.negative_300 : t.palette.negative_800, + }) + + if (hovered || focused) { + baseHover.push({ + backgroundColor: + t.name === 'light' ? t.palette.negative_25 : t.palette.negative_900, + borderColor: t.palette.negative_500, + }) + } + } + + if (disabled) { + base.push({ + backgroundColor: t.palette.contrast_100, + borderColor: t.palette.contrast_400, + }) + } + + return { + baseStyles: base, + baseHoverStyles: disabled ? [] : baseHover, + indicatorStyles: indicator, + } +} + +export function Checkbox() { + const t = useTheme() + const {selected, hovered, focused, disabled, isInvalid} = useItemContext() + const {baseStyles, baseHoverStyles, indicatorStyles} = + createSharedToggleStyles({ + theme: t, + hovered, + focused, + selected, + disabled, + isInvalid, + }) + return ( + + {selected ? ( + + ) : null} + + ) +} + +export function Switch() { + const t = useTheme() + const {selected, hovered, focused, disabled, isInvalid} = useItemContext() + const {baseStyles, baseHoverStyles, indicatorStyles} = + createSharedToggleStyles({ + theme: t, + hovered, + focused, + selected, + disabled, + isInvalid, + }) + return ( + + + + ) +} + +export function Radio() { + const t = useTheme() + const {selected, hovered, focused, disabled, isInvalid} = + React.useContext(ItemContext) + const {baseStyles, baseHoverStyles, indicatorStyles} = + createSharedToggleStyles({ + theme: t, + hovered, + focused, + selected, + disabled, + isInvalid, + }) + return ( + + {selected ? ( + + ) : null} + + ) +} diff --git a/src/components/forms/ToggleButton.tsx b/src/components/forms/ToggleButton.tsx new file mode 100644 index 0000000000..615fedae8b --- /dev/null +++ b/src/components/forms/ToggleButton.tsx @@ -0,0 +1,124 @@ +import React from 'react' +import {View, AccessibilityProps, TextStyle, ViewStyle} from 'react-native' + +import {atoms as a, useTheme, native} from '#/alf' +import {Text} from '#/components/Typography' + +import * as Toggle from '#/components/forms/Toggle' + +export type ItemProps = Omit & + AccessibilityProps & + React.PropsWithChildren<{}> + +export type GroupProps = Omit & { + multiple?: boolean +} + +export function Group({children, multiple, ...props}: GroupProps) { + const t = useTheme() + return ( + + + {children} + + + ) +} + +export function Button({children, ...props}: ItemProps) { + return ( + + {children} + + ) +} + +function ButtonInner({children}: React.PropsWithChildren<{}>) { + const t = useTheme() + const state = Toggle.useItemContext() + + const {baseStyles, hoverStyles, activeStyles, textStyles} = + React.useMemo(() => { + const base: ViewStyle[] = [] + const hover: ViewStyle[] = [] + const active: ViewStyle[] = [] + const text: TextStyle[] = [] + + hover.push( + t.name === 'light' ? t.atoms.bg_contrast_100 : t.atoms.bg_contrast_25, + ) + + if (state.selected) { + active.push({ + backgroundColor: t.palette.contrast_800, + }) + text.push(t.atoms.text_inverted) + hover.push({ + backgroundColor: t.palette.contrast_800, + }) + + if (state.disabled) { + active.push({ + backgroundColor: t.palette.contrast_500, + }) + } + } + + if (state.disabled) { + base.push({ + backgroundColor: t.palette.contrast_100, + }) + text.push({ + opacity: 0.5, + }) + } + + return { + baseStyles: base, + hoverStyles: hover, + activeStyles: active, + textStyles: text, + } + }, [t, state]) + + return ( + + {typeof children === 'string' ? ( + + {children} + + ) : ( + children + )} + + ) +} diff --git a/src/components/hooks/useInteractionState.ts b/src/components/hooks/useInteractionState.ts new file mode 100644 index 0000000000..653b1c10e6 --- /dev/null +++ b/src/components/hooks/useInteractionState.ts @@ -0,0 +1,21 @@ +import React from 'react' + +export function useInteractionState() { + const [state, setState] = React.useState(false) + + const onIn = React.useCallback(() => { + setState(true) + }, [setState]) + const onOut = React.useCallback(() => { + setState(false) + }, [setState]) + + return React.useMemo( + () => ({ + state, + onIn, + onOut, + }), + [state, onIn, onOut], + ) +} diff --git a/src/components/icons/ArrowTopRight.tsx b/src/components/icons/ArrowTopRight.tsx new file mode 100644 index 0000000000..92ad30a129 --- /dev/null +++ b/src/components/icons/ArrowTopRight.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const ArrowTopRight_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M8 6a1 1 0 0 1 1-1h9a1 1 0 0 1 1 1v9a1 1 0 1 1-2 0V8.414l-9.793 9.793a1 1 0 0 1-1.414-1.414L15.586 7H9a1 1 0 0 1-1-1Z', +}) diff --git a/src/components/icons/CalendarDays.tsx b/src/components/icons/CalendarDays.tsx new file mode 100644 index 0000000000..72cc48e261 --- /dev/null +++ b/src/components/icons/CalendarDays.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const CalendarDays_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M4 3a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H4Zm1 16V9h14v10H5ZM5 7h14V5H5v2Zm3 10.25a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5ZM17.25 12a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0ZM12 13.25a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5ZM9.25 12a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0ZM12 17.25a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Z', +}) diff --git a/src/components/icons/ColorPalette.tsx b/src/components/icons/ColorPalette.tsx new file mode 100644 index 0000000000..157fa7fa13 --- /dev/null +++ b/src/components/icons/ColorPalette.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const ColorPalette_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M4 12c0-4.09 3.527-7.5 8-7.5s8 3.41 8 7.5c0 1.579-.419 2.056-.708 2.236-.388.241-1.031.286-2.058.153-.33-.043-.652-.096-.991-.152a65.905 65.905 0 0 0-.531-.087c-.52-.081-1.077-.156-1.61-.164-1.065-.016-2.336.245-2.996 1.567-.418.834-.295 1.67-.078 2.314.18.534.47 1.055.683 1.437v.001l.097.175.01.018C7.432 19.407 4 16.033 4 12Zm8-9.5C6.532 2.5 2 6.7 2 12s4.532 9.5 10 9.5c.401 0 .812-.04 1.166-.193.41-.176.761-.517.866-1.028.085-.416-.03-.796-.118-1.029a5.981 5.981 0 0 0-.351-.73l-.12-.215c-.215-.392-.403-.73-.52-1.078-.13-.387-.111-.614-.029-.78.146-.291.404-.473 1.178-.461.385.005.825.06 1.329.14.15.023.308.05.47.077.36.059.742.122 1.105.17 1.021.132 2.325.213 3.373-.439C21.496 15.22 22 13.874 22 12c0-5.3-4.532-9.5-10-9.5Zm3.5 8.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM9 12.25a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Zm1.5-2.75a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z', +}) diff --git a/src/components/icons/Globe.tsx b/src/components/icons/Globe.tsx new file mode 100644 index 0000000000..f81b3ff7a0 --- /dev/null +++ b/src/components/icons/Globe.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Globe_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M4.062 11h2.961c.103-2.204.545-4.218 1.235-5.77.06-.136.123-.269.188-.399A8.007 8.007 0 0 0 4.062 11ZM12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2Zm0 2c-.227 0-.518.1-.868.432-.354.337-.719.872-1.047 1.61-.561 1.263-.958 2.991-1.06 4.958h5.95c-.102-1.967-.499-3.695-1.06-4.958-.328-.738-.693-1.273-1.047-1.61C12.518 4.099 12.227 4 12 4Zm4.977 7c-.103-2.204-.545-4.218-1.235-5.77a9.78 9.78 0 0 0-.188-.399A8.006 8.006 0 0 1 19.938 11h-2.961Zm-2.003 2H9.026c.101 1.966.498 3.695 1.06 4.958.327.738.692 1.273 1.046 1.61.35.333.641.432.868.432.227 0 .518-.1.868-.432.354-.337.719-.872 1.047-1.61.561-1.263.958-2.991 1.06-4.958Zm.58 6.169c.065-.13.128-.263.188-.399.69-1.552 1.132-3.566 1.235-5.77h2.961a8.006 8.006 0 0 1-4.384 6.169Zm-7.108 0a9.877 9.877 0 0 1-.188-.399c-.69-1.552-1.132-3.566-1.235-5.77H4.062a8.006 8.006 0 0 0 4.384 6.169Z', +}) diff --git a/src/components/icons/TEMPLATE.tsx b/src/components/icons/TEMPLATE.tsx new file mode 100644 index 0000000000..9fc1470375 --- /dev/null +++ b/src/components/icons/TEMPLATE.tsx @@ -0,0 +1,48 @@ +import React from 'react' +import Svg, {Path} from 'react-native-svg' + +import {useCommonSVGProps, Props} from '#/components/icons/common' + +export const IconTemplate_Stroke2_Corner0_Rounded = React.forwardRef( + function LogoImpl(props: Props, ref) { + const {fill, size, style, ...rest} = useCommonSVGProps(props) + + return ( + + + + ) + }, +) + +export function createSinglePathSVG({path}: {path: string}) { + return React.forwardRef(function LogoImpl(props, ref) { + const {fill, size, style, ...rest} = useCommonSVGProps(props) + + return ( + + + + ) + }) +} diff --git a/src/components/icons/common.ts b/src/components/icons/common.ts new file mode 100644 index 0000000000..9e9f15c4dd --- /dev/null +++ b/src/components/icons/common.ts @@ -0,0 +1,32 @@ +import {StyleSheet, TextProps} from 'react-native' +import type {SvgProps, PathProps} from 'react-native-svg' + +import {tokens} from '#/alf' + +export type Props = { + fill?: PathProps['fill'] + style?: TextProps['style'] + size?: keyof typeof sizes +} & Omit + +export const sizes = { + xs: 12, + sm: 16, + md: 20, + lg: 24, + xl: 28, +} + +export function useCommonSVGProps(props: Props) { + const {fill, size, ...rest} = props + const style = StyleSheet.flatten(rest.style) + const _fill = fill || style?.color || tokens.color.blue_500 + const _size = Number(size ? sizes[size] : rest.width || sizes.md) + + return { + fill: _fill, + size: _size, + style, + ...rest, + } +} diff --git a/src/state/dialogs/index.tsx b/src/state/dialogs/index.tsx new file mode 100644 index 0000000000..4cafaa0861 --- /dev/null +++ b/src/state/dialogs/index.tsx @@ -0,0 +1,44 @@ +import React from 'react' +import {DialogControlProps} from '#/components/Dialog' + +const DialogContext = React.createContext<{ + activeDialogs: React.MutableRefObject< + Map> + > +}>({ + activeDialogs: { + current: new Map(), + }, +}) + +const DialogControlContext = React.createContext<{ + closeAllDialogs(): void +}>({ + closeAllDialogs: () => {}, +}) + +export function useDialogStateContext() { + return React.useContext(DialogContext) +} + +export function useDialogStateControlContext() { + return React.useContext(DialogControlContext) +} + +export function Provider({children}: React.PropsWithChildren<{}>) { + const activeDialogs = React.useRef< + Map> + >(new Map()) + const closeAllDialogs = React.useCallback(() => { + activeDialogs.current.forEach(dialog => dialog.current.close()) + }, []) + const context = React.useMemo(() => ({activeDialogs}), []) + const controls = React.useMemo(() => ({closeAllDialogs}), [closeAllDialogs]) + return ( + + + {children} + + + ) +} diff --git a/src/view/com/Button.tsx b/src/view/com/Button.tsx deleted file mode 100644 index d1f70d4aeb..0000000000 --- a/src/view/com/Button.tsx +++ /dev/null @@ -1,204 +0,0 @@ -import React from 'react' -import {Pressable, Text, PressableProps, TextProps} from 'react-native' -import * as tokens from '#/alf/tokens' -import {atoms} from '#/alf' - -export type ButtonType = - | 'primary' - | 'secondary' - | 'tertiary' - | 'positive' - | 'negative' -export type ButtonSize = 'small' | 'large' - -export type VariantProps = { - type?: ButtonType - size?: ButtonSize -} -type ButtonState = { - pressed: boolean - hovered: boolean - focused: boolean -} -export type ButtonProps = Omit & - VariantProps & { - children: - | ((props: { - state: ButtonState - type?: ButtonType - size?: ButtonSize - }) => React.ReactNode) - | React.ReactNode - | string - } -export type ButtonTextProps = TextProps & VariantProps - -export function Button({children, style, type, size, ...rest}: ButtonProps) { - const {baseStyles, hoverStyles} = React.useMemo(() => { - const baseStyles = [] - const hoverStyles = [] - - switch (type) { - case 'primary': - baseStyles.push({ - backgroundColor: tokens.color.blue_500, - }) - break - case 'secondary': - baseStyles.push({ - backgroundColor: tokens.color.gray_200, - }) - hoverStyles.push({ - backgroundColor: tokens.color.gray_100, - }) - break - default: - } - - switch (size) { - case 'large': - baseStyles.push( - atoms.py_md, - atoms.px_xl, - atoms.rounded_md, - atoms.gap_sm, - ) - break - case 'small': - baseStyles.push( - atoms.py_sm, - atoms.px_md, - atoms.rounded_sm, - atoms.gap_xs, - ) - break - default: - } - - return { - baseStyles, - hoverStyles, - } - }, [type, size]) - - const [state, setState] = React.useState({ - pressed: false, - hovered: false, - focused: false, - }) - - const onPressIn = React.useCallback(() => { - setState(s => ({ - ...s, - pressed: true, - })) - }, [setState]) - const onPressOut = React.useCallback(() => { - setState(s => ({ - ...s, - pressed: false, - })) - }, [setState]) - const onHoverIn = React.useCallback(() => { - setState(s => ({ - ...s, - hovered: true, - })) - }, [setState]) - const onHoverOut = React.useCallback(() => { - setState(s => ({ - ...s, - hovered: false, - })) - }, [setState]) - const onFocus = React.useCallback(() => { - setState(s => ({ - ...s, - focused: true, - })) - }, [setState]) - const onBlur = React.useCallback(() => { - setState(s => ({ - ...s, - focused: false, - })) - }, [setState]) - - return ( - [ - atoms.flex_row, - atoms.align_center, - ...baseStyles, - ...(state.hovered ? hoverStyles : []), - typeof style === 'function' ? style(state) : style, - ]} - onPressIn={onPressIn} - onPressOut={onPressOut} - onHoverIn={onHoverIn} - onHoverOut={onHoverOut} - onFocus={onFocus} - onBlur={onBlur}> - {typeof children === 'string' ? ( - - {children} - - ) : typeof children === 'function' ? ( - children({state, type, size}) - ) : ( - children - )} - - ) -} - -export function ButtonText({ - children, - style, - type, - size, - ...rest -}: ButtonTextProps) { - const textStyles = React.useMemo(() => { - const base = [] - - switch (type) { - case 'primary': - base.push({color: tokens.color.white}) - break - case 'secondary': - base.push({ - color: tokens.color.gray_700, - }) - break - default: - } - - switch (size) { - case 'small': - base.push(atoms.text_sm, {paddingBottom: 1}) - break - case 'large': - base.push(atoms.text_md, {paddingBottom: 1}) - break - default: - } - - return base - }, [type, size]) - - return ( - - {children} - - ) -} diff --git a/src/view/com/pager/FeedsTabBarMobile.tsx b/src/view/com/pager/FeedsTabBarMobile.tsx index 2c5ba5dfb2..9c562f67d7 100644 --- a/src/view/com/pager/FeedsTabBarMobile.tsx +++ b/src/view/com/pager/FeedsTabBarMobile.tsx @@ -20,6 +20,11 @@ import {useNavigation} from '@react-navigation/native' import {NavigationProp} from 'lib/routes/types' import {Logo} from '#/view/icons/Logo' +import {IS_DEV} from '#/env' +import {atoms} from '#/alf' +import {Link as Link2} from '#/components/Link' +import {ColorPalette_Stroke2_Corner0_Rounded as ColorPalette} from '#/components/icons/ColorPalette' + export function FeedsTabBar( props: RenderTabBarFnProps & {testID?: string; onPressSelected: () => void}, ) { @@ -68,7 +73,7 @@ export function FeedsTabBar( headerHeight.value = e.nativeEvent.layout.height }}> - + - + + {IS_DEV && ( + + + + )} + {hasSession && ( export const Logo = React.forwardRef(function LogoImpl(props: Props, ref) { const {fill, ...rest} = props const gradient = fill === 'sky' - const _fill = gradient ? 'url(#sky)' : fill || colors.blue3 + const styles = StyleSheet.flatten(props.style) + const _fill = gradient ? 'url(#sky)' : fill || styles?.color || colors.blue3 // @ts-ignore it's fiiiiine const size = parseInt(rest.width || 32) return ( @@ -29,7 +32,7 @@ export const Logo = React.forwardRef(function LogoImpl(props: Props, ref) { ref={ref} viewBox="0 0 64 57" {...rest} - style={{width: size, height: size * ratio}}> + style={[{width: size, height: size * ratio}, styles]}> {gradient && ( diff --git a/src/view/screens/DebugNew.tsx b/src/view/screens/DebugNew.tsx deleted file mode 100644 index 0b7c5f03bc..0000000000 --- a/src/view/screens/DebugNew.tsx +++ /dev/null @@ -1,541 +0,0 @@ -import React from 'react' -import {View} from 'react-native' -import {CenteredView, ScrollView} from '#/view/com/util/Views' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' - -import {useSetColorMode} from '#/state/shell' -import * as tokens from '#/alf/tokens' -import {atoms as a, useTheme, useBreakpoints, ThemeProvider as Alf} from '#/alf' -import {Button, ButtonText} from '#/view/com/Button' -import {Text, H1, H2, H3, H4, H5, H6} from '#/view/com/Typography' - -function ThemeSelector() { - const setColorMode = useSetColorMode() - - return ( - - - - - - ) -} - -function BreakpointDebugger() { - const t = useTheme() - const breakpoints = useBreakpoints() - - return ( - -

Breakpoint Debugger

- - Current breakpoint: {!breakpoints.gtMobile && mobile} - {breakpoints.gtMobile && !breakpoints.gtTablet && tablet} - {breakpoints.gtTablet && desktop} - - - {JSON.stringify(breakpoints, null, 2)} - -
- ) -} - -function ThemedSection() { - const t = useTheme() - - return ( - -

theme.atoms.text

- -

- theme.atoms.text_contrast_700 -

- -

- theme.atoms.text_contrast_500 -

- - - - - theme.bg - - - theme.bg_contrast_100 - - - - - theme.bg_contrast_200 - - - theme.bg_contrast_300 - - - - - theme.bg_positive - - - theme.bg_negative - - - - ) -} - -export function DebugScreen() { - const t = useTheme() - - return ( - - - - - - - - - - - - -

Heading 1

-

Heading 2

-

Heading 3

-

Heading 4

-
Heading 5
-
Heading 6
- - atoms.text_xxl - atoms.text_xl - atoms.text_lg - atoms.text_md - atoms.text_sm - atoms.text_xs - atoms.text_xxs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Spacing

- - - - xxs (2px) - - - - - xs (4px) - - - - - sm (8px) - - - - - md (12px) - - - - - lg (18px) - - - - - xl (24px) - - - - - xxl (32px) - - - - - - - -
-
- ) -} diff --git a/src/view/screens/Storybook/Breakpoints.tsx b/src/view/screens/Storybook/Breakpoints.tsx new file mode 100644 index 0000000000..1b846d517c --- /dev/null +++ b/src/view/screens/Storybook/Breakpoints.tsx @@ -0,0 +1,25 @@ +import React from 'react' +import {View} from 'react-native' + +import {atoms as a, useTheme, useBreakpoints} from '#/alf' +import {Text, H3} from '#/components/Typography' + +export function Breakpoints() { + const t = useTheme() + const breakpoints = useBreakpoints() + + return ( + +

Breakpoint Debugger

+ + Current breakpoint: {!breakpoints.gtMobile && mobile} + {breakpoints.gtMobile && !breakpoints.gtTablet && tablet} + {breakpoints.gtTablet && desktop} + + + {JSON.stringify(breakpoints, null, 2)} + +
+ ) +} diff --git a/src/view/screens/Storybook/Buttons.tsx b/src/view/screens/Storybook/Buttons.tsx new file mode 100644 index 0000000000..fbdc84eb4b --- /dev/null +++ b/src/view/screens/Storybook/Buttons.tsx @@ -0,0 +1,124 @@ +import React from 'react' +import {View} from 'react-native' + +import {atoms as a} from '#/alf' +import { + Button, + ButtonVariant, + ButtonColor, + ButtonIcon, + ButtonText, +} from '#/components/Button' +import {H1} from '#/components/Typography' +import {ArrowTopRight_Stroke2_Corner0_Rounded as ArrowTopRight} from '#/components/icons/ArrowTopRight' +import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe' + +export function Buttons() { + return ( + +

Buttons

+ + + {['primary', 'secondary', 'negative'].map(color => ( + + {['solid', 'outline', 'ghost'].map(variant => ( + + + + + ))} + + ))} + + + + {['gradient_sky', 'gradient_midnight', 'gradient_sunrise'].map( + name => ( + + + + + ), + )} + + + {['gradient_sunset', 'gradient_nordic', 'gradient_bonfire'].map( + name => ( + + + + + ), + )} + + + + + + + + + +
+ ) +} diff --git a/src/view/screens/Storybook/Dialogs.tsx b/src/view/screens/Storybook/Dialogs.tsx new file mode 100644 index 0000000000..db568c6bd5 --- /dev/null +++ b/src/view/screens/Storybook/Dialogs.tsx @@ -0,0 +1,90 @@ +import React from 'react' +import {View} from 'react-native' + +import {atoms as a} from '#/alf' +import {Button} from '#/components/Button' +import {H3, P} from '#/components/Typography' +import * as Dialog from '#/components/Dialog' +import * as Prompt from '#/components/Prompt' +import {useDialogStateControlContext} from '#/state/dialogs' + +export function Dialogs() { + const control = Dialog.useDialogControl() + const prompt = Prompt.usePromptControl() + const {closeAllDialogs} = useDialogStateControlContext() + + return ( + + + + + + + This is a prompt + + This is a generic prompt component. It accepts a title and a + description, as well as two actions. + + + Cancel + Confirm + + + + + + + + +

Dialog

+

+ A scrollable dialog with an input within it. +

+ {}} label="Type here" /> + + + + + + + +
+
+
+ ) +} diff --git a/src/view/screens/Storybook/Forms.tsx b/src/view/screens/Storybook/Forms.tsx new file mode 100644 index 0000000000..9396cca67b --- /dev/null +++ b/src/view/screens/Storybook/Forms.tsx @@ -0,0 +1,215 @@ +import React from 'react' +import {View} from 'react-native' + +import {atoms as a} from '#/alf' +import {H1, H3} from '#/components/Typography' +import * as TextField from '#/components/forms/TextField' +import {DateField, Label} from '#/components/forms/DateField' +import * as Toggle from '#/components/forms/Toggle' +import * as ToggleButton from '#/components/forms/ToggleButton' +import {Button} from '#/components/Button' +import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe' + +export function Forms() { + const [toggleGroupAValues, setToggleGroupAValues] = React.useState(['a']) + const [toggleGroupBValues, setToggleGroupBValues] = React.useState(['a', 'b']) + const [toggleGroupCValues, setToggleGroupCValues] = React.useState(['a', 'b']) + const [toggleGroupDValues, setToggleGroupDValues] = React.useState(['warn']) + + const [value, setValue] = React.useState('') + const [date, setDate] = React.useState('2001-01-01') + + return ( + +

Forms

+ + +

InputText

+ + + + + + + + + + Text field + + + + @gmail.com + + + + + Textarea + + + +

DateField

+ + + + { + console.log(date) + setDate(date) + }} + label="Input" + /> + +
+ + +

Toggles

+ + + + Uncontrolled toggle + + + + + + + Click me + + + + Click me + + + + Click me + + + + Click me + + + + Click me + + + + + + + + + Click me + + + + Click me + + + + Click me + + + + Click me + + + + Click me + + + + + + + + + Click me + + + + Click me + + + + Click me + + + + Click me + + + + Click me + + + +
+ + + + +

ToggleButton

+ + + + Hide + + + Warn + + + Show + + +
+
+ ) +} diff --git a/src/view/screens/Storybook/Icons.tsx b/src/view/screens/Storybook/Icons.tsx new file mode 100644 index 0000000000..73466e077f --- /dev/null +++ b/src/view/screens/Storybook/Icons.tsx @@ -0,0 +1,41 @@ +import React from 'react' +import {View} from 'react-native' + +import {atoms as a, useTheme} from '#/alf' +import {H1} from '#/components/Typography' +import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe' +import {ArrowTopRight_Stroke2_Corner0_Rounded as ArrowTopRight} from '#/components/icons/ArrowTopRight' +import {CalendarDays_Stroke2_Corner0_Rounded as CalendarDays} from '#/components/icons/CalendarDays' + +export function Icons() { + const t = useTheme() + return ( + +

Icons

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ ) +} diff --git a/src/view/screens/Storybook/Links.tsx b/src/view/screens/Storybook/Links.tsx new file mode 100644 index 0000000000..c3b1c0e0f3 --- /dev/null +++ b/src/view/screens/Storybook/Links.tsx @@ -0,0 +1,48 @@ +import React from 'react' +import {View} from 'react-native' + +import {atoms as a} from '#/alf' +import {ButtonText} from '#/components/Button' +import {Link} from '#/components/Link' +import {H1, H3} from '#/components/Typography' + +export function Links() { + return ( + +

Links

+ + + + External + + +

External with custom children

+ + + https://blueskyweb.xyz + + + Internal + + + + Link as a button + +
+
+ ) +} diff --git a/src/view/screens/Storybook/Palette.tsx b/src/view/screens/Storybook/Palette.tsx new file mode 100644 index 0000000000..b521fe8607 --- /dev/null +++ b/src/view/screens/Storybook/Palette.tsx @@ -0,0 +1,336 @@ +import React from 'react' +import {View} from 'react-native' + +import * as tokens from '#/alf/tokens' +import {atoms as a} from '#/alf' + +export function Palette() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/src/view/screens/Storybook/Shadows.tsx b/src/view/screens/Storybook/Shadows.tsx new file mode 100644 index 0000000000..f92112395f --- /dev/null +++ b/src/view/screens/Storybook/Shadows.tsx @@ -0,0 +1,53 @@ +import React from 'react' +import {View} from 'react-native' + +import {atoms as a, useTheme} from '#/alf' +import {H1, Text} from '#/components/Typography' + +export function Shadows() { + const t = useTheme() + + return ( + +

Shadows

+ + + + shadow_sm + + + + shadow_md + + + + shadow_lg + + +
+ ) +} diff --git a/src/view/screens/Storybook/Spacing.tsx b/src/view/screens/Storybook/Spacing.tsx new file mode 100644 index 0000000000..d7faf93a80 --- /dev/null +++ b/src/view/screens/Storybook/Spacing.tsx @@ -0,0 +1,64 @@ +import React from 'react' +import {View} from 'react-native' + +import {atoms as a, useTheme} from '#/alf' +import {Text, H1} from '#/components/Typography' + +export function Spacing() { + const t = useTheme() + return ( + +

Spacing

+ + + 2xs (2px) + + + + + xs (4px) + + + + + sm (8px) + + + + + md (12px) + + + + + lg (16px) + + + + + xl (20px) + + + + + 2xl (24px) + + + + + 3xl (28px) + + + + + 4xl (32px) + + + + + 5xl (40px) + + + + ) +} diff --git a/src/view/screens/Storybook/Theming.tsx b/src/view/screens/Storybook/Theming.tsx new file mode 100644 index 0000000000..a054434734 --- /dev/null +++ b/src/view/screens/Storybook/Theming.tsx @@ -0,0 +1,56 @@ +import React from 'react' +import {View} from 'react-native' + +import {atoms as a, useTheme} from '#/alf' +import {Text} from '#/components/Typography' +import {Palette} from './Palette' + +export function Theming() { + const t = useTheme() + + return ( + + + + theme.atoms.text + + + + theme.atoms.text_contrast_600 + + + + + theme.atoms.text_contrast_500 + + + + + theme.atoms.text_contrast_400 + + + + + + + theme.atoms.bg + + + theme.atoms.bg_contrast_25 + + + theme.atoms.bg_contrast_50 + + + theme.atoms.bg_contrast_100 + + + theme.atoms.bg_contrast_200 + + + theme.atoms.bg_contrast_300 + + + + ) +} diff --git a/src/view/screens/Storybook/Typography.tsx b/src/view/screens/Storybook/Typography.tsx new file mode 100644 index 0000000000..2e1f04a66e --- /dev/null +++ b/src/view/screens/Storybook/Typography.tsx @@ -0,0 +1,30 @@ +import React from 'react' +import {View} from 'react-native' + +import {atoms as a} from '#/alf' +import {Text, H1, H2, H3, H4, H5, H6, P} from '#/components/Typography' + +export function Typography() { + return ( + +

H1 Heading

+

H2 Heading

+

H3 Heading

+

H4 Heading

+
H5 Heading
+
H6 Heading
+

P Paragraph

+ + atoms.text_5xl + atoms.text_4xl + atoms.text_3xl + atoms.text_2xl + atoms.text_xl + atoms.text_lg + atoms.text_md + atoms.text_sm + atoms.text_xs + atoms.text_2xs +
+ ) +} diff --git a/src/view/screens/Storybook/index.tsx b/src/view/screens/Storybook/index.tsx new file mode 100644 index 0000000000..d8898f20e8 --- /dev/null +++ b/src/view/screens/Storybook/index.tsx @@ -0,0 +1,78 @@ +import React from 'react' +import {View} from 'react-native' +import {CenteredView, ScrollView} from '#/view/com/util/Views' + +import {atoms as a, useTheme, ThemeProvider} from '#/alf' +import {useSetColorMode} from '#/state/shell' +import {Button} from '#/components/Button' + +import {Theming} from './Theming' +import {Typography} from './Typography' +import {Spacing} from './Spacing' +import {Buttons} from './Buttons' +import {Links} from './Links' +import {Forms} from './Forms' +import {Dialogs} from './Dialogs' +import {Breakpoints} from './Breakpoints' +import {Shadows} from './Shadows' +import {Icons} from './Icons' + +export function Storybook() { + const t = useTheme() + const setColorMode = useSetColorMode() + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/src/view/shell/index.tsx b/src/view/shell/index.tsx index 51c03ae3dd..5320aebfc0 100644 --- a/src/view/shell/index.tsx +++ b/src/view/shell/index.tsx @@ -28,6 +28,7 @@ import {isAndroid} from 'platform/detection' import {useSession} from '#/state/session' import {useCloseAnyActiveElement} from '#/state/util' import * as notifications from 'lib/notifications/notifications' +import {Outlet as PortalOutlet} from '#/components/Portal' function ShellInner() { const isDrawerOpen = useIsDrawerOpen() @@ -94,6 +95,7 @@ function ShellInner() {
+ ) diff --git a/src/view/shell/index.web.tsx b/src/view/shell/index.web.tsx index 20bc0dff1f..1ada883c9c 100644 --- a/src/view/shell/index.web.tsx +++ b/src/view/shell/index.web.tsx @@ -15,6 +15,7 @@ import {useAuxClick} from 'lib/hooks/useAuxClick' import {t} from '@lingui/macro' import {useIsDrawerOpen, useSetDrawerOpen} from '#/state/shell' import {useCloseAllActiveElements} from '#/state/util' +import {Outlet as PortalOutlet} from '#/components/Portal' function ShellInner() { const isDrawerOpen = useIsDrawerOpen() @@ -41,6 +42,7 @@ function ShellInner() {
+ {!isDesktop && isDrawerOpen && ( Date: Thu, 18 Jan 2024 22:48:22 -0600 Subject: [PATCH 16/28] Allow images to use specified aspectRatios (#2558) --- src/view/com/util/post-embeds/index.tsx | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/view/com/util/post-embeds/index.tsx b/src/view/com/util/post-embeds/index.tsx index 00a102e7bf..6f168a2936 100644 --- a/src/view/com/util/post-embeds/index.tsx +++ b/src/view/com/util/post-embeds/index.tsx @@ -22,7 +22,6 @@ import {Link} from '../Link' import {ImageLayoutGrid} from '../images/ImageLayoutGrid' import {useLightboxControls, ImagesLightbox} from '#/state/lightbox' import {usePalette} from 'lib/hooks/usePalette' -import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {ExternalLinkEmbed} from './ExternalLinkEmbed' import {MaybeQuoteEmbed} from './QuoteEmbed' import {AutoSizedImage} from '../images/AutoSizedImage' @@ -51,7 +50,6 @@ export function PostEmbeds({ }) { const pal = usePalette('default') const {openLightbox} = useLightboxControls() - const {isMobile} = useWebMediaQueries() // quote post with media // = @@ -129,10 +127,7 @@ export function PostEmbeds({ dimensionsHint={aspectRatio} onPress={() => _openLightbox(0)} onPressIn={() => onPressIn(0)} - style={[ - styles.singleImage, - isMobile && styles.singleImageMobile, - ]}> + style={[styles.singleImage]}> {alt === '' ? null : ( @@ -151,11 +146,7 @@ export function PostEmbeds({ images={embed.images} onPress={_openLightbox} onPressIn={onPressIn} - style={ - embed.images.length === 1 - ? [styles.singleImage, isMobile && styles.singleImageMobile] - : undefined - } + style={embed.images.length === 1 ? [styles.singleImage] : undefined} /> ) @@ -188,10 +179,6 @@ const styles = StyleSheet.create({ }, singleImage: { borderRadius: 8, - maxHeight: 1000, - }, - singleImageMobile: { - maxHeight: 500, }, extOuter: { borderWidth: 1, From 95f70a9a6aec3a4c1b23f837a26bc5c0d4266554 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Thu, 18 Jan 2024 20:48:51 -0800 Subject: [PATCH 17/28] Phone number verification in account creation (#2564) * Add optional sms verification * Add support link to account creation * Add e2e tests * Bump api@0.9.0 * Update lockfile * Bump api@0.9.1 * Include the phone number in the ui * Add phone number validation and normalization --- __e2e__/mock-server.ts | 3 +- __e2e__/tests/create-account.test.ts | 12 +- __e2e__/tests/invite-codes.test.ts | 13 +- .../invites-and-text-verification.test.ts | 57 +++ __e2e__/tests/text-verification.test.ts | 85 +++++ __e2e__/util.ts | 2 +- jest/test-pds.ts | 38 +- package.json | 3 +- src/state/session/index.tsx | 14 +- src/view/com/auth/create/CreateAccount.tsx | 26 +- src/view/com/auth/create/Step1.tsx | 345 ++++++++++-------- src/view/com/auth/create/Step2.tsx | 277 +++++++------- src/view/com/auth/create/Step3.tsx | 2 +- src/view/com/auth/create/StepHeader.tsx | 37 +- src/view/com/auth/create/state.ts | 107 +++++- src/view/icons/index.tsx | 6 + yarn.lock | 13 +- 17 files changed, 701 insertions(+), 339 deletions(-) create mode 100644 __e2e__/tests/invites-and-text-verification.test.ts create mode 100644 __e2e__/tests/text-verification.test.ts diff --git a/__e2e__/mock-server.ts b/__e2e__/mock-server.ts index 482df6ef63..1bf240ccbd 100644 --- a/__e2e__/mock-server.ts +++ b/__e2e__/mock-server.ts @@ -14,7 +14,8 @@ async function main() { await server?.close() console.log('Starting new server') const inviteRequired = url?.query && 'invite' in url.query - server = await createServer({inviteRequired}) + const phoneRequired = url?.query && 'phone' in url.query + server = await createServer({inviteRequired, phoneRequired}) console.log('Listening at', server.pdsUrl) if (url?.query) { if ('users' in url.query) { diff --git a/__e2e__/tests/create-account.test.ts b/__e2e__/tests/create-account.test.ts index eab3e538b3..a6724e8e45 100644 --- a/__e2e__/tests/create-account.test.ts +++ b/__e2e__/tests/create-account.test.ts @@ -16,14 +16,12 @@ describe('Create account', () => { await element(by.id('createAccountButton')).tap() await device.takeScreenshot('1- opened create account screen') - await element(by.id('otherServerBtn')).tap() + await element(by.id('selectServiceButton')).tap() await device.takeScreenshot('2- selected other server') - await element(by.id('customServerInput')).clearText() - await element(by.id('customServerInput')).typeText(service) + await element(by.id('customServerTextInput')).typeText(service) + await element(by.id('customServerTextInput')).tapReturnKey() + await element(by.id('customServerSelectBtn')).tap() await device.takeScreenshot('3- input test server URL') - - await element(by.id('nextBtn')).tap() - await element(by.id('emailInput')).typeText('example@test.com') await element(by.id('passwordInput')).typeText('hunter2') await device.takeScreenshot('4- entered account details') @@ -31,7 +29,7 @@ describe('Create account', () => { await element(by.id('nextBtn')).tap() await element(by.id('handleInput')).typeText('e2e-test') - await device.takeScreenshot('4- entered handle') + await device.takeScreenshot('5- entered handle') await element(by.id('nextBtn')).tap() diff --git a/__e2e__/tests/invite-codes.test.ts b/__e2e__/tests/invite-codes.test.ts index 7db7c595a9..7ab5b1477b 100644 --- a/__e2e__/tests/invite-codes.test.ts +++ b/__e2e__/tests/invite-codes.test.ts @@ -1,10 +1,5 @@ /* eslint-env detox/detox */ -/** - * This test is being skipped until we can resolve the detox crash issue - * with the side drawer. - */ - import {describe, beforeAll, it} from '@jest/globals' import {expect} from 'detox' import {openApp, loginAsAlice, createServer} from '../util' @@ -31,12 +26,12 @@ describe('invite-codes', () => { await element(by.id('e2eOpenLoggedOutView')).tap() await element(by.id('createAccountButton')).tap() await device.takeScreenshot('1- opened create account screen') - await element(by.id('otherServerBtn')).tap() + await element(by.id('selectServiceButton')).tap() await device.takeScreenshot('2- selected other server') - await element(by.id('customServerInput')).clearText() - await element(by.id('customServerInput')).typeText(service) + await element(by.id('customServerTextInput')).typeText(service) + await element(by.id('customServerTextInput')).tapReturnKey() + await element(by.id('customServerSelectBtn')).tap() await device.takeScreenshot('3- input test server URL') - await element(by.id('nextBtn')).tap() await element(by.id('inviteCodeInput')).typeText(inviteCode) await element(by.id('emailInput')).typeText('example@test.com') await element(by.id('passwordInput')).typeText('hunter2') diff --git a/__e2e__/tests/invites-and-text-verification.test.ts b/__e2e__/tests/invites-and-text-verification.test.ts new file mode 100644 index 0000000000..850ca6d5c7 --- /dev/null +++ b/__e2e__/tests/invites-and-text-verification.test.ts @@ -0,0 +1,57 @@ +/* eslint-env detox/detox */ + +import {describe, beforeAll, it} from '@jest/globals' +import {expect} from 'detox' +import {openApp, loginAsAlice, createServer} from '../util' + +describe('invite-codes', () => { + let service: string + let inviteCode = '' + beforeAll(async () => { + service = await createServer('?users&invite&phone') + await openApp({permissions: {notifications: 'YES'}}) + }) + + it('I can fetch invite codes', async () => { + await loginAsAlice() + await element(by.id('e2eOpenInviteCodesModal')).tap() + await expect(element(by.id('inviteCodesModal'))).toBeVisible() + const attrs = await element(by.id('inviteCode-0-code')).getAttributes() + inviteCode = attrs.text + await element(by.id('closeBtn')).tap() + await element(by.id('e2eSignOut')).tap() + }) + + it('I can create a new account with the invite code', async () => { + await element(by.id('e2eOpenLoggedOutView')).tap() + await element(by.id('createAccountButton')).tap() + await device.takeScreenshot('1- opened create account screen') + await element(by.id('selectServiceButton')).tap() + await device.takeScreenshot('2- selected other server') + await element(by.id('customServerTextInput')).typeText(service) + await element(by.id('customServerTextInput')).tapReturnKey() + await element(by.id('customServerSelectBtn')).tap() + await device.takeScreenshot('3- input test server URL') + await element(by.id('inviteCodeInput')).typeText(inviteCode) + await element(by.id('emailInput')).typeText('example@test.com') + await element(by.id('passwordInput')).typeText('hunter2') + await device.takeScreenshot('4- entered account details') + await element(by.id('nextBtn')).tap() + await element(by.id('phoneInput')).typeText('5558675309') + await element(by.id('requestCodeBtn')).tap() + await device.takeScreenshot('5- requested code') + await element(by.id('codeInput')).typeText('000000') + await device.takeScreenshot('6- entered code') + await element(by.id('nextBtn')).tap() + await element(by.id('handleInput')).typeText('e2e-test') + await device.takeScreenshot('7- entered handle') + await element(by.id('nextBtn')).tap() + await expect(element(by.id('welcomeOnboarding'))).toBeVisible() + await element(by.id('continueBtn')).tap() + await expect(element(by.id('recommendedFeedsOnboarding'))).toBeVisible() + await element(by.id('continueBtn')).tap() + await expect(element(by.id('recommendedFollowsOnboarding'))).toBeVisible() + await element(by.id('continueBtn')).tap() + await expect(element(by.id('homeScreen'))).toBeVisible() + }) +}) diff --git a/__e2e__/tests/text-verification.test.ts b/__e2e__/tests/text-verification.test.ts new file mode 100644 index 0000000000..a307a95ffc --- /dev/null +++ b/__e2e__/tests/text-verification.test.ts @@ -0,0 +1,85 @@ +/* eslint-env detox/detox */ + +import {describe, beforeAll, it} from '@jest/globals' +import {expect} from 'detox' +import {openApp, createServer} from '../util' + +describe('Create account', () => { + let service: string + beforeAll(async () => { + service = await createServer('?phone') + await openApp({permissions: {notifications: 'YES'}}) + }) + + it('I can create a new account with text verification', async () => { + await element(by.id('e2eOpenLoggedOutView')).tap() + + await element(by.id('createAccountButton')).tap() + await device.takeScreenshot('1- opened create account screen') + await element(by.id('selectServiceButton')).tap() + await device.takeScreenshot('2- selected other server') + await element(by.id('customServerTextInput')).typeText(service) + await element(by.id('customServerTextInput')).tapReturnKey() + await element(by.id('customServerSelectBtn')).tap() + await device.takeScreenshot('3- input test server URL') + await element(by.id('emailInput')).typeText('text-verification@test.com') + await element(by.id('passwordInput')).typeText('hunter2') + await device.takeScreenshot('4- entered account details') + await element(by.id('nextBtn')).tap() + + await element(by.id('phoneInput')).typeText('1234567890') + await element(by.id('requestCodeBtn')).tap() + await device.takeScreenshot('5- requested code') + + await element(by.id('codeInput')).typeText('000000') + await device.takeScreenshot('6- entered code') + await element(by.id('nextBtn')).tap() + + await element(by.id('handleInput')).typeText('text-verification-test') + await device.takeScreenshot('7- entered handle') + + await element(by.id('nextBtn')).tap() + + await expect(element(by.id('welcomeOnboarding'))).toBeVisible() + await element(by.id('continueBtn')).tap() + await expect(element(by.id('recommendedFeedsOnboarding'))).toBeVisible() + await element(by.id('continueBtn')).tap() + await expect(element(by.id('recommendedFollowsOnboarding'))).toBeVisible() + await element(by.id('continueBtn')).tap() + await expect(element(by.id('homeScreen'))).toBeVisible() + }) + + it('failed text verification correctly goes back to the code input screen', async () => { + await element(by.id('e2eSignOut')).tap() + await element(by.id('e2eOpenLoggedOutView')).tap() + + await element(by.id('createAccountButton')).tap() + await device.takeScreenshot('1- opened create account screen') + await element(by.id('selectServiceButton')).tap() + await device.takeScreenshot('2- selected other server') + await element(by.id('customServerTextInput')).typeText(service) + await element(by.id('customServerTextInput')).tapReturnKey() + await element(by.id('customServerSelectBtn')).tap() + await device.takeScreenshot('3- input test server URL') + await element(by.id('emailInput')).typeText('text-verification2@test.com') + await element(by.id('passwordInput')).typeText('hunter2') + await device.takeScreenshot('4- entered account details') + await element(by.id('nextBtn')).tap() + + await element(by.id('phoneInput')).typeText('1234567890') + await element(by.id('requestCodeBtn')).tap() + await device.takeScreenshot('5- requested code') + + await element(by.id('codeInput')).typeText('111111') + await device.takeScreenshot('6- entered code') + await element(by.id('nextBtn')).tap() + + await element(by.id('handleInput')).typeText('text-verification-test2') + await device.takeScreenshot('7- entered handle') + + await element(by.id('nextBtn')).tap() + + await expect(element(by.id('codeInput'))).toBeVisible() + await device.takeScreenshot('8- got error') + }) +}) diff --git a/__e2e__/util.ts b/__e2e__/util.ts index c5668d042e..8c47406c07 100644 --- a/__e2e__/util.ts +++ b/__e2e__/util.ts @@ -105,7 +105,7 @@ async function openAppForDebugBuild(platform: string, opts: any) { await sleep(3000) } -export async function createServer(path = '') { +export async function createServer(path = ''): Promise { return new Promise(function (resolve, reject) { var req = http.request( { diff --git a/jest/test-pds.ts b/jest/test-pds.ts index d86ebd787a..1912ffc6a7 100644 --- a/jest/test-pds.ts +++ b/jest/test-pds.ts @@ -1,7 +1,7 @@ import net from 'net' import path from 'path' import fs from 'fs' -import {TestNetwork} from '@atproto/dev-env' +import {TestNetwork, TestPds} from '@atproto/dev-env' import {AtUri, BskyAgent} from '@atproto/api' export interface TestUser { @@ -55,19 +55,36 @@ class StringIdGenerator { const ids = new StringIdGenerator() export async function createServer( - {inviteRequired}: {inviteRequired: boolean} = {inviteRequired: false}, + { + inviteRequired, + phoneRequired, + }: {inviteRequired: boolean; phoneRequired: boolean} = { + inviteRequired: false, + phoneRequired: false, + }, ): Promise { - const port = await getPort() + const port = 3000 const port2 = await getPort(port + 1) const port3 = await getPort(port2 + 1) const pdsUrl = `http://localhost:${port}` const id = ids.next() + const phoneParams = phoneRequired + ? { + phoneVerificationRequired: true, + twilioAccountSid: 'ACXXXXXXX', + twilioAuthToken: 'AUTH', + twilioServiceSid: 'VAXXXXXXXX', + } + : {} + const testNet = await TestNetwork.create({ pds: { port, hostname: 'localhost', + dbPostgresSchema: `pds_${id}`, inviteRequired, + ...phoneParams, }, bsky: { dbPostgresSchema: `bsky_${id}`, @@ -76,6 +93,7 @@ export async function createServer( }, plc: {port: port2}, }) + mockTwilio(testNet.pds) const pic = fs.readFileSync( path.join(__dirname, '..', 'assets', 'default-avatar.png'), @@ -144,6 +162,8 @@ class Mocker { email, handle: name + '.test', password: 'hunter2', + verificationPhone: '1234567890', + verificationCode: '000000', }) await agent.upsertProfile(async () => { const blob = await agent.uploadBlob(this.pic, { @@ -430,3 +450,15 @@ async function getPort(start = 3000) { } throw new Error('Unable to find an available port') } + +export const mockTwilio = (pds: TestPds) => { + if (!pds.ctx.twilio) return + + pds.ctx.twilio.sendCode = async (_number: string) => { + // do nothing + } + + pds.ctx.twilio.verifyCode = async (_number: string, code: string) => { + return code === '000000' + } +} diff --git a/package.json b/package.json index ff0ddd3e9b..120e653ff0 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "nuke": "rm -rf ./node_modules && rm -rf ./ios && rm -rf ./android" }, "dependencies": { - "@atproto/api": "^0.8.0", + "@atproto/api": "^0.9.1", "@bam.tech/react-native-image-resizer": "^3.0.4", "@braintree/sanitize-url": "^6.0.2", "@emoji-mart/react": "^1.1.1", @@ -120,6 +120,7 @@ "js-sha256": "^0.9.0", "jwt-decode": "^4.0.0", "lande": "^1.0.10", + "libphonenumber-js": "^1.10.53", "lodash.chunk": "^4.2.0", "lodash.debounce": "^4.0.8", "lodash.isequal": "^4.5.0", diff --git a/src/state/session/index.tsx b/src/state/session/index.tsx index 0a565c9759..e49bc2b390 100644 --- a/src/state/session/index.tsx +++ b/src/state/session/index.tsx @@ -44,6 +44,8 @@ export type ApiContext = { password: string handle: string inviteCode?: string + verificationPhone?: string + verificationCode?: string }) => Promise login: (props: { service: string @@ -203,7 +205,15 @@ export function Provider({children}: React.PropsWithChildren<{}>) { }, [setStateAndPersist, queryClient]) const createAccount = React.useCallback( - async ({service, email, password, handle, inviteCode}: any) => { + async ({ + service, + email, + password, + handle, + inviteCode, + verificationPhone, + verificationCode, + }: any) => { logger.info(`session: creating account`, { service, handle, @@ -217,6 +227,8 @@ export function Provider({children}: React.PropsWithChildren<{}>) { password, email, inviteCode, + verificationPhone, + verificationCode, }) if (!agent.session) { diff --git a/src/view/com/auth/create/CreateAccount.tsx b/src/view/com/auth/create/CreateAccount.tsx index 74307a631c..449afb0d36 100644 --- a/src/view/com/auth/create/CreateAccount.tsx +++ b/src/view/com/auth/create/CreateAccount.tsx @@ -22,12 +22,13 @@ import { useSetSaveFeedsMutation, DEFAULT_PROD_FEEDS, } from '#/state/queries/preferences' -import {IS_PROD} from '#/lib/constants' +import {FEEDBACK_FORM_URL, IS_PROD} from '#/lib/constants' import {Step1} from './Step1' import {Step2} from './Step2' import {Step3} from './Step3' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' +import {TextLink} from '../../util/Link' export function CreateAccount({onPressBack}: {onPressBack: () => void}) { const {screen} = useAnalytics() @@ -117,7 +118,7 @@ export function CreateAccount({onPressBack}: {onPressBack: () => void}) { return ( @@ -176,6 +177,27 @@ export function CreateAccount({onPressBack}: {onPressBack: () => void}) { ) : undefined}
+ + + + + Having trouble?{' '} + + + + + diff --git a/src/view/com/auth/create/Step1.tsx b/src/view/com/auth/create/Step1.tsx index 0f8581c0be..2ce77cf530 100644 --- a/src/view/com/auth/create/Step1.tsx +++ b/src/view/com/auth/create/Step1.tsx @@ -1,25 +1,38 @@ import React from 'react' -import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native' +import { + ActivityIndicator, + Keyboard, + StyleSheet, + TouchableWithoutFeedback, + View, +} from 'react-native' +import {CreateAccountState, CreateAccountDispatch, is18} from './state' import {Text} from 'view/com/util/text/Text' +import {DateInput} from 'view/com/util/forms/DateInput' import {StepHeader} from './StepHeader' -import {CreateAccountState, CreateAccountDispatch} from './state' -import {useTheme} from 'lib/ThemeContext' -import {usePalette} from 'lib/hooks/usePalette' import {s} from 'lib/styles' -import {HelpTip} from '../util/HelpTip' +import {usePalette} from 'lib/hooks/usePalette' import {TextInput} from '../util/TextInput' -import {Button} from 'view/com/util/forms/Button' +import {Button} from '../../util/forms/Button' +import {Policies} from './Policies' import {ErrorMessage} from 'view/com/util/error/ErrorMessage' -import {msg, Trans} from '@lingui/macro' +import {isWeb} from 'platform/detection' +import {Trans, msg} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {useModalControls} from '#/state/modals' +import {logger} from '#/logger' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {LOCAL_DEV_SERVICE, STAGING_SERVICE, PROD_SERVICE} from 'lib/constants' -import {LOGIN_INCLUDE_DEV_SERVERS} from 'lib/build-flags' +function sanitizeDate(date: Date): Date { + if (!date || date.toString() === 'Invalid Date') { + logger.error(`Create account: handled invalid date for birthDate`, { + hasDate: !!date, + }) + return new Date() + } + return date +} -/** STEP 1: Your hosting provider - * @field Bluesky (default) - * @field Other (staging, local dev, your own PDS, etc.) - */ export function Step1({ uiState, uiDispatch, @@ -28,136 +41,175 @@ export function Step1({ uiDispatch: CreateAccountDispatch }) { const pal = usePalette('default') - const [isDefaultSelected, setIsDefaultSelected] = React.useState(true) const {_} = useLingui() + const {openModal} = useModalControls() - const onPressDefault = React.useCallback(() => { - setIsDefaultSelected(true) - uiDispatch({type: 'set-service-url', value: PROD_SERVICE}) - }, [setIsDefaultSelected, uiDispatch]) + const onPressSelectService = React.useCallback(() => { + openModal({ + name: 'server-input', + initialService: uiState.serviceUrl, + onSelect: (url: string) => + uiDispatch({type: 'set-service-url', value: url}), + }) + Keyboard.dismiss() + }, [uiDispatch, uiState.serviceUrl, openModal]) - const onPressOther = React.useCallback(() => { - setIsDefaultSelected(false) - uiDispatch({type: 'set-service-url', value: 'https://'}) - }, [setIsDefaultSelected, uiDispatch]) + const onPressWaitlist = React.useCallback(() => { + openModal({name: 'waitlist'}) + }, [openModal]) - const onChangeServiceUrl = React.useCallback( - (v: string) => { - uiDispatch({type: 'set-service-url', value: v}) - }, - [uiDispatch], - ) + const birthDate = React.useMemo(() => { + return sanitizeDate(uiState.birthDate) + }, [uiState.birthDate]) return ( - - - This is the service that keeps you online. - - + + {!uiState.serviceDescription ? ( + + ) : ( + <> + {uiState.isInviteCodeRequired && ( + + + Invite code + + uiDispatch({type: 'set-invite-code', value})} + accessibilityLabel={_(msg`Invite code`)} + accessibilityHint={_(msg`Input invite code to proceed`)} + autoCapitalize="none" + autoComplete="off" + autoCorrect={false} + autoFocus={true} /> )} - - + + {!uiState.inviteCode && uiState.isInviteCodeRequired ? ( + + + Don't have an invite code?{' '} + + + + + Join the waitlist. + + + + + ) : ( + <> + + + Email address + + uiDispatch({type: 'set-email', value})} + accessibilityLabel={_(msg`Email`)} + accessibilityHint={_(msg`Input email for Bluesky account`)} + accessibilityLabelledBy="email" + autoCapitalize="none" + autoComplete="off" + autoCorrect={false} + autoFocus={!uiState.isInviteCodeRequired} + /> + + + + + Password + + uiDispatch({type: 'set-password', value})} + accessibilityLabel={_(msg`Password`)} + accessibilityHint={_(msg`Set password`)} + accessibilityLabelledBy="password" + autoCapitalize="none" + autoComplete="off" + autoCorrect={false} + /> + + + + + Your birth date + + + uiDispatch({type: 'set-birth-date', value}) + } + buttonType="default-light" + buttonStyle={[pal.border, styles.dateInputButton]} + buttonLabelType="lg" + accessibilityLabel={_(msg`Birthday`)} + accessibilityHint={_(msg`Enter your birth date`)} + accessibilityLabelledBy="birthDate" + /> + + + {uiState.serviceDescription && ( + + )} + + )} + + )} {uiState.error ? ( - ) : ( - - )} - - ) -} - -function Option({ - children, - isSelected, - label, - help, - onPress, - testID, -}: React.PropsWithChildren<{ - isSelected: boolean - label: string - help?: string - onPress: () => void - testID?: string -}>) { - const theme = useTheme() - const pal = usePalette('default') - const {_} = useLingui() - const circleFillStyle = React.useMemo( - () => ({ - backgroundColor: theme.palette.primary.background, - }), - [theme], - ) - - return ( - - - - - {isSelected ? ( - - ) : undefined} - - - {label} - {help ? ( - - {help} - - ) : undefined} - - - - {isSelected && children} + ) : undefined} ) } @@ -165,34 +217,15 @@ function Option({ const styles = StyleSheet.create({ error: { borderRadius: 6, + marginTop: 10, }, - - option: { + dateInputButton: { borderWidth: 1, borderRadius: 6, - marginBottom: 10, + paddingVertical: 14, }, - optionHeading: { - flexDirection: 'row', - alignItems: 'center', - padding: 10, - }, - circle: { - width: 26, - height: 26, - borderRadius: 15, - padding: 4, - borderWidth: 1, - marginRight: 10, - }, - circleFill: { - width: 16, - height: 16, - borderRadius: 10, - }, - - otherForm: { - paddingBottom: 10, - paddingHorizontal: 12, + // @ts-expect-error: Suppressing error due to incomplete `ViewStyle` type definition in react-native-web, missing `cursor` prop as discussed in https://github.com/necolas/react-native-web/issues/832. + touchable: { + ...(isWeb && {cursor: 'pointer'}), }, }) diff --git a/src/view/com/auth/create/Step2.tsx b/src/view/com/auth/create/Step2.tsx index 53e1e02c9b..f938bb9cea 100644 --- a/src/view/com/auth/create/Step2.tsx +++ b/src/view/com/auth/create/Step2.tsx @@ -1,39 +1,28 @@ import React from 'react' -import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native' -import {CreateAccountState, CreateAccountDispatch, is18} from './state' +import { + ActivityIndicator, + StyleSheet, + TouchableWithoutFeedback, + View, +} from 'react-native' +import { + CreateAccountState, + CreateAccountDispatch, + requestVerificationCode, +} from './state' import {Text} from 'view/com/util/text/Text' -import {DateInput} from 'view/com/util/forms/DateInput' import {StepHeader} from './StepHeader' import {s} from 'lib/styles' import {usePalette} from 'lib/hooks/usePalette' import {TextInput} from '../util/TextInput' -import {Policies} from './Policies' +import {Button} from '../../util/forms/Button' import {ErrorMessage} from 'view/com/util/error/ErrorMessage' import {isWeb} from 'platform/detection' import {Trans, msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {useModalControls} from '#/state/modals' -import {logger} from '#/logger' +import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' +import parsePhoneNumber from 'libphonenumber-js' -function sanitizeDate(date: Date): Date { - if (!date || date.toString() === 'Invalid Date') { - logger.error(`Create account: handled invalid date for birthDate`, { - hasDate: !!date, - }) - return new Date() - } - return date -} - -/** STEP 2: Your account - * @field Invite code or waitlist - * @field Email address - * @field Email address - * @field Email address - * @field Password - * @field Birth date - * @readonly Terms of service & privacy policy - */ export function Step2({ uiState, uiDispatch, @@ -43,130 +32,155 @@ export function Step2({ }) { const pal = usePalette('default') const {_} = useLingui() - const {openModal} = useModalControls() + const {isMobile} = useWebMediaQueries() - const onPressWaitlist = React.useCallback(() => { - openModal({name: 'waitlist'}) - }, [openModal]) + const onPressRequest = React.useCallback(() => { + if ( + uiState.verificationPhone.length >= 9 && + parsePhoneNumber(uiState.verificationPhone, 'US') + ) { + requestVerificationCode({uiState, uiDispatch, _}) + } else { + uiDispatch({ + type: 'set-error', + value: _( + msg`There's something wrong with this number. Please include your country and/or area code!`, + ), + }) + } + }, [uiState, uiDispatch, _]) - const birthDate = React.useMemo(() => { - return sanitizeDate(uiState.birthDate) - }, [uiState.birthDate]) + const onPressRetry = React.useCallback(() => { + uiDispatch({type: 'set-has-requested-verification-code', value: false}) + }, [uiDispatch]) + + const phoneNumberFormatted = React.useMemo( + () => + uiState.hasRequestedVerificationCode + ? parsePhoneNumber( + uiState.verificationPhone, + 'US', + )?.formatInternational() + : '', + [uiState.hasRequestedVerificationCode, uiState.verificationPhone], + ) return ( - + - {uiState.isInviteCodeRequired && ( - - - Invite code - - uiDispatch({type: 'set-invite-code', value})} - accessibilityLabel={_(msg`Invite code`)} - accessibilityHint={_(msg`Input invite code to proceed`)} - autoCapitalize="none" - autoComplete="off" - autoCorrect={false} - /> - - )} + {!uiState.hasRequestedVerificationCode ? ( + <> + + + Phone number + + + uiDispatch({type: 'set-verification-phone', value}) + } + accessibilityLabel={_(msg`Email`)} + accessibilityHint={_( + msg`Input phone number for SMS verification`, + )} + accessibilityLabelledBy="phoneNumber" + keyboardType="phone-pad" + autoCapitalize="none" + autoComplete="tel" + autoCorrect={false} + autoFocus={true} + /> + + + Please enter a phone number that can receive SMS text messages. + + + - {!uiState.inviteCode && uiState.isInviteCodeRequired ? ( - - Don't have an invite code?{' '} - - - - Join the waitlist. - - - - + + {uiState.isProcessing ? ( + + ) : ( +