commit 618ffff00f8c46474d1e3f5e486b538c88c304eb
parent a370d4be1d8d2e2792c8b94c85b9ab51d2ea53b2
Author: Michael Camilleri <[email protected]>
Date: Fri, 27 Feb 2026 08:51:09 +0900
Animate clearing of completed tasks
Co-Authored-By: Codex GPT 5.3 <[email protected]>
Diffstat:
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/ListlessiOS/Views/TaskListView.swift b/ListlessiOS/Views/TaskListView.swift
@@ -12,6 +12,7 @@ struct TaskListView: View, TaskListViewProtocol {
var pullToCreate = PullToCreateState()
var pullUpOffset: CGFloat = 0
var isDragging: Bool = false
+ var clearingTaskIDs: Set<UUID> = []
var rowFrames: [UUID: CGRect] = [:]
}
@@ -242,6 +243,7 @@ struct TaskListView: View, TaskListViewProtocol {
ForEach(completedTasks) { task in
let taskID = task.id
+ let isBeingCleared = iState.clearingTaskIDs.contains(taskID)
TaskRowView(
task: task,
taskID: taskID,
@@ -252,6 +254,8 @@ struct TaskListView: View, TaskListViewProtocol {
onDelete: { deleteTask($0) },
onSelect: { selectTask($0) }
)
+ .opacity(isBeingCleared ? 0 : 1)
+ .offset(y: isBeingCleared ? 40 : 0)
}
}
.frame(maxWidth: .infinity, alignment: .topLeading)
@@ -284,7 +288,15 @@ struct TaskListView: View, TaskListViewProtocol {
pullCreateThreshold: pullCreateThreshold,
pullClearThreshold: pullClearThreshold,
onCreateTaskAtTop: { createNewTaskAtTop() },
- onClearCompleted: { clearCompletedTasks() }
+ onClearCompleted: {
+ let ids = Set(completedTasks.map(\.id))
+ withAnimation(.easeIn(duration: 0.35)) {
+ iState.clearingTaskIDs = ids
+ } completion: {
+ iState.clearingTaskIDs = []
+ clearCompletedTasks()
+ }
+ }
)
}
}