feat(V2-1d): packages/i18n 추출 — Electron 독립 i18n 엔진
packages/i18n (@d3ro/i18n) 신규:
- src/locales/ 12개 JSON (ko/en/ja/zh/zh-TW/es/fr/de/pt/ru/vi/th)
- src/index.tsx: TFunction/Locale/LOCALE_META/resolveTranslation/
포맷 유틸(createFormatDate/Number/RelativeDate/Time)/
I18nContext/useI18n/I18nProvider
Electron 독립성 확보 (monorepo 원칙 준수):
- I18nStorage interface 신설 (load/save 어댑터 추상화)
- window.electronAPI.config 직접 호출 제거
- I18nProvider는 storage prop으로 영속화 어댑터 주입
- 기본값 noopStorage (메모리 한정, 세션 범위)
- 결과: packages/i18n은 React에만 의존, web/mobile에서 재사용 가능
apps/desktop 어댑터:
- App.tsx에 electronI18nStorage 구현 (config.get/set 래핑)
- <I18nProvider storage={electronI18nStorage}>로 주입
apps/desktop 설정:
- package.json: @d3ro/i18n '*' dep 추가
- tsconfig.node/web.json paths에 @d3ro/i18n 추가
- electron.vite.config.ts alias + externalize exclude 추가
- vitest.config.ts alias 추가
일괄 치환 (29 파일):
- ./i18n, ../i18n, ../../i18n → @d3ro/i18n
apps/desktop/src/renderer/i18n/ 디렉토리 완전 제거.
검증: typecheck + build + dev 런타임 모두 통과.
Phase V2-1 전체 완료 (a/b/c/d).
This commit is contained in:
parent
a041f1b6a9
commit
3524e958ba
51 changed files with 175 additions and 66 deletions
|
|
@ -5,12 +5,23 @@
|
|||
import { useState, useEffect, useMemo, useRef } from 'react'
|
||||
import { ThemeProvider, CssBaseline, useMediaQuery } from '@mui/material'
|
||||
import { getTheme } from '@d3ro/ui/theme'
|
||||
import { I18nProvider } from './i18n'
|
||||
import { I18nProvider, type I18nStorage, type Locale } from '@d3ro/i18n'
|
||||
import { AppLayout } from './components/AppLayout'
|
||||
import { UpgradePromptModal } from './components/UpgradePromptModal'
|
||||
import { startSystemAudioCapture, stopSystemAudioCapture } from './utils/systemAudioCapture'
|
||||
import type { ThemeMode, ConfigChangedEvent } from '@d3ro/core/types'
|
||||
|
||||
// Electron ConfigService에 바인딩된 i18n 영속화 어댑터
|
||||
const electronI18nStorage: I18nStorage = {
|
||||
load: async () => {
|
||||
const result = await window.electronAPI.config.get({ key: 'language' })
|
||||
return result.success && result.data ? (result.data as string) : null
|
||||
},
|
||||
save: (locale: Locale) => {
|
||||
window.electronAPI.config.set({ key: 'language', value: locale })
|
||||
}
|
||||
}
|
||||
|
||||
export function App(): React.ReactElement {
|
||||
const [themeMode, setThemeMode] = useState<ThemeMode>('auto')
|
||||
const prefersDark = useMediaQuery('(prefers-color-scheme: dark)')
|
||||
|
|
@ -60,7 +71,7 @@ export function App(): React.ReactElement {
|
|||
const theme = useMemo(() => getTheme(themeMode, prefersDark), [themeMode, prefersDark])
|
||||
|
||||
return (
|
||||
<I18nProvider>
|
||||
<I18nProvider storage={electronI18nStorage}>
|
||||
<ThemeProvider theme={theme}>
|
||||
<CssBaseline />
|
||||
<AppLayout />
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue