diff --git a/apps/desktop/electron/event-dedupe.ts b/apps/desktop/electron/event-dedupe.ts index ec14d67e851b..a2d12a8f2cba 100644 --- a/apps/desktop/electron/event-dedupe.ts +++ b/apps/desktop/electron/event-dedupe.ts @@ -2,22 +2,21 @@ // sound, spoken replies). Every desktop window is its own renderer process, so N // open windows each independently react to the same backend event. The main // process is the one place they all share and it handles IPC serially, so it's -// the race-free owner: the first window to claim a key within the window wins; -// peers see it's taken and stay quiet. -// -// Pure + injectable clock so it's unit-testable without Electron. +// the race-free owner: the first window to claim a key within the interval wins; +// peers see it's taken and stay quiet. Pure + injectable clock, so it's +// unit-testable without Electron. -const DEDUPE_WINDOW_MS = 1000 +const DEDUPE_INTERVAL_MS = 1000 -// Returns true when `key` was already claimed within the window (caller drops +// Returns true when `key` was already claimed within the interval (caller drops // this one). Self-evicting: stale keys are pruned on every call, so the map // can't grow unbounded. -function createEventDeduper(windowMs = DEDUPE_WINDOW_MS) { +export function createEventDeduper(intervalMs = DEDUPE_INTERVAL_MS) { const lastSeenAt = new Map() return function isDuplicate(key: string, now = Date.now()): boolean { for (const [k, at] of lastSeenAt) { - if (now - at >= windowMs) { + if (now - at >= intervalMs) { lastSeenAt.delete(k) } } @@ -31,5 +30,3 @@ function createEventDeduper(windowMs = DEDUPE_WINDOW_MS) { return false } } - -export { createEventDeduper, DEDUPE_WINDOW_MS } diff --git a/apps/desktop/src/lib/completion-sound.ts b/apps/desktop/src/lib/completion-sound.ts index f1faa150bf0f..1557c58e419e 100644 --- a/apps/desktop/src/lib/completion-sound.ts +++ b/apps/desktop/src/lib/completion-sound.ts @@ -462,17 +462,13 @@ export function playCompletionSound(dedupeKey?: string) { return } - if (!dedupeKey) { - playVariant($completionSoundVariantId.get()) + const play = () => playVariant($completionSoundVariantId.get()) - return + if (!dedupeKey) { + return play() } - void ownsAmbientCue(`sound:${dedupeKey}`).then(owns => { - if (owns) { - playVariant($completionSoundVariantId.get()) - } - }) + void ownsAmbientCue(`sound:${dedupeKey}`).then(owns => owns && play()) } interface AirPuffSpec {