fix(tasks): timed tasks become overdue immediately when time passes (TickTick behavior)

Previous logic compared dueDate against startOfDay for all tasks, so a task
due at 2:00 PM stayed in "Today" until midnight even after the time passed.

TickTick rule:
- hasTime=true  → overdue the moment dueDate < now (wall clock)
- hasTime=false → overdue at start of next day (dueDate < startOfDay)

overdueTasks: now uses `dueDate < now` for timed tasks, `dueDate < today`
for date-only tasks.

todayTasks: now excludes timed tasks whose time has already passed — those
belong in overdue, not today — while keeping date-only tasks in Today for
the full calendar day.

Co-Authored-By: Kutesir <tqwyy79vzn@privaterelay.appleid.com>
This commit is contained in:
kutesir
2026-06-23 19:00:57 +03:00
parent 23d3d201f7
commit eeb60dc51b

View File

@@ -238,12 +238,29 @@ class TaskViewModel: ObservableObject {
}
var overdueTasks: [TaskItem] {
let today = Calendar.current.startOfDay(for: Date())
// Non-recurring past-due only recurring surfaces its next occurrence instead.
return tasks.filter { !recurs($0) && !$0.isComplete && ($0.dueDate ?? .distantFuture) < today }
let now = Date()
let today = Calendar.current.startOfDay(for: now)
// TickTick rule: timed tasks become overdue the moment the clock passes;
// date-only tasks become overdue at the start of the next day (midnight).
return tasks.filter {
guard !recurs($0) && !$0.isComplete, let due = $0.dueDate else { return false }
return $0.hasTime ? due < now : due < today
}
.sorted { ($0.dueDate ?? .distantFuture) < ($1.dueDate ?? .distantFuture) }
}
var todayTasks: [TaskItem] {
let now = Date()
let cal = Calendar.current
let start = cal.startOfDay(for: now)
let end = cal.date(byAdding: .day, value: 1, to: start)!
// Timed tasks whose time has already passed belong in overdue, not today.
return activeRows().filter {
guard let d = $0.dueDate else { return false }
if $0.hasTime && d < now { return false }
return d >= start && d < end
}
.sorted { ($0.dueDate ?? .distantFuture) < ($1.dueDate ?? .distantFuture) }
}
var todayTasks: [TaskItem] { bucket(from: 0, to: 1) } // due today
var tomorrowTasks: [TaskItem] { bucket(from: 1, to: 2) } // due tomorrow
var next7DaysTasks: [TaskItem] { bucket(from: 2, to: 8) } // due in 27 days
var laterTasks: [TaskItem] { bucket(from: 8, to: nil) } // beyond 7 days