From fe3739fdbbdd657d902f96eb1f76cb6a2e28c0eb Mon Sep 17 00:00:00 2001 From: jake Date: Mon, 16 Mar 2026 23:26:27 +0000 Subject: [PATCH] fix(kon): task sidebar overlay, Parakeet model management, conditional engine settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TaskSidebar: - Changed from flex layout member to fixed overlay with backdrop - Click backdrop or press Escape to close - Content no longer shrinks when sidebar opens — buttons stay accessible - Positioned at z-50 over main content, top offset for titlebar Settings — Parakeet model management: - Added Parakeet model state: download, check, load status - New downloadParakeet() and loadParakeet() functions - Listens for parakeet-download-progress events - Parakeet section shows download/load/status controls Settings — conditional engine sections: - Whisper model selector only shows when engine === "whisper" - Parakeet model controls only show when engine === "parakeet" - Cleaner UI — only active engine's options visible Co-Authored-By: Claude Opus 4.6 (1M context) --- src/lib/pages/SettingsPage.svelte | 132 ++++++++++++++++++++++++------ src/routes/+layout.svelte | 21 +++-- 2 files changed, 122 insertions(+), 31 deletions(-) diff --git a/src/lib/pages/SettingsPage.svelte b/src/lib/pages/SettingsPage.svelte index 5c002cd..0352d6a 100644 --- a/src/lib/pages/SettingsPage.svelte +++ b/src/lib/pages/SettingsPage.svelte @@ -16,6 +16,14 @@ let downloadProgress = $state(0); let unlisten = null; + // Parakeet state + let parakeetStatus = $state("Checking..."); + let parakeetOk = $state(false); + let parakeetDownloaded = $state(false); + let parakeetDownloading = $state(false); + let parakeetProgress = $state(0); + let unlistenParakeet = null; + // Profiles & Templates let showProfiles = $state(false); let showTemplates = $state(false); @@ -39,13 +47,27 @@ downloadedModels = await invoke("list_models"); } catch {} + // Parakeet status + try { + parakeetOk = await invoke("check_parakeet_engine"); + parakeetDownloaded = await invoke("check_parakeet_model", { name: "ctc-int8" }); + parakeetStatus = parakeetOk ? "Model loaded" : parakeetDownloaded ? "Downloaded (not loaded)" : "Not downloaded"; + } catch { + parakeetStatus = "Engine not ready"; + } + unlisten = await listen("model-download-progress", (event) => { - downloadProgress = event.payload.progress; + downloadProgress = event.payload.percent || event.payload.progress || 0; + }); + + unlistenParakeet = await listen("parakeet-download-progress", (event) => { + parakeetProgress = event.payload.percent || event.payload.progress || 0; }); }); onDestroy(() => { if (unlisten) unlisten(); + if (unlistenParakeet) unlistenParakeet(); }); // Auto-save on any change @@ -105,6 +127,33 @@ Medium: "~1.5GB · best quality, slower", }; + async function downloadParakeet() { + parakeetDownloading = true; + parakeetProgress = 0; + try { + await invoke("download_parakeet_model", { name: "ctc-int8" }); + parakeetDownloaded = true; + parakeetDownloading = false; + parakeetStatus = "Downloaded (not loaded)"; + } catch { + parakeetDownloading = false; + parakeetStatus = "Download failed"; + } + } + + async function loadParakeet() { + parakeetStatus = "Loading..."; + parakeetOk = false; + try { + await invoke("load_parakeet_model", { name: "ctc-int8" }); + parakeetOk = true; + parakeetStatus = "Model loaded"; + } catch (err) { + parakeetOk = false; + parakeetStatus = typeof err === "string" ? err : "Load failed"; + } + } + // --- Profile management --- function createProfile() { if (!newProfileName.trim()) return; @@ -180,33 +229,64 @@

- -
-

Whisper Model

- -

{modelDescriptions[settings.modelSize]}

+ + {#if settings.engine === "whisper"} +
+

Whisper Model

+ +

{modelDescriptions[settings.modelSize]}

- -
- {#if isModelDownloaded(settings.modelSize)} - - - Downloaded - - - {:else if downloadingModel === settings.modelSize.toLowerCase()} - {downloadProgress}% downloading... - {:else} - - {/if} +
+ {#if isModelDownloaded(settings.modelSize)} + + + Downloaded + + + {:else if downloadingModel === settings.modelSize.toLowerCase()} + {downloadProgress}% downloading... + {:else} + + {/if} +
-
+ {:else} +
+

Parakeet Model

+

Parakeet CTC 0.6B (int8) — ~613MB, near-instant transcription

+ +
+ {#if parakeetOk} + + + Model loaded + + {:else if parakeetDownloaded} + + + Downloaded + + + {:else if parakeetDownloading} + {parakeetProgress}% downloading... + {:else} + + {/if} +
+
+ {/if}
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index f1d0e64..68a50cd 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -98,7 +98,7 @@ }); - + { if (e.key === "Escape" && page.taskSidebarOpen) page.taskSidebarOpen = false; }} /> {#if page.recording}
-
+
{#if page.current !== "first-run"} {/if}
{@render children()}
- {#if page.taskSidebarOpen && page.current !== "first-run"} - - {/if}
+ + + {#if page.taskSidebarOpen && page.current !== "first-run" && !isSecondaryWindow} + + + +
+ +
+ {/if} {/if}