Make DevTools a toggle in Settings > Developer tab
Some checks failed
Release / Bump version and tag (push) Successful in 7s
Release / Build App (macOS) (push) Successful in 1m17s
Release / Build App (Windows) (push) Successful in 3m29s
Release / Build App (Linux) (push) Has been cancelled

- DevTools off by default (no more auto-open on launch)
- New "Developer" tab in Settings with a checkbox to toggle devtools
- Toggle takes effect immediately (opens/closes inspector)
- Setting persists: devtools restored on next launch if enabled
- toggle_devtools Tauri command wraps window.open/close_devtools

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude
2026-03-22 10:55:48 -07:00
parent 33443c8b00
commit 7f1fa1904c
5 changed files with 42 additions and 5 deletions

View File

@@ -32,3 +32,16 @@ pub fn save_settings(settings: Value) -> Result<(), String> {
fs::write(&path, json).map_err(|e| format!("Cannot write settings: {e}"))?; fs::write(&path, json).map_err(|e| format!("Cannot write settings: {e}"))?;
Ok(()) Ok(())
} }
/// Toggle devtools on the main window.
#[tauri::command]
pub fn toggle_devtools(app: tauri::AppHandle, open: bool) {
use tauri::Manager;
if let Some(window) = app.get_webview_window("main") {
if open {
window.open_devtools();
} else {
window.close_devtools();
}
}
}

View File

@@ -13,7 +13,7 @@ use commands::project::{
create_project, delete_project, get_project, list_projects, load_project_file, create_project, delete_project, get_project, list_projects, load_project_file,
load_project_transcript, save_project_file, save_project_transcript, update_segment, load_project_transcript, save_project_file, save_project_transcript, update_segment,
}; };
use commands::settings::{load_settings, save_settings}; use commands::settings::{load_settings, save_settings, toggle_devtools};
use commands::sidecar::{check_sidecar, check_sidecar_update, download_sidecar}; use commands::sidecar::{check_sidecar, check_sidecar_update, download_sidecar};
use commands::system::{ use commands::system::{
get_data_dir, llama_list_models, llama_start, llama_status, llama_stop, log_frontend, get_data_dir, llama_list_models, llama_start, llama_status, llama_stop, log_frontend,
@@ -41,8 +41,6 @@ pub fn run() {
// Set the webview background to match the app's dark theme // Set the webview background to match the app's dark theme
if let Some(window) = app.get_webview_window("main") { if let Some(window) = app.get_webview_window("main") {
let _ = window.set_background_color(Some(Color(10, 10, 35, 255))); let _ = window.set_background_color(Some(Color(10, 10, 35, 255)));
// Enable right-click → Inspect (requires "devtools" feature in Cargo.toml)
window.open_devtools();
} }
Ok(()) Ok(())
}) })
@@ -74,6 +72,7 @@ pub fn run() {
download_sidecar, download_sidecar,
check_sidecar_update, check_sidecar_update,
log_frontend, log_frontend,
toggle_devtools,
]) ])
.run(tauri::generate_context!()) .run(tauri::generate_context!())
.expect("error while running tauri application"); .expect("error while running tauri application");

View File

@@ -11,7 +11,7 @@
let { visible, onClose }: Props = $props(); let { visible, onClose }: Props = $props();
let localSettings = $state<AppSettings>({ ...$settings }); let localSettings = $state<AppSettings>({ ...$settings });
let activeTab = $state<'transcription' | 'speakers' | 'ai' | 'local'>('transcription'); let activeTab = $state<'transcription' | 'speakers' | 'ai' | 'local' | 'developer'>('transcription');
let modelStatus = $state<'idle' | 'downloading' | 'success' | 'error'>('idle'); let modelStatus = $state<'idle' | 'downloading' | 'success' | 'error'>('idle');
let modelError = $state(''); let modelError = $state('');
let revealedFields = $state<Set<string>>(new Set()); let revealedFields = $state<Set<string>>(new Set());
@@ -84,6 +84,9 @@
<button class="tab" class:active={activeTab === 'local'} onclick={() => activeTab = 'local'}> <button class="tab" class:active={activeTab === 'local'} onclick={() => activeTab = 'local'}>
Local AI Local AI
</button> </button>
<button class="tab" class:active={activeTab === 'developer'} onclick={() => activeTab = 'developer'}>
Developer
</button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
@@ -242,6 +245,21 @@
Place GGUF model files in ~/.voicetonotes/models/ for auto-detection. Place GGUF model files in ~/.voicetonotes/models/ for auto-detection.
The local AI server uses the OpenAI-compatible API from llama.cpp. The local AI server uses the OpenAI-compatible API from llama.cpp.
</p> </p>
{:else if activeTab === 'developer'}
<div class="field checkbox">
<label>
<input
type="checkbox"
checked={localSettings.devtools_enabled}
onchange={async (e) => {
localSettings.devtools_enabled = (e.target as HTMLInputElement).checked;
await invoke('toggle_devtools', { open: localSettings.devtools_enabled });
}}
/>
Enable Developer Tools
</label>
<p class="hint">Opens the browser inspector for debugging. Changes take effect immediately.</p>
</div>
{/if} {/if}
</div> </div>

View File

@@ -18,6 +18,7 @@ export interface AppSettings {
skip_diarization: boolean; skip_diarization: boolean;
hf_token: string; hf_token: string;
num_speakers: number | null; num_speakers: number | null;
devtools_enabled: boolean;
} }
const defaults: AppSettings = { const defaults: AppSettings = {
@@ -37,6 +38,7 @@ const defaults: AppSettings = {
skip_diarization: false, skip_diarization: false,
hf_token: '', hf_token: '',
num_speakers: null, num_speakers: null,
devtools_enabled: false,
}; };
export const settings = writable<AppSettings>({ ...defaults }); export const settings = writable<AppSettings>({ ...defaults });

View File

@@ -63,7 +63,12 @@
} }
onMount(() => { onMount(() => {
loadSettings(); loadSettings().then(() => {
// Restore devtools state from settings
if ($settings.devtools_enabled) {
invoke('toggle_devtools', { open: true });
}
});
checkSidecar().then(() => { checkSidecar().then(() => {
if (sidecarReady) { if (sidecarReady) {
checkSidecarUpdate(); checkSidecarUpdate();