feat(desktop): honest, unified dictation popups with Esc to cancel
Wave 3 of the 2026-09-28 design overhaul. - Esc (no modifiers) cancels an in-progress dictation, recording or processing: VoiceModeService.requestEscape() queues the dead 'escape' action. Clicking the capsule cancels only while recording, so a stray click during processing no longer throws the text away. - Errors show in the user's language: bootstrap now passes error.code to the tip (the translated branch never ran), and one core classifier (voice-error-message) feeds both the tip and the main-window alert. - Capsule: bars stay flat without input (no fake "alive" wobble before the mic opens), an indeterminate bar replaces the made-up percentage, the partial transcript stays visible while processing, an Esc hint, and a brief "Inserted" state so success is visible. - All six popups share popups/_shared (Pretendard, one panel radius, selection, kbd hints, reduced motion). History/command popups get titles, listbox roles and window sizes from popup-list-geometry (empty states were clipped); the command popup's "0" key is registered; result popup explains why it appeared and can be closed; captions keep a theme-independent dark backing on purpose. - Popup themes follow the OS when set to system and the document lang follows the app language. - Site hero demo mirrors the new capsule (done state, indeterminate bar, Esc hint; 10 locales).
This commit is contained in:
parent
f064c93197
commit
7b1210b5d1
41 changed files with 1565 additions and 1143 deletions
|
|
@ -15,6 +15,7 @@ interface FakeWebContents {
|
|||
send: (channel: string, data: unknown) => void
|
||||
isDestroyed: () => boolean
|
||||
insertCSS: () => Promise<string>
|
||||
executeJavaScript: () => Promise<unknown>
|
||||
invalidate: () => void
|
||||
setWindowOpenHandler: () => void
|
||||
}
|
||||
|
|
@ -56,6 +57,7 @@ vi.mock('electron', () => {
|
|||
},
|
||||
isDestroyed: () => false,
|
||||
insertCSS: async () => '',
|
||||
executeJavaScript: async () => undefined,
|
||||
invalidate: () => undefined,
|
||||
setWindowOpenHandler: () => undefined
|
||||
}
|
||||
|
|
@ -91,6 +93,8 @@ vi.mock('electron', () => {
|
|||
|
||||
const scaled = (value: number): number => Math.round(value / state.scale)
|
||||
return {
|
||||
// 팝업 테마: 시스템 테마 해석(2026-09-28)
|
||||
nativeTheme: { shouldUseDarkColors: true, on: () => undefined, removeListener: () => undefined },
|
||||
app: { quit: vi.fn(), getPath: vi.fn(() => '.'), on: vi.fn(), getVersion: vi.fn(() => '1.0.0'), isPackaged: false },
|
||||
BrowserWindow: Object.assign(FakeBrowserWindow, { getAllWindows: vi.fn(() => []) }),
|
||||
screen: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue