fix: Add circular progress for delete countdown

This commit is contained in:
Ilyas Hallak 2025-09-04 12:14:20 +02:00
parent df8a7b64b2
commit 8fb2a2a14e
2 changed files with 21 additions and 27 deletions

View File

@ -59,17 +59,26 @@ struct BookmarkCardView: View {
.opacity(pendingDelete != nil ? 0.4 : 1.0)
.animation(.easeInOut(duration: 0.2), value: pendingDelete != nil)
// Undo button overlay
// Undo toast overlay with progress background
if let pendingDelete = pendingDelete {
VStack(spacing: 0) {
Spacer()
// Undo button area - only when user interacts
// Undo button area with circular progress
HStack {
HStack(spacing: 6) {
Image(systemName: "trash")
.foregroundColor(.secondary)
.font(.caption2)
HStack(spacing: 8) {
// Circular progress indicator
ZStack {
Circle()
.stroke(Color.gray.opacity(0.3), lineWidth: 2)
.frame(width: 16, height: 16)
Circle()
.trim(from: 0, to: CGFloat(pendingDelete.progress))
.stroke(Color.accentColor, style: StrokeStyle(lineWidth: 2, lineCap: .round))
.rotationEffect(.degrees(-90))
.frame(width: 16, height: 16)
.animation(.linear(duration: 0.1), value: pendingDelete.progress)
}
Text("Deleting...")
.font(.caption2)
@ -99,24 +108,6 @@ struct BookmarkCardView: View {
.shadow(color: .black.opacity(0.1), radius: 2, x: 0, y: 1)
.transition(.opacity.combined(with: .move(edge: .bottom)))
}
// Progress Bar am unteren Rand
if let pendingDelete = pendingDelete {
VStack(spacing: 0) {
Spacer()
// Progress Bar
ProgressView(value: pendingDelete.progress, total: 1.0)
.progressViewStyle(LinearProgressViewStyle(tint: .red))
.scaleEffect(x: 1, y: 1.5, anchor: .center)
.clipShape(
.rect(
bottomLeadingRadius: layout == .compact ? 8 : 12,
bottomTrailingRadius: layout == .compact ? 8 : 12
)
)
}
}
}
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
if pendingDelete == nil {

View File

@ -234,7 +234,7 @@ class BookmarksViewModel {
private func startDeleteCountdown(for bookmarkId: String) {
let timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { [weak self] timer in
Task { @MainActor in
DispatchQueue.main.async {
guard let self = self,
let pendingDelete = self.pendingDeletes[bookmarkId] else {
timer.invalidate()
@ -243,6 +243,9 @@ class BookmarksViewModel {
pendingDelete.progress += 1.0 / 30.0 // 3 seconds / 0.1 interval = 30 steps
// Trigger UI update by modifying the dictionary
self.pendingDeletes[bookmarkId] = pendingDelete
if pendingDelete.progress >= 1.0 {
timer.invalidate()
}
@ -273,10 +276,10 @@ class BookmarksViewModel {
}
}
class PendingDelete: Identifiable, ObservableObject {
class PendingDelete: Identifiable {
let id = UUID()
let bookmark: Bookmark
@Published var progress: Double = 0.0
var progress: Double = 0.0
var timer: Timer?
var deleteTask: Task<Void, Never>?