diff --git a/.gitmodules b/.gitmodules index ebc30a0..a438bef 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "common/modules/CommonCss"] path = common/modules/CommonCss url = https://github.com/TinyWebEx/CommonCss +[submodule "common/modules/Localizer"] + path = common/modules/Localizer + url = https://github.com/TinyWebEx/Localizer diff --git a/_locales/en/messages.json b/_locales/en/messages.json new file mode 100644 index 0000000..6b48746 --- /dev/null +++ b/_locales/en/messages.json @@ -0,0 +1,507 @@ +{ + // manifest.json + "extensionName": { + "message": "FileLink provider for Send", + "description": "Name of the extension." + }, + "extensionDescription": { + "message": "Securely encrypt and upload large attachments to any Send service instance (formerly Firefox Send).", + "description": "Description of the extension." + }, + "composeActionButtonTitle": { + "message": "Thunderbird Send, Add attachment to get started", + "description": "The title for the button, which opens the popup." + }, + "composeActionButtonLabel": { + "message": "Thunderbird Send", + "description": "The label for the button, which opens the popup." + }, + + // errors or other messages (mostly for settings) + "errorShowingMessage": { + "message": "Could not show this message.", + "description": "When there is an error when showing the error/info/…." + }, + "couldNotLoadOptions": { + "message": "Could not load settings.", + "description": "When one or all settings could not be loaded." + }, + "couldNotSaveOption": { + "message": "Could not save this setting.", + "description": "When a setting could not be saved." + }, + "messageUndoButton": { + "message": "Undo", + "description": "The text of a button that undoes the last action." + }, + "couldNotUndoAction": { + "message": "Could not undo action.", + "description": "Shown when an action cannot be undone." + }, + "resettingOptionsWorked": { + "message": "All settings are now back to defaults again!", + "description": "The message shown, when the options of the settings were reset." + }, + "resettingOptionsFailed": { + "message": "Could not reset options!", + "description": "The message shown, when the options of the settings could not have been reset." + }, + + // options + "someSettingsAreManaged": { + "message": "Some settings are managed by your system administrator and cannot be changed.", + "description": "The message, which appears, when settings are pre-defined (as managed options) by administrators." + }, + "optionIsDisabledBecauseManaged": { + "message": "This option is disabled, because it has been configured by your system administrator.", + "description": "The title (tooltip) shown, when hovering over a disabled, managed option." + }, + "optionLearnMore": { + "message": "Learn more", + "description": "When a link to an explainer needs to be added, this is the link text." + }, + "optionsResetButton": { + "message": "Reset all settings to defaults", + "description": "The button to delete all current settings and load the defaults, shown in the add-on settings." + }, + + // options footer + "translatorCredit": { + "message": "This add-on has been translated into English by $TRANSLATORS$.", + "description": "The credit text for the translator. See https://github.com/TinyWebEx/common/blob/master/CONTRIBUTING.md#translator-credit-inside-of-add-on for how to translate this.", + "placeholders": { + "translators": { + "content": "$1", + "example": "@rugk" + } + } + }, + "translatorLink": { + "message": "https://github.com/tdulcet", + "description": "The link to the translator's GitHub profile." + }, + "translatorUsername": { + "message": "Teal Dulcet", + "description": "The username that the translator wants to be referred to." + }, + + // ARIA labels/descriptions + "dismissIconDescription": { + "message": "Close this message", + "description": "the aria label for the close button of the message box" + }, + "ariaMessageLoading": { + "message": "loading message", + "description": "the aria label to label the message box as an info message box" + }, + "ariaMessageInfo": { + "message": "info message", + "description": "the aria label to label the message box as an info message box" + }, + "ariaMessageSuccess": { + "message": "success message", + "description": "the aria label to label the message box as an success message box" + }, + "ariaMessageError": { + "message": "error message", + "description": "the aria label to label the message box as an error message box" + }, + "ariaMessageWarning": { + "message": "warning message", + "description": "the aria label to label the message box as an warning message box" + }, + "infoButton": { + "message": "ℹ️ Information" + }, + "optionsButton": { + "message": "⚙️ Options" + }, + "donateButton": { + "message": "❤️ Donate" + }, + "resetButton": { + "message": "Reset all settings to defaults" + }, + "manageTitle": { + "message": "Account Settings" + }, + "manageNote": { + "message": "This is your account settings for the selected Thunderbird Send account. For the global options/preferences page, go to the Thunderbird 🧩 Add-ons manager or click the button above." + }, + "manageGetList": { + "message": "Click this link for a list of $link$ and their respective maximum file size.", + "placeholders": { + "link": { + "content": "$1" + } + } + }, + "manageListLinkText": { + "message": "public Send service instances" + }, + "manageService": { + "message": "Send service instance URL:" + }, + "manageVerifyButton": { + "message": "Verify" + }, + "manageDownloadLimit": { + "message": "Default download limit:" + }, + "manageDownloadLimitHelp": { + "message": "The files will expire after this number of downloads. Make sure it is less than the maximum downloads supported by this Send service instance." + }, + "manageTimeLimit": { + "message": "Default time limit:" + }, + "manageTimeLimitHelp": { + "message": "The files will expire after this time. Make sure it is less than the maximum time supported by this Send service instance." + }, + "manageDays": { + "message": "days" + }, + "manageHours": { + "message": "hours" + }, + "manageMinutes": { + "message": "minutes" + }, + "manageMaxSize": { + "message": "Maximum file size:" + }, + "manageMaxSizeHelp": { + "message": "Maximum file size supported by this Send service instance." + }, + "manageGiB": { + "message": "GiB" + }, + "manageSuccess": { + "message": "Send server verified!" + }, + "manageError": { + "message": "Unable to verify Send server" + }, + "popupFile": { + "message": "Filename:" + }, + "popupTotalSize": { + "message": "Total Size:" + }, + "popupSize": { + "message": "Size:" + }, + "popupDownloadLimit": { + "message": "Download limit:" + }, + "popupDownloadLimitDesc": { + "message": "The file will expire after this number of downloads. Make sure it is less than the maximum downloads supported by this Send service instance." + }, + "popupTimeLimit": { + "message": "Time limit:" + }, + "popupDays": { + "message": "days" + }, + "popupHours": { + "message": "hours" + }, + "popupMinutes": { + "message": "minutes" + }, + "popupTimeLimitDesc": { + "message": "The file will expire after this time. Make sure it is less than the maximum time supported by this Send service instance." + }, + "popupPwdProtect": { + "message": "Protect with password (click to add)" + }, + "popupPwdWarning": { + "message": "Use different methods to send the password and file to the recipients. Including the password in the same e-mail as the link to the file does not provide any additional security." + }, + "popupPassword": { + "message": "Optional password:" + }, + "popupPwdPlaceholder": { + "message": "Password" + }, + "popupPwdShow": { + "message": "Show password" + }, + "popupPwdHelp": { + "message": "Optionally protect the file with a password." + }, + "popupPwdPronunciation": { + "message": "Password pronunciation:" + }, + "popupPwdSuggest": { + "message": "Suggest strong password (click to show)" + }, + "popupPwdGenOpt1": { + "message": "Password with symbols (15 characters)" + }, + "popupPwdGenOpt1Title": { + "message": "Password with upper/lowercase letters, numbers and symbols" + }, + "popupPwdGenOpt2": { + "message": "Password (15 characters)" + }, + "popupPwdGenOpt2Title": { + "message": "Password with only upper/lowercase letters and numbers" + }, + "popupPwdGenOpt3": { + "message": "Passphrase, long words (6)" + }, + "popupPwdGenOpt3Title": { + "message": "Passphrase with long words up to 9 characters" + }, + "popupPwdGenOpt4": { + "message": "Passphrase, short words (8)" + }, + "popupPwdGenOpt4Title": { + "message": "Passphrase with short words up to 5 characters" + }, + "popupPwdGenOpt5": { + "message": "Emoji password with sequences (7)" + }, + "popupPwdGenOpt5Title": { + "message": "Emoji password with basic emoji and the family, role, gendered, hair and other sequences" + }, + "popupPwdGenOpt6": { + "message": "Emoji password (8)" + }, + "popupPwdGenOpt6Title": { + "message": "Emoji password with only the basic emoji" + }, + "popupPwdGenButton": { + "message": "🔒 Securely Generate" + }, + "popupUploadButton": { + "message": "📤 Encrypt and Upload" + }, + "popupCancelButton": { + "message": "❌ Cancel" + }, + "popupB": { + "message": "B" + }, + "optionsTitle": { + "message": "Options" + }, + "optionsNote": { + "message": "This is your global options/preferences for Thunderbird Send. For the account management pages, go to the Thunderbird ⚙️ Options/Preferences." + }, + "optionsNotifLabel": { + "message": "Display Desktop notifications" + }, + "optionsPopupLabel": { + "message": "Use compose action popups" + }, + "optionsPopupDesc": { + "message": "Use compose action popups in the compose window instead of standalone popup windows. Experimental and requires Thunderbird 115 or greater to automatically open the compose action popups." + }, + "optionsLinkLabel": { + "message": "Create link for Send service instance" + }, + "optionsLinkDesc": { + "message": "Adds a “Learn more about” link for the Send service instance to footer of messages." + }, + "notifInstallTitle": { + "message": "$name$ installed", + "placeholders": { + "name": { + "content": "$1" + } + } + }, + "notifInstallMessage": { + "message": "Thank you for installing the “$name$” add-on!\nVersion: $version$", + "placeholders": { + "name": { + "content": "$1" + }, + "version": { + "content": "$2" + } + } + }, + "notifUpdateTitle": { + "message": "$name$ updated", + "placeholders": { + "name": { + "content": "$1" + } + } + }, + "notifUpdateMessage": { + "message": "The “$name$” add-on has been updated to version $version$. Click to see the release notes.\n\n❤️ Huge thanks to the generous donors that have allowed me to continue to work on this extension!", + "placeholders": { + "name": { + "content": "$1" + }, + "version": { + "content": "$2" + } + } + }, + "notifUnsupportedVersionTitle": { + "message": "❌ Unsupported Send server version" + }, + "notifUnsupportedVersionMessage": { + "message": "Error: The “$service$” Send service instance has an unsupported server version: $version$. This extension requires at least version 3.", + "placeholders": { + "service": { + "content": "$1" + }, + "version": { + "content": "$2" + } + } + }, + "notifUnableVersionTitle": { + "message": "❌ Unable to determine Send server version" + }, + "notifUnableVersionMessage": { + "message": "Error: Unable to determine the “$service$” Send service instance server version. Please check your internet connection and settings.", + "placeholders": { + "service": { + "content": "$1" + } + } + }, + "notifOpenPopupTitle": { + "message": "ℹ️ Open compose action popup to continue" + }, + "notifOpenPopupMessage": { + "message": "The add-on was unable to open the popup directly, so please click the “Thunderbird Send” button in the compose window toolbar to continue." + }, + "notifUploadTitle": { + "message": "📤 Encrypting and uploading attachment" + }, + "notifUploadCancelTitle": { + "message": "❌ Upload of attachment aborted" + }, + "notifUploadCancelMessage": { + "message": "Upload of the “$filename$” file was aborted.", + "placeholders": { + "filename": { + "content": "$1" + } + } + }, + "notifUploadUnableTitle": { + "message": "❌ Unable upload attachment" + }, + "notifUploadUnableMessage": { + "message": "Error: Unable to upload the “$filename$” file: $error$. The download or time limit is likely above the maximum supported by this Send service instance.", + "placeholders": { + "filename": { + "content": "$1" + }, + "error": { + "content": "$2" + } + } + }, + "notifUnablePasswordTitle": { + "message": "❌ Unable add password to attachment" + }, + "notifUnablePasswordMessage": { + "message": "Error: Unable to add password to the “$filename$” file.", + "placeholders": { + "filename": { + "content": "$1" + } + } + }, + "notifUploadDoneTitle": { + "message": "🔗 Attachment encrypted and uploaded" + }, + "notifUploadDoneMessage": { + "message": "The “$filename$” file was successfully encrypted and uploaded in $time$! Expires after:", + "placeholders": { + "filename": { + "content": "$1" + }, + "time": { + "content": "$2" + } + } + }, + "notifUploadErrorMessage": { + "message": "Error: Unable to upload the “$filename$” file: $error$. Please check your internet connection.", + "placeholders": { + "filename": { + "content": "$1" + }, + "error": { + "content": "$2" + } + } + }, + "notifCancelAlreadyTitle": { + "message": "❌ Upload already canceled" + }, + "notifCancelAlreadyMessage": { + "message": "Error: Upload of the “$filename$” file was already canceled.", + "placeholders": { + "filename": { + "content": "$1" + } + } + }, + "notifUploadCancelingTitle": { + "message": "ℹ️ Canceling upload" + }, + "notifUploadCancelingMessage": { + "message": "Canceling upload of the “$filename$” file.", + "placeholders": { + "filename": { + "content": "$1" + } + } + }, + "notifNotFoundTitle": { + "message": "❌ Unable to find file" + }, + "notifNotFoundCancelMessage": { + "message": "Error: Unable to find file to cancel upload. It may have already been deleted." + }, + "notifNotFoundDeleteMessage": { + "message": "Error: Unable to find uploaded file to delete. It may have already been deleted." + }, + "notifDeletingTitle": { + "message": "ℹ️ Deleting file" + }, + "notifDeletingMessage": { + "message": "Deleting the “$filename$” uploaded file.", + "placeholders": { + "filename": { + "content": "$1" + } + } + }, + "notifDeleteSuccessTitle": { + "message": "🗑️ File deleted" + }, + "notifDeleteSuccessMessage": { + "message": "The “$filename$” uploaded file was successfully deleted.", + "placeholders": { + "filename": { + "content": "$1" + } + } + }, + "notifDeleteUnableTitle": { + "message": "❌ Unable delete file" + }, + "notifDeleteUnableMessage": { + "message": "Error: Unable to delete the “$filename$” uploaded file: $text$. It may have expired or already been deleted.", + "placeholders": { + "filename": { + "content": "$1" + }, + "text": { + "content": "$2" + } + } + } +} \ No newline at end of file diff --git a/_locales/fr/messages.json b/_locales/fr/messages.json new file mode 100644 index 0000000..aaef955 --- /dev/null +++ b/_locales/fr/messages.json @@ -0,0 +1,507 @@ +{ + // manifest.json + "extensionName": { + "message": "Fournisseur FileLink pour Send", + "description": "Name of the extension." + }, + "extensionDescription": { + "message": "Chiffrement et téléversement sécurisés de pièces jointes volumineuses sur une instance Send (anciennement Firefox Send).", + "description": "Description of the extension." + }, + "composeActionButtonTitle": { + "message": "Thunderbird Send - Ajouter une pièce jointe pour commencer", + "description": "The title for the button, which opens the popup." + }, + "composeActionButtonLabel": { + "message": "Thunderbird Send", + "description": "The label for the button, which opens the popup." + }, + + // errors or other messages (mostly for settings) + "errorShowingMessage": { + "message": "Impossible d’afficher ce message.", + "description": "When there is an error when showing the error/info/…." + }, + "couldNotLoadOptions": { + "message": "Impossible de charger les paramètres.", + "description": "When one or all settings could not be loaded." + }, + "couldNotSaveOption": { + "message": "Impossible d’enregistrer ce paramètre.", + "description": "When a setting could not be saved." + }, + "messageUndoButton": { + "message": "Annuler la réinitialisation", + "description": "The text of a button that undoes the last action." + }, + "couldNotUndoAction": { + "message": "Impossible d’annuler l’action.", + "description": "Shown when an action cannot be undone." + }, + "resettingOptionsWorked": { + "message": "Tous les paramètres sont maintenant rétablis à leurs valeurs par défaut !", + "description": "The message shown, when the options of the settings were reset." + }, + "resettingOptionsFailed": { + "message": "Impossible de réinitialiser les options !", + "description": "The message shown, when the options of the settings could not have been reset." + }, + + // options + "someSettingsAreManaged": { + "message": "Certains paramètres sont gérés par votre administrateur système et ne peuvent pas être modifiés.", + "description": "The message, which appears, when settings are pre-defined (as managed options) by administrators." + }, + "optionIsDisabledBecauseManaged": { + "message": "Cette option est désactivée car elle a été configurée par votre administrateur système.", + "description": "The title (tooltip) shown, when hovering over a disabled, managed option." + }, + "optionLearnMore": { + "message": "En savoir plus", + "description": "When a link to an explainer needs to be added, this is the link text." + }, + "optionsResetButton": { + "message": "Réinitialiser tous les paramètres", + "description": "The button to delete all current settings and load the defaults, shown in the add-on settings." + }, + + // options footer + "translatorCredit": { + "message": "Cette extension a été traduite en français par $TRANSLATORS$.", + "description": "The credit text for the translator. See https://github.com/TinyWebEx/common/blob/master/CONTRIBUTING.md#translator-credit-inside-of-add-on for how to translate this.", + "placeholders": { + "translators": { + "content": "$1", + "example": "@rugk" + } + } + }, + "translatorLink": { + "message": "https://github.com/denb10", + "description": "The link to the translator's GitHub profile." + }, + "translatorUsername": { + "message": "DenB", + "description": "The username that the translator wants to be referred to." + }, + + // ARIA labels/descriptions + "dismissIconDescription": { + "message": "Fermer ce message", + "description": "the aria label for the close button of the message box" + }, + "ariaMessageLoading": { + "message": "chargement du message", + "description": "the aria label to label the message box as an info message box" + }, + "ariaMessageInfo": { + "message": "message d’information", + "description": "the aria label to label the message box as an info message box" + }, + "ariaMessageSuccess": { + "message": "message de réussite", + "description": "the aria label to label the message box as an success message box" + }, + "ariaMessageError": { + "message": "message d’erreur", + "description": "the aria label to label the message box as an error message box" + }, + "ariaMessageWarning": { + "message": "message d’avertissement", + "description": "the aria label to label the message box as an warning message box" + }, + "infoButton": { + "message": "ℹ️ Informations" + }, + "optionsButton": { + "message": "⚙️ Options" + }, + "donateButton": { + "message": "❤️ Faire un don" + }, + "resetButton": { + "message": "Réinitialiser tous les paramètres" + }, + "manageTitle": { + "message": "Paramètres du compte" + }, + "manageNote": { + "message": "Configurez ici le compte Thunderbird Send sélectionné. Pour accéder aux options/préférences globales, cliquez sur le bouton ci-dessus ou allez dans le 🧩 Gestionnaire de modules complémentaires de Thunderbird." + }, + "manageGetList": { + "message": "Cliquez sur le lien pour consulter une liste d’$link$ et leurs limites supportées.", + "placeholders": { + "link": { + "content": "$1" + } + } + }, + "manageListLinkText": { + "message": "instances Send publiques" + }, + "manageService": { + "message": "URL de l’instance Send :" + }, + "manageVerifyButton": { + "message": "Vérifier" + }, + "manageDownloadLimit": { + "message": "Nombre limite de téléchargements par défaut :" + }, + "manageDownloadLimitHelp": { + "message": "Les liens expireront après ce nombre de téléchargements. Vérifiez qu’il est inférieur à la limite imposée par l’instance Send choisie." + }, + "manageTimeLimit": { + "message": "Validité des liens par défaut :" + }, + "manageTimeLimitHelp": { + "message": "Les liens expireront après ce délai. Vérifiez qu’il est inférieur à la limite imposée par l’instance Send choisie." + }, + "manageDays": { + "message": "jours" + }, + "manageHours": { + "message": "heures" + }, + "manageMinutes": { + "message": "minutes" + }, + "manageMaxSize": { + "message": "Taille de fichier maximale autorisée :" + }, + "manageMaxSizeHelp": { + "message": "Taille maximale de fichier acceptée par l’instance Send choisie." + }, + "manageGiB": { + "message": "Gio" + }, + "manageSuccess": { + "message": "Serveur Send vérifié" + }, + "manageError": { + "message": "Impossible de vérifier le serveur Send" + }, + "popupFile": { + "message": "Fichier :" + }, + "popupTotalSize": { + "message": "Taille totale :" + }, + "popupSize": { + "message": "Taille :" + }, + "popupDownloadLimit": { + "message": "Limite de téléchargement :" + }, + "popupDownloadLimitDesc": { + "message": "Le lien expirera après ce nombre de téléchargements. S’assurer que ce nombre est inférieur au nombre maximum de téléchargements autorisés par l’instance Send choisie." + }, + "popupTimeLimit": { + "message": "Délai de validité :" + }, + "popupDays": { + "message": "jours" + }, + "popupHours": { + "message": "heures" + }, + "popupMinutes": { + "message": "minutes" + }, + "popupTimeLimitDesc": { + "message": "Le lien expirera quand ce temps sera dépassé. S’assurer que ce délai est inférieur à la limite imposée par l’instance Send choisie." + }, + "popupPwdProtect": { + "message": "Protection par mot de passe (cliquer pour ajouter)" + }, + "popupPwdWarning": { + "message": "Utiliser des méthodes différentes pour envoyer le mot de passe et le fichier aux destinataires. Ajouter le mot de passe à l’e-mail contenant le lien vers le fichier n’apporte pas de sécurité supplémentaire." + }, + "popupPassword": { + "message": "Mot de passe (facultatif) :" + }, + "popupPwdPlaceholder": { + "message": "mot de passe" + }, + "popupPwdShow": { + "message": "Afficher" + }, + "popupPwdHelp": { + "message": "Il est possible de protéger le fichier par un mot de passe." + }, + "popupPwdPronunciation": { + "message": "Prononciation :" + }, + "popupPwdSuggest": { + "message": "Suggestion d’un mot de passe fort (cliquer pour afficher)" + }, + "popupPwdGenOpt1": { + "message": "Mot de passe avec symboles (15 caractères)" + }, + "popupPwdGenOpt1Title": { + "message": "Mot de passe avec des lettres majuscules et minuscules, des chiffres et des caractères spéciaux" + }, + "popupPwdGenOpt2": { + "message": "Mot de passe (15 caractères)" + }, + "popupPwdGenOpt2Title": { + "message": "Mot de passe avec uniquement des lettres majuscules et minuscules, et des chiffres" + }, + "popupPwdGenOpt3": { + "message": "Phrase secrète, mots longs (6)" + }, + "popupPwdGenOpt3Title": { + "message": "Phrase secrète avec des mots longs de 9 caractères au maximum" + }, + "popupPwdGenOpt4": { + "message": "Phrase secrète, mots courts (8)" + }, + "popupPwdGenOpt4Title": { + "message": "Phrase secrète avec des mots courts de 5 caractères au maximum" + }, + "popupPwdGenOpt5": { + "message": "Mot de passe emoji avec séquences (7)" + }, + "popupPwdGenOpt5Title": { + "message": "Mot de passe emoji composé des emojis de base et des séquences famille, rôle, genre, cheveux et autres" + }, + "popupPwdGenOpt6": { + "message": "Mot de passe emoji (8)" + }, + "popupPwdGenOpt6Title": { + "message": "Mot de passe emoji composé uniquement des emojis de base" + }, + "popupPwdGenButton": { + "message": "🔒 Générer en toute sécurité" + }, + "popupUploadButton": { + "message": "📤 Chiffrer et téléverser" + }, + "popupCancelButton": { + "message": "❌ Annuler" + }, + "popupB": { + "message": "o" + }, + "optionsTitle": { + "message": "Options" + }, + "optionsNote": { + "message": "Il s’agit de vos options/préférences globales pour Thunderbird Send. Pour configurer un compte, allez dans les ⚙️ Paramètres de Thunderbird." + }, + "optionsNotifLabel": { + "message": "Afficher les notifications" + }, + "optionsPopupLabel": { + "message": "Utiliser un panneau contextuel" + }, + "optionsPopupDesc": { + "message": "La fenêtre contextuelle séparée sera remplacée par un panneau contextuel dans la fenêtre de composition. Cette fonction est expérimentale." + }, + "optionsLinkLabel": { + "message": "Créer un lien vers l’instance Send" + }, + "optionsLinkDesc": { + "message": "Le lien « En savoir plus sur Send » sera ajouté au bas du message." + }, + "notifInstallTitle": { + "message": "$name$ installé", + "placeholders": { + "name": { + "content": "$1" + } + } + }, + "notifInstallMessage": { + "message": "Merci d’avoir installé l’extension « $name$ » !\nVersion : $version$", + "placeholders": { + "name": { + "content": "$1" + }, + "version": { + "content": "$2" + } + } + }, + "notifUpdateTitle": { + "message": "$name$ mis à jour", + "placeholders": { + "name": { + "content": "$1" + } + } + }, + "notifUpdateMessage": { + "message": "« $name$ » vient d’être mis à jour en version $version$. Cliquez pour voir les notes de version.\n\n❤️ Un grand merci aux généreux donateurs qui m’ont permis de poursuivre !", + "placeholders": { + "name": { + "content": "$1" + }, + "version": { + "content": "$2" + } + } + }, + "notifUnsupportedVersionTitle": { + "message": "❌ Version du serveur Send non supportée" + }, + "notifUnsupportedVersionMessage": { + "message": "Erreur : version de serveur de l’instance Send « $service$ » non supportée : $version$. Cette extension requiert au moins la version 3.", + "placeholders": { + "service": { + "content": "$1" + }, + "version": { + "content": "$2" + } + } + }, + "notifUnableVersionTitle": { + "message": "❌ Version de serveur Send impossible à déterminer" + }, + "notifUnableVersionMessage": { + "message": "Erreur : impossible de déterminer la version de serveur de l’instance Send « $service$ ». Veuillez vérifier votre connexion et vos paramètres internet", + "placeholders": { + "service": { + "content": "$1" + } + } + }, + "notifOpenPopupTitle": { + "message": "ℹ️ Ouvrir le panneau contextuel dans la fenêtre de composition pour continuer" + }, + "notifOpenPopupMessage": { + "message": "L’extension n’a pas pu ouvrir le panneau directement. Cliquez sur le bouton « Thunderbird Send » dans la barre d’outils de la fenêtre de composition pour continuer." + }, + "notifUploadTitle": { + "message": "📤 Chiffrement et téléversement de la pièce jointe" + }, + "notifUploadCancelTitle": { + "message": "❌ Abandon du téléversement de la pièce jointe" + }, + "notifUploadCancelMessage": { + "message": "Le téléversement du fichier « $filename$ » a été interrompu.", + "placeholders": { + "filename": { + "content": "$1" + } + } + }, + "notifUploadUnableTitle": { + "message": "❌ Téléversement de la pièce jointe impossible" + }, + "notifUploadUnableMessage": { + "message": "Erreur : impossible de téléverser le fichier « $filename$ » : $error$. La limite de téléchargement ou le délai de validité fixé dépasse probablement le maximum supporté par cette instance Send.", + "placeholders": { + "filename": { + "content": "$1" + }, + "error": { + "content": "$2" + } + } + }, + "notifUnablePasswordTitle": { + "message": "❌ Ajout du mot de passe à la pièce jointe impossible" + }, + "notifUnablePasswordMessage": { + "message": "Erreur : Impossible d’ajouter le mot de passe au fichier « $filename$ ».", + "placeholders": { + "filename": { + "content": "$1" + } + } + }, + "notifUploadDoneTitle": { + "message": "🔗 Pièce jointe chiffrée et téléversée" + }, + "notifUploadDoneMessage": { + "message": "Le fichier « $filename$ » a été chiffré et téléversé avec succès en $time$. Le lien expirera après :", + "placeholders": { + "filename": { + "content": "$1" + }, + "time": { + "content": "$2" + } + } + }, + "notifUploadErrorMessage": { + "message": "Erreur : impossible de téléverser le fichier « $filename$ » : $error. Veuillez vérifier votre connexion internet.", + "placeholders": { + "filename": { + "content": "$1" + }, + "error": { + "content": "$2" + } + } + }, + "notifCancelAlreadyTitle": { + "message": "❌ Téléversement déjà annulé" + }, + "notifCancelAlreadyMessage": { + "message": "Erreur : le téléversement du fichier « $filename$ » a déjà été annulé.", + "placeholders": { + "filename": { + "content": "$1" + } + } + }, + "notifUploadCancelingTitle": { + "message": "ℹ️ Annulation du téléversement" + }, + "notifUploadCancelingMessage": { + "message": "Annulation du téléversement du fichier « $filename$ ».", + "placeholders": { + "filename": { + "content": "$1" + } + } + }, + "notifNotFoundTitle": { + "message": "❌ Fichier introuvable" + }, + "notifNotFoundCancelMessage": { + "message": "Erreur : impossible de trouver le fichier dont le téléversement doit être annulé. Il se peut qu’il ait déjà été supprimé." + }, + "notifNotFoundDeleteMessage": { + "message": "Erreur : impossible de trouver le fichier téléversé à supprimer. Il se peut qu’il ait déjà été supprimé." + }, + "notifDeletingTitle": { + "message": "ℹ️ Suppression du fichier" + }, + "notifDeletingMessage": { + "message": "Suppression du fichier téléversé « $filename$ ».", + "placeholders": { + "filename": { + "content": "$1" + } + } + }, + "notifDeleteSuccessTitle": { + "message": "🗑️ Fichier supprimé" + }, + "notifDeleteSuccessMessage": { + "message": "Le fichier téléversé « $filename$ » a été supprimé avec succès.", + "placeholders": { + "filename": { + "content": "$1" + } + } + }, + "notifDeleteUnableTitle": { + "message": "❌ Suppression du fichier impossible" + }, + "notifDeleteUnableMessage": { + "message": "Erreur : impossible de supprimer le fichier téléversé « $filename$ » : $text$. Il se peut qu’il ait expiré ou qu’il ait déjà été supprimé.", + "placeholders": { + "filename": { + "content": "$1" + }, + "text": { + "content": "$2" + } + } + } +} diff --git a/background.js b/background.js index 6abe6a4..bbecd5f 100644 --- a/background.js +++ b/background.js @@ -4,7 +4,7 @@ import { BACKGROUND, POPUP, VERIFY, numberFormat, outputunit } from "/common.js" import * as AddonSettings from "/common/modules/AddonSettings/AddonSettings.js"; -const TITLE = "FileLink provider for Send"; +const TITLE = browser.i18n.getMessage("extensionName"); const NONCE_LENGTH = 12; const TAG_LENGTH = 16; @@ -523,13 +523,13 @@ async function checkServerVersion(service) { if (version?.startsWith("v") && Number.parseInt(version.slice(1).split(".")[0], 10) >= 3) { return true; } - notification("❌ Unsupported Send server version", `Error: The “${service}” Send service instance has an unsupported server version: ${version}. This extension requires at least version 3.`); + notification(browser.i18n.getMessage("notifUnsupportedVersionTitle"), browser.i18n.getMessage("notifUnsupportedVersionMessage", [service, version])); return false; } const text = await response.text(); console.error(text); - notification("❌ Unable to determine Send server version", `Error: Unable to determine the “${service}” Send service instance server version. Please check your internet connection and settings.`); + notification(browser.i18n.getMessage("notifUnableVersionTitle"), browser.i18n.getMessage("notifUnableVersionMessage", service)); return false; } @@ -598,7 +598,7 @@ async function uploaded(account, fileInfo, tab, relatedFileInfo) { await browser.composeAction.openPopup().catch((error) => { console.error(error); - notification("ℹ️ Open compose action popup to continue", "The add-on was unable to open the popup directly, so please click the “Thunderbird Send” button in the compose window toolbar to continue."); + notification(browser.i18n.getMessage("notifOpenPopupTitle"), browser.i18n.getMessage("notifOpenPopupMessage")); }); } @@ -678,7 +678,8 @@ async function uploaded(account, fileInfo, tab, relatedFileInfo) { return { aborted: true }; } - notification("📤 Encrypting and uploading attachment", `📛: ${file.name}\n⬆️: ${outputunit(file.size, false)}B${file.size >= 1000 ? ` (${outputunit(file.size, true)}B)` : ""}`); + const b = browser.i18n.getMessage("popupB"); + notification(browser.i18n.getMessage("notifUploadTitle"), `📛: ${file.name}\n⬆️: ${outputunit(file.size, false)}${b}${file.size >= 1000 ? ` (${outputunit(file.size, true)}${b})` : ""}`); const start = performance.now(); @@ -687,7 +688,7 @@ async function uploaded(account, fileInfo, tab, relatedFileInfo) { } if (upload.canceled) { - notification("❌ Upload of attachment aborted", `Upload of the “${file.name}” file was aborted.`); + notification(browser.i18n.getMessage("notifUploadCancelTitle"), browser.i18n.getMessage("notifUploadCancelMessage", file.name)); return { aborted: true }; } @@ -776,7 +777,7 @@ async function uploaded(account, fileInfo, tab, relatedFileInfo) { ws.send(JSON.stringify(fileMeta)); const uploadInfo = await uploadInfoResponse; if (uploadInfo.error) { - notification("❌ Unable upload attachment", `Error: Unable to upload the “${file.name}” file: ${uploadInfo.error}. The download or time limit is likely above the maximum supported by this Send service instance.`); + notification(browser.i18n.getMessage("notifUploadUnableTitle"), browser.i18n.getMessage("notifUploadUnableMessage", [file.name, uploadInfo.error])); return { error: true }; // throw new Error(uploadInfo.error); } @@ -816,7 +817,7 @@ async function uploaded(account, fileInfo, tab, relatedFileInfo) { if (upload.canceled) { console.timeEnd(id); - notification("❌ Upload of attachment aborted", `Upload of the “${file.name}” file was aborted.`); + notification(browser.i18n.getMessage("notifUploadCancelTitle"), browser.i18n.getMessage("notifUploadCancelMessage", file.name)); return { aborted: true }; } @@ -869,7 +870,7 @@ async function uploaded(account, fileInfo, tab, relatedFileInfo) { // console.log(response); if (!response.ok) { - notification("❌ Unable add password to attachment", `Error: Unable to add password to the “${file.name}” file.`); + notification(browser.i18n.getMessage("notifUnablePasswordTitle"), browser.i18n.getMessage("notifUnablePasswordMessage", file.name)); } } @@ -877,9 +878,9 @@ async function uploaded(account, fileInfo, tab, relatedFileInfo) { console.timeEnd(id); if (json.ok) { - notification("🔗 Attachment encrypted and uploaded", `The “${file.name}” file was successfully encrypted and uploaded in ${getSecondsAsDigitalClock(Math.floor((end - start) / 1000))}! Expires after:\n⬇️: ${numberFormat.format(upload.downloads)}\n⏲️: ${getSecondsAsDigitalClock(upload.time * 60)}\n\n${url}`); + notification(browser.i18n.getMessage("notifUploadDoneTitle"), `${browser.i18n.getMessage("notifUploadDoneMessage", getSecondsAsDigitalClock(Math.floor((end - start) / 1000)))}\n⬇️: ${numberFormat.format(upload.downloads)}\n⏲️: ${getSecondsAsDigitalClock(upload.time * 60)}\n\n${url}`); } else { - notification("❌ Unable upload attachment", `Error: Unable to upload the “${file.name}” file: ${json.error}. Please check your internet connection.`); + notification(browser.i18n.getMessage("notifUploadUnableTitle"), browser.i18n.getMessage("notifUploadErrorMessage", [file.name, json.error])); } const icon = `https://${aurl}/icon.718f87fb.svg`; @@ -915,13 +916,13 @@ function canceled(account, id/* , tab */) { const upload = uploads.get(id); if (upload) { if (upload.canceled) { - notification("❌ Upload already canceled", `Error: Upload of the “${upload.file.name}” file was already canceled.`); + notification(browser.i18n.getMessage("notifCancelAlreadyTitle"), browser.i18n.getMessage("notifCancelAlreadyMessage", upload.file.name)); } else { upload.canceled = true; - notification("ℹ️ Canceling upload", `Canceling upload of the “${upload.file.name}” file.`); + notification(browser.i18n.getMessage("notifUploadCancelingTitle"), browser.i18n.getMessage("notifUploadCancelingMessage", upload.file.name)); } } else { - notification("❌ Unable to find file", "Error: Unable to find file to cancel upload. It may have already been deleted."); + notification(browser.i18n.getMessage("notifNotFoundTitle"), browser.i18n.getMessage("notifNotFoundCancelMessage")); } } @@ -941,11 +942,11 @@ async function deleted(account, id/* , tab */) { aaccount = aaccount[account.id] || aaccount; const upload = uploads.get(id); if (!upload || !("id" in upload)) { - notification("❌ Unable to find file", "Error: Unable to find uploaded file to delete. It may have already been deleted."); + notification(browser.i18n.getMessage("notifNotFoundTitle"), browser.i18n.getMessage("notifNotFoundDeleteMessage")); return; } - notification("ℹ️ Deleting file", `Deleting the “${upload.file.name}” uploaded file.`); + notification(browser.i18n.getMessage("notifDeletingTitle"), browser.i18n.getMessage("notifDeletingMessage", upload.file.name)); const url = `https://${new URL(aaccount.service).host}/api/delete/${upload.id}`; const fetchInfo = { @@ -958,11 +959,11 @@ async function deleted(account, id/* , tab */) { // console.log(response); if (response.ok) { - notification("🗑️ File deleted", `The “${upload.file.name}” uploaded file was successfully deleted.`); + notification(browser.i18n.getMessage("notifDeleteSuccessTitle"), browser.i18n.getMessage("notifDeleteSuccessMessage", upload.file.name)); } else { const text = await response.text(); console.error(text); - notification("❌ Unable delete file", `Error: Unable to delete the “${upload.file.name}” uploaded file: ${text}. It may have expired or already been deleted.`); + notification(browser.i18n.getMessage("notifDeleteUnableTitle"), browser.i18n.getMessage("notifDeleteUnableMessage", [upload.file.name, text])); } uploads.delete(id); @@ -1062,15 +1063,15 @@ browser.runtime.onInstalled.addListener((details) => { const manifest = browser.runtime.getManifest(); switch (details.reason) { case "install": - notification(`🎉 ${manifest.name} installed`, `Thank you for installing the “${TITLE}” add-on!\nVersion: ${manifest.version}`); + notification(`🎉 ${browser.i18n.getMessage("notifInstallTitle", manifest.name)}`, browser.i18n.getMessage("notifInstallMessage", [TITLE, manifest.version])); break; case "update": if (SEND) { browser.notifications.create({ type: "basic", iconUrl: browser.runtime.getURL("icons/icon.svg"), - title: `✨ ${manifest.name} updated`, - message: `The “${TITLE}” add-on has been updated to version ${manifest.version}. Click to see the release notes.\n\n❤️ Huge thanks to the generous donors that have allowed me to continue to work on this extension!` + title: `✨ ${browser.i18n.getMessage("notifUpdateTitle", manifest.name)}`, + message: browser.i18n.getMessage("notifUpdateMessage", [TITLE, manifest.version]) }).then((notificationId) => { const url = `https://addons.thunderbird.net/thunderbird/addon/filelink-provider-for-send/versions/${manifest.version}`; notifications.set(notificationId, url); diff --git a/common/modules/Localizer b/common/modules/Localizer new file mode 160000 index 0000000..f6da4ca --- /dev/null +++ b/common/modules/Localizer @@ -0,0 +1 @@ +Subproject commit f6da4ca47caf7d4c93725363f2bbc994f1d655fd diff --git a/management/management.html b/management/management.html index 2563bf7..47ec48f 100644 --- a/management/management.html +++ b/management/management.html @@ -7,82 +7,81 @@ - +
-