diff --git a/src/i18n.ts b/src/i18n.ts new file mode 100644 index 0000000..3ef93c3 --- /dev/null +++ b/src/i18n.ts @@ -0,0 +1,28 @@ +import en from './locales/en.json'; +import zh from './locales/zh.json'; + +export type Language = 'en' | 'zh'; +export type LocaleKey = keyof typeof en; + +// Typed as Record so a key missing from zh.json is a compile error. +const locales: Record> = { en, zh }; + +let current: Language = 'en'; + +export function setLanguage(lang: Language): void { + current = lang; +} + +export function t(key: LocaleKey, vars?: Record): string { + let s = locales[current][key]; + if (vars) { + for (const [k, v] of Object.entries(vars)) s = s.split(`{${k}}`).join(String(v)); + } + return s; +} + +// Every language's value for a key — parsing must recognize notes written +// under any language setting, not just the current one. +export function variants(key: LocaleKey): string[] { + return (Object.keys(locales) as Language[]).map((l) => locales[l][key]); +} diff --git a/src/locales/en.json b/src/locales/en.json new file mode 100644 index 0000000..b3d2cde --- /dev/null +++ b/src/locales/en.json @@ -0,0 +1,45 @@ +{ + "settings.language": "Language", + "settings.storageHeading": "Storage locations", + "settings.videoNotesFolder.name": "Video notes folder", + "settings.videoNotesFolder.desc": "One note per video: cover, hook, and keyframe clips all merge into the same note. Default: Clips/Videos", + "settings.coverFolder.name": "Cover images folder", + "settings.coverFolder.desc": "Video cover images (