diff --git a/packages/backend/src/server/web/boot.js b/packages/backend/src/server/web/boot.js index 4275dc9527..09b2475abb 100644 --- a/packages/backend/src/server/web/boot.js +++ b/packages/backend/src/server/web/boot.js @@ -33,59 +33,6 @@ return; } - //#region Detect language & fetch translations - if (!localStorage.hasOwnProperty('locale')) { - const supportedLangs = LANGS; - let lang = localStorage.getItem('lang'); - if (lang == null || !supportedLangs.includes(lang)) { - if (supportedLangs.includes(navigator.language)) { - lang = navigator.language; - } else { - lang = supportedLangs.find(x => x.split('-')[0] === navigator.language); - - // Fallback - if (lang == null) lang = 'en-US'; - } - } - - const metaRes = await window.fetch('/api/meta', { - method: 'POST', - body: JSON.stringify({}), - credentials: 'omit', - cache: 'no-cache', - headers: { - 'Content-Type': 'application/json', - }, - }); - if (metaRes.status !== 200) { - renderError('META_FETCH'); - return; - } - const meta = await metaRes.json(); - const v = meta.version; - if (v == null) { - renderError('META_FETCH_V'); - return; - } - - // for https://github.com/misskey-dev/misskey/issues/10202 - if (lang == null || lang.toString == null || lang.toString() === 'null') { - console.error('invalid lang value detected!!!', typeof lang, lang); - lang = 'en-US'; - } - - const localRes = await window.fetch(`/assets/locales/${lang}.${v}.json`); - if (localRes.status === 200) { - localStorage.setItem('lang', lang); - localStorage.setItem('locale', await localRes.text()); - localStorage.setItem('localeVersion', v); - } else { - renderError('LOCALE_FETCH'); - return; - } - } - //#endregion - //#region Script async function importAppScript() { await import(`/vite/${CLIENT_ENTRY}`) @@ -176,10 +123,10 @@ Reload / リロード

The following actions may solve the problem. / 以下を行うと解決する可能性があります。

-

Clear the browser cache / ブラウザのキャッシュをクリアする

Update your os and browser / ブラウザおよびOSを最新バージョンに更新する

Disable an adblocker / アドブロッカーを無効にする

-

(Tor Browser) Set dom.webaudio.enabled to true / dom.webaudio.enabledをtrueに設定する

+

Clear the browser cache / ブラウザのキャッシュをクリアする

+

(Tor Browser) Set dom.webaudio.enabled to true / dom.webaudio.enabledをtrueに設定する

Other options / その他のオプション @@ -212,7 +159,7 @@ ERROR CODE: ${code} - ${JSON.stringify(details)}`; + ${details.toString()} ${JSON.stringify(details)}`; errorsElement.appendChild(detailsElement); addStyle(` * { @@ -320,6 +267,6 @@ #errorInfo { width: 50%; } - }`) + }`); } })(); diff --git a/packages/frontend/src/_dev_boot_.ts b/packages/frontend/src/_dev_boot_.ts index 7c6e537fbc..a43ee6d23f 100644 --- a/packages/frontend/src/_dev_boot_.ts +++ b/packages/frontend/src/_dev_boot_.ts @@ -23,27 +23,6 @@ async function main() { //#region Detect language & fetch translations - // dev-modeの場合は常に取り直す - const supportedLangs = _LANGS_.map(it => it[0]); - let lang: string | null | undefined = localStorage.getItem('lang'); - if (lang == null || !supportedLangs.includes(lang)) { - if (supportedLangs.includes(navigator.language)) { - lang = navigator.language; - } else { - lang = supportedLangs.find(x => x.split('-')[0] === navigator.language); - - // Fallback - if (lang == null) lang = 'en-US'; - } - } - - // TODO:今のままだと言語ファイル変更後はpnpm devをリスタートする必要があるので、chokidarを使ったり等で対応できるようにする - const locale = _LANGS_FULL_.find(it => it[0] === lang); - localStorage.setItem('lang', lang); - localStorage.setItem('locale', JSON.stringify(locale[1])); - localStorage.setItem('localeVersion', _VERSION_); - //#endregion - //#region Theme const theme = localStorage.getItem('theme'); if (theme) { diff --git a/packages/frontend/src/boot/common.ts b/packages/frontend/src/boot/common.ts index d86ae18ffe..605ea8ef3f 100644 --- a/packages/frontend/src/boot/common.ts +++ b/packages/frontend/src/boot/common.ts @@ -8,10 +8,10 @@ import { compareVersions } from 'compare-versions'; import widgets from '@/widgets/index.js'; import directives from '@/directives/index.js'; import components from '@/components/index.js'; -import { version, lang, updateLocale, locale } from '@/config.js'; +import { version, lang } from '@/config.js'; import { applyTheme } from '@/scripts/theme.js'; import { isDeviceDarkmode } from '@/scripts/is-device-darkmode.js'; -import { updateI18n } from '@/i18n.js'; +import { locale, updateI18n, updateLocale } from '@/i18n.js'; import { $i, refreshAccount, login } from '@/account.js'; import { defaultStore, ColdDeviceStorage } from '@/store.js'; import { fetchInstance, instance } from '@/instance.js'; @@ -78,22 +78,6 @@ export async function common(createVue: () => App) { } //#endregion - //#region Detect language & fetch translations - const localeVersion = miLocalStorage.getItem('localeVersion'); - const localeOutdated = (localeVersion == null || localeVersion !== version || locale == null); - if (localeOutdated) { - const res = await window.fetch(`/assets/locales/${lang}.${version}.json`); - if (res.status === 200) { - const newLocale = await res.text(); - const parsedNewLocale = JSON.parse(newLocale); - miLocalStorage.setItem('locale', newLocale); - miLocalStorage.setItem('localeVersion', version); - updateLocale(parsedNewLocale); - updateI18n(parsedNewLocale); - } - } - //#endregion - // タッチデバイスでCSSの:hoverを機能させる document.addEventListener('touchend', () => {}, { passive: true }); @@ -282,6 +266,7 @@ export async function common(createVue: () => App) { } function removeSplash() { + console.log('remove splash'); const splash = document.getElementById('splash'); if (splash) { splash.style.opacity = '0'; diff --git a/packages/frontend/src/config.ts b/packages/frontend/src/config.ts index 277dfc12aa..29b10a6f22 100644 --- a/packages/frontend/src/config.ts +++ b/packages/frontend/src/config.ts @@ -5,6 +5,28 @@ import { miLocalStorage } from '@/local-storage.js'; +//#region language detection +const supportedLangs = _LANGS_.map(it => it[0]); +let _lang = miLocalStorage.getItem('lang'); +if (_lang == null || !supportedLangs.includes(_lang)) { + if (supportedLangs.includes(navigator.language)) { + _lang = navigator.language; + } else { + _lang = supportedLangs.find(x => x.split('-')[0] === navigator.language) ?? null; + + // Fallback + if (_lang == null) _lang = 'en-US'; + } + miLocalStorage.setItem('lang', _lang); +} +// for https://github.com/misskey-dev/misskey/issues/10202 +if (_lang.toString == null || _lang.toString() === 'null') { + console.error('invalid lang value detected!!!', typeof _lang, _lang); + _lang = 'en-US'; + miLocalStorage.setItem('lang', _lang); +} +//#endregion + const address = new URL(document.querySelector('meta[property="instance_url"]')?.content || location.href); const siteName = document.querySelector('meta[property="og:site_name"]')?.content; @@ -13,15 +35,9 @@ export const hostname = address.hostname; export const url = address.origin; export const apiUrl = location.origin + '/api'; export const wsOrigin = location.origin; -export const lang = miLocalStorage.getItem('lang') ?? 'en-US'; +export const lang = _lang; export const langs = _LANGS_; -const preParseLocale = miLocalStorage.getItem('locale'); -export let locale = preParseLocale ? JSON.parse(preParseLocale) : null; export const version = _VERSION_; export const instanceName = siteName === 'Misskey' || siteName == null ? host : siteName; export const ui = miLocalStorage.getItem('ui'); export const debug = miLocalStorage.getItem('debug') === 'true'; - -export function updateLocale(newLocale): void { - locale = newLocale; -} diff --git a/packages/frontend/src/i18n.ts b/packages/frontend/src/i18n.ts index 10d6adbcd0..edf505ce00 100644 --- a/packages/frontend/src/i18n.ts +++ b/packages/frontend/src/i18n.ts @@ -5,8 +5,50 @@ import { markRaw } from 'vue'; import type { Locale } from '../../../locales/index.js'; -import { locale } from '@/config.js'; import { I18n } from '@/scripts/i18n.js'; +import { miLocalStorage } from '@/local-storage.js'; +import { version, lang } from '@/config.js'; + +const preParseLocale = miLocalStorage.getItem('locale'); +export let locale = preParseLocale ? JSON.parse(preParseLocale) : null; + +if (locale == null) { + const localRes = await window.fetch(`/assets/locales/${lang}.${version}.json`); + if (localRes.status === 200) { + locale = await localRes.json(); + localStorage.setItem('locale', JSON.stringify(locale)); + localStorage.setItem('localeVersion', version); + } else { + throw new Error('Failed to fetch locale file'); + } +} + +//#region Detect language & fetch translations +const localeVersion = miLocalStorage.getItem('localeVersion'); +const localeOutdated = (localeVersion == null || localeVersion !== version); +if (localeOutdated) { + const res = await window.fetch(`/assets/locales/${lang}.${version}.json`); + if (res.status === 200) { + const newLocale = await res.text(); + const parsedNewLocale = JSON.parse(newLocale); + miLocalStorage.setItem('locale', newLocale); + miLocalStorage.setItem('localeVersion', version); + locale = parsedNewLocale; + } +} +//#endregion + +// dev-modeの場合は常に取り直す +if (_DEV_) { + const x = _LANGS_FULL_.find(it => it[0] === lang)!; + localStorage.setItem('locale', JSON.stringify(x[1])); + localStorage.setItem('localeVersion', version); + locale = x[1]; +} + +export function updateLocale(newLocale): void { + locale = newLocale; +} export const i18n = markRaw(new I18n(locale));