mac,ios: cancelling a reply no longer blanks the feed (#318)
The delete-implosion put a scale(0.05) REMOVAL transition on every row. When the composer inset shrinks (a reply cancelled, a banner dismissed), SwiftUI runs an animated layout pass and the LazyVStack destroys off-screen rows inside it — firing the scale removal on the whole feed, which imploded to nothing until you left and returned. Removal is a plain fade now; a delete still fades out gracefully. A safer targeted implosion can come back later.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2 files changed,
+7
−4
ios/LChat/Views/NativeChatScreen.swift+6 −1ios/LChatMac/NativeFeedView.swift+1 −3
diff --git a/ios/LChat/Views/NativeChatScreen.swift b/ios/LChat/Views/NativeChatScreen.swift| index 0ab3776..970c703 100644 |
| --- a/ios/LChat/Views/NativeChatScreen.swift |
| +++ b/ios/LChat/Views/NativeChatScreen.swift |
| @@ -295,9 +295,14 @@ struct NativeChatScreen: View { |
| ForEach(Array(model.messages.enumerated()), id: \.element.id) { i, m in |
| row(m, previous: i > 0 ? model.messages[i - 1] : nil, proxy: proxy) |
| .id(m.id) |
| + // Removal is a plain fade, NOT a scale-implosion: |
| + // the LazyVStack destroys off-screen rows during |
| + // animated layout passes (cancelling a reply shrinks |
| + // the composer inset), and a scale removal imploded |
| + // the WHOLE feed to nothing until you left + returned. |
| .transition(.asymmetric( |
| insertion: .move(edge: .bottom).combined(with: .opacity), |
| - removal: .scale(scale: 0.05).combined(with: .opacity))) |
| + removal: .opacity)) |
| .onAppear { |
| // `settled` gate: the opening pin-jump |
| // transiently materialises top rows, and each |
diff --git a/ios/LChatMac/NativeFeedView.swift b/ios/LChatMac/NativeFeedView.swift| index 55e3446..262ac6c 100644 |
| --- a/ios/LChatMac/NativeFeedView.swift |
| +++ b/ios/LChatMac/NativeFeedView.swift |
| @@ -152,9 +152,7 @@ struct NativeFeedView: View { |
| .id(m.id) |
| // Deleted messages implode — a quick shrink-and- |
| // fade where the bubble stood. |
| - .transition(.asymmetric( |
| - insertion: .identity, |
| - removal: .scale(scale: 0.05).combined(with: .opacity))) |
| + .transition(.opacity) // plain fade — a scale-implosion removal blanked the whole feed on inset changes |
| // Geometry probe for "is this row already in view?" |
| // (jump-without-scroll). Writes to the frame store, |
| // never to state. |