listless

A simple list app for Apple platforms
Log | Files | Refs | README | LICENSE

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:
MListlessiOS/Views/TaskListView.swift | 14+++++++++++++-
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() + } + } ) } }