Swipe to reply

This commit is contained in:
Ali
2023-09-29 16:13:34 +04:00
parent 99fa059e08
commit b704bdaa9b
7 changed files with 191 additions and 41 deletions

View File

@@ -284,6 +284,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
private var appliedForwardInfo: (Peer?, String?)?
private var replyRecognizer: ChatSwipeToReplyRecognizer?
private var currentSwipeAction: ChatControllerInteractionSwipeAction?
private var wasPending: Bool = false
@@ -450,6 +451,10 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
self.view.addGestureRecognizer(recognizer)
let replyRecognizer = ChatSwipeToReplyRecognizer(target: self, action: #selector(self.swipeToReplyGesture(_:)))
if let item = self.item {
replyRecognizer.allowBothDirections = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply
self.view.disablesInteractiveTransitionGestureRecognizer = true
}
replyRecognizer.shouldBegin = { [weak self] in
if let strongSelf = self, let item = strongSelf.item {
if strongSelf.selectionNode != nil {
@@ -470,6 +475,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
return false
}
self.replyRecognizer = replyRecognizer
self.view.addGestureRecognizer(replyRecognizer)
}
@@ -510,6 +516,9 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
private var setupTimestamp: Double?
private func setupNode(item: ChatMessageItem) {
self.replyRecognizer?.allowBothDirections = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply
self.view.disablesInteractiveTransitionGestureRecognizer = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply
guard self.animationNode == nil else {
return
}
@@ -2419,11 +2428,14 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
private var playedSwipeToReplyHaptic = false
@objc func swipeToReplyGesture(_ recognizer: ChatSwipeToReplyRecognizer) {
var offset: CGFloat = 0.0
var leftOffset: CGFloat = 0.0
var swipeOffset: CGFloat = 45.0
if let item = self.item, item.content.effectivelyIncoming(item.context.account.peerId, associatedData: item.associatedData) {
offset = -24.0
leftOffset = -10.0
} else {
offset = 10.0
leftOffset = -10.0
swipeOffset = 60.0
}
@@ -2451,7 +2463,11 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
if translation.x < 0.0 {
translation.x = max(-180.0, min(0.0, -rubberBandingOffset(offset: abs(translation.x), bandingStart: swipeOffset)))
} else {
translation.x = 0.0
if recognizer.allowBothDirections {
translation.x = -max(-180.0, min(0.0, -rubberBandingOffset(offset: abs(translation.x), bandingStart: swipeOffset)))
} else {
translation.x = 0.0
}
}
if let item = self.item, self.swipeToReplyNode == nil {
@@ -2469,7 +2485,13 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
if let swipeToReplyNode = self.swipeToReplyNode {
swipeToReplyNode.bounds = CGRect(origin: .zero, size: CGSize(width: 33.0, height: 33.0))
swipeToReplyNode.position = CGPoint(x: bounds.size.width + offset + 33.0 * 0.5, y: self.contentSize.height / 2.0)
if translation.x < 0.0 {
swipeToReplyNode.bounds = CGRect(origin: .zero, size: CGSize(width: 33.0, height: 33.0))
swipeToReplyNode.position = CGPoint(x: bounds.size.width + offset + 33.0 * 0.5, y: self.contentSize.height / 2.0)
} else {
swipeToReplyNode.bounds = CGRect(origin: .zero, size: CGSize(width: 33.0, height: 33.0))
swipeToReplyNode.position = CGPoint(x: leftOffset - 33.0 * 0.5, y: self.contentSize.height / 2.0)
}
if let (rect, containerSize) = self.absoluteRect {
let mappedRect = CGRect(origin: CGPoint(x: rect.minX + swipeToReplyNode.frame.minX, y: rect.minY + swipeToReplyNode.frame.minY), size: swipeToReplyNode.frame.size)
@@ -2488,7 +2510,15 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
self.swipeToReplyFeedback = nil
let translation = recognizer.translation(in: self.view)
if case .ended = recognizer.state, translation.x < -swipeOffset {
let gestureRecognized: Bool
if recognizer.allowBothDirections {
gestureRecognized = abs(translation.x) > swipeOffset
} else {
gestureRecognized = translation.x < -swipeOffset
}
if case .ended = recognizer.state, gestureRecognized {
if let item = self.item {
if let currentSwipeAction = currentSwipeAction {
switch currentSwipeAction {