mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-25 17:53:48 +02:00
feat: add system language detection and prompt on first launch
This commit is contained in:
@@ -4,29 +4,25 @@ const localizedStringsUrls = import.meta.glob('./*.json', {
|
||||
import: 'default'
|
||||
});
|
||||
|
||||
async function fetchJson(url) {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
console.warn(`Failed to fetch localization: ${response.status}`);
|
||||
}
|
||||
return response.json();
|
||||
}
|
||||
|
||||
async function getLocalizedStrings(code) {
|
||||
const fallbackUrl = localizedStringsUrls['./en.json'];
|
||||
const localizedStringsUrl =
|
||||
localizedStringsUrls[`./${code}.json`] || fallbackUrl;
|
||||
const url = localizedStringsUrls[`./${code}.json`] || fallbackUrl;
|
||||
|
||||
let localizedStrings = {};
|
||||
try {
|
||||
localizedStrings = await fetchJson(localizedStringsUrl);
|
||||
const res = await fetch(url);
|
||||
if (!res.ok) throw new Error(res.status);
|
||||
return await res.json();
|
||||
} catch {
|
||||
if (localizedStringsUrl !== fallbackUrl) {
|
||||
localizedStrings = await fetchJson(fallbackUrl).catch(() => ({}));
|
||||
if (url !== fallbackUrl) {
|
||||
try {
|
||||
const res = await fetch(fallbackUrl);
|
||||
return await res.json();
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
return localizedStrings;
|
||||
}
|
||||
|
||||
const languageNames = import.meta.glob('./*.json', {
|
||||
@@ -38,5 +34,45 @@ function getLanguageName(code) {
|
||||
return String(languageNames[`./${code}.json`] ?? code);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} systemLanguage - BCP-47 code from AppApi.CurrentLanguage()
|
||||
* @param {string[]} codes - supported language codes
|
||||
* @returns {string | null} matched language code, or null
|
||||
*/
|
||||
function resolveSystemLanguage(systemLanguage, codes) {
|
||||
if (!systemLanguage) return null;
|
||||
|
||||
// Exact match (e.g. zh-CN → zh-CN)
|
||||
if (codes.includes(systemLanguage)) {
|
||||
return systemLanguage;
|
||||
}
|
||||
|
||||
const lang = systemLanguage.split('-')[0];
|
||||
|
||||
// Chinese: script-tag and region-aware mapping
|
||||
// BCP-47 forms: zh-CN, zh-TW, zh-Hant, zh-Hans, zh-Hant-HK, zh-Hans-CN, etc.
|
||||
if (lang === 'zh') {
|
||||
const parts = systemLanguage.split('-').slice(1); // everything after 'zh'
|
||||
const hasHant = parts.includes('Hant');
|
||||
const hasHans = parts.includes('Hans');
|
||||
const traditionalRegions = ['TW', 'HK', 'MO'];
|
||||
const hasTraditionalRegion = parts.some((p) =>
|
||||
traditionalRegions.includes(p)
|
||||
);
|
||||
|
||||
if (hasHant || hasTraditionalRegion) {
|
||||
return codes.includes('zh-TW') ? 'zh-TW' : null;
|
||||
}
|
||||
if (hasHans) {
|
||||
return codes.includes('zh-CN') ? 'zh-CN' : null;
|
||||
}
|
||||
// Bare 'zh' or unknown region (e.g. zh-SG) → simplified
|
||||
return codes.includes('zh-CN') ? 'zh-CN' : null;
|
||||
}
|
||||
|
||||
// Generic prefix match (e.g. ja-JP → ja)
|
||||
return codes.find((code) => code.split('-')[0] === lang) ?? null;
|
||||
}
|
||||
|
||||
export * from './locales';
|
||||
export { getLanguageName, getLocalizedStrings };
|
||||
export { getLanguageName, getLocalizedStrings, resolveSystemLanguage };
|
||||
|
||||
Reference in New Issue
Block a user