diff --git a/src/UI/UIDesktop.js b/src/UI/UIDesktop.js index a351cc0e..1a2da3a0 100644 --- a/src/UI/UIDesktop.js +++ b/src/UI/UIDesktop.js @@ -1217,7 +1217,7 @@ $(document).on('click', '.user-options-menu-btn', async function(e){ message: `
${i18n('confirm_open_apps_log_out')}
`, buttons:[ { - label: i18n('close_all_Windows_and_log_out'), + label: i18n('close_all_windows_and_log_out'), value: 'close_and_log_out', type: 'primary', }, diff --git a/src/UI/UIItem.js b/src/UI/UIItem.js index 01219ec6..996611e6 100644 --- a/src/UI/UIItem.js +++ b/src/UI/UIItem.js @@ -783,7 +783,7 @@ function UIItem(options){ // Donwload // ------------------------------------------- menu_items.push({ - html: i18n('Download'), + html: i18n('download'), onClick: async function(){ let items = []; for (let index = 0; index < $selected_items.length; index++) { @@ -987,7 +987,7 @@ function UIItem(options){ ) ){ const alert_resp = await UIAlert({ - message: `${i18n('change_allways_open_with')} ` + html_encode(suggested_app.title) + '?', + message: `${i18n('change_always_open_with')} ` + html_encode(suggested_app.title) + '?', body_icon: suggested_app.icon, buttons:[ { @@ -1113,11 +1113,11 @@ function UIItem(options){ }); } // ------------------------------------------- - // Donwload + // Download // ------------------------------------------- if(!is_trash && !is_trashed && (options.associated_app_name === null || options.associated_app_name === undefined)){ menu_items.push({ - html: i18n('Download'), + html: i18n('download'), disabled: options.is_dir && !window.feature_flags.download_directory, onClick: async function(){ if(options.is_dir) diff --git a/src/UI/UIPrompt.js b/src/UI/UIPrompt.js index f30f43a8..7d48f72c 100644 --- a/src/UI/UIPrompt.js +++ b/src/UI/UIPrompt.js @@ -38,7 +38,7 @@ function UIPrompt(options){ if(!options.buttons || options.buttons.length === 0){ options.buttons = [ {label: i18n('cancel'), value: false, type: 'default'}, - {label: i18n('OK'), value: true, type: 'primary'}, + {label: i18n('ok'), value: true, type: 'primary'}, ] } @@ -53,7 +53,7 @@ function UIPrompt(options){ if(options.buttons && options.buttons.length > 0){ h += ` `; } diff --git a/src/UI/UIWindow.js b/src/UI/UIWindow.js index 26863d52..88ead0f4 100644 --- a/src/UI/UIWindow.js +++ b/src/UI/UIWindow.js @@ -1956,7 +1956,7 @@ async function UIWindow(options) { if (window.user.is_temp && !await UIWindowSaveAccount({ send_confirmation_code: true, - message: i18n('save_account_to_publish_website'), + message: i18n('save_account_to_publish'), window_options: { backdrop: true, close_on_backdrop_click: false, diff --git a/src/UI/UIWindowFontPicker.js b/src/UI/UIWindowFontPicker.js index f4208b14..517e8152 100644 --- a/src/UI/UIWindowFontPicker.js +++ b/src/UI/UIWindowFontPicker.js @@ -60,7 +60,7 @@ async function UIWindowFontPicker(options){ h += ``; // Select - h += `` + h += `` h += ``; h += ``; h += ``; diff --git a/src/UI/UIWindowUploadProgress.js b/src/UI/UIWindowUploadProgress.js index e436fc74..23c5d5ec 100644 --- a/src/UI/UIWindowUploadProgress.js +++ b/src/UI/UIWindowUploadProgress.js @@ -41,7 +41,7 @@ async function UIWindowUploadProgress(options){ h += ``; const el_window = await UIWindow({ - title: i18n('Upload'), + title: i18n('upload'), icon: window.icons[`app-icon-uploader.svg`], uid: null, is_dir: false, diff --git a/src/i18n/translations/br.js b/src/i18n/translations/br.js index ae8ca572..40ccc905 100644 --- a/src/i18n/translations/br.js +++ b/src/i18n/translations/br.js @@ -39,7 +39,7 @@ const br = { change_username: "Alterar Nome de Utilizador", close_all_windows: "Fechar Todas as Janelas", close_all_windows_and_log_out: 'Fechar Janelas e Sair', - change_allways_open_with: "Quer sempre abrir arquivos deste tipo com", + change_always_open_with: "Quer sempre abrir arquivos deste tipo com", color: 'Cor', confirm_account_for_free_referral_storage_c2a: 'Crie uma conta e confirme o endereço do email para receber 1 GB de armazenamento gratuito. Seu amigo receberá 1 GB de armazenamento gratuito também.', confirm_delete_multiple_items: 'Quer apagar estes itens permanentemente?', diff --git a/src/i18n/translations/en.js b/src/i18n/translations/en.js index 19433f55..5375cde5 100644 --- a/src/i18n/translations/en.js +++ b/src/i18n/translations/en.js @@ -34,12 +34,13 @@ const en = { cancel: 'Cancel', center: 'Center', change_desktop_background: 'Change desktop background…', + change_email: "Change Email", change_language: "Change Language", change_password: "Change Password", change_username: "Change Username", close_all_windows: "Close All Windows", close_all_windows_and_log_out: 'Close Windows and Log Out', - change_allways_open_with: "Do you want to always open this type of file with", + change_always_open_with: "Do you want to always open this type of file with", color: 'Color', confirm_account_for_free_referral_storage_c2a: 'Create an account and confirm your email address to receive 1 GB of free storage. Your friend will get 1 GB of free storage too.', confirm_delete_multiple_items: 'Are you sure you want to permanently delete these items?', @@ -47,6 +48,7 @@ const en = { confirm_open_apps_log_out: 'You have open apps. Are you sure you want to log out?', confirm_new_password: "Confirm New Password", confirm_delete_user: "Are you sure you want to delete your account? All your files and data will be permanently deleted. This action cannot be undone.", + confirm_delete_user_title: "Delete Account?", contact_us: "Contact Us", contain: 'Contain', continue: "Continue", @@ -86,6 +88,7 @@ const en = { feedback: "Feedback", feedback_c2a: "Please use the form below to send us your feedback, comments, and bug reports.", feedback_sent_confirmation: "Thank you for contacting us. If you have an email associated with your account, you will hear back from us as soon as possible.", + fit: "Fit", forgot_pass_c2a: "Forgot password?", from: "From", general: "General", @@ -94,6 +97,7 @@ const en = { hide_all_windows: "Hide All Windows", html_document: 'HTML document', image: 'Image', + incorrect_password: "Incorrect password", invite_link: "Invite Link", item: 'item', items_in_trash_cannot_be_renamed: `This item can't be renamed because it's in the trash. To rename this item, first drag it out of the Trash.`, diff --git a/src/i18n/translations/nb.js b/src/i18n/translations/nb.js index 5d361085..6fdc67e4 100644 --- a/src/i18n/translations/nb.js +++ b/src/i18n/translations/nb.js @@ -36,7 +36,7 @@ const nb = { change_username: "Endre brukernavn", close_all_windows: "Lukk alle vinduer", close_all_windows_and_log_out: 'Lukk alle vinduer og logg ut', - change_allways_open_with: "Ønsker du å alltid åpne denne filtypen med", + change_always_open_with: "Ønsker du å alltid åpne denne filtypen med", color: "Farge", confirm_account_for_free_referral_storage_c2a: "Opprett en konto og bekreft e-postadressen din for å motta 1 GB gratis lagringsplass. Din venn vil også få 1 GB gratis lagringsplass.", confirm_delete_multiple_items: 'Er du sikker på at du vil slette disse elementene permanent?', diff --git a/src/i18n/translations/nl.js b/src/i18n/translations/nl.js index 1591147d..de53dd04 100644 --- a/src/i18n/translations/nl.js +++ b/src/i18n/translations/nl.js @@ -39,7 +39,7 @@ const nl = { change_username: "Gebruikersnaam veranderen", close_all_windows: "Alle schermen sluiten", close_all_windows_and_log_out: 'Alle schermen sluiten en afmelden', - change_allways_open_with: "Dit type bestand altijd openen met", + change_always_open_with: "Dit type bestand altijd openen met", color: 'Kleur', confirm_account_for_free_referral_storage_c2a: 'Maak een account en bevestig uw emailadres om 1 GB aan gratis opslag te ontvangen. Uw vriend krijgt ook 1 GB aan gratis opslag.', confirm_delete_multiple_items: 'Weet u zeker dat u deze bestanden permanent wilt verwijderen?', diff --git a/src/i18n/translations/pl.js b/src/i18n/translations/pl.js index c12d30b6..74628cb2 100644 --- a/src/i18n/translations/pl.js +++ b/src/i18n/translations/pl.js @@ -36,7 +36,7 @@ const pl = { change_username: "Zmień użytkownika", close_all_windows: "Zamknij wszystkie okna", close_all_windows_and_log_out: 'Zamknij wszystkie okna i wyloguj', - change_allways_open_with: "Czy chcesz zawsze otwierać ten typ pliku używając", + change_always_open_with: "Czy chcesz zawsze otwierać ten typ pliku używając", color: 'Kolor', confirm_account_for_free_referral_storage_c2a: 'Stwórz konto i potwierdź swój adres e-mail, żeby dostać 1 GB darmowego miejsca. Twój znajomy również dostanie 1 GB darmowego miejsca.', confirm_delete_multiple_items: 'Czy na pewno chcesz na zawsze usunąć te przedmioty?', diff --git a/src/i18n/translations/pt.js b/src/i18n/translations/pt.js index 3835939d..0d346828 100644 --- a/src/i18n/translations/pt.js +++ b/src/i18n/translations/pt.js @@ -39,7 +39,7 @@ const pt = { change_username: "Alterar o Nome de Utilizador", close_all_windows: "Fechar Todas as Janelas", close_all_windows_and_log_out: 'Fechar Janelas e Sair', - change_allways_open_with: "Queres que ficheiros deste tipo abram sempre com", + change_always_open_with: "Queres que ficheiros deste tipo abram sempre com", color: 'Cor', confirm_account_for_free_referral_storage_c2a: 'Cria uma conta e confirma o endereço do email para receber 1 GB de armazenamento gratuito. O teu amigo também receberá 1 GB de armazenamento gratuito.', confirm_delete_multiple_items: 'Tens a certeza que queres apagar estes itens permanentemente?', diff --git a/tools/check-translations.js b/tools/check-translations.js index b718ec63..f5f45b38 100644 --- a/tools/check-translations.js +++ b/tools/check-translations.js @@ -53,6 +53,7 @@ async function checkTranslationRegistrations() { } } +// Ensure that translations only contain keys that exist in the en dictionary function checkTranslationKeys() { const enDictionary = translations.en.dictionary; @@ -71,8 +72,40 @@ function checkTranslationKeys() { } } +// Ensure that all keys passed to i18n() exist in the en dictionary +async function checkTranslationUsage() { + const enDictionary = translations.en.dictionary; + + const sourceDirectories = [ + './src/helpers', + './src/UI', + ]; + + // Looks for i18n() calls using either ' or " for the key string. + // The key itself is at index 2 of the result. + const i18nRegex = /i18n\((['"])(.*?)\1\)/g; + + for (const dir of sourceDirectories) { + const files = await fs.promises.readdir(dir, { recursive: true }); + for (const relativeFileName of files) { + if (!relativeFileName.endsWith('.js')) continue; + const fileName = `${dir}/${relativeFileName}`; + + const fileContents = await fs.promises.readFile(fileName, { encoding: 'utf8' }); + const i18nUses = fileContents.matchAll(i18nRegex); + for (const use of i18nUses) { + const key = use[2]; + if (!enDictionary.hasOwnProperty(key)) { + reportError(`Unrecognized i18n key: call ${use[0]} in ${fileName}`); + } + } + } + } +} + await checkTranslationRegistrations(); checkTranslationKeys(); +await checkTranslationUsage(); if (hadError) { process.stdout.write('Errors were found in translation files.\n');