feat(timer): wire VisualTimer to tasks with notifications and persistence

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
jake
2026-03-21 13:59:12 +00:00
parent f1ef171acb
commit 2fc4ee7087
11 changed files with 371 additions and 5 deletions

View File

@@ -5,6 +5,7 @@
import Sidebar from "$lib/Sidebar.svelte";
import TaskSidebar from "$lib/components/TaskSidebar.svelte";
import Titlebar from "$lib/components/Titlebar.svelte";
import TaskTimer from "$lib/components/TaskTimer.svelte";
import { page, settings, saveSettings } from "$lib/stores/page.svelte.js";
import { getPreferences, updatePreferences } from "$lib/stores/preferences.svelte.js";
@@ -14,6 +15,16 @@
const prefs = getPreferences();
// Task timer — bound component for cross-page timer control
let taskTimer = $state(null);
function handleStartTimer(e) {
if (taskTimer) {
const { id, text, duration } = e.detail;
taskTimer.startTimer(id, text, duration || 120);
}
}
// Detect secondary windows (float, viewer) — they use +layout@.svelte
// but as a fallback, hide chrome if the URL matches
let isSecondaryWindow = $derived(
@@ -99,6 +110,7 @@
// Auto-collapse if window is already narrow on first load
handleResize();
window.addEventListener("resize", handleResize);
window.addEventListener("kon:start-timer", handleStartTimer);
try {
const whisper = await invoke("list_models");
@@ -113,6 +125,7 @@
onDestroy(() => {
window.removeEventListener("resize", handleResize);
window.removeEventListener("kon:start-timer", handleStartTimer);
if (registeredHotkey) {
import("@tauri-apps/plugin-global-shortcut")
.then((mod) => mod.unregister(registeredHotkey))
@@ -140,8 +153,12 @@
{#if page.current !== "first-run"}
<Sidebar />
{/if}
<div class="flex-1 overflow-hidden bg-bg">
{@render children()}
<div class="flex-1 overflow-hidden bg-bg flex flex-col">
<!-- Active timer (persists across page navigation) -->
<TaskTimer bind:this={taskTimer} />
<div class="flex-1 overflow-hidden">
{@render children()}
</div>
</div>
</div>
</div>