Commit 24feba272c

24feba272c86eff40f715343a1a619d37ac74b3a

parent: 30150d90cb

Unsigned

cmc <hello@cleberg.net> · 2026-07-16 05:18 UTC

fix: stop destructive swipes animating rows out before confirmation

Swiping to delete made the row vanish and then spring back while the
confirmation was still on screen. A destructive swipe action left to full-swipe
performs itself on the gesture and animates the row away, but these actions only
set pending state and wait for an answer, so the row returned when the data had
not changed.

allowsFullSwipe: false, which PasteListView already uses for exactly this
confirm-then-delete shape. Both new swipes had the same omission.

Layout: unified · split

Hutch/Views/Lists/MailingListListView.swift +5 −1
@@ -367,7 +367,11 @@ struct MailingListListView: View {
367 } 367 }
368 .padding(.vertical, 2) 368 .padding(.vertical, 2)
369 } 369 }
370 .swipeActions(edge: .trailing) { 370 // allowsFullSwipe: false, as in PasteListView. A destructive
371 // action left to full-swipe animates the row out on the gesture,
372 // before the confirmation is answered, so it flickers back when
373 // the data has not actually changed.
374 .swipeActions(edge: .trailing, allowsFullSwipe: false) {
371 if isOwned(mailingList) { 375 if isOwned(mailingList) {
372 Button(role: .destructive) { 376 Button(role: .destructive) {
373 pendingDeletion = mailingList 377 pendingDeletion = mailingList
Hutch/Views/Repositories/ArtifactsView.swift +3 −1
@@ -22,7 +22,9 @@ struct ArtifactsView: View {
22 ArtifactRow(artifact: artifact) { 22 ArtifactRow(artifact: artifact) {
23 openURL(artifact.url) 23 openURL(artifact.url)
24 } 24 }
25 .swipeActions(edge: .trailing) { 25 // See MailingListListView: a full-swipe destructive
26 // action animates the row out before the confirmation.
27 .swipeActions(edge: .trailing, allowsFullSwipe: false) {
26 if isOwnedByCurrentUser { 28 if isOwnedByCurrentUser {
27 Button(role: .destructive) { 29 Button(role: .destructive) {
28 pendingDeletion = artifact 30 pendingDeletion = artifact