@@ -10,6 +10,7 @@ public struct MessageContainerView<Factory: ViewFactory>: View {
1010 @StateObject var messageViewModel : MessageViewModel
1111 @Environment ( \. channelTranslationLanguage) var translationLanguage
1212 @Environment ( \. highlightedMessageId) var highlightedMessageId
13+ @Environment ( \. messageListSwipe) var messageListSwipe
1314
1415 @Injected ( \. fonts) private var fonts
1516 @Injected ( \. colors) private var colors
@@ -32,7 +33,6 @@ public struct MessageContainerView<Factory: ViewFactory>: View {
3233 @State private var computeFrame = false
3334 @State private var offsetX : CGFloat = 0
3435 @State private var offsetYAvatar : CGFloat = 0
35- @GestureState private var offset : CGSize = . zero
3636
3737 private let replyThreshold : CGFloat = 60
3838 private var paddingValue : CGFloat {
@@ -129,6 +129,9 @@ public struct MessageContainerView<Factory: ViewFactory>: View {
129129 . onChange ( of: computeFrame, perform: { _ in
130130 frame = proxy. frame ( in: . global)
131131 } )
132+ . onChange ( of: messageListSwipe, perform: { messageListSwipe in
133+ handleMessageListSwipe ( messageListSwipe, geometry: proxy)
134+ } )
132135 }
133136 )
134137 . onTapGesture ( count: 2 ) {
@@ -140,40 +143,6 @@ public struct MessageContainerView<Factory: ViewFactory>: View {
140143 handleGestureForMessage ( showsMessageActions: true )
141144 } )
142145 . offset ( x: min ( self . offsetX, maximumHorizontalSwipeDisplacement) )
143- . simultaneousGesture (
144- DragGesture (
145- minimumDistance: minimumSwipeDistance,
146- coordinateSpace: . local
147- )
148- . updating ( $offset) { ( value, gestureState, _) in
149- guard messageViewModel. isSwipeToQuoteReplyPossible else {
150- return
151- }
152- // Using updating since onEnded is not called if the gesture is canceled.
153- let diff = CGSize (
154- width: value. location. x - value. startLocation. x,
155- height: value. location. y - value. startLocation. y
156- )
157-
158- if diff == . zero {
159- gestureState = . zero
160- } else {
161- gestureState = value. translation
162- }
163- }
164- )
165- . onChange ( of: offset, perform: { _ in
166- if !channel. config. quotesEnabled {
167- return
168- }
169-
170- if offset == . zero {
171- // gesture ended or cancelled
172- setOffsetX ( value: 0 )
173- } else {
174- dragChanged ( to: offset. width)
175- }
176- } )
177146 . accessibilityElement ( children: . contain)
178147 . accessibilityIdentifier ( " MessageView " )
179148
@@ -351,6 +320,18 @@ public struct MessageContainerView<Factory: ViewFactory>: View {
351320 private var messageListConfig : MessageListConfig {
352321 utils. messageListConfig
353322 }
323+
324+ private func handleMessageListSwipe( _ messageListSwipe: MessageListSwipe ? , geometry: GeometryProxy ) {
325+ guard messageViewModel. isSwipeToQuoteReplyPossible else { return }
326+ guard let messageListSwipe else { return }
327+ // The view is moving during the swipe handling, therefore we skip the contains check if it is in progress
328+ guard offsetX > 0 || geometry. frame ( in: . global) . contains ( messageListSwipe. startLocation) else { return }
329+ if messageListSwipe. horizontalOffset == 0 {
330+ setOffsetX ( value: 0 )
331+ } else {
332+ dragChanged ( to: messageListSwipe. horizontalOffset)
333+ }
334+ }
354335
355336 private func dragChanged( to value: CGFloat ) {
356337 let horizontalTranslation = value
0 commit comments