Skip to main content

max / goingson

3.3 KB · 112 lines History Blame Raw
1 //! Snooze and waiting-for-response commands for tasks.
2
3 use std::sync::Arc;
4 use tauri::State;
5 use tracing::instrument;
6
7 use goingson_core::TaskId;
8
9 use crate::state::{AppState, DESKTOP_USER_ID};
10 use super::{ApiError, OptionNotFound, SnoozeInput, WaitingInput};
11 use super::task::TaskResponse;
12
13 // ============ Snooze Commands ============
14
15 /// Lists all currently snoozed tasks.
16 ///
17 /// # Errors
18 ///
19 /// Returns `DATABASE_ERROR` if the query fails.
20 #[tauri::command]
21 #[instrument(skip_all)]
22 pub async fn list_snoozed_tasks(state: State<'_, Arc<AppState>>) -> Result<Vec<TaskResponse>, ApiError> {
23 let tasks = state.tasks.list_snoozed(DESKTOP_USER_ID).await?;
24 Ok(tasks.into_iter().map(TaskResponse::from).collect())
25 }
26
27 /// Snoozes a task until the specified date/time.
28 ///
29 /// Snoozed tasks are hidden from the main task list until their snooze expires.
30 ///
31 /// # Errors
32 ///
33 /// Returns `NOT_FOUND` if the task doesn't exist.
34 /// Returns `DATABASE_ERROR` if the update fails.
35 #[tauri::command]
36 #[instrument(skip_all)]
37 pub async fn snooze_task(state: State<'_, Arc<AppState>>, id: TaskId, input: SnoozeInput) -> Result<TaskResponse, ApiError> {
38 let task = state.tasks
39 .snooze(id, DESKTOP_USER_ID, input.until)
40 .await?
41 .or_not_found("task", id)?;
42
43 Ok(TaskResponse::from(task))
44 }
45
46 /// Removes the snooze from a task, making it visible again.
47 ///
48 /// # Errors
49 ///
50 /// Returns `NOT_FOUND` if the task doesn't exist.
51 /// Returns `DATABASE_ERROR` if the update fails.
52 #[tauri::command]
53 #[instrument(skip_all)]
54 pub async fn unsnooze_task(state: State<'_, Arc<AppState>>, id: TaskId) -> Result<TaskResponse, ApiError> {
55 let task = state.tasks
56 .unsnooze(id, DESKTOP_USER_ID)
57 .await?
58 .or_not_found("task", id)?;
59
60 Ok(TaskResponse::from(task))
61 }
62
63 // ============ Waiting Commands ============
64
65 /// Lists all tasks marked as waiting for a response.
66 ///
67 /// # Errors
68 ///
69 /// Returns `DATABASE_ERROR` if the query fails.
70 #[tauri::command]
71 #[instrument(skip_all)]
72 pub async fn list_waiting_tasks(state: State<'_, Arc<AppState>>) -> Result<Vec<TaskResponse>, ApiError> {
73 let tasks = state.tasks.list_waiting(DESKTOP_USER_ID).await?;
74 Ok(tasks.into_iter().map(TaskResponse::from).collect())
75 }
76
77 /// Marks a task as waiting for an external response.
78 ///
79 /// Use this when you're blocked waiting for someone else (email reply, approval, etc.).
80 ///
81 /// # Errors
82 ///
83 /// Returns `NOT_FOUND` if the task doesn't exist.
84 /// Returns `DATABASE_ERROR` if the update fails.
85 #[tauri::command]
86 #[instrument(skip_all)]
87 pub async fn mark_task_waiting(state: State<'_, Arc<AppState>>, id: TaskId, input: WaitingInput) -> Result<TaskResponse, ApiError> {
88 let task = state.tasks
89 .mark_waiting(id, DESKTOP_USER_ID, input.expected_response_date)
90 .await?
91 .or_not_found("task", id)?;
92
93 Ok(TaskResponse::from(task))
94 }
95
96 /// Clears the waiting status from a task.
97 ///
98 /// # Errors
99 ///
100 /// Returns `NOT_FOUND` if the task doesn't exist.
101 /// Returns `DATABASE_ERROR` if the update fails.
102 #[tauri::command]
103 #[instrument(skip_all)]
104 pub async fn clear_task_waiting(state: State<'_, Arc<AppState>>, id: TaskId) -> Result<TaskResponse, ApiError> {
105 let task = state.tasks
106 .clear_waiting(id, DESKTOP_USER_ID)
107 .await?
108 .or_not_found("task", id)?;
109
110 Ok(TaskResponse::from(task))
111 }
112