feat: add Korean-English localization and light theme

Localize studio, curriculum, visualization and loading interfaces. Add persistent language and theme settings, refine module loading states, and normalize remote shell locales.
This commit is contained in:
2026-09-29 13:27:11 +09:00
parent 4125f71792
commit d44180db67
74 changed files with 2519 additions and 998 deletions
+48
View File
@@ -0,0 +1,48 @@
const { test } = require('node:test')
const assert = require('node:assert/strict')
const fs = require('node:fs')
const path = require('node:path')
const vm = require('node:vm')
const ts = require('typescript')
const root = path.resolve(__dirname, '../src/renderer/src/features/workspace')
function setup(saved, blocked = false) {
const storage = new Map([['autonomy-studio.lms.studio-theme', saved]])
const events = new Map()
const exports = {}
const code = ts.transpileModule(fs.readFileSync(path.join(root, 'studioTheme.ts'), 'utf8'), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022 }
}).outputText
vm.runInNewContext(code, { exports,
require: () => ({ useSyncExternalStore: (_subscribe, snapshot) => snapshot() }),
localStorage: {
getItem(key) { if (blocked) throw Error('blocked'); return storage.get(key) },
setItem(key, value) { if (blocked) throw Error('blocked'); storage.set(key, value) }
},
window: { addEventListener: (type, listener) => events.set(type, listener) }
})
return { api: exports, storage, events }
}
test('theme defaults dark, persists light, and restores the preference', () => {
const { api, storage } = setup('invalid')
assert.equal(api.useStudioTheme(), 'dark')
api.setStudioTheme('light')
assert.equal(api.useStudioTheme(), 'light')
assert.equal(storage.get(api.STUDIO_THEME_KEY), 'light')
assert.equal(setup('light').api.useStudioTheme(), 'light')
})
test('theme remains usable when storage is blocked', () => {
const { api } = setup(null, true)
api.setStudioTheme('light')
assert.equal(api.useStudioTheme(), 'light')
})
test('theme synchronizes across windows without writing runtime settings', () => {
const { api, storage, events } = setup('dark')
storage.set(api.STUDIO_THEME_KEY, 'light')
events.get('storage')({ key: api.STUDIO_THEME_KEY })
assert.equal(api.useStudioTheme(), 'light')
storage.clear()
events.get('storage')({ key: null })
assert.equal(api.useStudioTheme(), 'dark')
})