keep mention panel if mentioning with long press

This commit is contained in:
kukuruzka 2025-03-12 01:39:24 +02:00
parent f6a07a64a3
commit 583433e1a3
2 changed files with 31 additions and 12 deletions

View File

@ -32,7 +32,7 @@ private struct MentionChatInputContextPanelEntry: Comparable, Identifiable {
return lhs.index < rhs.index
}
func item(context: AccountContext, presentationData: PresentationData, inverted: Bool, setPeerIdRevealed: @escaping (EnginePeer.Id?) -> Void, peerSelected: @escaping (EnginePeer) -> Void, removeRequested: @escaping (EnginePeer.Id) -> Void) -> ListViewItem {
func item(context: AccountContext, presentationData: PresentationData, inverted: Bool, setPeerIdRevealed: @escaping (EnginePeer.Id?) -> Void, peerSelected: @escaping (EnginePeer, Bool) -> Void, removeRequested: @escaping (EnginePeer.Id) -> Void) -> ListViewItem {
return MentionChatInputPanelItem(context: context, presentationData: ItemListPresentationData(presentationData), inverted: inverted, peer: self.peer._asPeer(), revealed: self.revealed, setPeerIdRevealed: setPeerIdRevealed, peerSelected: peerSelected, removeRequested: removeRequested)
}
}
@ -43,7 +43,7 @@ private struct CommandChatInputContextPanelTransition {
let updates: [ListViewUpdateItem]
}
private func preparedTransition(from fromEntries: [MentionChatInputContextPanelEntry], to toEntries: [MentionChatInputContextPanelEntry], context: AccountContext, presentationData: PresentationData, inverted: Bool, forceUpdate: Bool, setPeerIdRevealed: @escaping (EnginePeer.Id?) -> Void, peerSelected: @escaping (EnginePeer) -> Void, removeRequested: @escaping (EnginePeer.Id) -> Void) -> CommandChatInputContextPanelTransition {
private func preparedTransition(from fromEntries: [MentionChatInputContextPanelEntry], to toEntries: [MentionChatInputContextPanelEntry], context: AccountContext, presentationData: PresentationData, inverted: Bool, forceUpdate: Bool, setPeerIdRevealed: @escaping (EnginePeer.Id?) -> Void, peerSelected: @escaping (EnginePeer, Bool) -> Void, removeRequested: @escaping (EnginePeer.Id) -> Void) -> CommandChatInputContextPanelTransition {
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries, allUpdated: forceUpdate)
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
@ -121,7 +121,7 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
strongSelf.revealedPeerId = peerId
strongSelf.updateResults(strongSelf.currentResults)
}
}, peerSelected: { [weak self] peer in
}, peerSelected: { [weak self] peer, mentionNext in
if let strongSelf = self, let interfaceInteraction = strongSelf.interfaceInteraction {
switch strongSelf.mode {
case .input:
@ -138,7 +138,7 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
let inputText = NSMutableAttributedString(attributedString: textInputState.inputText)
if let addressName = peer.addressName, !addressName.isEmpty {
let replacementText = addressName + " "
let replacementText = addressName + (mentionNext ? " @" : " ")
inputText.replaceCharacters(in: range, with: replacementText)
@ -148,7 +148,7 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
} else if !peer.compactDisplayTitle.isEmpty {
let replacementText = NSMutableAttributedString()
replacementText.append(NSAttributedString(string: peer.compactDisplayTitle, attributes: [ChatTextInputAttributes.textMention: ChatTextInputTextMentionAttribute(peerId: peer.id)]))
replacementText.append(NSAttributedString(string: " "))
replacementText.append(NSAttributedString(string: mentionNext ? " @" : " "))
let updatedRange = NSRange(location: range.location - 1, length: range.length + 1)

View File

@ -17,13 +17,13 @@ final class MentionChatInputPanelItem: ListViewItem {
fileprivate let revealed: Bool
fileprivate let inverted: Bool
fileprivate let peer: Peer
private let peerSelected: (EnginePeer) -> Void
let peerSelected: (EnginePeer, Bool) -> Void
fileprivate let setPeerIdRevealed: (EnginePeer.Id?) -> Void
fileprivate let removeRequested: (EnginePeer.Id) -> Void
let selectable: Bool = true
public init(context: AccountContext, presentationData: ItemListPresentationData, inverted: Bool, peer: Peer, revealed: Bool, setPeerIdRevealed: @escaping (PeerId?) -> Void, peerSelected: @escaping (EnginePeer) -> Void, removeRequested: @escaping (PeerId) -> Void) {
public init(context: AccountContext, presentationData: ItemListPresentationData, inverted: Bool, peer: Peer, revealed: Bool, setPeerIdRevealed: @escaping (PeerId?) -> Void, peerSelected: @escaping (EnginePeer, Bool) -> Void, removeRequested: @escaping (PeerId) -> Void) {
self.context = context
self.presentationData = presentationData
self.inverted = inverted
@ -85,14 +85,14 @@ final class MentionChatInputPanelItem: ListViewItem {
if self.revealed {
self.setPeerIdRevealed(nil)
} else {
self.peerSelected(EnginePeer(self.peer))
self.peerSelected(EnginePeer(self.peer), false)
}
}
}
private let avatarFont = avatarPlaceholderFont(size: 16.0)
final class MentionChatInputPanelItemNode: ListViewItemNode {
final class MentionChatInputPanelItemNode: ListViewItemNode, UIGestureRecognizerDelegate {
static let itemHeight: CGFloat = 42.0
private let avatarNode: AvatarNode
@ -147,7 +147,13 @@ final class MentionChatInputPanelItemNode: ListViewItemNode {
let recognizer = ItemListRevealOptionsGestureRecognizer(target: self, action: #selector(self.revealGesture(_:)))
self.recognizer = recognizer
recognizer.allowAnyDirection = false
recognizer.delegate = self
self.view.addGestureRecognizer(recognizer)
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.longPressed(_:)))
longPressRecognizer.minimumPressDuration = 0.3
longPressRecognizer.delegate = self
self.view.addGestureRecognizer(longPressRecognizer)
}
override public func layoutForParams(_ params: ListViewItemLayoutParams, item: ListViewItem, previousItem: ListViewItem?, nextItem: ListViewItem?) {
@ -161,6 +167,17 @@ final class MentionChatInputPanelItemNode: ListViewItemNode {
}
}
@objc private func longPressed(_ gestureRecognizer: UILongPressGestureRecognizer) {
switch gestureRecognizer.state {
case .began:
if let item = self.item {
item.peerSelected(EnginePeer(item.peer), true)
}
default:
break
}
}
func asyncLayout() -> (_ item: MentionChatInputPanelItem, _ params: ListViewItemLayoutParams, _ mergedTop: Bool, _ mergedBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation) -> Void) {
let makeTextLayout = TextNode.asyncLayout(self.textNode)
@ -328,11 +345,13 @@ final class MentionChatInputPanelItemNode: ListViewItemNode {
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if let recognizer = self.recognizer, otherGestureRecognizer == recognizer {
if gestureRecognizer is ItemListRevealOptionsGestureRecognizer && otherGestureRecognizer is UILongPressGestureRecognizer {
return true
} else {
return false
}
if gestureRecognizer is UILongPressGestureRecognizer && otherGestureRecognizer is ItemListRevealOptionsGestureRecognizer {
return true
}
return false
}
@objc func revealGesture(_ recognizer: ItemListRevealOptionsGestureRecognizer) {