refactor(popup): 5종 팝업 _i18n 주입 + 색상 토큰화 (WS-POPUP)
- 4종 팝업(command/history/result/recording-tip) _i18n 주입: WindowManager getPopupI18nStrings() + 팝업 script applyI18nToHtml() - 한국어/영어 하드코딩 -> popup.* i18n 키 (ko/en 17키) - theme-vars.ts에 --d3-wave-1~9, --d3-status-error/success 토큰 추가 (6 테마) - 팝업 style.css hex -> CSS var 토큰 - packages/i18n getI18n() (main 프로세스용) 추가 SKIP: caption-overlay _i18n(별도 IPC 구조), wave box-shadow 보간(opacity 단순화) 정책: docs/REFACTOR_POLICY.md DP3, 이식 인사이트 P5
This commit is contained in:
parent
660e622a93
commit
00a99e4087
15 changed files with 256 additions and 35 deletions
|
|
@ -226,3 +226,21 @@ export function useI18n(): I18nContextValue {
|
|||
export function isValidLocale(value: string): value is Locale {
|
||||
return value in LOCALE_MAP
|
||||
}
|
||||
|
||||
// ── Main 프로세스용 i18n (React 없음) ───────────────────
|
||||
/**
|
||||
* Electron main 프로세스에서 사용하는 간단한 i18n 함수.
|
||||
* React Context 없이 로케일 문자열로 직접 번역 map을 반환.
|
||||
* @param locale 로케일 코드 (기본값 'ko')
|
||||
* @returns 번역 함수 map (t: (key) => translated string)
|
||||
*/
|
||||
export function getI18n(locale: Locale = 'ko'): {
|
||||
t: (key: TranslationKey, params?: Record<string, string | number>) => string
|
||||
locale: Locale
|
||||
} {
|
||||
const translations = LOCALE_MAP[locale] ?? ko
|
||||
const t = (key: TranslationKey, params?: Record<string, string | number>): string => {
|
||||
return resolveTranslation(key, translations, params)
|
||||
}
|
||||
return { t, locale }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -553,5 +553,23 @@
|
|||
"onboarding.sttModelSize": "Size: ~1.6GB — takes 2–10 min depending on network speed",
|
||||
"onboarding.step": "Step {{current}}/{{total}}",
|
||||
"onboarding.progressDetail": "{{downloaded}} / {{total}} MB",
|
||||
"onboarding.ollamaNotRunning": "Ollama server is not running. Please retry shortly."
|
||||
"onboarding.ollamaNotRunning": "Ollama server is not running. Please retry shortly.",
|
||||
|
||||
"popup.commandSelect": "COMMAND SELECT",
|
||||
"popup.hints.select": "↑↓ Select",
|
||||
"popup.hints.apply": "⏎ Apply",
|
||||
"popup.hints.clear": "0 Clear",
|
||||
"popup.hints.close": "ESC ×",
|
||||
"popup.noCommands": "No commands",
|
||||
"popup.noCommand": "No command (insert original)",
|
||||
"popup.hints.selectEn": "↑↓ Select",
|
||||
"popup.hints.paste": "⏎ Paste",
|
||||
"popup.noHistory": "No history yet",
|
||||
"popup.time.justNow": "just now",
|
||||
"popup.time.minutesAgo": "{{m}}m ago",
|
||||
"popup.time.hoursAgo": "{{h}}h ago",
|
||||
"popup.time.daysAgo": "{{d}}d ago",
|
||||
"popup.copy": "Copy",
|
||||
"popup.error.default": "An error occurred",
|
||||
"popup.caption.loading": "⏳ Loading STT model..."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -553,5 +553,23 @@
|
|||
"onboarding.sttModelSize": "크기: 약 1.6GB — 네트워크 속도에 따라 2~10분 소요",
|
||||
"onboarding.step": "단계 {{current}}/{{total}}",
|
||||
"onboarding.progressDetail": "{{downloaded}} / {{total}} MB",
|
||||
"onboarding.ollamaNotRunning": "Ollama 서버가 실행되지 않았습니다. 잠시 후 다시 시도하세요."
|
||||
"onboarding.ollamaNotRunning": "Ollama 서버가 실행되지 않았습니다. 잠시 후 다시 시도하세요.",
|
||||
|
||||
"popup.commandSelect": "명령어 선택",
|
||||
"popup.hints.select": "↑↓ 선택",
|
||||
"popup.hints.apply": "⏎ 적용",
|
||||
"popup.hints.clear": "0 해제",
|
||||
"popup.hints.close": "ESC ×",
|
||||
"popup.noCommands": "명령어 없음",
|
||||
"popup.noCommand": "없음 (원본 삽입)",
|
||||
"popup.hints.selectEn": "↑↓ Select",
|
||||
"popup.hints.paste": "⏎ Paste",
|
||||
"popup.noHistory": "히스토리 없음",
|
||||
"popup.time.justNow": "방금",
|
||||
"popup.time.minutesAgo": "{{m}}분 전",
|
||||
"popup.time.hoursAgo": "{{h}}시간 전",
|
||||
"popup.time.daysAgo": "{{d}}일 전",
|
||||
"popup.copy": "복사",
|
||||
"popup.error.default": "오류가 발생했습니다",
|
||||
"popup.caption.loading": "⏳ STT 모델 로딩 중..."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,20 @@ interface PopupThemeVars {
|
|||
'--d3-action-btn-hover-bg': string
|
||||
/** 결과 팝업 버튼 hover 색상 */
|
||||
'--d3-action-btn-hover': string
|
||||
/** recording-tip 9단계 wave-bar 색상 (wave1~4 보간) */
|
||||
'--d3-wave-1': string
|
||||
'--d3-wave-2': string
|
||||
'--d3-wave-3': string
|
||||
'--d3-wave-4': string
|
||||
'--d3-wave-5': string
|
||||
'--d3-wave-6': string
|
||||
'--d3-wave-7': string
|
||||
'--d3-wave-8': string
|
||||
'--d3-wave-9': string
|
||||
/** 에러 상태 색상 (recording-tip error-icon) */
|
||||
'--d3-status-error': string
|
||||
/** 성공 상태 색상 (result-popup copied 상태) */
|
||||
'--d3-status-success': string
|
||||
}
|
||||
|
||||
const POPUP_THEME_VARS: Record<PopupThemeKey, PopupThemeVars> = {
|
||||
|
|
@ -68,6 +82,18 @@ const POPUP_THEME_VARS: Record<PopupThemeKey, PopupThemeVars> = {
|
|||
'--d3-action-btn': '#60a5fa',
|
||||
'--d3-action-btn-hover-bg': 'rgba(59,130,246,0.14)',
|
||||
'--d3-action-btn-hover': '#93a4c8',
|
||||
// wave-bar 9단계: theme.ts RAW.dark.gradient.wave1-4 보간
|
||||
'--d3-wave-1': '#22d3ee',
|
||||
'--d3-wave-2': '#28bef0',
|
||||
'--d3-wave-3': '#2fa9f2',
|
||||
'--d3-wave-4': '#3596f4',
|
||||
'--d3-wave-5': '#3b82f6',
|
||||
'--d3-wave-6': '#4f78f6',
|
||||
'--d3-wave-7': '#636ff6',
|
||||
'--d3-wave-8': '#7765f6',
|
||||
'--d3-wave-9': '#8b5cf6',
|
||||
'--d3-status-error': '#ef4444',
|
||||
'--d3-status-success': '#34d399',
|
||||
},
|
||||
light: {
|
||||
'--d3-bg-card': '#ffffff',
|
||||
|
|
@ -89,6 +115,18 @@ const POPUP_THEME_VARS: Record<PopupThemeKey, PopupThemeVars> = {
|
|||
'--d3-action-btn': '#3b82f6',
|
||||
'--d3-action-btn-hover-bg': 'rgba(37,99,235,0.10)',
|
||||
'--d3-action-btn-hover': '#4b5a75',
|
||||
// theme.ts RAW.light.gradient.wave1-4 보간
|
||||
'--d3-wave-1': '#06b6d4',
|
||||
'--d3-wave-2': '#1cbff8',
|
||||
'--d3-wave-3': '#32bbfc',
|
||||
'--d3-wave-4': '#3b82f6',
|
||||
'--d3-wave-5': '#4966eb',
|
||||
'--d3-wave-6': '#574ae0',
|
||||
'--d3-wave-7': '#6c2edd',
|
||||
'--d3-wave-8': '#8112da',
|
||||
'--d3-wave-9': '#d946ef',
|
||||
'--d3-status-error': '#ef4444',
|
||||
'--d3-status-success': '#34d399',
|
||||
},
|
||||
nord: {
|
||||
'--d3-bg-card': '#3b4252',
|
||||
|
|
@ -110,6 +148,18 @@ const POPUP_THEME_VARS: Record<PopupThemeKey, PopupThemeVars> = {
|
|||
'--d3-action-btn': 'rgba(216,222,233,0.4)',
|
||||
'--d3-action-btn-hover-bg': 'rgba(216,222,233,0.08)',
|
||||
'--d3-action-btn-hover': 'rgba(216,222,233,0.7)',
|
||||
// theme.ts RAW.nord.gradient.wave1-4 보간
|
||||
'--d3-wave-1': '#8fbcbb',
|
||||
'--d3-wave-2': '#8dbdcd',
|
||||
'--d3-wave-3': '#8bbea0',
|
||||
'--d3-wave-4': '#88c0d0',
|
||||
'--d3-wave-5': '#85c6d0',
|
||||
'--d3-wave-6': '#a3be8c',
|
||||
'--d3-wave-7': '#b48ead',
|
||||
'--d3-wave-8': '#bf88a8',
|
||||
'--d3-wave-9': '#d08770',
|
||||
'--d3-status-error': '#bf616a',
|
||||
'--d3-status-success': '#a3be8c',
|
||||
},
|
||||
solarized: {
|
||||
'--d3-bg-card': '#073642',
|
||||
|
|
@ -131,6 +181,18 @@ const POPUP_THEME_VARS: Record<PopupThemeKey, PopupThemeVars> = {
|
|||
'--d3-action-btn': 'rgba(147,161,161,0.4)',
|
||||
'--d3-action-btn-hover-bg': 'rgba(131,148,150,0.10)',
|
||||
'--d3-action-btn-hover': 'rgba(147,161,161,0.7)',
|
||||
// theme.ts RAW.solarized.gradient.wave1-4 보간
|
||||
'--d3-wave-1': '#2aa198',
|
||||
'--d3-wave-2': '#2693cb',
|
||||
'--d3-wave-3': '#268bd2',
|
||||
'--d3-wave-4': '#268bd2',
|
||||
'--d3-wave-5': '#4676d9',
|
||||
'--d3-wave-6': '#6c71c4',
|
||||
'--d3-wave-7': '#6c71c4',
|
||||
'--d3-wave-8': '#9a33d3',
|
||||
'--d3-wave-9': '#d33682',
|
||||
'--d3-status-error': '#dc322f',
|
||||
'--d3-status-success': '#859900',
|
||||
},
|
||||
catppuccin: {
|
||||
'--d3-bg-card': '#313244',
|
||||
|
|
@ -152,6 +214,18 @@ const POPUP_THEME_VARS: Record<PopupThemeKey, PopupThemeVars> = {
|
|||
'--d3-action-btn': 'rgba(166,173,200,0.4)',
|
||||
'--d3-action-btn-hover-bg': 'rgba(205,214,244,0.06)',
|
||||
'--d3-action-btn-hover': 'rgba(205,214,244,0.7)',
|
||||
// theme.ts RAW.catppuccin.gradient.wave1-4 보간
|
||||
'--d3-wave-1': '#89dceb',
|
||||
'--d3-wave-2': '#89cff4',
|
||||
'--d3-wave-3': '#89c2f9',
|
||||
'--d3-wave-4': '#89b4fa',
|
||||
'--d3-wave-5': '#b4a9f2',
|
||||
'--d3-wave-6': '#df9eea',
|
||||
'--d3-wave-7': '#cba6f7',
|
||||
'--d3-wave-8': '#e5b6f6',
|
||||
'--d3-wave-9': '#f5c2e7',
|
||||
'--d3-status-error': '#f38ba8',
|
||||
'--d3-status-success': '#a6e3a1',
|
||||
},
|
||||
dracula: {
|
||||
'--d3-bg-card': '#44475a',
|
||||
|
|
@ -173,6 +247,18 @@ const POPUP_THEME_VARS: Record<PopupThemeKey, PopupThemeVars> = {
|
|||
'--d3-action-btn': 'rgba(169,176,208,0.4)',
|
||||
'--d3-action-btn-hover-bg': 'rgba(248,248,242,0.06)',
|
||||
'--d3-action-btn-hover': 'rgba(248,248,242,0.7)',
|
||||
// theme.ts RAW.dracula.gradient.wave1-4 보간
|
||||
'--d3-wave-1': '#8be9fd',
|
||||
'--d3-wave-2': '#a6fbff',
|
||||
'--d3-wave-3': '#c1fdff',
|
||||
'--d3-wave-4': '#bd93f9',
|
||||
'--d3-wave-5': '#d485ff',
|
||||
'--d3-wave-6': '#eb77ff',
|
||||
'--d3-wave-7': '#ff79c6',
|
||||
'--d3-wave-8': '#ff88c4',
|
||||
'--d3-wave-9': '#ffb86c',
|
||||
'--d3-status-error': '#ff5555',
|
||||
'--d3-status-success': '#50fa7b',
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue