mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-11-01 08:05:23 +00:00
v26.10.1 (#1599)
* feat: AI translations at release, 7 new languages and regional fallback * fix: proper plural forms for count strings and full translations * fix: plural forms for selected, hidden and active counts * fix: synced plugin updates failing on desktop and server-only plugins shown as stopped * fix: restore rounded corners on app icons and favicon * feat: desktop app auto updates with automatic, ask first or never modes * feat: community and custom plugin registries * feat: plugin guide for AI tools in the SDK with a lint check * fix: keep the terminal WebSocket open past nginx's 60s default (#1588) * chore: update changelog * feat: show plugin download counts only and stop CI builds inflating them * feat: hide installed plugins in the browse tab by default * chore: pin bundled plugins to latest releases * chore: update translations * fix: focusing a saved password field and saving no longer erases it * fix: tell desktop users when their 2.8 data needs 2.9 first * fix: point windows update info at the x64 installer * fix: keep desktop client tunnel sockets alive behind proxies * chore: pin bundled plugins to latest releases * fix: cover client tunnel keepalive in the c2s runtime tests * fix: typing after opening a host no longer goes to the host search * fix: accept tab and = separators in SSH config import (#1598) * chore: update changelog * chore: drop plugin versions from core changelog * chore: update translations * chore: lint, format, and bump version to 26.10.1 --------- Co-authored-by: Darnel Hunter <68697450+innotelinc@users.noreply.github.com> Co-authored-by: Iain <Iain1970@protonmail.com>
This commit is contained in:
174 files changed
+94334
-39995
No files matched your search
+19
-41
@@ -3,46 +3,14 @@ import { initReactI18next } from "react-i18next";
|
||||
import LanguageDetector from "i18next-browser-languagedetector";
|
||||
|
||||
import enTranslation from "../locales/en.json";
|
||||
import { TRANSLATED_LANGUAGES } from "./languages";
|
||||
|
||||
type LocaleModule = { default: ResourceKey };
|
||||
|
||||
/** i18n code -> translated file name, shared by core and plugin locales. */
|
||||
export const LOCALE_FILES = {
|
||||
af: "af_ZA",
|
||||
ar: "ar_SA",
|
||||
bn: "bn_BD",
|
||||
bg: "bg_BG",
|
||||
ca: "ca_ES",
|
||||
cs: "cs_CZ",
|
||||
da: "da_DK",
|
||||
de: "de_DE",
|
||||
el: "el_GR",
|
||||
"es-ES": "es_ES",
|
||||
fi: "fi_FI",
|
||||
fr: "fr_FR",
|
||||
he: "he_IL",
|
||||
hi: "hi_IN",
|
||||
hu: "hu_HU",
|
||||
id: "id_ID",
|
||||
it: "it_IT",
|
||||
ja: "ja_JP",
|
||||
ko: "ko_KR",
|
||||
nl: "nl_NL",
|
||||
no: "no_NO",
|
||||
pl: "pl_PL",
|
||||
"pt-PT": "pt_PT",
|
||||
"pt-BR": "pt_BR",
|
||||
ro: "ro_RO",
|
||||
ru: "ru_RU",
|
||||
sr: "sr_SP",
|
||||
"sv-SE": "sv_SE",
|
||||
th: "th_TH",
|
||||
tr: "tr_TR",
|
||||
uk: "uk_UA",
|
||||
vi: "vi_VN",
|
||||
"zh-CN": "zh_CN",
|
||||
"zh-TW": "zh_TW",
|
||||
} as const satisfies Record<string, string>;
|
||||
export const LOCALE_FILES: Record<string, string> = Object.fromEntries(
|
||||
TRANSLATED_LANGUAGES.map(({ code, file }) => [code, file]),
|
||||
);
|
||||
|
||||
const translatedFiles = import.meta.glob<LocaleModule>(
|
||||
"../locales/translated/*.json",
|
||||
@@ -94,8 +62,20 @@ export function normalizeLanguageCode(language?: string | null): string {
|
||||
);
|
||||
if (exactMatch) return exactMatch;
|
||||
|
||||
const baseLanguage = normalized.split("-")[0];
|
||||
return supportedLngs.includes(baseLanguage) ? baseLanguage : "en";
|
||||
const baseLanguage = normalized.split("-")[0].toLowerCase();
|
||||
if (supportedLngs.includes(baseLanguage)) return baseLanguage;
|
||||
|
||||
// Regional variants we don't ship (es-MX, pt, sv) use the closest one we do.
|
||||
if (baseLanguage === "zh") {
|
||||
return /-(tw|hk|mo|hant)\b/i.test(normalized) ? "zh-TW" : "zh-CN";
|
||||
}
|
||||
if (baseLanguage === "nb" || baseLanguage === "nn") return "no";
|
||||
if (baseLanguage === "pt") return "pt-BR";
|
||||
return (
|
||||
supportedLngs.find((supported) =>
|
||||
supported.toLowerCase().startsWith(`${baseLanguage}-`),
|
||||
) ?? "en"
|
||||
);
|
||||
}
|
||||
|
||||
const localeBackend: BackendModule = {
|
||||
@@ -106,9 +86,7 @@ const localeBackend: BackendModule = {
|
||||
|
||||
if (namespace !== CORE_NAMESPACE) {
|
||||
const file =
|
||||
normalizedLanguage === "en"
|
||||
? "en"
|
||||
: (LOCALE_FILES as Record<string, string>)[normalizedLanguage];
|
||||
normalizedLanguage === "en" ? "en" : LOCALE_FILES[normalizedLanguage];
|
||||
if (!pluginLocaleResolver || !file) {
|
||||
callback(null, {});
|
||||
return;
|
||||
|
||||
Reference in new issue
Block a user