feat: add file watchers for whisper models and settings#27
Conversation
Watch the models directory and settings file for external changes, emitting events to the frontend so the UI stays reactive without manual refreshes. Includes 500ms debounce, .bin file filtering, and cross-platform parent-directory watching for settings. Closes CodeRabbit suggestion from PR #2.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds a Whisper file-watching subsystem: registers a new WhisperWatcherState with two mutex-protected watchers, initializes filesystem watchers for models and settings at startup, emits "whisper:models-changed" and "whisper:settings-changed" events, and adds frontend listeners that refresh UI when the whisper settings modal is open. Changes
Sequence Diagram(s)sequenceDiagram
participant FS as Filesystem
participant Watcher as Whisper Watchers
participant App as Tauri App
participant UI as Renderer
FS->>Watcher: filesystem event (.bin create/remove/rename or settings modify)
activate Watcher
Watcher->>Watcher: debounce (500ms) & filter relevant event
Watcher-->>App: emit "whisper:models-changed" / "whisper:settings-changed"
deactivate Watcher
rect rgba(100, 200, 100, 0.5)
App->>UI: deliver event to renderer
UI->>UI: check if whisper settings modal is visible
alt modal visible
UI->>App: call loadModelList() or get_whisper_settings
App-->>UI: respond with updated models/settings
UI->>UI: update model list / inputs
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/tauri/src/main.js`:
- Around line 1105-1118: The settings-changed handler
(listen("whisper:settings-changed") / invoke("get_whisper_settings")) currently
only updates shortcut/threshold inputs; extend it to also refresh the modal's
model selection UI so external changes to active_model are reflected without
reopening. After fetching settings, locate the model buttons inside the modal
(e.g., elements with a class or data attribute used for model selection, such as
".model-btn" or data-model), remove any existing "active" state from them, and
add the "active" class/state to the button whose model id matches
settings.active_model (also handle a null/undefined active_model by clearing
active state). Ensure the logic runs only when modal && modal.style.display ===
"flex" to avoid unnecessary DOM ops.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
apps/tauri/src-tauri/src/lib.rsapps/tauri/src-tauri/src/whisper/mod.rsapps/tauri/src-tauri/src/whisper/watcher.rsapps/tauri/src/main.js
| listen("whisper:settings-changed", async () => { | ||
| const modal = document.getElementById("whisper-settings-modal"); | ||
| if (modal && modal.style.display === "flex") { | ||
| try { | ||
| const settings = await invoke("get_whisper_settings"); | ||
| const shortcutInput = document.getElementById("shortcut-input"); | ||
| const thresholdInput = document.getElementById("threshold-input"); | ||
| if (shortcutInput) shortcutInput.value = settings.shortcut || "Alt+Space"; | ||
| if (thresholdInput) thresholdInput.value = settings.long_recording_threshold || 60; | ||
| } catch (e) { | ||
| console.warn("Failed to refresh whisper settings:", e); | ||
| } | ||
| } | ||
| }); |
There was a problem hiding this comment.
Refresh model activation UI on settings-file changes.
Line 1109 reloads settings, but this handler only updates shortcut/threshold inputs. If active_model changes externally, the modal’s model buttons can stay stale until reopening.
💡 Proposed fix
listen("whisper:settings-changed", async () => {
const modal = document.getElementById("whisper-settings-modal");
if (modal && modal.style.display === "flex") {
try {
const settings = await invoke("get_whisper_settings");
const shortcutInput = document.getElementById("shortcut-input");
const thresholdInput = document.getElementById("threshold-input");
if (shortcutInput) shortcutInput.value = settings.shortcut || "Alt+Space";
if (thresholdInput) thresholdInput.value = settings.long_recording_threshold || 60;
+ await loadModelList();
} catch (e) {
console.warn("Failed to refresh whisper settings:", e);
}
}
});🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/tauri/src/main.js` around lines 1105 - 1118, The settings-changed
handler (listen("whisper:settings-changed") / invoke("get_whisper_settings"))
currently only updates shortcut/threshold inputs; extend it to also refresh the
modal's model selection UI so external changes to active_model are reflected
without reopening. After fetching settings, locate the model buttons inside the
modal (e.g., elements with a class or data attribute used for model selection,
such as ".model-btn" or data-model), remove any existing "active" state from
them, and add the "active" class/state to the button whose model id matches
settings.active_model (also handle a null/undefined active_model by clearing
active state). Ensure the logic runs only when modal && modal.style.display ===
"flex" to avoid unnecessary DOM ops.
- Remove unused `_models_dir` parameter from `create_models_watcher` - Canonicalize settings file path for reliable macOS FSEvents matching - Make models/settings watcher setup independent (one failing doesn't block the other) - Use graceful mutex locking in `should_emit` (return false on poison instead of panicking the watcher thread) - Extend settings-changed handler to also refresh model list so external active_model changes are reflected without reopening modal - Add doc comments for debounce rationale and self-trigger behavior
Summary
notify-based file watchers for the Whisper models directory (~/.arandu/models/) and settings file (whisper-settings.json), emitting Tauri events so the frontend can reactively refresh without manual interventionwhisper/watcher.rsmodule follows the existingWatcherState/create_file_watcherpattern fromlib.rsMotivation
During PR #2 review, CodeRabbit suggested adding file watching for the Whisper models directory and settings file. This enables the app to stay in sync when:
What changed
src-tauri/src/whisper/watcher.rsWhisperWatcherState, watcher creation helpers,init()functionsrc-tauri/src/whisper/mod.rspub mod watcherexportsrc-tauri/src/lib.rsWhisperWatcherStatein.manage(), callwatcher::init()insetup()src/main.jswhisper:models-changedandwhisper:settings-changedevent listenersDesign decisions
notifyv7 crate; debounce usesstd::time::Instant(notokio::timeornotify-debouncer-minineeded)Create/Remove/Modify(Name)for.binfiles, ignoring.tmppartial downloads; settings watcher fires onCreate/Modifyverified against the exact file pathopenWhisperSettings()call loads fresh data naturallyTest plan
.binfile to~/.arandu/models/→ verify UI refreshes if modal is openwhisper-settings.jsonexternally → verify shortcut/threshold fields update if modal is open.tmpwrites should be filtered)Closes #4
Summary by CodeRabbit
New Features
Bug Fixes