enhance(dev): 開発モード時にlocaleと型定義が自動的に再生成されるように (#12481)
* enhance: localeを任意のタイミングでリビルドできるように * enhance: localeも監視し、必要であればlocaleをリビルドするように * feat: devモードの時のみナビゲーションバーからキャッシュクリアができるように * refactor: キャッシュクリア部分を共通化 * fix: localesのファイル変更イベントが取れないのを修正 * fix: replaceAllでコケるのを修正 * change: 開発モードに関係なくナビゲーションバーからキャッシュクリアできるように * refactor: 必要のないリビルドをしないように * update: CHANGELOG.md --------- Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
This commit is contained in:
parent
4f6e098542
commit
22d6fa1fdf
8 changed files with 80 additions and 44 deletions
|
@ -25,6 +25,7 @@
|
||||||
- Enhance: ユーザーのRawデータを表示するページが復活
|
- Enhance: ユーザーのRawデータを表示するページが復活
|
||||||
- Enhance: リアクション選択時に音を鳴らせるように
|
- Enhance: リアクション選択時に音を鳴らせるように
|
||||||
- Enhance: サウンドにドライブのファイルを使用できるように
|
- Enhance: サウンドにドライブのファイルを使用できるように
|
||||||
|
- Enhance: ナビゲーションバーに項目「キャッシュを削除」を追加
|
||||||
- Enhance: Shareページで投稿を完了すると、親ウィンドウ(親フレーム)にpostMessageするように
|
- Enhance: Shareページで投稿を完了すると、親ウィンドウ(親フレーム)にpostMessageするように
|
||||||
- Enhance: チャンネル、クリップ、ページ、Play、ギャラリーにURLのコピーボタンを設置 #11305
|
- Enhance: チャンネル、クリップ、ページ、Play、ギャラリーにURLのコピーボタンを設置 #11305
|
||||||
- Enhance: ノートプレビューに「内容を隠す」が反映されるように
|
- Enhance: ノートプレビューに「内容を隠す」が反映されるように
|
||||||
|
|
|
@ -56,6 +56,18 @@ export default function generateDTS() {
|
||||||
ts.NodeFlags.Const | ts.NodeFlags.Ambient | ts.NodeFlags.ContextFlags,
|
ts.NodeFlags.Const | ts.NodeFlags.Ambient | ts.NodeFlags.ContextFlags,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
ts.factory.createFunctionDeclaration(
|
||||||
|
[ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
|
||||||
|
undefined,
|
||||||
|
ts.factory.createIdentifier('build'),
|
||||||
|
undefined,
|
||||||
|
[],
|
||||||
|
ts.factory.createTypeReferenceNode(
|
||||||
|
ts.factory.createIdentifier('Locale'),
|
||||||
|
undefined,
|
||||||
|
),
|
||||||
|
undefined,
|
||||||
|
),
|
||||||
ts.factory.createExportDefault(ts.factory.createIdentifier('locales')),
|
ts.factory.createExportDefault(ts.factory.createIdentifier('locales')),
|
||||||
];
|
];
|
||||||
const printed = ts.createPrinter({
|
const printed = ts.createPrinter({
|
||||||
|
|
1
locales/index.d.ts
vendored
1
locales/index.d.ts
vendored
|
@ -2505,4 +2505,5 @@ export interface Locale {
|
||||||
declare const locales: {
|
declare const locales: {
|
||||||
[lang: string]: Locale;
|
[lang: string]: Locale;
|
||||||
};
|
};
|
||||||
|
export function build(): Locale;
|
||||||
export default locales;
|
export default locales;
|
||||||
|
|
|
@ -51,33 +51,37 @@ const primaries = {
|
||||||
// 何故か文字列にバックスペース文字が混入することがあり、YAMLが壊れるので取り除く
|
// 何故か文字列にバックスペース文字が混入することがあり、YAMLが壊れるので取り除く
|
||||||
const clean = (text) => text.replace(new RegExp(String.fromCodePoint(0x08), 'g'), '');
|
const clean = (text) => text.replace(new RegExp(String.fromCodePoint(0x08), 'g'), '');
|
||||||
|
|
||||||
const locales = languages.reduce((a, c) => (a[c] = yaml.load(clean(fs.readFileSync(new URL(`${c}.yml`, import.meta.url), 'utf-8'))) || {}, a), {});
|
export function build() {
|
||||||
|
const locales = languages.reduce((a, c) => (a[c] = yaml.load(clean(fs.readFileSync(new URL(`${c}.yml`, import.meta.url), 'utf-8'))) || {}, a), {});
|
||||||
|
|
||||||
// 空文字列が入ることがあり、フォールバックが動作しなくなるのでプロパティごと消す
|
// 空文字列が入ることがあり、フォールバックが動作しなくなるのでプロパティごと消す
|
||||||
const removeEmpty = (obj) => {
|
const removeEmpty = (obj) => {
|
||||||
for (const [k, v] of Object.entries(obj)) {
|
for (const [k, v] of Object.entries(obj)) {
|
||||||
if (v === '') {
|
if (v === '') {
|
||||||
delete obj[k];
|
delete obj[k];
|
||||||
} else if (typeof v === 'object') {
|
} else if (typeof v === 'object') {
|
||||||
removeEmpty(v);
|
removeEmpty(v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return obj;
|
||||||
return obj;
|
};
|
||||||
};
|
removeEmpty(locales);
|
||||||
removeEmpty(locales);
|
|
||||||
|
|
||||||
export default Object.entries(locales)
|
return Object.entries(locales)
|
||||||
.reduce((a, [k ,v]) => (a[k] = (() => {
|
.reduce((a, [k, v]) => (a[k] = (() => {
|
||||||
const [lang] = k.split('-');
|
const [lang] = k.split('-');
|
||||||
switch (k) {
|
switch (k) {
|
||||||
case 'ja-JP': return v;
|
case 'ja-JP': return v;
|
||||||
case 'ja-KS':
|
case 'ja-KS':
|
||||||
case 'en-US': return merge(locales['ja-JP'], v);
|
case 'en-US': return merge(locales['ja-JP'], v);
|
||||||
default: return merge(
|
default: return merge(
|
||||||
locales['ja-JP'],
|
locales['ja-JP'],
|
||||||
locales['en-US'],
|
locales['en-US'],
|
||||||
locales[`${lang}-${primaries[lang]}`] ?? {},
|
locales[`${lang}-${primaries[lang]}`] ?? {},
|
||||||
v
|
v
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})(), a), {});
|
})(), a), {});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default build();
|
||||||
|
|
|
@ -12,6 +12,7 @@ import * as os from '@/os.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { ui } from '@/config.js';
|
import { ui } from '@/config.js';
|
||||||
import { unisonReload } from '@/scripts/unison-reload.js';
|
import { unisonReload } from '@/scripts/unison-reload.js';
|
||||||
|
import { clearCache } from './scripts/clear-cache.js';
|
||||||
|
|
||||||
export const navbarItemDef = reactive({
|
export const navbarItemDef = reactive({
|
||||||
notifications: {
|
notifications: {
|
||||||
|
@ -171,4 +172,11 @@ export const navbarItemDef = reactive({
|
||||||
show: computed(() => $i != null),
|
show: computed(() => $i != null),
|
||||||
to: `/@${$i?.username}`,
|
to: `/@${$i?.username}`,
|
||||||
},
|
},
|
||||||
|
cacheClear: {
|
||||||
|
title: i18n.ts.cacheClear,
|
||||||
|
icon: 'ti ti-trash',
|
||||||
|
action: (ev) => {
|
||||||
|
clearCache();
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,13 +33,11 @@ import { i18n } from '@/i18n.js';
|
||||||
import MkInfo from '@/components/MkInfo.vue';
|
import MkInfo from '@/components/MkInfo.vue';
|
||||||
import MkSuperMenu from '@/components/MkSuperMenu.vue';
|
import MkSuperMenu from '@/components/MkSuperMenu.vue';
|
||||||
import { signout, $i } from '@/account.js';
|
import { signout, $i } from '@/account.js';
|
||||||
import { unisonReload } from '@/scripts/unison-reload.js';
|
import { clearCache } from '@/scripts/clear-cache.js';
|
||||||
import { instance } from '@/instance.js';
|
import { instance } from '@/instance.js';
|
||||||
import { useRouter } from '@/router.js';
|
import { useRouter } from '@/router.js';
|
||||||
import { definePageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata.js';
|
import { definePageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { miLocalStorage } from '@/local-storage.js';
|
|
||||||
import { fetchCustomEmojis } from '@/custom-emojis.js';
|
|
||||||
|
|
||||||
const indexInfo = {
|
const indexInfo = {
|
||||||
title: i18n.ts.settings,
|
title: i18n.ts.settings,
|
||||||
|
@ -182,13 +180,7 @@ const menuDef = computed(() => [{
|
||||||
icon: 'ti ti-trash',
|
icon: 'ti ti-trash',
|
||||||
text: i18n.ts.clearCache,
|
text: i18n.ts.clearCache,
|
||||||
action: async () => {
|
action: async () => {
|
||||||
os.waiting();
|
await clearCache();
|
||||||
miLocalStorage.removeItem('locale');
|
|
||||||
miLocalStorage.removeItem('theme');
|
|
||||||
miLocalStorage.removeItem('emojis');
|
|
||||||
miLocalStorage.removeItem('lastEmojisFetchedAt');
|
|
||||||
await fetchCustomEmojis(true);
|
|
||||||
unisonReload();
|
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
type: 'button',
|
type: 'button',
|
||||||
|
|
14
packages/frontend/src/scripts/clear-cache.ts
Normal file
14
packages/frontend/src/scripts/clear-cache.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import { unisonReload } from '@/scripts/unison-reload.js';
|
||||||
|
import * as os from '@/os.js';
|
||||||
|
import { miLocalStorage } from '@/local-storage.js';
|
||||||
|
import { fetchCustomEmojis } from '@/custom-emojis.js';
|
||||||
|
|
||||||
|
export async function clearCache() {
|
||||||
|
os.waiting();
|
||||||
|
miLocalStorage.removeItem('locale');
|
||||||
|
miLocalStorage.removeItem('theme');
|
||||||
|
miLocalStorage.removeItem('emojis');
|
||||||
|
miLocalStorage.removeItem('lastEmojisFetchedAt');
|
||||||
|
await fetchCustomEmojis(true);
|
||||||
|
unisonReload();
|
||||||
|
}
|
|
@ -9,10 +9,12 @@ import cssnano from 'cssnano';
|
||||||
import postcss from 'postcss';
|
import postcss from 'postcss';
|
||||||
import * as terser from 'terser';
|
import * as terser from 'terser';
|
||||||
|
|
||||||
import locales from '../locales/index.js';
|
import { build as buildLocales } from '../locales/index.js';
|
||||||
import generateDTS from '../locales/generateDTS.js';
|
import generateDTS from '../locales/generateDTS.js';
|
||||||
import meta from '../package.json' assert { type: "json" };
|
import meta from '../package.json' assert { type: "json" };
|
||||||
|
|
||||||
|
let locales = buildLocales();
|
||||||
|
|
||||||
async function copyFrontendFonts() {
|
async function copyFrontendFonts() {
|
||||||
await fs.cp('./packages/frontend/node_modules/three/examples/fonts', './built/_frontend_dist_/fonts', { dereference: true, recursive: true });
|
await fs.cp('./packages/frontend/node_modules/three/examples/fonts', './built/_frontend_dist_/fonts', { dereference: true, recursive: true });
|
||||||
}
|
}
|
||||||
|
@ -89,10 +91,12 @@ async function build() {
|
||||||
await build();
|
await build();
|
||||||
|
|
||||||
if (process.argv.includes("--watch")) {
|
if (process.argv.includes("--watch")) {
|
||||||
const watcher = fs.watch('./packages', { recursive: true });
|
const watcher = fs.watch('./locales');
|
||||||
for await (const event of watcher) {
|
for await (const event of watcher) {
|
||||||
if (/^[a-z]+\/src/.test(event.filename)) {
|
const filename = event.filename?.replaceAll('\\', '/');
|
||||||
await build();
|
if (/^[a-z]+-[A-Z]+\.yml/.test(filename)) {
|
||||||
}
|
locales = buildLocales();
|
||||||
}
|
await copyFrontendLocales()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue