feat: configurable locales path per story, dynamic language switching from story data
This commit is contained in:
@@ -161,6 +161,7 @@ export function useGameEngine(videoEls: () => [HTMLVideoElement | null, HTMLVide
|
||||
engine.achievementSystem.init(data.achievements || [], achieved)
|
||||
|
||||
store.setEndings(data.endings || [])
|
||||
store.setStoryLocales(data.locales)
|
||||
|
||||
const visitedIds = await saveSystem.getVisitedSceneIds()
|
||||
store.setVisitedSceneIds(visitedIds)
|
||||
|
||||
@@ -4,20 +4,28 @@ import enUI from '@/locales/en.json'
|
||||
import jaUI from '@/locales/ja.json'
|
||||
|
||||
const uiMessages = { zh: zhUI, en: enUI, ja: jaUI } as const
|
||||
type Lang = 'zh' | 'en' | 'ja'
|
||||
|
||||
const currentLang = ref<Lang>(
|
||||
(localStorage.getItem('lang') as Lang) || 'zh',
|
||||
)
|
||||
type Lang = string
|
||||
|
||||
const currentLang = ref<Lang>(localStorage.getItem('lang') || 'zh')
|
||||
const storyMessages = ref<Record<string, Record<string, any>>>({})
|
||||
const storyLoading = new Set<Lang>()
|
||||
const storyLoading = new Set<string>()
|
||||
let localesPath = ''
|
||||
|
||||
async function loadStoryMessages(lang: Lang) {
|
||||
if (storyMessages.value[lang] || storyLoading.has(lang)) return
|
||||
function resolveLocalePath(lang: string): string {
|
||||
const base = localesPath.endsWith('/') ? localesPath : localesPath + '/'
|
||||
return base + lang + '.json'
|
||||
}
|
||||
|
||||
export async function initStoryLocales(path: string, lang?: string) {
|
||||
localesPath = path
|
||||
return loadStoryMessages(lang || currentLang.value)
|
||||
}
|
||||
|
||||
async function loadStoryMessages(lang: string) {
|
||||
if (!localesPath || storyMessages.value[lang] || storyLoading.has(lang)) return
|
||||
storyLoading.add(lang)
|
||||
try {
|
||||
const resp = await fetch(`/locales/${lang}.json`)
|
||||
const resp = await fetch(resolveLocalePath(lang))
|
||||
if (resp.ok) {
|
||||
storyMessages.value = {
|
||||
...storyMessages.value,
|
||||
@@ -31,8 +39,6 @@ async function loadStoryMessages(lang: Lang) {
|
||||
}
|
||||
}
|
||||
|
||||
loadStoryMessages(currentLang.value)
|
||||
|
||||
function t(key: string): string {
|
||||
const parts = key.split('.')
|
||||
|
||||
@@ -42,7 +48,8 @@ function t(key: string): string {
|
||||
}
|
||||
if (typeof result === 'string') return result
|
||||
|
||||
let fallback: any = uiMessages[currentLang.value]
|
||||
const uiLang = currentLang.value as keyof typeof uiMessages
|
||||
let fallback: any = (uiMessages as any)[uiLang] || uiMessages.zh
|
||||
for (const p of parts) {
|
||||
fallback = fallback?.[p]
|
||||
}
|
||||
@@ -51,7 +58,7 @@ function t(key: string): string {
|
||||
return key
|
||||
}
|
||||
|
||||
async function setLang(lang: Lang) {
|
||||
async function setLang(lang: string) {
|
||||
await loadStoryMessages(lang)
|
||||
currentLang.value = lang
|
||||
localStorage.setItem('lang', lang)
|
||||
|
||||
Reference in New Issue
Block a user