Merge pull request #151 from Coffey-Labs/i18n-french

French, on the same terms as German
This commit is contained in:
Coffey Labs
2026-08-31 12:14:42 -07:00
committed by GitHub
4 changed files with 888 additions and 10 deletions
+10 -4
View File
@@ -22,16 +22,22 @@ describe("resolveUiLanguage", () => {
// The account travels between machines and can outlive a catalogue. A
// page that says lang="fr" while rendering English is worse than one that
// admits to English: it stops the reader translating it themselves.
expect(resolveUiLanguage("fr")).toBe("en");
// Derived rather than named, so shipping another language does not turn
// this into a failing test that is really just out of date.
const unshipped = ["cy", "is", "mt", "eu"].find((tag) => !UI_LANGUAGES.some((l) => l.tag === tag))!;
expect(resolveUiLanguage(unshipped)).toBe("en");
expect(resolveUiLanguage("xx-XX")).toBe("en");
});
it("carries the Beta flag until a person has signed the language off", () => {
// Not a completeness measure. A catalogue can be word-for-word finished
// and still read like a machine wrote it, which is what this marks.
const de = UI_LANGUAGES.find((l) => l.tag === "de");
expect(de?.beta).toBe(true);
expect(UI_LANGUAGES.find((l) => l.tag === "en")?.beta).toBeUndefined();
// Every shipped language except English is unreviewed, and stays marked
// until a person says otherwise.
for (const l of UI_LANGUAGES) {
if (l.tag === "en") expect(l.beta).toBeUndefined();
else expect(l.beta).toBe(true);
}
});
it("honours one that is", () => {
+1
View File
@@ -38,6 +38,7 @@ export interface UiLanguage {
export const UI_LANGUAGES: readonly UiLanguage[] = [
{ tag: "en", name: "English" },
{ tag: "de", name: "Deutsch", beta: true },
{ tag: "fr", name: "Français", beta: true },
];
/** Where to report a bad translation. Beta languages depend on it. */
+862
View File
@@ -0,0 +1,862 @@
import type { Catalog } from "@/lib/i18n";
/**
* French — generated by AI, and not reviewed by a native speaker.
*
* Same standing as the German catalogue, and the same honesty about it: this
* was written against the terminology French mail clients already use rather
* than invented, but "written carefully" and "correct" are different claims
* and only the first is being made. The app says so, the picker marks it Beta,
* and the setting carries a link for reporting what reads wrongly. That is the
* review process until somebody who speaks French signs it off.
*
* A string missing from here renders its English source, so this file can be
* incomplete without the app breaking. Deleting a bad entry is a valid fix.
*
* ── Decisions this file is consistent about ──────────────────────────────
*
* Register: **vous**, throughout, which follows the "Sie" decision made for
* German and for the same reason — ihasmail is as often a company's mail as
* somebody's own, and "tu" from software a workplace deployed is presumptuous
* in a way "vous" never is. Where a string can avoid the question it does
* ("Supprimer ce message ?" rather than "Voulez-vous supprimer…"), which is
* ordinary good French UI.
*
* French spacing: a narrow no-break space before « ? », « ! » and « : » is the
* typographic rule, and it is deliberately NOT used here. It is invisible in a
* diff, easy to lose in an editor, and a plain space is what every French
* webmail actually ships. Guillemets « » are used for quoted names, because
* those are visible and do read as wrong when missing.
*
* Terminology, fixed once so it cannot drift:
*
* Inbox Boîte de réception Archive (verb) archiver
* Drafts Brouillons Delete supprimer
* Sent Envoyés Move to déplacer vers
* Deleted Items Corbeille Reply répondre
* Junk / Spam Spam Reply all répondre à tous
* Folder Dossier Forward transférer
* Label Libellé Star suivi
* Conversation Conversation Read / unread lu / non lu
* Message Message Settings Paramètres
* Attachment Pièce jointe Signature Signature
* Contact Contact Identity Identité
*
* "Libellé" rather than leaving "Label" in English, which is the opposite of
* the German choice and deliberately so: Gmail established "Libellé" in French
* and a reader will find it there, whereas no German client translates it.
* The rule is "use what the reader will meet elsewhere", not "always translate"
* or "never".
*
* Product names are never translated: ihasmail, Stalwart, JMAP, Sieve, vCard.
*/
export const catalog: Catalog = {
strings: {
// ── Actions ────────────────────────────────────────────────────────
"Archive": "Archiver",
"Archive (e)": "Archiver (e)",
"Delete": "Supprimer",
"Delete (#)": "Supprimer (#)",
"Reply": "Répondre",
"Reply (r)": "Répondre (r)",
"Reply all": "Répondre à tous",
"Forward": "Transférer",
"Move to…": "Déplacer vers…",
"Move to (v)": "Déplacer vers (v)",
"Move to folder": "Déplacer vers un dossier",
"Move here": "Déplacer ici",
"Mark as read": "Marquer comme lu",
"Mark as read (Shift+I)": "Marquer comme lu (Maj+I)",
"Mark as unread": "Marquer comme non lu",
"Mark as unread (Shift+U)": "Marquer comme non lu (Maj+U)",
"Mark all as read": "Tout marquer comme lu",
"Mark all as read, incl. subfolders": "Tout marquer comme lu, sous-dossiers compris",
"Star": "Suivi",
"Labels": "Libellés",
"Labels (l)": "Libellés (l)",
"Label as": "Appliquer un libellé",
"Label…": "Libellé…",
"Compose": "Nouveau message",
"Compose message": "Rédiger un message",
"Send": "Envoyer",
"Send at": "Envoyer le",
"Cancel send": "Annuler l'envoi",
"Schedule send": "Programmer l'envoi",
"Save": "Enregistrer",
"Save & activate": "Enregistrer et activer",
"Save & close (Esc)": "Enregistrer et fermer (Échap)",
"Save as template": "Enregistrer comme modèle",
"Save draft now": "Enregistrer le brouillon maintenant",
"Cancel": "Annuler",
"Close": "Fermer",
"Done": "Terminé",
"Continue": "Continuer",
"Edit": "Modifier",
"Edit…": "Modifier…",
"Rename": "Renommer",
"Remove": "Retirer",
"Restore": "Restaurer",
"Retry": "Réessayer",
"Reload": "Recharger",
"Refresh": "Actualiser",
"Copy": "Copier",
"Copy email address": "Copier l'adresse e-mail",
"Download": "Télécharger",
"Download all": "Tout télécharger",
"Download (.eml)": "Télécharger (.eml)",
"Download latest as .eml": "Télécharger le plus récent en .eml",
"Upload": "Envoyer un fichier",
"Upload files…": "Envoyer des fichiers…",
"Print": "Imprimer",
"Print conversation": "Imprimer la conversation",
"Undo (Ctrl+Z)": "Annuler (Ctrl+Z)",
"Redo": "Rétablir",
"Dismiss": "Fermer",
"Discard changes": "Abandonner les modifications",
"Discard draft": "Supprimer le brouillon",
"Duplicate": "Dupliquer",
"Validate": "Vérifier",
"Revoke": "Révoquer",
"Turn off": "Désactiver",
"Clear": "Vider",
"Clear selection": "Annuler la sélection",
"Clear custom colour": "Retirer la couleur personnalisée",
"Select": "Sélectionner",
"Select all": "Tout sélectionner",
"Unsubscribe": "Se désabonner",
"Share…": "Partager…",
"Stop sharing": "Arrêter le partage",
"Open": "Ouvrir",
"Open in new tab": "Ouvrir dans un nouvel onglet",
"Open in calendar": "Ouvrir dans l'agenda",
"Back": "Retour",
"Back (u)": "Retour (u)",
"Back to list": "Retour à la liste",
"Back to my files": "Retour à mes fichiers",
"Go back to the list": "Revenir à la liste",
"Next": "Suivant",
"Previous": "Précédent",
"More": "Plus",
"More actions": "Autres actions",
"More options": "Autres options",
"Move up": "Monter",
"Move down": "Descendre",
"Drag to reorder": "Faire glisser pour réordonner",
"Right-click for options": "Clic droit pour les options",
// ── Mail ───────────────────────────────────────────────────────────
"Mail": "E-mail",
"Message": "Message",
"Messages": "Messages",
"Message body": "Corps du message",
"Message headers": "En-têtes du message",
"Message size": "Taille du message",
"Message-ID": "Message-ID",
"Original message": "Message d'origine",
"Delete this message": "Supprimer ce message",
"New message to this address": "Nouveau message à cette adresse",
"Conversation view": "Vue par conversation",
"Draft": "Brouillon",
"Unread": "Non lus",
"Unread only": "Non lus uniquement",
"All mail": "Tous les messages",
"Sender": "Expéditeur",
"Sender domain": "Domaine de l'expéditeur",
"Recipients": "Destinataires",
"From": "De",
"To": "À",
"Cc": "Cc",
"Bcc": "Cci",
"Subject": "Objet",
"Subject (optional)": "Objet (facultatif)",
"Body": "Corps",
"Body text": "Texte courant",
"Attach files": "Joindre des fichiers",
"Attach from Files": "Joindre depuis Fichiers",
"Remove attachment": "Retirer la pièce jointe",
"Has attachment": "Contient une pièce jointe",
"Has the words": "Contient les mots",
"Header name": "Nom de l'en-tête",
"Show headers": "Afficher les en-têtes",
"Show original": "Afficher l'original",
"Show details": "Afficher les détails",
"Show images": "Afficher les images",
"Remote images": "Images distantes",
"Remote images are blocked to protect your privacy.": "Les images distantes sont bloquées pour protéger votre vie privée.",
"Always from {email}": "Toujours de {email}",
"This looks like a mailing list.": "Ceci ressemble à une liste de diffusion.",
"This folder is empty": "Ce dossier est vide",
"This folder is empty.": "Ce dossier est vide.",
"Delete all spam now": "Supprimer tout le spam maintenant",
"Deleting spam is permanent — it does not go to Deleted Items first.": "La suppression du spam est définitive — il ne passe pas par la corbeille.",
"Keep in Inbox": "Conserver dans la boîte de réception",
"Newer (k)": "Plus récent (k)",
"Older (j)": "Plus ancien (j)",
"Open the next (older) conversation": "Ouvrir la conversation suivante (plus ancienne)",
"Open the previous (newer) conversation": "Ouvrir la conversation précédente (plus récente)",
"Loading conversation…": "Chargement de la conversation…",
"Important": "Important",
"Unverified": "Non vérifié",
"Priority": "Priorité",
"High": "Haute",
"Normal": "Normale",
"Low": "Basse",
"to {recipients}": "à {recipients}",
"From: {sender}": "De : {sender}",
"Waiting on the server — goes out {when}.": "En attente sur le serveur — envoi {when}.",
"Scheduled — click to clear the schedule": "Programmé — cliquez pour annuler la programmation",
"Nothing scheduled": "Rien de programmé",
"The message waits on the server, so it goes out whether or not ihasmail is open.": "Le message attend sur le serveur : il part que ihasmail soit ouvert ou non.",
"This server holds a message for up to {span}.": "Ce serveur conserve un message jusqu'à {span}.",
"Date and time to send": "Date et heure d'envoi",
"Undo send window": "Délai d'annulation d'envoi",
"Read receipt requested": "Accusé de réception demandé",
"The sender asked for a read receipt.": "L'expéditeur a demandé un accusé de réception.",
"Request read receipt": "Demander un accusé de réception",
"Always request read receipts": "Toujours demander un accusé de réception",
"Receipt": "Accusé",
"Never send one": "Ne jamais en envoyer",
"Not this time": "Pas cette fois",
"It would go to {address}, which is not where the message came from.": "Il irait à {address}, qui n'est pas l'origine du message.",
"Use “Show original” for the complete raw message.": "Utilisez « Afficher l'original » pour le message brut complet.",
// ── Folders, calendar, contacts, files ─────────────────────────────
"Folder": "Dossier",
"Folders": "Dossiers",
"Folder options": "Options du dossier",
"New folder": "Nouveau dossier",
"New subfolder": "Nouveau sous-dossier",
"Delete folder": "Supprimer le dossier",
"No matching folders": "Aucun dossier correspondant",
"No subfolders here.": "Aucun sous-dossier ici.",
"Type a folder name…": "Saisissez un nom de dossier…",
" New folder…": " Nouveau dossier…",
"Create, rename and hide folders.": "Créer, renommer et masquer des dossiers.",
"Show unsubscribed (hidden) folders": "Afficher les dossiers non abonnés (masqués)",
"Storage: {used} of {total} used.": "Stockage : {used} utilisés sur {total}.",
"{used} of {total}": "{used} sur {total}",
"Calendar": "Agenda",
"My calendars": "Mes agendas",
"New calendar": "Nouvel agenda",
"Calendar options": "Options de l'agenda",
"Calendar & contacts": "Agenda et contacts",
"Calendar is not available": "L'agenda n'est pas disponible",
"Event": "Événement",
"New event": "Nouvel événement",
"(new event)": "(nouvel événement)",
"New all-day event": "Nouvel événement sur la journée",
"Add title": "Ajouter un titre",
"Add location": "Ajouter un lieu",
"Add to calendar": "Ajouter à l'agenda",
"Add to my calendar": "Ajouter à mon agenda",
"Remove from calendar": "Retirer de l'agenda",
"Remove from my calendar": "Retirer de mon agenda",
"All day": "Journée entière",
"all-day": "journée entière",
"Starts": "Début",
"Starts (optional)": "Début (facultatif)",
"Ends": "Fin",
"Ends (optional)": "Fin (facultatif)",
"Day": "Jour",
"Week": "Semaine",
"Month": "Mois",
"Agenda": "Planning",
"Today": "Aujourd'hui",
"Go to day": "Aller au jour",
"Go to week": "Aller à la semaine",
"Previous month": "Mois précédent",
"Next month": "Mois suivant",
"Does not repeat": "Ne se répète pas",
"Daily": "Tous les jours",
"Every weekday": "Chaque jour de semaine",
"Yearly": "Tous les ans",
"Custom…": "Personnalisé…",
"Weekly on {weekday}": "Toutes les semaines le {weekday}",
"Monthly on day {day}": "Tous les mois le {day}",
"Repeat every": "Répéter tous les",
"Repeat until": "Répéter jusqu'au",
"after N times": "après N fois",
"on date": "à une date",
"never": "jamais",
"day(s)": "jour(s)",
"week(s)": "semaine(s)",
"month(s)": "mois",
"year(s)": "an(s)",
"Reminders": "Rappels",
"Add reminder": "Ajouter un rappel",
"Remove reminder": "Retirer le rappel",
"Default reminder": "Rappel par défaut",
"At time of event": "À l'heure de l'événement",
"5 minutes before": "5 minutes avant",
"10 minutes before": "10 minutes avant",
"15 minutes before": "15 minutes avant",
"30 minutes before": "30 minutes avant",
"1 hour before": "1 heure avant",
"1 day before": "1 jour avant",
"15 minutes": "15 minutes",
"30 minutes": "30 minutes",
"45 minutes": "45 minutes",
"1 hour": "1 heure",
"1.5 hours": "1 h 30",
"2 hours": "2 heures",
"Default event length": "Durée par défaut d'un événement",
"Default view": "Vue par défaut",
"Guests": "Participants",
"Add guests by name or email": "Ajouter des participants par nom ou e-mail",
"Send invitation emails to guests": "Envoyer les invitations par e-mail aux participants",
"Going?": "Vous participez ?",
"Yes": "Oui",
"No": "Non",
"Maybe": "Peut-être",
"Confirmed": "Confirmé",
"Tentative": "Provisoire",
"Cancelled": "Annulé",
"organizer": "organisateur",
"Organizer: {name}": "Organisateur : {name}",
"Free": "Disponible",
"Busy": "Occupé",
"Free/busy": "Disponibilité",
"Show as": "Afficher comme",
"Availability on {date}": "Disponibilité le {date}",
"Count all events as busy": "Compter tous les événements comme occupé",
"Only events I'm attending": "Uniquement les événements auxquels je participe",
"Don't include in availability": "Ne pas inclure dans la disponibilité",
"Meeting link": "Lien de réunion",
"No events in the next 60 days.": "Aucun événement dans les 60 prochains jours.",
"Working hours": "Heures de travail",
"Working hours start": "Début des heures de travail",
"Working hours end": "Fin des heures de travail",
"Colour categories": "Catégories de couleur",
"Category": "Catégorie",
"No category": "Aucune catégorie",
"New category": "Nouvelle catégorie",
"Delete category": "Supprimer la catégorie",
"Manage categories…": "Gérer les catégories…",
"Use category color": "Utiliser la couleur de la catégorie",
"Use calendar color": "Utiliser la couleur de l'agenda",
"Use the default colour": "Utiliser la couleur par défaut",
"+{n} more": "+{n} autres",
"Contacts": "Contacts",
"Contacts are not available": "Les contacts ne sont pas disponibles",
"New contact": "Nouveau contact",
"Edit contact": "Modifier le contact",
"Select a contact": "Sélectionner un contact",
"All contacts": "Tous les contacts",
"Search contacts": "Rechercher des contacts",
"Search contacts to add…": "Rechercher des contacts à ajouter…",
"Loading contacts…": "Chargement des contacts…",
"Add to contacts": "Ajouter aux contacts",
"Add to my contacts": "Ajouter à mes contacts",
"Remove from my contacts": "Retirer de mes contacts",
"Address book": "Carnet d'adresses",
"Address books": "Carnets d'adresses",
"All address books": "Tous les carnets d'adresses",
"My address books": "Mes carnets d'adresses",
"New address book": "Nouveau carnet d'adresses",
"No address books yet.": "Aucun carnet d'adresses pour le moment.",
"Choose from address books": "Choisir dans les carnets d'adresses",
"Import vCard": "Importer une vCard",
"Export all": "Tout exporter",
"Export book": "Exporter le carnet",
"Email group": "Écrire au groupe",
"Email everyone": "Écrire à tous",
"Members": "Membres",
"Members ({count})": "Membres ({count})",
"Group": "Groupe",
"· group": "· groupe",
"Person": "Personne",
"First name": "Prénom",
"Last name": "Nom",
"Middle name": "Deuxième prénom",
"More name fields": "Autres champs de nom",
"Nickname": "Surnom",
"Prefix": "Civilité",
"Suffix": "Suffixe",
"Dr.": "Dr",
"Jr.": "Jr",
"Display name": "Nom affiché",
"Job title": "Fonction",
"Organization": "Organisation",
"Company": "Société",
"Birthday": "Anniversaire",
"Notes": "Notes",
"Website": "Site web",
"Phone": "Téléphone",
"Add phone": "Ajouter un téléphone",
"Add email": "Ajouter un e-mail",
"Add address": "Ajouter une adresse",
"Address": "Adresse",
"Street": "Rue",
"City": "Ville",
"State / Region": "État / Région",
"Postal code": "Code postal",
"Country": "Pays",
"Change photo": "Changer la photo",
"Remove photo": "Retirer la photo",
"Updated {date}": "Mis à jour le {date}",
"Modified": "Modifié",
"Search names and addresses": "Rechercher noms et adresses",
"Add a person or group…": "Ajouter une personne ou un groupe…",
"Choose recipients": "Choisir les destinataires",
"Available to add": "Disponibles à ajouter",
"vCard": "vCard",
"vCard attachment": "Pièce jointe vCard",
"Files": "Fichiers",
"My files": "Mes fichiers",
"File storage is not available": "Le stockage de fichiers n'est pas disponible",
"Drag files here or use Upload.": "Déposez des fichiers ici ou utilisez « Envoyer un fichier ».",
"Shared": "Partagé",
"Shared with me": "Partagés avec moi",
"Nothing is shared with you.": "Rien n'est partagé avec vous.",
"Not shared with anyone yet.": "Pas encore partagé.",
"Check for new shares": "Rechercher de nouveaux partages",
"Shared files are copied to your account when attached.": "Les fichiers partagés sont copiés dans votre compte lorsqu'ils sont joints.",
"Viewer": "Lecture",
"Editor": "Modification",
"Size": "Taille",
"Add files": "Ajouter des fichiers",
"Minimize": "Réduire",
// ── Settings ───────────────────────────────────────────────────────
"Settings": "Paramètres",
"All settings": "Tous les paramètres",
"Sections": "Sections",
"General": "Général",
"Appearance": "Apparence",
"Make ihasmail yours.": "Faites de ihasmail le vôtre.",
"Reading": "Lecture",
"Reading pane": "Volet de lecture",
"Reading, sending and list behaviour. Settings are stored in this browser.": "Comportement de lecture, d'envoi et de liste. Les paramètres sont enregistrés dans ce navigateur.",
"Right of the list": "À droite de la liste",
"Below the list": "Sous la liste",
"Hidden (open full width)": "Masqué (ouvrir en pleine largeur)",
"Off (open messages full width)": "Désactivé (messages en pleine largeur)",
"Off": "Désactivé",
"Composing": "Rédaction",
"Default format": "Format par défaut",
"Rich text (HTML)": "Texte enrichi (HTML)",
"Plain text": "Texte brut",
"Quote original message in replies": "Citer le message d'origine dans les réponses",
"Place signature above quoted text": "Placer la signature au-dessus du texte cité",
"Attachment reminder": "Rappel de pièce jointe",
"Warn when the message mentions an attachment but none is attached.": "Avertir lorsque le message mentionne une pièce jointe alors qu'aucune n'est jointe.",
"Spell check while typing": "Vérification orthographique pendant la saisie",
"Confirm before deleting": "Confirmer avant de supprimer",
"Show message snippets": "Afficher un aperçu des messages",
"Preview the first line of each message in the list.": "Afficher la première ligne de chaque message dans la liste.",
"Show sender avatars": "Afficher les avatars des expéditeurs",
"Group messages from the same thread together.": "Regrouper les messages d'un même fil.",
"After archiving or deleting": "Après archivage ou suppression",
"Ask before showing (recommended)": "Demander avant d'afficher (recommandé)",
"Always (all messages)": "Toujours (tous les messages)",
"Show automatically from my contacts": "Afficher automatiquement pour mes contacts",
"Immediately when opened": "Dès l'ouverture",
"After 2 seconds": "Après 2 secondes",
"After 5 seconds": "Après 5 secondes",
"Never automatically": "Jamais automatiquement",
"When someone requests a read receipt": "Lorsqu'un accusé de réception est demandé",
"Ask me on each message": "Me demander pour chaque message",
"5 seconds": "5 secondes",
"8 seconds": "8 secondes",
"15 seconds": "15 secondes",
"30 seconds": "30 secondes",
"Locale": "Régional",
"Language": "Langue",
"Interface language": "Langue de l'interface",
"Language & region": "Langue et région",
"Date format": "Format de date",
"Time format": "Format d'heure",
"Time zone": "Fuseau horaire",
"Week starts on": "La semaine commence le",
"Monday": "Lundi",
"Tuesday": "Mardi",
"Wednesday": "Mercredi",
"Thursday": "Jeudi",
"Friday": "Vendredi",
"Saturday": "Samedi",
"Sunday": "Dimanche",
"12-hour clock (6:23 PM)": "Format 12 heures (6:23 PM)",
"24-hour clock (18:23)": "Format 24 heures (18:23)",
"Browser default ({zone})": "Valeur du navigateur ({zone})",
"Default ({zone})": "Par défaut ({zone})",
"Automatic ({example})": "Automatique ({example})",
"Automatic ({locale})": "Automatique ({locale})",
"Automatic": "Automatique",
"Preview: {example}": "Aperçu : {example}",
"Dates, times and month names follow this choice.": "Les dates, heures et noms de mois suivent ce choix.",
"Your mail server reports {name} ({tag}).": "Votre serveur de messagerie indique {name} ({tag}).",
"Your mail server does not report a locale, so the browser's is used.": "Votre serveur de messagerie n'indique aucune langue ; celle du navigateur est utilisée.",
"Dates": "Dates",
"Date": "Date",
"Time": "Heure",
"When": "Quand",
"Then": "Alors",
"then": "alors",
"Theme": "Thème",
"Accent color": "Couleur d'accentuation",
"Color": "Couleur",
"Colour": "Couleur",
"Text color": "Couleur du texte",
"Density & text": "Densité et texte",
"Display density": "Densité d'affichage",
"Comfortable": "Confortable",
"Cozy (default)": "Équilibrée (par défaut)",
"Compact": "Compacte",
"Text size": "Taille du texte",
"Font size": "Taille de police",
"Small": "Petite",
"Medium": "Moyenne",
"Large": "Grande",
"Huge": "Très grande",
"Sidebar": "Barre latérale",
"Show labels in the sidebar": "Afficher les libellés dans la barre latérale",
"Collapse sidebar to icons": "Réduire la barre latérale en icônes",
"Apply the theme to messages too": "Appliquer le thème aux messages",
"Swiping": "Balayage",
"Swipe left": "Balayer vers la gauche",
"Swipe right": "Balayer vers la droite",
"Backup": "Sauvegarde",
"Export settings": "Exporter les paramètres",
"Import settings": "Importer des paramètres",
"Settings imported": "Paramètres importés",
"Invalid settings file": "Fichier de paramètres invalide",
"Reset to defaults": "Rétablir les valeurs par défaut",
"Default mail app": "Application de messagerie par défaut",
"Documentation": "Documentation",
"About ihasmail": "À propos de ihasmail",
"About": "À propos",
"Server": "Serveur",
"Server capabilities": "Fonctionnalités du serveur",
"Accounts": "Comptes",
"Account": "Compte",
"Max upload": "Envoi maximal",
"{size} MB": "{size} Mo",
"KB": "Ko",
"Image privacy proxy": "Proxy de confidentialité des images",
"enabled": "activé",
"disabled": "désactivé",
"Enabled": "Activé",
"active": "actif",
"hidden": "masqué",
"connected": "connecté",
"reconnecting…": "reconnexion…",
"AGPL-3.0 source": "Code source AGPL-3.0",
// ── Identities, templates, filters ─────────────────────────────────
"Identities & signatures": "Identités et signatures",
"Add identity": "Ajouter une identité",
"Delete identity": "Supprimer l'identité",
"Make default": "Définir par défaut",
"Default": "Par défaut",
"Show when composing": "Afficher lors de la rédaction",
"Hide when composing": "Masquer lors de la rédaction",
"Signature": "Signature",
"Your signature…": "Votre signature…",
"Reply-To": "Répondre à",
"Reply-To (optional)": "Répondre à (facultatif)",
"Reply-To: {addresses}": "Répondre à : {addresses}",
"Replies go to…": "Les réponses vont à…",
"Set a Reply-To address": "Définir une adresse de réponse",
"{email} is now your default identity": "{email} est désormais votre identité par défaut",
"Templates": "Modèles",
"New template": "Nouveau modèle",
"Delete template": "Supprimer le modèle",
"Insert template": "Insérer un modèle",
"Template text…": "Texte du modèle…",
"Subject: {subject}": "Objet : {subject}",
"Filters & rules": "Filtres et règles",
"Filters unavailable": "Filtres indisponibles",
"Rules": "Règles",
"Rule name": "Nom de la règle",
"New rule": "Nouvelle règle",
"Delete rule": "Supprimer la règle",
"No filters yet": "Aucun filtre pour le moment",
"Add condition": "Ajouter une condition",
"Remove condition": "Retirer la condition",
"Add action": "Ajouter une action",
"Remove action": "Retirer l'action",
"all of the following match": "toutes les conditions suivantes",
"any of the following match": "l'une des conditions suivantes",
"contains": "contient",
"does not contain": "ne contient pas",
"is": "est",
"is not": "n'est pas",
"matches (wildcards * ?)": "correspond à (jokers * ?)",
"does not match": "ne correspond pas à",
"matches regex": "correspond à l'expression régulière",
"does not match regex": "ne correspond pas à l'expression régulière",
"exists": "existe",
"does not exist": "n'existe pas",
"is larger than": "est plus grand que",
"is smaller than": "est plus petit que",
"Stop processing more rules": "Arrêter le traitement des règles suivantes",
"keep copy": "conserver une copie",
"Forward to": "Transférer à",
"Reject with message": "Rejeter avec un message",
"Scripts": "Scripts",
"Scripts (advanced)": "Scripts (avancé)",
"Script name": "Nom du script",
"New script": "Nouveau script",
"Delete script": "Supprimer le script",
"Sieve source": "Source Sieve",
"Preview generated Sieve script": "Aperçu du script Sieve généré",
"Start with rules": "Commencer avec des règles",
"Switch to rules?": "Passer aux règles ?",
"Create filter": "Créer un filtre",
"Filter messages like this": "Filtrer les messages de ce type",
"Filter messages like this…": "Filtrer les messages de ce type…",
"Also apply to existing messages in": "Appliquer aussi aux messages existants dans",
"keyword (e.g. $important, work)": "mot-clé (par ex. $important, travail)",
"Other header…": "Autre en-tête…",
"Out of office": "Absence du bureau",
"Auto-reply enabled": "Réponse automatique activée",
// ── Security, sessions, notifications ──────────────────────────────
"Security & sessions": "Sécurité et sessions",
"Password": "Mot de passe",
"Your password": "Votre mot de passe",
"Current password": "Mot de passe actuel",
"New password": "Nouveau mot de passe",
"Confirm new password": "Confirmer le nouveau mot de passe",
"Current code": "Code actuel",
"Code from your authenticator": "Code de votre application d'authentification",
"Two-factor authentication": "Authentification à deux facteurs",
"Turn off two-factor authentication": "Désactiver l'authentification à deux facteurs",
"Your password alone will be enough to sign in again.": "Votre mot de passe seul suffira pour vous reconnecter.",
"App passwords": "Mots de passe d'application",
"New app password for": "Nouveau mot de passe d'application pour",
"Your new app password": "Votre nouveau mot de passe d'application",
"Secret": "Secret",
"Thunderbird on my laptop": "Thunderbird sur mon portable",
"Active webmail sessions": "Sessions webmail actives",
"Sign out": "Se déconnecter",
"Sign out here": "Se déconnecter ici",
"Sign out all other sessions": "Déconnecter toutes les autres sessions",
"Signed in as": "Connecté en tant que",
"This is my own device": "Cet appareil est le mien",
"this device": "cet appareil",
"Device": "Appareil",
"IP": "IP",
"Last active": "Dernière activité",
"Created": "Créé",
"Expires": "Expire",
"Status": "État",
"Online": "En ligne",
"Reason": "Motif",
"Type": "Type",
"Email or username": "E-mail ou nom d'utilisateur",
"Use your usual address as the username.": "Utilisez votre adresse habituelle comme nom d'utilisateur.",
"Fast, friendly webmail. Your mailbox, your way.": "Un webmail rapide et agréable. Votre boîte, à votre façon.",
"Notifications": "Notifications",
"Notifications are blocked in your browser settings.": "Les notifications sont bloquées dans les paramètres de votre navigateur.",
"Not supported in this browser.": "Non pris en charge par ce navigateur.",
"Desktop notifications while ihasmail is open": "Notifications système lorsque ihasmail est ouvert",
"Notify me even when ihasmail is closed": "Me notifier même lorsque ihasmail est fermé",
"Play a sound for new mail": "Émettre un son à l'arrivée d'un message",
"Test notification": "Tester la notification",
"Background notifications are on": "Les notifications en arrière-plan sont activées",
"The tab title and favicon always show your unread Inbox count.": "Le titre de l'onglet et le favicon indiquent toujours le nombre de messages non lus.",
"Live updates are delivered via JMAP push ({state}).": "Les mises à jour en direct passent par JMAP push ({state}).",
"Shows a system notification when new mail arrives in your Inbox while the tab is in the background.": "Affiche une notification système à l'arrivée d'un message dans votre boîte de réception lorsque l'onglet est en arrière-plan.",
// ── Editor, search, shortcuts, misc ────────────────────────────────
"Formatting": "Mise en forme",
"Formatting options": "Options de mise en forme",
"Remove formatting": "Supprimer la mise en forme",
"Bold (Ctrl+B)": "Gras (Ctrl+B)",
"Italic (Ctrl+I)": "Italique (Ctrl+I)",
"Underline (Ctrl+U)": "Souligné (Ctrl+U)",
"Strikethrough": "Barré",
"Highlight": "Surligner",
"Bulleted list": "Liste à puces",
"Numbered list": "Liste numérotée",
"Increase indent": "Augmenter le retrait",
"Decrease indent": "Diminuer le retrait",
"Align left": "Aligner à gauche",
"Align right": "Aligner à droite",
"Center": "Centrer",
"Quote": "Citation",
"Code block": "Bloc de code",
"Normal text": "Texte normal",
"Insert link (Ctrl+K)": "Insérer un lien (Ctrl+K)",
"Insert image": "Insérer une image",
"Link": "Lien",
"List": "Liste",
"Emoji": "Émoji",
"Write your message…": "Écrivez votre message…",
"Search": "Rechercher",
"Search mail": "Rechercher dans les messages",
"Advanced search": "Recherche avancée",
"Keyboard shortcuts": "Raccourcis clavier",
"Keyboard shortcuts (?)": "Raccourcis clavier (?)",
"Shortcuts": "Raccourcis",
"Go to": "Aller à",
"Menu": "Menu",
"Options": "Options",
"Send options": "Options d'envoi",
"Name": "Nom",
"Email": "E-mail",
"Email address": "Adresse e-mail",
"Description": "Description",
"Location": "Lieu",
"Visibility": "Visibilité",
"Private": "Privé",
"Work": "Professionnel",
"Loading…": "Chargement…",
"None": "Aucun",
"optional": "facultatif",
"Always show": "Toujours afficher",
"to": "à",
"Received": "Reçu",
"In-Reply-To": "In-Reply-To",
"References": "References",
"Add label / keyword": "Ajouter un libellé / mot-clé",
"Manage labels": "Gérer les libellés",
"Create “{name}”": "Créer « {name} »",
"Type a name to create your first label.": "Saisissez un nom pour créer votre premier libellé.",
"Labels are IMAP keywords stored on your messages, so they sync to other clients. Names and colours are kept in this browser.": "Les libellés sont des mots-clés IMAP enregistrés dans vos messages : ils se synchronisent donc avec les autres clients. Les noms et couleurs restent dans ce navigateur.",
"New label": "Nouveau libellé",
"Delete label": "Supprimer le libellé",
"PDF": "PDF",
"Large attachments may be rejected by some servers": "Les pièces jointes volumineuses peuvent être refusées par certains serveurs",
"Images are stored in your Files (folder “ihasmail”) and embedded when you send.": "Les images sont enregistrées dans vos Fichiers (dossier « ihasmail ») et intégrées à l'envoi.",
"Thanks for your message. I'm away until … and will reply when I'm back.": "Merci pour votre message. Je suis absent jusqu'au … et vous répondrai à mon retour.",
"Automatically reply to people who email you while you're away. Each sender gets at most one reply.": "Répondre automatiquement aux personnes qui vous écrivent pendant votre absence. Chaque expéditeur reçoit au plus une réponse.",
"Sort incoming mail automatically. Rules run on the server (Sieve), so they work for every client you use.": "Trier automatiquement le courrier entrant. Les règles s'exécutent sur le serveur (Sieve) et valent donc pour tous vos clients.",
"Canned responses you can insert into any message from the composer's template button.": "Des réponses toutes prêtes, insérables dans n'importe quel message depuis le bouton Modèles de l'éditeur.",
"Create a rule to move newsletters to a folder, flag important senders, or forward mail.": "Créez une règle pour classer les newsletters dans un dossier, signaler les expéditeurs importants ou transférer du courrier.",
"Advanced: manage raw Sieve scripts. Only one script can be active at a time.": "Avancé : gérer directement les scripts Sieve. Un seul script peut être actif à la fois.",
"Only part of your filter script arrived.": "Votre script de filtrage n'est arrivé que partiellement.",
"Your active script “{name}” was written by hand.": "Votre script actif « {name} » a été écrit à la main.",
"Another script (“{name}”) is active. Saving rules here will activate the “ihasmail” script instead.": "Un autre script (« {name} ») est actif. Enregistrer des règles ici activera le script « ihasmail » à la place.",
"“{name}” will be deactivated (not deleted) and a new “ihasmail” script will take over.": "« {name} » sera désactivé (non supprimé) et un nouveau script « ihasmail » prendra le relais.",
"Sieve filtering is not available for this account.": "Le filtrage Sieve n'est pas disponible pour ce compte.",
"Sieve filtering is not enabled for this account.": "Le filtrage Sieve n'est pas activé pour ce compte.",
"Vacation responses are not available for this account.": "Les réponses d'absence ne sont pas disponibles pour ce compte.",
"This account does not have the JMAP calendars capability.": "Ce compte ne dispose pas de la fonctionnalité JMAP Agendas.",
"This account does not have the JMAP contacts capability.": "Ce compte ne dispose pas de la fonctionnalité JMAP Contacts.",
"This account does not have the JMAP file storage capability.": "Ce compte ne dispose pas de la fonctionnalité JMAP Fichiers.",
// ── Labels held in constants, translated where they render ─────────
"Add": "Ajouter",
"Create subfolders": "Créer des sous-dossiers",
"Dark": "Sombre",
"Light": "Clair",
"Match system": "Suivre le système",
"Day.Month.Year": "Jour.Mois.Année",
"Day/Month/Year": "Jour/Mois/Année",
"Month/Day/Year": "Mois/Jour/Année",
"Year-Month-Day (ISO 8601)": "Année-Mois-Jour (ISO 8601)",
"Edit all": "Tout modifier",
"Edit contents": "Modifier le contenu",
"Edit own": "Modifier les siens",
"Flag": "Marquer",
"Mark read": "Marquer comme lu",
"Private props": "Propriétés privées",
"Read": "Lire",
"Read events": "Lire les événements",
"RSVP": "Répondre",
"See free/busy": "Voir la disponibilité",
"Share": "Partager",
"Write": "Écrire",
"Live updates connected": "Mises à jour en direct connectées",
"Live updates reconnecting…": "Reconnexion des mises à jour en direct…",
"Live updates off — checking periodically instead": "Mises à jour en direct désactivées — vérification périodique à la place",
"Mark as read / unread": "Marquer comme lu / non lu",
"Star / unstar": "Suivre / ne plus suivre",
"Report spam / not spam": "Signaler comme spam / non-spam",
"Report spam": "Signaler comme spam",
"Not spam": "Non-spam",
"Nothing": "Rien",
"Later today": "Plus tard aujourd'hui",
"Tomorrow morning": "Demain matin",
"Tomorrow afternoon": "Demain après-midi",
"Monday morning": "Lundi matin",
"Deleted Items": "Corbeille",
"Open draft": "Ouvrir le brouillon",
"Undo": "Annuler",
"Choose a date": "Choisir une date",
"Choose a date and time": "Choisir une date et une heure",
"Pick date and time…": "Choisir date et heure…",
"After": "Après",
"Before": "Avant",
// ── Folder names shown for a JMAP role (see lib/mailboxName.ts) ────
"folder\u0004Inbox": "Boîte de réception",
"folder\u0004Archive": "Archives",
"folder\u0004Drafts": "Brouillons",
"folder\u0004Sent": "Envoyés",
"folder\u0004Deleted Items": "Corbeille",
"folder\u0004Junk Mail": "Spam",
"folder\u0004Important": "Important",
"folder\u0004All mail": "Tous les messages",
"folder": "dossier",
"“{name}” moved into “{parent}”": "« {name} » a été déplacé dans « {parent} »",
"“{name}” moved to the top level": "« {name} » a été déplacé au niveau supérieur",
"Could not move “{name}”: {reason}": "Impossible de déplacer « {name} » : {reason}",
"Delete “{name}”?": "Supprimer « {name} » ?",
"Rename folder": "Renommer le dossier",
"Search: {query}": "Recherche : {query}",
"No conversation selected": "Aucune conversation sélectionnée",
"Drop here for the top level": "Déposer ici pour le niveau supérieur",
// ── Longer prose ───────────────────────────────────────────────────
"Search mail (from:, to:, subject:, has:attachment, is:unread, in:, before:, after:)": "Rechercher dans les messages (from:, to:, subject:, has:attachment, is:unread, in:, before:, after:)",
"Settings → Filters & rules": "Paramètres → Filtres et règles",
"Open the Mail view to see all shortcuts.": "Ouvrez la vue E-mail pour voir tous les raccourcis.",
"Gmail-style shortcuts are always on. Press {key} anywhere to see this list.": "Les raccourcis façon Gmail sont toujours actifs. Appuyez sur {key} n'importe où pour afficher cette liste.",
"Select a conversation to read it here · Press {key} for shortcuts": "Sélectionnez une conversation pour la lire ici · {key} pour les raccourcis",
"Tip: press {key} on a conversation to apply labels. Search with {operator}.": "Astuce : appuyez sur {key} sur une conversation pour appliquer des libellés. Recherchez avec {operator}.",
"A fast, friendly, open-source webmail for {server}, built on JMAP.": "Un webmail libre, rapide et agréable pour {server}, bâti sur JMAP.",
"Defaults for the calendar views and new events.": "Valeurs par défaut des vues d'agenda et des nouveaux événements.",
"Replies will go to this address instead of the From address": "Les réponses iront à cette adresse plutôt qu'à l'adresse d'expédition",
"Replies to mail sent from this identity go here instead of the From address.": "Les réponses aux messages envoyés depuis cette identité arrivent ici plutôt qu'à l'adresse d'expédition.",
"New identities must use an address this account is allowed to send from (aliases configured on the server).": "Une nouvelle identité doit utiliser une adresse depuis laquelle ce compte est autorisé à envoyer (alias configurés sur le serveur).",
"Not offered when composing. It still receives mail, and you can still send from it by showing it again.": "Non proposée lors de la rédaction. L'adresse reçoit toujours du courrier, et vous pouvez de nouveau envoyer depuis elle en la réaffichant.",
"Each identity is a sender address with its own name, Reply-To and signature. The default identity is preselected when you compose; set a Reply-To when replies should go somewhere other than the From address.": "Chaque identité est une adresse d'expédition avec son propre nom, sa propre adresse de réponse et sa propre signature. L'identité par défaut est présélectionnée à la rédaction ; définissez une adresse de réponse lorsque les réponses doivent arriver ailleurs qu'à l'adresse d'expédition.",
"This signature is larger than the server's {limit}-byte limit. ihasmail will keep the full version in your Files and store a short text fallback on the server — other mail clients will see the plain-text version.": "Cette signature dépasse la limite de {limit} octets du serveur. ihasmail conservera la version complète dans vos Fichiers et enregistrera une version texte courte sur le serveur — les autres clients verront la version en texte brut.",
"Outlook-style categories you can assign to events from the right-click menu or the event editor. The category name is stored on the event, so it syncs to other clients.": "Des catégories façon Outlook, attribuables aux événements depuis le menu contextuel ou l'éditeur d'événement. Le nom de la catégorie est enregistré dans l'événement et se synchronise donc avec les autres clients.",
"Plain-text mail already follows the theme. With this on, HTML mail that brings no colours of its own does as well, instead of sitting on a white card. Messages that style themselves are left exactly as the sender designed them.": "Les messages en texte brut suivent déjà le thème. Avec cette option, les messages HTML sans couleurs propres le suivent aussi, au lieu de s'afficher sur un fond blanc. Les messages qui définissent leur propre style restent exactement tels que l'expéditeur les a conçus.",
"This is separate from {setting} in General, which decides how dates, times and numbers are written. You can read an English interface with German dates, or the other way round.": "Ceci est indépendant de {setting} dans Général, qui détermine l'écriture des dates, heures et nombres. Vous pouvez lire une interface anglaise avec des dates françaises, ou l'inverse.",
"On a touchscreen, drag a message sideways to act on it. Each direction can do one thing, or nothing. These follow your account, so a phone and a tablet agree; a mouse ignores them and keeps dragging messages into folders instead.": "Sur un écran tactile, faites glisser un message sur le côté pour agir dessus. Chaque direction peut faire une chose, ou rien. Ces réglages suivent votre compte : téléphone et tablette sont donc d'accord. À la souris, ils sont ignorés et le glisser-déposer vers les dossiers continue de fonctionner.",
"This screen has no touchscreen, so nothing here changes what it does. Your phone or tablet will pick these up.": "Cet écran n'est pas tactile : rien ici ne change son comportement. Votre téléphone ou votre tablette reprendra ces réglages.",
"Holding a message selects it, and holding a folder opens its menu. Pull the top of the message list down to check for new mail.": "Un appui long sur un message le sélectionne, un appui long sur un dossier ouvre son menu. Tirez le haut de la liste vers le bas pour relever le courrier.",
"A receipt tells whoever asked that this address is live and when the message was read, and the sender chooses where it goes — so there is no automatic option. Bulk mail, mailing lists and anything marked auto-submitted are never offered one at all.": "Un accusé indique au demandeur que cette adresse est active et à quel moment le message a été lu, et l'expéditeur choisit où il est envoyé — il n'y a donc pas d'option automatique. Le courrier de masse, les listes de diffusion et tout ce qui est marqué comme envoyé automatiquement n'en obtiennent jamais.",
"This browser cannot register apps for {scheme} links. Safari, in particular, has no such API — you can still make ihasmail the default from your operating system if you install it as an app.": "Ce navigateur ne peut pas enregistrer d'applications pour les liens {scheme}. Safari, en particulier, n'a pas d'interface pour cela — vous pouvez tout de même définir ihasmail par défaut depuis votre système d'exploitation en l'installant comme application.",
"Registering for {scheme} links requires a secure (HTTPS) connection.": "L'enregistrement pour les liens {scheme} nécessite une connexion sécurisée (HTTPS).",
"Open {scheme} links — in web pages, documents and other apps — in ihasmail instead of a desktop mail client. Your browser will ask you to confirm, and you can change it later in its own settings (Chrome: Settings Privacy and security Site settings Protocol handlers; Firefox: Settings General Applications).": "Ouvrir les liens {scheme} — dans les pages web, les documents et les autres applications — avec ihasmail plutôt qu'avec un client de messagerie local. Votre navigateur vous demandera de confirmer, et vous pourrez le modifier plus tard dans ses propres paramètres (Chrome : Paramètres Confidentialité et sécurité Paramètres des sites Gestionnaires de protocole ; Firefox : Paramètres Général Applications).",
"Requested in this browser. Whether it took effect is up to the browser — check its settings if mail links still open elsewhere.": "Demandé dans ce navigateur. C'est à lui de décider si cela a pris effet — vérifiez ses paramètres si les liens de messagerie s'ouvrent toujours ailleurs.",
"For a system-wide default, install ihasmail as an app first (in Chrome: the install icon in the address bar). Your operating system can then offer ihasmail directly wherever it asks which mail app to use.": "Pour un réglage valable dans tout le système, installez d'abord ihasmail comme application (dans Chrome : l'icône d'installation dans la barre d'adresse). Votre système pourra alors proposer ihasmail directement partout où il demande quelle application de messagerie utiliser.",
"Needs a browser with the Push API and a mail server that publishes a push key.": "Nécessite un navigateur doté de l'API Push et un serveur de messagerie publiant une clé push.",
"Your mail server delivers these straight to your browser, so they arrive with no ihasmail tab open, naming the sender and subject. Your browser still has to be running — if you quit it completely, notifications wait and arrive when you open it again.": "Votre serveur les remet directement à votre navigateur : elles arrivent donc sans onglet ihasmail ouvert, avec l'expéditeur et l'objet. Votre navigateur doit tout de même être en cours d'exécution — si vous le quittez complètement, les notifications attendent et arrivent à sa réouverture.",
"Your mail server can wake this browser, but will not include the sender or subject. Your browser still has to be running.": "Votre serveur peut réveiller ce navigateur, mais sans indiquer l'expéditeur ni l'objet. Votre navigateur doit tout de même être en cours d'exécution.",
"This is what a new-mail notification looks like.": "Voici à quoi ressemble une notification de nouveau message.",
"You're signed in as {user}. Your password is never stored in the browser; the server keeps it encrypted per-session for talking to Stalwart.": "Vous êtes connecté en tant que {user}. Votre mot de passe n'est jamais enregistré dans le navigateur ; le serveur le conserve chiffré, par session, pour dialoguer avec Stalwart.",
"App passwords are managed by your mail administrator.": "Les mots de passe d'application sont gérés par votre administrateur de messagerie.",
"Changing your password signs out your other webmail sessions. Any app passwords keep working.": "Changer votre mot de passe déconnecte vos autres sessions webmail. Les mots de passe d'application continuent de fonctionner.",
"This account has two-factor authentication on. ihasmail can't sign you in with a code yet, so signing in on another device needs an app password — or you can turn two-factor authentication off here.": "L'authentification à deux facteurs est activée sur ce compte. ihasmail ne sait pas encore vous connecter avec un code : la connexion sur un autre appareil nécessite donc un mot de passe d'application — ou vous pouvez désactiver l'authentification à deux facteurs ici.",
"A separate password for a mail app or device, which you can revoke on its own. App passwords skip two-factor codes, so they keep working in apps that can't ask for one.": "Un mot de passe distinct pour une application ou un appareil, révocable indépendamment. Les mots de passe d'application contournent les codes à deux facteurs et fonctionnent donc dans les applications qui ne peuvent pas en demander.",
"Copy it into {name} now — it isn't shown again.": "Copiez-le dans {name} maintenant — il ne sera plus affiché.",
"No other users found in the directory, so nobody new can be added. Sharing already in place is listed below and can still be removed.": "Aucun autre utilisateur trouvé dans l'annuaire : personne de nouveau ne peut être ajouté. Les partages déjà en place sont listés ci-dessous et restent supprimables.",
"Stalwart does not publish its version number to mail clients, so ihasmail reports the edition where the server gives one. ihasmail requires 0.16 or newer, and sign-in refuses anything older.": "Stalwart ne communique pas son numéro de version aux clients de messagerie ; ihasmail indique donc l'édition lorsque le serveur en fournit une. ihasmail requiert la version 0.16 ou ultérieure, et la connexion refuse toute version antérieure.",
"It {damage}, so the rules in it can't be shown or edited — saving what did arrive would write it back over the rest. Reload the page to try again. Your rules are still on the server; nothing here has changed them.": "Il {damage} : les règles qu'il contient ne peuvent donc être ni affichées ni modifiées — enregistrer ce qui est arrivé écraserait le reste. Rechargez la page pour réessayer. Vos règles sont toujours sur le serveur ; rien ici ne les a modifiées.",
"The visual rule editor only manages scripts it created. You can edit the script in the {tab} tab, or start fresh with rules (the existing script will be kept but deactivated).": "L'éditeur visuel de règles ne gère que les scripts qu'il a créés. Vous pouvez modifier le script dans l'onglet {tab}, ou repartir de zéro avec des règles (le script existant sera conservé mais désactivé).",
"Your filter script {damage}, so only part of it arrived. Adding a rule would write that part back over the whole thing. Reload the page and try again.": "Votre script de filtrage {damage} : il n'est arrivé que partiellement. Ajouter une règle écraserait l'ensemble par cette partie. Rechargez la page et réessayez.",
"Your filter script couldn't be read just now, so adding a rule would risk overwriting it. Reload the page and try again.": "Votre script de filtrage n'a pas pu être lu à l'instant ; ajouter une règle risquerait de l'écraser. Rechargez la page et réessayez.",
"Your active Sieve script was written by hand, so rules can't be added automatically. Open {where} to edit the script or switch to managed rules.": "Votre script Sieve actif a été écrit à la main : les règles ne peuvent donc pas être ajoutées automatiquement. Ouvrez {where} pour modifier le script ou passer aux règles gérées.",
"Only languages ihasmail has been translated into appear here, so this list grows as translations land rather than ahead of them — a language offered without strings behind it would leave the page claiming to be in a language it is not.": "Seules les langues dans lesquelles ihasmail a été traduit apparaissent ici : la liste s'allonge donc à mesure que les traductions arrivent, et non avant — une langue proposée sans textes derrière elle ferait prétendre à la page qu'elle est dans une langue qui n'est pas la sienne.",
"tell us about it": "signalez-le-nous",
"This translation was generated by AI and has not been checked by a native speaker, so it is marked Beta until somebody who speaks it signs it off. Anything that reads wrongly is worth reporting — {report}.": "Cette traduction a été générée par une IA et n'a pas été relue par une personne de langue maternelle française ; elle est donc marquée Beta jusqu'à validation. Tout ce qui sonne faux mérite d'être signalé — {report}.",
"{name} is the palette from {site}, and what a new account starts on. It is a dark theme, so it counts as dark wherever that matters, and the accent colour below still applies on top of it.": "{name} est la palette de {site}, et celle d'un nouveau compte. C'est un thème sombre : il compte donc comme sombre partout où cela importe, et la couleur d'accentuation ci-dessous s'y applique toujours.",
"ihasmail's own version is the date of the commit it was built from, followed by where that commit came from: {example} was built from a commit dated the 30th of August 2026 that arrived through pull request 129. A commit that did not come through one carries its short SHA instead — {sha}. The version deliberately says nothing about Stalwart; what this build needs from the server is the line above.": "La version de ihasmail est la date du commit à partir duquel elle a été construite, suivie de l'origine de ce commit : {example} provient d'un commit daté du 30 août 2026 arrivé via la pull request 129. Un commit qui n'est pas passé par là porte à la place son SHA court — {sha}. La version ne dit délibérément rien de Stalwart ; ce dont cette build a besoin du serveur figure à la ligne ci-dessus.",
},
plurals: {
"{n} messages": { one: "{n} message", other: "{n} messages" },
"{n} selected": { one: "{n} sélectionné", other: "{n} sélectionnés" },
"{n} conversations": { one: "{n} conversation", other: "{n} conversations" },
},
};
+15 -6
View File
@@ -2,6 +2,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import { applyLang, DEFAULT_SETTINGS } from "@/store/settings";
import { UI_LANGUAGES } from "@/lib/languages";
/**
* `<html lang>` has to be right *before first paint*, not after mount.
@@ -34,15 +35,23 @@ describe("applyLang", () => {
expect(document.documentElement.lang).toBe("en");
});
it("serves a language whose catalogue is shipped", () => {
applyLang({ ...DEFAULT_SETTINGS, uiLanguage: "de" });
expect(document.documentElement.lang).toBe("de");
it("serves every language whose catalogue is shipped", () => {
for (const l of UI_LANGUAGES) {
applyLang({ ...DEFAULT_SETTINGS, uiLanguage: l.tag });
expect(document.documentElement.lang).toBe(l.tag);
}
});
it("falls back to English rather than claiming a language it cannot render", () => {
// A tag no catalogue exists for -- an account carrying a preference from a
// build that shipped more languages than this one.
applyLang({ ...DEFAULT_SETTINGS, uiLanguage: "fr" });
/*
* The tag is derived, not written down. Naming a real language here means
* the test breaks the day that language ships -- which it did, twice, for
* German and then French, each time reporting a failure that was really
* the test being out of date.
*/
const unshipped = ["cy", "is", "mt", "eu"].find((tag) => !UI_LANGUAGES.some((l) => l.tag === tag));
expect(unshipped).toBeDefined();
applyLang({ ...DEFAULT_SETTINGS, uiLanguage: unshipped! });
expect(document.documentElement.lang).toBe("en");
});