perf(meeting): only run process poller while auto-capture is enabled
Previously the 15-second meeting-detection setInterval was started in onMount unconditionally (when Tauri runtime was available). When `settings.meetingAutoCapture` was disabled the callback still fired every 15 s, just to early-return — burning a wakeup that did no useful work and confusing "is this firing? did the toggle take effect?" debugging. Move the timer into a `$effect` whose only tracked dependency is `settings.meetingAutoCapture`. Toggling off now clears the interval; toggling on creates a fresh one. Reads of `meetingAutoCaptureApps` and `globalHotkey` happen inside the interval callback (post-setup) so they don't trigger the effect to tear down on every keystroke in the apps editor. The `meetingCapturePoller` variable and its `onDestroy` cleanup are gone — the effect's own cleanup return takes care of it on unmount. https://claude.ai/code/session_0189xUb6ie6t9qHkzatGZ9Rb
This commit is contained in:
@@ -340,14 +340,28 @@
|
||||
invoke("prewarm_default_model_cmd").catch(() => {});
|
||||
}
|
||||
|
||||
// Meeting auto-capture: poll the process list and toast when a match
|
||||
// appears (edge-triggered — no repeat toasts until the app goes away
|
||||
// and comes back). We never start recording from this signal; the
|
||||
// user decides whether to hit the hotkey.
|
||||
if (tauriRuntimeAvailable) {
|
||||
// Meeting auto-capture is wired up below as a `$effect` so the
|
||||
// 15-second poller only exists while the setting is enabled —
|
||||
// toggling off in Settings stops the wakeups, not just the work.
|
||||
});
|
||||
|
||||
// Meeting auto-capture poller. Edge-triggered: the first time a matching
|
||||
// process appears we surface a non-modal toast; subsequent ticks where
|
||||
// the same match is still present stay quiet until the app exits and
|
||||
// returns. We never start recording from this signal — the user decides.
|
||||
//
|
||||
// The effect's only tracked dependencies are `tauriRuntimeAvailable`
|
||||
// (constant after mount) and `settings.meetingAutoCapture`. Reads of
|
||||
// `settings.meetingAutoCaptureApps` and `settings.globalHotkey` happen
|
||||
// inside the interval callback, which runs after the synchronous setup
|
||||
// and therefore is not tracked — editing the apps list doesn't tear
|
||||
// down the poller.
|
||||
$effect(() => {
|
||||
if (!tauriRuntimeAvailable) return;
|
||||
if (!settings.meetingAutoCapture) return;
|
||||
|
||||
let previous: Set<string> = new Set();
|
||||
meetingCapturePoller = window.setInterval(async () => {
|
||||
if (!settings.meetingAutoCapture) { previous = new Set(); return; }
|
||||
const id = window.setInterval(async () => {
|
||||
const patterns = settings.meetingAutoCaptureApps;
|
||||
if (!Array.isArray(patterns) || patterns.length === 0) return;
|
||||
try {
|
||||
@@ -364,19 +378,14 @@
|
||||
previous = current;
|
||||
} catch { /* ignore — backend may be mid-restart */ }
|
||||
}, 15000);
|
||||
}
|
||||
});
|
||||
|
||||
let meetingCapturePoller: number | null = null;
|
||||
return () => { window.clearInterval(id); };
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
window.removeEventListener("resize", handleResize);
|
||||
if (onWindowError) window.removeEventListener("error", onWindowError);
|
||||
if (onUnhandledRejection) window.removeEventListener("unhandledrejection", onUnhandledRejection);
|
||||
if (meetingCapturePoller !== null) {
|
||||
window.clearInterval(meetingCapturePoller);
|
||||
meetingCapturePoller = null;
|
||||
}
|
||||
if (!tauriRuntimeAvailable) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user