Fix press-and-hold mic dying instantly in private chats (#1405)

The private-chat sheet wraps its entire content — composer included — in a
high-priority swipe-right-to-leave DragGesture. A high-priority ancestor
drag preempts child gestures, so the composer mic's press-and-hold was
cancelled 3-10 ms after touch-down (observed on both iOS and macOS in field
logs), making voice notes unrecordable inside DMs while working fine in the
public timeline. Same starvation mechanism as the DM image-reveal bug
(#1402), hitting a drag instead of a tap.

The swipe-to-leave gesture now attaches to the message list only — where
users actually swipe — leaving the composer's gestures (mic hold, text
field, buttons) out of its reach.

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
jack
2026-07-08 09:20:54 +02:00
committed by GitHub
co-authored by jack Claude Fable 5
parent e642f696cb
commit 6886035632
+17 -11
View File
@@ -393,6 +393,11 @@ private struct ContentPrivateChatSheetView: View {
)
.themedSurface()
.frame(maxWidth: .infinity, maxHeight: .infinity)
// Swipe-right-to-leave lives on the message list only. On the
// whole sheet it preempted the composer's press-and-hold mic
// gesture (a high-priority ancestor drag cancels child gestures
// within milliseconds same starvation as the image-reveal bug).
.highPriorityGesture(swipeToLeaveGesture)
if !theme.usesGlassChrome {
Divider()
@@ -423,18 +428,19 @@ private struct ContentPrivateChatSheetView: View {
}
.themedSheetBackground()
.foregroundColor(palette.primary)
.highPriorityGesture(
DragGesture(minimumDistance: 25, coordinateSpace: .local)
.onEnded { value in
let horizontal = value.translation.width
let vertical = abs(value.translation.height)
guard horizontal > 80, vertical < 60 else { return }
withAnimation(.easeInOut(duration: TransportConfig.uiAnimationMediumSeconds)) {
showSidebar = true
privateConversationModel.endConversation()
}
}
private var swipeToLeaveGesture: some Gesture {
DragGesture(minimumDistance: 25, coordinateSpace: .local)
.onEnded { value in
let horizontal = value.translation.width
let vertical = abs(value.translation.height)
guard horizontal > 80, vertical < 60 else { return }
withAnimation(.easeInOut(duration: TransportConfig.uiAnimationMediumSeconds)) {
showSidebar = true
privateConversationModel.endConversation()
}
)
}
}
/// Persistent one-line reminder that this composer feeds a private