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

@@ -4,5 +4,6 @@ pub mod hardware;
pub mod history;
pub mod models;
pub mod tasks;
pub mod timer;
pub mod transcription;
pub mod windows;

View File

@@ -0,0 +1,56 @@
use serde::Serialize;
use crate::AppState;
use kon_storage::{clear_timer_state, get_timer_state, save_timer_state};
/// Serialisable timer state response.
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TimerStateResponse {
pub task_id: String,
pub total_seconds: i64,
pub remaining_seconds: i64,
pub started_at: String,
pub paused: bool,
}
/// Save or update the active timer state.
#[tauri::command]
pub async fn save_timer(
state: tauri::State<'_, AppState>,
task_id: String,
total_seconds: i64,
remaining_seconds: i64,
paused: bool,
) -> Result<(), String> {
save_timer_state(&state.db, &task_id, total_seconds, remaining_seconds, paused)
.await
.map_err(|e| e.to_string())
}
/// Retrieve the active timer state (for context restoration on app restart).
#[tauri::command]
pub async fn get_timer(
state: tauri::State<'_, AppState>,
) -> Result<Option<TimerStateResponse>, String> {
let row = get_timer_state(&state.db)
.await
.map_err(|e| e.to_string())?;
Ok(row.map(|r| TimerStateResponse {
task_id: r.task_id,
total_seconds: r.total_seconds,
remaining_seconds: r.remaining_seconds,
started_at: r.started_at,
paused: r.paused,
}))
}
/// Clear the active timer (completed or cancelled).
#[tauri::command]
pub async fn clear_timer(
state: tauri::State<'_, AppState>,
) -> Result<(), String> {
clear_timer_state(&state.db)
.await
.map_err(|e| e.to_string())
}