소스 검색

feat: feature for english translation fallback values

Sv443 11 달 전
부모
커밋
c0e7c5a67a

+ 14 - 2
assets/translations/README.md

@@ -17,7 +17,7 @@ To submit or edit a translation, please follow [this guide](../../contributing.m
 |   | Locale | Translated keys | Based on |
 | :----: | ------ | --------------- | :------: |
 | ─ | [`en_US`](./en_US.json) | 213 (default locale) |  |
-| ✅ | [`de_DE`](./de_DE.json) | `213/213` (100%) | ─ |
+| ⚠ | [`de_DE`](./de_DE.json) | `207/213` (97.2%) | ─ |
 | ─ | [`en_UK`](./en_UK.json) | `213/213` (100%) | `en_US` |
 | ✅ | [`es_ES`](./es_ES.json) | `213/213` (100%) | ─ |
 | ✅ | [`fr_FR`](./fr_FR.json) | `213/213` (100%) | ─ |
@@ -44,4 +44,16 @@ This means to figure out which keys are untranslated, you will need to manually
 <br>
 
 ### Missing keys:
-No missing keys
+
+<details><summary><code>de_DE</code> - 6 missing keys <i>(click to show)</i></summary><br>
+
+| Key | English text |
+| --- | ------------ |
+| `config_menu_option` | `%1 Configuration` |
+| `config_menu_title` | `%1 - Configuration` |
+| `changelog_menu_title` | `%1 - Changelog` |
+| `export_menu_title` | `%1 - Export Configuration` |
+| `import_menu_title` | `%1 - Import Configuration` |
+| `open_menu_tooltip` | `Open %1's configuration menu` |
+
+<br></details>

+ 1 - 0
assets/translations/de_DE.json

@@ -220,6 +220,7 @@
     "feature_helptext_advancedLyricsFilter": "Erweiterte Filterung beinhaltet mehrere Schichten von Filtern, die darauf abzielen, die Songtext-Suchen zuverlässiger zu machen.\nDiese Filter funktionieren möglicherweise nicht gut für Songs in deiner Sprache und Songs und Künstler mit weniger eindeutigen Titeln im Allgemeinen.\nWarnung: Diese Funktion ist immer noch experimentell und könnte tatsächlich nicht besser funktionieren als die Standard-Songtext-Suche. Stelle sicher, dass du die Meldung bestätigst, die erscheint, wenn du diese Einstellung geändert hast.",
 
     "feature_desc_locale": "Sprache",
+    "feature_desc_localeFallback": "Verwende für fehlende Übersetzungen Englisch (deaktivieren, wenn du zu Übersetzungen beiträgst)",
     "feature_desc_versionCheck": "Prüfe alle 24 Stunden auf Updates",
     "feature_helptext_versionCheck": "Diese Funktion prüft alle 24 Stunden auf Updates, benachrichtigt dich, wenn eine neue Version verfügbar ist und ermöglicht es dir, das Skript manuell zu aktualisieren.\nWenn dein Userscript-Manager Skripte automatisch aktualisiert, kannst du diese Funktion deaktivieren.",
     "feature_desc_checkVersionNow": "Manuell nach einer neuen Version suchen",

+ 1 - 0
assets/translations/en_US.json

@@ -220,6 +220,7 @@
     "feature_helptext_advancedLyricsFilter": "Advanced filtering includes multiple layers of filters that aim to make the lyrics lookups more reliable.\nThese filters may not work well for songs in your language, and songs and artists with less unique titles in general.\nWarning: This feature is still experimental and might not actually perform any better than the default lyrics lookup. Make sure to confirm the prompt that appears if you changed this setting.",
 
     "feature_desc_locale": "Language",
+    "feature_desc_localeFallback": "Use English as a fallback for missing translations (disable if you are contributing translations)",
     "feature_desc_versionCheck": "Check for updates every 24 hours",
     "feature_helptext_versionCheck": "This feature checks for updates every 24 hours, notifies you if a new version is available and allows you to update the script manually.\nIf your userscript manager extension updates scripts automatically, you can disable this feature.",
     "feature_desc_checkVersionNow": "Manually check for a new version",

+ 1 - 0
assets/translations/es_ES.json

@@ -220,6 +220,7 @@
     "feature_helptext_advancedLyricsFilter": "El filtrado avanzado incluye múltiples capas de filtros que tienen como objetivo hacer que las búsquedas de letras sean más confiables.\nEstos filtros pueden no funcionar bien para canciones en su idioma y canciones y artistas con títulos menos únicos en general.\nAdvertencia: esta función todavía es experimental y es posible que no funcione mejor que la búsqueda de letras predeterminada. Asegúrese de confirmar el mensaje que aparece si cambió esta configuración.",
 
     "feature_desc_locale": "Idioma",
+    "feature_desc_localeFallback": "Utilizar el inglés para las traducciones que faltan (desactivar si contribuye a las traducciones)",
     "feature_desc_versionCheck": "Compruebe si hay actualizaciones",
     "feature_helptext_versionCheck": "Esta función comprueba si hay actualizaciones cada 24 horas, le notifica si hay una nueva versión disponible y le permite actualizar el script manualmente.\nSi su extensión de administrador de usuarios de scripts actualiza los scripts automáticamente, puede desactivar esta función.",
     "feature_desc_checkVersionNow": "Compruebe manualmente si hay una nueva versión",

+ 1 - 0
assets/translations/fr_FR.json

@@ -220,6 +220,7 @@
     "feature_helptext_advancedLyricsFilter": "Le filtrage avancé comprend plusieurs couches de filtres qui visent à rendre les recherches de paroles plus fiables.\nCes filtres peuvent ne pas bien fonctionner pour les chansons dans votre langue et les chansons et artistes avec des titres moins uniques en général.\nAvertissement: Cette fonctionnalité est encore expérimentale et pourrait ne pas fonctionner mieux que la recherche de paroles par défaut. Assurez-vous de confirmer l'invite qui apparaît si vous avez modifié ce paramètre.",
 
     "feature_desc_locale": "Langue",
+    "feature_desc_localeFallback": "Utiliser l'anglais pour les traductions manquantes (désactiver si vous contribuez aux traductions)",
     "feature_desc_versionCheck": "Vérifier les mises à jour",
     "feature_helptext_versionCheck": "Cette fonctionnalité vérifie les mises à jour toutes les 24 heures, vous avertit si une nouvelle version est disponible et vous permet de mettre à jour le script manuellement.\nSi votre gestionnaire de scripts utilisateur met à jour les scripts automatiquement, vous pouvez désactiver cette fonctionnalité.",
     "feature_desc_checkVersionNow": "Rechercher manuellement une nouvelle version",

+ 1 - 0
assets/translations/hi_IN.json

@@ -220,6 +220,7 @@
     "feature_helptext_advancedLyricsFilter": "उन्नत फ़िल्टरिंग में विभिन्न फ़िल्टरों के कई स्तर शामिल हैं जो बोल खोज को अधिक विश्वसनीय बनाने का उद्देश्य रखते हैं।\nयह फ़िल्टर आपकी भाषा में गानों और कम अनूठे शीर्षक वाले गानों और कलाकारों के लिए अच्छे परिणाम नहीं दे सकते हैं।\nचेतावनी: यह सुविधा अभी भी प्रायोगिक है और डिफ़ॉल्ट बोल खोज की तुलना में वास्तव में अधिक अच्छा प्रदर्शन नहीं कर सकती है। यह सुनिश्चित करें कि आपने इस सेटिंग को बदलने पर प्रॉम्प्ट की पुष्टि की है।",
 
     "feature_desc_locale": "भाषा",
+    "feature_desc_localeFallback": "अनुवादों के लिए अंग्रेजी का उपयोग करें (अनुवाद में योगदान कर रहे हैं तो इसे अक्षम करें)",
     "feature_desc_versionCheck": "अपडेट की जांच करें",
     "feature_helptext_versionCheck": "यह सुविधा हर 24 घंटे में अपडेट की जांच करती है, आपको अगर एक नया संस्करण उपलब्ध है तो सूचित करती है और आपको स्क्रिप्ट को मैन्युअल रूप से अपडेट करने की अनुमति देती है।\nयदि आपके यूज़रस्क्रिप्ट प्रबंधक एक्सटेंशन स्क्रिप्ट को स्वचालित रूप से अपडेट करता है, तो आप इस सुविधा को अक्षम कर सकते हैं।",
     "feature_desc_checkVersionNow": "मैन्युअल रूप से नया संस्करण जांचें",

+ 1 - 0
assets/translations/ja_JA.json

@@ -220,6 +220,7 @@
     "feature_helptext_advancedLyricsFilter": "高度なフィルタリングには、歌詞検索をより信頼性の高いものにするための複数のフィルタのレイヤが含まれています。\nこれらのフィルタは、あなたの言語の曲や、一般的にタイトルが一意でない曲やアーティストにはうまく機能しないかもしれません。\n警告: この機能はまだ実験的であり、デフォルトの歌詞検索よりも実際に優れたパフォーマンスを発揮しないかもしれません。この設定を変更した場合は、表示されるプロンプトを確認してください。",
 
     "feature_desc_locale": "言語",
+    "feature_desc_localeFallback": "翻訳が欠落している場合に英語をフォールバック言語として使用する(翻訳を提供している場合は無効にする)",
     "feature_desc_versionCheck": "バージョンチェック",
     "feature_helptext_versionCheck": "この機能は 24 時間ごとに更新をチェックし、新しいバージョンが利用可能な場合に通知し、スクリプトを手動で更新することができます。\nユーザースクリプトマネージャー拡張機能がスクリプトを自動的に更新する場合、この機能を無効にすることができます。",
     "feature_desc_checkVersionNow": "手動で新しいバージョンをチェックする",

+ 1 - 0
assets/translations/pt_BR.json

@@ -220,6 +220,7 @@
     "feature_helptext_advancedLyricsFilter": "A filtragem avançada inclui várias camadas de filtros que visam tornar as pesquisas de letras mais confiáveis.\nEsses filtros podem não funcionar bem para músicas em seu idioma e músicas e artistas com títulos menos únicos em geral.\nAviso: Este recurso ainda é experimental e pode não funcionar melhor do que a pesquisa de letras padrão. Certifique-se de confirmar o prompt que aparece se você alterou esta configuração.",
 
     "feature_desc_locale": "Idioma",
+    "feature_desc_localeFallback": "Utilizar o inglês para traduções em falta (desativar se contribuir para traduções)",
     "feature_desc_versionCheck": "Verificar atualizações",
     "feature_helptext_versionCheck": "Este recurso verifica atualizações a cada 24 horas, notifica você se uma nova versão estiver disponível e permite que você atualize o script manualmente.\nSe o seu gerenciador de scripts de usuário atualiza scripts automaticamente, você pode desativar este recurso.",
     "feature_desc_checkVersionNow": "Verificar manualmente uma nova versão",

+ 1 - 0
assets/translations/zh_CN.json

@@ -220,6 +220,7 @@
     "feature_helptext_advancedLyricsFilter": "高级过滤包括多层过滤器,旨在使歌词查找更可靠。\n这些过滤器可能不适用于您的语言的歌曲,以及标题不太独特的歌曲和艺术家。\n警告:此功能仍处于实验阶段,可能实际上并不比默认歌词查找更好。确保确认更改此设置时出现的提示。",
 
     "feature_desc_locale": "语言",
+    "feature_desc_localeFallback": "如果找不到翻译,请使用英语(如果您提供翻译,请禁用)。",
     "feature_desc_versionCheck": "检查更新",
     "feature_helptext_versionCheck": "此功能每 24 小时检查更新,如果有新版本可用,会通知您并允许您手动更新脚本。\n如果您的用户脚本管理器扩展自动更新脚本,您可以禁用此功能。",
     "feature_desc_checkVersionNow": "手动检查新版本",

+ 2 - 2
contributing.md

@@ -49,11 +49,11 @@ To edit an existing translation, please follow these steps:
 1. Set up the project for local development by following [this section](#setting-up-the-project-for-local-development)  
   Make sure you have forked the repository and cloned your fork instead of cloning the original repository.  
 2. Find the file for the language you want to edit in the folder [`assets/translations/`](./assets/translations/)
-3. Run the command `npm run tr-format -- -p -o=languageCode_localeCode`, where `languageCode_localeCode` is the part of the file name before the `.json` extension  
+3. Run the command `npm run tr-format -- -p -o=language_LOCALE`, where `language_LOCALE` is the part of the file name before the `.json` extension  
   This will prepare the file for translation by providing the missing keys once in English and once without any value and also formatting the file to have the same structure as the base file `en_US.json`
 4. Edit the strings inside the file, while making sure not to change the keys on the left side of the colon and to preserve the placeholders with the format %n (where n is any number starting at 1).
 5. Make sure there are no duplicate keys in the file
-6. Run the command `npm run tr-format -- -o=languageCode_localeCode` to make sure the file is formatted correctly
+6. Run the command `npm run tr-format -- -o=language_LOCALE` to make sure the file is formatted correctly
 7. Test for syntax errors and update translation progress with the command `npm run tr-progress`
 8. Open the file [`assets/translations/README.md`](./assets/translations/README.md) to see if you're still missing any untranslated keys (you don't have to translate them all, but it would of course be nice)
 9. I highly encourage you to test your changes to see if the wording fits into the respective context by following [this section](#setting-up-the-project-for-local-development)

+ 1 - 1
src/config.ts

@@ -45,7 +45,7 @@ export const migrations: DataMigrationsDict = {
   },
   // 4 -> 5 (v2.0)
   5: (oldData: FeatureConfig) => useDefaultConfig(oldData, [
-    "geniUrlBase", "geniUrlToken",
+    "localeFallback", "geniUrlBase", "geniUrlToken",
     "lyricsCacheMaxSize", "lyricsCacheTTL",
     "clearLyricsCache", "advancedMode",
     "checkVersionNow", "advancedLyricsFilter",

+ 7 - 0
src/features/index.ts

@@ -532,6 +532,13 @@ export const featInfo = {
     default: getPreferredLocale(),
     textAdornment: () => combineAdornments([adornments.globe, adornments.reloadRequired]),
   },
+  localeFallback: {
+    type: "toggle",
+    category: "general",
+    default: true,
+    advanced: true,
+    textAdornment: () => combineAdornments([adornments.advanced, adornments.reloadRequired]),
+  },
   versionCheck: {
     type: "toggle",
     category: "general",

+ 2 - 0
src/types.ts

@@ -424,6 +424,8 @@ export interface FeatureConfig {
   //#region misc
   /** The locale to use for translations */
   locale: TrLocale;
+  /** Whether to default to US-English if the translation for the set locale is missing */
+  localeFallback: boolean;
   /** Whether to check for updates to the script */
   versionCheck: boolean;
   /** Button to check for updates */

+ 1 - 1
src/utils/misc.ts

@@ -166,7 +166,7 @@ export function getPreferredLocale(): TrLocale {
   // if navigator.languages has entries that aren't locale codes in the format xx_XX
   if(navigator.languages.some(lang => lang.match(/^[a-z]{2}$/))) {
     for(const lang of navLangs) {
-      const foundLoc = Object.entries(langMapping).find(([key]) => key.startsWith(lang))?.[0];
+      const foundLoc = Object.entries(langMapping).find(([ key ]) => key.startsWith(lang))?.[0];
       if(foundLoc)
         return foundLoc as TrLocale;
     }

+ 13 - 3
src/utils/translations.ts

@@ -1,15 +1,16 @@
 import { tr, Stringifiable, fetchAdvanced, FetchAdvancedOpts } from "@sv443-network/userutils";
 import { error, getResourceUrl, info } from ".";
+import { emitInterface, setGlobalProp } from "../interface";
+import { getFeature } from "../config";
 import langMapping from "../../assets/locales.json" assert { type: "json" };
 import type tr_enUS from "../../assets/translations/en_US.json";
-import { emitInterface, setGlobalProp } from "../interface";
 
 export type TrLocale = keyof typeof langMapping;
 export type TrKey = keyof (typeof tr_enUS["translations"]);
 type TFuncKey = TrKey | (string & {});
 
 const fetchOpts: FetchAdvancedOpts = {
-  timeout: 10000,
+  timeout: 6_000,
 };
 
 /** Contains all translation keys of all initialized and loaded translations */
@@ -28,11 +29,20 @@ export async function initTranslations(locale: TrLocale) {
     const transUrl = await getResourceUrl(`trans-${locale}` as "_");
     const transFile = await (await fetchAdvanced(transUrl, fetchOpts)).json();
 
+    let fallbackTrans: Partial<typeof tr_enUS["translations"]> = {};
+
+    if(getFeature("localeFallback"))
+      fallbackTrans = (await (await fetchAdvanced(await getResourceUrl("trans-en_US"), fetchOpts)).json()).translations;
+
     // merge with base translations if specified
     const baseTransUrl = transFile.base ? await getResourceUrl(`trans-${transFile.base}` as "_") : undefined;
     const baseTransFile = baseTransUrl ? await (await fetchAdvanced(baseTransUrl, fetchOpts)).json() : undefined;
 
-    const translations = { ...(baseTransFile?.translations ?? {}), ...transFile.translations };
+    const translations: typeof tr_enUS["translations"] = {
+      ...fallbackTrans,
+      ...(baseTransFile?.translations ?? {}),
+      ...transFile.translations,
+    };
 
     tr.addLanguage(locale, translations);
     allTrKeys.set(locale, new Set(Object.keys(translations) as TrKey[]));