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…
	
	Add table
		Add a link
		
	
		Reference in a new issue