forked from mirrors/misskey
per-locale bundle & inline locale (#16369)
* feat: split entry file by locale name
* chore: とりあえず transform hook で雑に分割
* chore: とりあえず transform 結果をいい感じに
* chore: concurrent buildで高速化
* chore: vite ではローケルのないものをビルドして後処理でどうにかするように
* chore: 後処理のためにi18n.jを単体になるように切り出す
* chore: use typescript
* chore: remove unref(i18n) in vite build process
* chore: inline variable
* fix: build error
* fix: i18n.ts.something.replaceAll() become error
* chore: ignore export specifier from error
* chore: support i18n.tsx as object
* chore: process literal for all files
* chore: split config and locale
* chore: inline locale name
* chore: remove updating locale in boot common
* chore: use top-level await to load locales
* chore: inline locale
* chore: remove loading locale from boot.js
* chore: remove loading locale from boot.js
* コメント追加
* fix test; fetchに失敗する
* import削除ログをdebugレベルに
* fix: watch pug
* chore: use hash for entry files
* chore: remove es-module-lexer from dependencies
* chore: move to frontend-builder
* chore: use inline locale in embed
* chore: refetch json on hot reload
* feat: store localization related to boot.js in backend in bootloaderLocales localstorage
* 応急処置を戻す
* fix spex
* fix `Using i18n identifier "e" directly. Skipping inlining.` warning
* refactor: use scriptsDir parameter
* chore: remove i18n from depmap
* chore: make build crash if errors
* error -> warn few conditions
* use inline object
* update localstorage keys
* remove accessing locale localstorage
* fix: failed to process i18n.tsx.aaa({x:i18n.bbb})
This commit is contained in:
@@ -5,9 +5,10 @@
|
||||
|
||||
import { computed, watch, version as vueVersion } from 'vue';
|
||||
import { compareVersions } from 'compare-versions';
|
||||
import { version, lang, updateLocale, locale, apiUrl, isSafeMode } from '@@/js/config.js';
|
||||
import { version, lang, apiUrl, isSafeMode } from '@@/js/config.js';
|
||||
import defaultLightTheme from '@@/themes/l-light.json5';
|
||||
import defaultDarkTheme from '@@/themes/d-green-lime.json5';
|
||||
import { storeBootloaderErrors } from '@@/js/store-boot-errors';
|
||||
import type { App } from 'vue';
|
||||
import widgets from '@/widgets/index.js';
|
||||
import directives from '@/directives/index.js';
|
||||
@@ -79,25 +80,7 @@ export async function common(createVue: () => Promise<App<Element>>) {
|
||||
//#endregion
|
||||
|
||||
//#region Detect language & fetch translations
|
||||
const localeVersion = miLocalStorage.getItem('localeVersion');
|
||||
const localeOutdated = (localeVersion == null || localeVersion !== version || locale == null);
|
||||
|
||||
async function fetchAndUpdateLocale({ useCache } = { useCache: true }) {
|
||||
const fetchOptions: RequestInit | undefined = useCache ? undefined : { cache: 'no-store' };
|
||||
const res = await window.fetch(`/assets/locales/${lang}.${version}.json`, fetchOptions);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (localeOutdated) {
|
||||
fetchAndUpdateLocale();
|
||||
}
|
||||
storeBootloaderErrors({ ...i18n.ts._bootErrors, reload: i18n.ts.reload });
|
||||
|
||||
if (import.meta.hot) {
|
||||
import.meta.hot.on('locale-update', async (updatedLang: string) => {
|
||||
@@ -106,7 +89,8 @@ export async function common(createVue: () => Promise<App<Element>>) {
|
||||
await new Promise(resolve => {
|
||||
window.setTimeout(resolve, 500);
|
||||
});
|
||||
await fetchAndUpdateLocale({ useCache: false });
|
||||
// fetch with cache: 'no-store' to ensure the latest locale is fetched
|
||||
await window.fetch(`/assets/locales/${lang}.${version}.json`, { cache: 'no-store' }).then(async res => res.status === 200 && await res.text());
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
<MkInfo :warn="true">{{ i18n.ts._externalResourceInstaller.checkVendorBeforeInstall }}</MkInfo>
|
||||
|
||||
<div v-if="isPlugin" class="_gaps_s">
|
||||
<div v-if="extension.type === 'plugin'" class="_gaps_s">
|
||||
<MkFolder :defaultOpen="true">
|
||||
<template #icon><i class="ti ti-info-circle"></i></template>
|
||||
<template #label>{{ i18n.ts.metadata }}</template>
|
||||
@@ -60,7 +60,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<MkCode :code="extension.raw"/>
|
||||
</MkFolder>
|
||||
</div>
|
||||
<div v-else-if="isTheme" class="_gaps_s">
|
||||
<div v-else-if="extension.type === 'theme'" class="_gaps_s">
|
||||
<MkFolder :defaultOpen="true">
|
||||
<template #icon><i class="ti ti-info-circle"></i></template>
|
||||
<template #label>{{ i18n.ts.metadata }}</template>
|
||||
@@ -78,7 +78,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</FormSplit>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts._externalResourceInstaller._meta.base }}</template>
|
||||
<template #value>{{ i18n.ts[extension.meta.base ?? 'none'] }}</template>
|
||||
<template #value>{{ { light: i18n.ts.light, dark: i18n.ts.dark, none: i18n.ts.none }[extension.meta.base ?? 'none'] }}</template>
|
||||
</MkKeyValue>
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
|
||||
import { markRaw } from 'vue';
|
||||
import { I18n } from '@@/js/i18n.js';
|
||||
import { locale } from '@@/js/locale.js';
|
||||
import type { Locale } from '../../../locales/index.js';
|
||||
import { locale } from '@@/js/config.js';
|
||||
|
||||
export const i18n = markRaw(new I18n<Locale>(locale, _DEV_));
|
||||
|
||||
// test 以外では使わないこと。インライン化されてるのでだいたい意味がない
|
||||
export function updateI18n(newLocale: Locale) {
|
||||
i18n.locale = newLocale;
|
||||
}
|
||||
|
||||
@@ -22,8 +22,7 @@ export type Keys = (
|
||||
'fontSize' |
|
||||
'ui' |
|
||||
'ui_temp' |
|
||||
'locale' |
|
||||
'localeVersion' |
|
||||
'bootloaderLocales' |
|
||||
'theme' |
|
||||
'themeId' |
|
||||
'customCss' |
|
||||
|
||||
@@ -886,8 +886,6 @@ const useSystemFont = ref(miLocalStorage.getItem('useSystemFont') != null);
|
||||
|
||||
watch(lang, () => {
|
||||
miLocalStorage.setItem('lang', lang.value as string);
|
||||
miLocalStorage.removeItem('locale');
|
||||
miLocalStorage.removeItem('localeVersion');
|
||||
});
|
||||
|
||||
watch(fontSize, () => {
|
||||
|
||||
@@ -13,8 +13,6 @@ export async function clearCache() {
|
||||
os.waiting();
|
||||
miLocalStorage.removeItem('instance');
|
||||
miLocalStorage.removeItem('instanceCachedAt');
|
||||
miLocalStorage.removeItem('locale');
|
||||
miLocalStorage.removeItem('localeVersion');
|
||||
miLocalStorage.removeItem('theme');
|
||||
miLocalStorage.removeItem('emojis');
|
||||
miLocalStorage.removeItem('lastEmojisFetchedAt');
|
||||
|
||||
Reference in New Issue
Block a user