Skip to content

Commit 7c7dfcb

Browse files
committed
feat: broadcast history updates and hotkey restart via IPC
- IPC handler broadcasts history:updated to all windows after dictation - Preload exposes onHistoryUpdated listener for live UI refresh - Settings update triggers hotkey listener restart when hotkey changes - Add broadcast dependency to IPC handler interface
1 parent 4013e3a commit 7c7dfcb

3 files changed

Lines changed: 23 additions & 1 deletion

File tree

src/main/ipc.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ interface IpcDependencies {
3030
showMainWindow: () => void;
3131
hideMainWindow: () => void;
3232
ensureHotkeyListener: () => Promise<void>;
33+
restartHotkeyListener: () => Promise<void>;
34+
broadcast: (channel: string, payload: unknown) => void;
3335
}
3436

3537
export function registerIpcHandlers(dependencies: IpcDependencies): void {
@@ -65,10 +67,19 @@ export function registerIpcHandlers(dependencies: IpcDependencies): void {
6567
ipcMain.handle('app:bootstrap', buildBootstrapState);
6668

6769
ipcMain.handle('settings:update', async (_event, updates: UpdateSettingsInput) => {
70+
const previousHotkey = dependencies.getSettings().hotkey;
6871
const nextSettings = await persistSettings(dependencies.getSettings(), updates);
6972
await ensureStorage(nextSettings);
7073
applyLaunchAtLogin(nextSettings.launchAtLogin);
7174
dependencies.setSettings(nextSettings);
75+
76+
if (updates.hotkey && (
77+
updates.hotkey.keyCode !== previousHotkey.keyCode ||
78+
updates.hotkey.modifiers !== previousHotkey.modifiers
79+
)) {
80+
await dependencies.restartHotkeyListener();
81+
}
82+
7283
return buildBootstrapState();
7384
});
7485

@@ -220,7 +231,7 @@ export function registerIpcHandlers(dependencies: IpcDependencies): void {
220231
setStatus: dependencies.setStatus,
221232
});
222233

223-
await addHistoryEntry({
234+
const history = await addHistoryEntry({
224235
rawText: result.rawText,
225236
finalText: result.finalText,
226237
transcriptionSource: result.transcriptionSource,
@@ -229,8 +240,13 @@ export function registerIpcHandlers(dependencies: IpcDependencies): void {
229240
appName: result.focusInfo?.appName,
230241
}).catch((error) => {
231242
console.warn('[openwhisp] Failed to save history entry:', error instanceof Error ? error.message : error);
243+
return null;
232244
});
233245

246+
if (history) {
247+
dependencies.broadcast('history:updated', history);
248+
}
249+
234250
return result;
235251
});
236252

src/preload/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ const api = {
7272
ipcRenderer.on('hotkey:event', wrapped);
7373
return () => ipcRenderer.removeListener('hotkey:event', wrapped);
7474
},
75+
onHistoryUpdated: (listener: (history: HistoryEntry[]) => void) => {
76+
const wrapped = (_event: Electron.IpcRendererEvent, history: HistoryEntry[]) => listener(history);
77+
ipcRenderer.on('history:updated', wrapped);
78+
return () => ipcRenderer.removeListener('history:updated', wrapped);
79+
},
7580
};
7681

7782
contextBridge.exposeInMainWorld('openWhisp', api);

src/renderer/env.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ declare global {
4848
revealStorage: () => Promise<void>;
4949
onStatus: (listener: (status: AppStatus) => void) => () => void;
5050
onHotkey: (listener: (event: HotkeyEvent) => void) => () => void;
51+
onHistoryUpdated: (listener: (history: HistoryEntry[]) => void) => () => void;
5152
};
5253
}
5354
}

0 commit comments

Comments
 (0)