fix: Add circular progress for delete countdown
This commit is contained in:
parent
df8a7b64b2
commit
8fb2a2a14e
@ -59,17 +59,26 @@ struct BookmarkCardView: View {
|
|||||||
.opacity(pendingDelete != nil ? 0.4 : 1.0)
|
.opacity(pendingDelete != nil ? 0.4 : 1.0)
|
||||||
.animation(.easeInOut(duration: 0.2), value: pendingDelete != nil)
|
.animation(.easeInOut(duration: 0.2), value: pendingDelete != nil)
|
||||||
|
|
||||||
// Undo button overlay
|
// Undo toast overlay with progress background
|
||||||
if let pendingDelete = pendingDelete {
|
if let pendingDelete = pendingDelete {
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
// Undo button area - only when user interacts
|
// Undo button area with circular progress
|
||||||
HStack {
|
HStack {
|
||||||
HStack(spacing: 6) {
|
HStack(spacing: 8) {
|
||||||
Image(systemName: "trash")
|
// Circular progress indicator
|
||||||
.foregroundColor(.secondary)
|
ZStack {
|
||||||
.font(.caption2)
|
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...")
|
Text("Deleting...")
|
||||||
.font(.caption2)
|
.font(.caption2)
|
||||||
@ -99,24 +108,6 @@ struct BookmarkCardView: View {
|
|||||||
.shadow(color: .black.opacity(0.1), radius: 2, x: 0, y: 1)
|
.shadow(color: .black.opacity(0.1), radius: 2, x: 0, y: 1)
|
||||||
.transition(.opacity.combined(with: .move(edge: .bottom)))
|
.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) {
|
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
|
||||||
if pendingDelete == nil {
|
if pendingDelete == nil {
|
||||||
|
|||||||
@ -234,7 +234,7 @@ class BookmarksViewModel {
|
|||||||
|
|
||||||
private func startDeleteCountdown(for bookmarkId: String) {
|
private func startDeleteCountdown(for bookmarkId: String) {
|
||||||
let timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { [weak self] timer in
|
let timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { [weak self] timer in
|
||||||
Task { @MainActor in
|
DispatchQueue.main.async {
|
||||||
guard let self = self,
|
guard let self = self,
|
||||||
let pendingDelete = self.pendingDeletes[bookmarkId] else {
|
let pendingDelete = self.pendingDeletes[bookmarkId] else {
|
||||||
timer.invalidate()
|
timer.invalidate()
|
||||||
@ -243,6 +243,9 @@ class BookmarksViewModel {
|
|||||||
|
|
||||||
pendingDelete.progress += 1.0 / 30.0 // 3 seconds / 0.1 interval = 30 steps
|
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 {
|
if pendingDelete.progress >= 1.0 {
|
||||||
timer.invalidate()
|
timer.invalidate()
|
||||||
}
|
}
|
||||||
@ -273,10 +276,10 @@ class BookmarksViewModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PendingDelete: Identifiable, ObservableObject {
|
class PendingDelete: Identifiable {
|
||||||
let id = UUID()
|
let id = UUID()
|
||||||
let bookmark: Bookmark
|
let bookmark: Bookmark
|
||||||
@Published var progress: Double = 0.0
|
var progress: Double = 0.0
|
||||||
var timer: Timer?
|
var timer: Timer?
|
||||||
var deleteTask: Task<Void, Never>?
|
var deleteTask: Task<Void, Never>?
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user