From 7cb3c6efd61cb2de8bb9e37522d221a3a0f21c96 Mon Sep 17 00:00:00 2001 From: Ruben Rosario Date: Sun, 21 Jun 2026 16:38:54 +0100 Subject: [PATCH] Feature 4: sort tasks - incomplete first by position, completed by updated_at - sort_tasks() extracts the sort logic into a standalone function - Applied in load_tasks, App::new, check_initial_load, refresh_if_needed - reorder_task guards: only NeedsAction tasks, never cross group boundary --- src/app.rs | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/src/app.rs b/src/app.rs index a507136..d548efd 100644 --- a/src/app.rs +++ b/src/app.rs @@ -79,12 +79,13 @@ impl App { }; let lists = db.get_lists(); - let tasks = if !lists.is_empty() { + let mut tasks = if !lists.is_empty() { let list_id = &lists[0].id; db.get_tasks(list_id) } else { Vec::new() }; + sort_tasks(&mut tasks); Self { lists, @@ -162,7 +163,9 @@ impl App { if !lists.is_empty() && self.lists.is_empty() { self.lists = lists; if !self.lists.is_empty() { - self.tasks = self.db.get_tasks(&self.lists[0].id); + let mut tasks = self.db.get_tasks(&self.lists[0].id); + sort_tasks(&mut tasks); + self.tasks = tasks; } } } @@ -172,7 +175,9 @@ impl App { self.last_sync_version = self.sync_stats.version; self.load_lists(); if !self.lists.is_empty() && self.selected_list < self.lists.len() { - self.tasks = self.db.get_tasks(&self.lists[self.selected_list].id); + let mut tasks = self.db.get_tasks(&self.lists[self.selected_list].id); + sort_tasks(&mut tasks); + self.tasks = tasks; } else { self.tasks.clear(); } @@ -739,13 +744,22 @@ impl App { return; } - let new_index = self.selected_task as i64 + direction; + let cur = self.selected_task; + if self.tasks[cur].status != TaskStatus::NeedsAction { + return; + } + + let new_index = cur as i64 + direction; if new_index < 0 || new_index >= self.tasks.len() as i64 { return; } - let task_id = self.tasks[self.selected_task].id.clone(); - let list_id = self.tasks[self.selected_task].list_id.clone(); + if self.tasks[new_index as usize].status != TaskStatus::NeedsAction { + return; + } + + let task_id = self.tasks[cur].id.clone(); + let list_id = self.tasks[cur].list_id.clone(); let new_pos = self.tasks[new_index as usize].position; @@ -772,7 +786,9 @@ impl App { fn load_tasks(&mut self) { if self.selected_list < self.lists.len() { - self.tasks = self.db.get_tasks(&self.lists[self.selected_list].id); + let mut tasks = self.db.get_tasks(&self.lists[self.selected_list].id); + sort_tasks(&mut tasks); + self.tasks = tasks; } else { self.tasks.clear(); } @@ -784,6 +800,18 @@ impl App { } } +fn sort_tasks(tasks: &mut Vec) { + tasks.sort_by(|a, b| match (&a.status, &b.status) { + (TaskStatus::NeedsAction, TaskStatus::Completed) => std::cmp::Ordering::Less, + (TaskStatus::Completed, TaskStatus::NeedsAction) => std::cmp::Ordering::Greater, + (TaskStatus::NeedsAction, TaskStatus::NeedsAction) => a.position.cmp(&b.position), + (TaskStatus::Completed, TaskStatus::Completed) => b + .updated_at + .unwrap_or(chrono::NaiveDateTime::MIN) + .cmp(&a.updated_at.unwrap_or(chrono::NaiveDateTime::MIN)), + }); +} + fn uuid_v4() -> String { use std::time::{SystemTime, UNIX_EPOCH}; let now = SystemTime::now()