//! Snooze and waiting-for-response commands for tasks. use std::sync::Arc; use tauri::State; use tracing::instrument; use goingson_core::TaskId; use crate::state::{AppState, DESKTOP_USER_ID}; use super::{ApiError, OptionNotFound, SnoozeInput, WaitingInput}; use super::task::TaskResponse; // ============ Snooze Commands ============ /// Lists all currently snoozed tasks. /// /// # Errors /// /// Returns `DATABASE_ERROR` if the query fails. #[tauri::command] #[instrument(skip_all)] pub async fn list_snoozed_tasks(state: State<'_, Arc>) -> Result, ApiError> { let tasks = state.tasks.list_snoozed(DESKTOP_USER_ID).await?; Ok(tasks.into_iter().map(TaskResponse::from).collect()) } /// Snoozes a task until the specified date/time. /// /// Snoozed tasks are hidden from the main task list until their snooze expires. /// /// # Errors /// /// Returns `NOT_FOUND` if the task doesn't exist. /// Returns `DATABASE_ERROR` if the update fails. #[tauri::command] #[instrument(skip_all)] pub async fn snooze_task(state: State<'_, Arc>, id: TaskId, input: SnoozeInput) -> Result { let task = state.tasks .snooze(id, DESKTOP_USER_ID, input.until) .await? .or_not_found("task", id)?; Ok(TaskResponse::from(task)) } /// Removes the snooze from a task, making it visible again. /// /// # Errors /// /// Returns `NOT_FOUND` if the task doesn't exist. /// Returns `DATABASE_ERROR` if the update fails. #[tauri::command] #[instrument(skip_all)] pub async fn unsnooze_task(state: State<'_, Arc>, id: TaskId) -> Result { let task = state.tasks .unsnooze(id, DESKTOP_USER_ID) .await? .or_not_found("task", id)?; Ok(TaskResponse::from(task)) } // ============ Waiting Commands ============ /// Lists all tasks marked as waiting for a response. /// /// # Errors /// /// Returns `DATABASE_ERROR` if the query fails. #[tauri::command] #[instrument(skip_all)] pub async fn list_waiting_tasks(state: State<'_, Arc>) -> Result, ApiError> { let tasks = state.tasks.list_waiting(DESKTOP_USER_ID).await?; Ok(tasks.into_iter().map(TaskResponse::from).collect()) } /// Marks a task as waiting for an external response. /// /// Use this when you're blocked waiting for someone else (email reply, approval, etc.). /// /// # Errors /// /// Returns `NOT_FOUND` if the task doesn't exist. /// Returns `DATABASE_ERROR` if the update fails. #[tauri::command] #[instrument(skip_all)] pub async fn mark_task_waiting(state: State<'_, Arc>, id: TaskId, input: WaitingInput) -> Result { let task = state.tasks .mark_waiting(id, DESKTOP_USER_ID, input.expected_response_date) .await? .or_not_found("task", id)?; Ok(TaskResponse::from(task)) } /// Clears the waiting status from a task. /// /// # Errors /// /// Returns `NOT_FOUND` if the task doesn't exist. /// Returns `DATABASE_ERROR` if the update fails. #[tauri::command] #[instrument(skip_all)] pub async fn clear_task_waiting(state: State<'_, Arc>, id: TaskId) -> Result { let task = state.tasks .clear_waiting(id, DESKTOP_USER_ID) .await? .or_not_found("task", id)?; Ok(TaskResponse::from(task)) }