mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Reaction improvements
This commit is contained in:
parent
94dc335d04
commit
e450862adf
@ -467,6 +467,7 @@ public enum PeerInfoControllerMode {
|
||||
case calls(messages: [Message])
|
||||
case nearbyPeer(distance: Int32)
|
||||
case group(PeerId)
|
||||
case reaction(MessageId)
|
||||
}
|
||||
|
||||
public enum ContactListActionItemInlineIconPosition {
|
||||
|
@ -179,7 +179,8 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
private let dismissTapNode: ASDisplayNode
|
||||
private let dismissAccessibilityArea: AccessibilityAreaNode
|
||||
private let clippingNode: ASDisplayNode
|
||||
private let scrollNode: ASScrollNode
|
||||
private let scroller: UIScrollView
|
||||
private let scrollNode: ASDisplayNode
|
||||
|
||||
private var reactionContextNode: ReactionContextNode?
|
||||
private var reactionContextNodeIsAnimatingOut: Bool = false
|
||||
@ -192,6 +193,14 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
|
||||
private var strings: PresentationStrings?
|
||||
|
||||
private enum OverscrollMode {
|
||||
case unrestricted
|
||||
case topOnly
|
||||
case disabled
|
||||
}
|
||||
|
||||
private var overscrollMode: OverscrollMode = .unrestricted
|
||||
|
||||
init(
|
||||
getController: @escaping () -> ContextControllerProtocol?,
|
||||
requestUpdate: @escaping (ContainedViewLayoutTransition) -> Void,
|
||||
@ -215,13 +224,17 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
self.clippingNode = ASDisplayNode()
|
||||
self.clippingNode.clipsToBounds = true
|
||||
|
||||
self.scrollNode = ASScrollNode()
|
||||
self.scrollNode.canCancelAllTouchesInViews = true
|
||||
self.scrollNode.view.delaysContentTouches = false
|
||||
self.scrollNode.view.showsVerticalScrollIndicator = false
|
||||
self.scroller = UIScrollView()
|
||||
self.scroller.canCancelContentTouches = true
|
||||
self.scroller.delaysContentTouches = false
|
||||
self.scroller.showsVerticalScrollIndicator = false
|
||||
if #available(iOS 11.0, *) {
|
||||
self.scrollNode.view.contentInsetAdjustmentBehavior = .never
|
||||
self.scroller.contentInsetAdjustmentBehavior = .never
|
||||
}
|
||||
self.scroller.alwaysBounceVertical = true
|
||||
|
||||
self.scrollNode = ASDisplayNode()
|
||||
self.scrollNode.view.addGestureRecognizer(self.scroller.panGestureRecognizer)
|
||||
|
||||
self.contentRectDebugNode = ASDisplayNode()
|
||||
self.contentRectDebugNode.isUserInteractionEnabled = false
|
||||
@ -244,11 +257,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
self.scrollNode.addSubnode(self.dismissAccessibilityArea)
|
||||
self.scrollNode.addSubnode(self.actionsStackNode)
|
||||
|
||||
/*#if DEBUG
|
||||
self.scrollNode.addSubnode(self.contentRectDebugNode)
|
||||
#endif*/
|
||||
|
||||
self.scrollNode.view.delegate = self
|
||||
self.scroller.delegate = self
|
||||
|
||||
self.dismissTapNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.dismissTapGesture(_:))))
|
||||
|
||||
@ -292,10 +301,65 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
}
|
||||
}
|
||||
|
||||
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
|
||||
if let reactionContextNode = self.reactionContextNode, (reactionContextNode.isExpanded || !reactionContextNode.canBeExpanded) {
|
||||
self.overscrollMode = .disabled
|
||||
self.scroller.alwaysBounceVertical = false
|
||||
} else {
|
||||
if scrollView.contentSize.height > scrollView.bounds.height {
|
||||
self.overscrollMode = .unrestricted
|
||||
self.scroller.alwaysBounceVertical = true
|
||||
} else {
|
||||
if self.reactionContextNode != nil {
|
||||
self.overscrollMode = .topOnly
|
||||
self.scroller.alwaysBounceVertical = true
|
||||
} else {
|
||||
self.overscrollMode = .disabled
|
||||
self.scroller.alwaysBounceVertical = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
var adjustedBounds = scrollView.bounds
|
||||
var topOverscroll: CGFloat = 0.0
|
||||
switch self.overscrollMode {
|
||||
case .unrestricted:
|
||||
if adjustedBounds.origin.y < 0.0 {
|
||||
topOverscroll = -adjustedBounds.origin.y
|
||||
}
|
||||
case .disabled:
|
||||
break
|
||||
case .topOnly:
|
||||
if scrollView.contentSize.height <= scrollView.bounds.height {
|
||||
if adjustedBounds.origin.y > 0.0 {
|
||||
adjustedBounds.origin.y = 0.0
|
||||
} else {
|
||||
topOverscroll = -adjustedBounds.origin.y
|
||||
}
|
||||
} else {
|
||||
if adjustedBounds.origin.y < 0.0 {
|
||||
topOverscroll = -adjustedBounds.origin.y
|
||||
} else if adjustedBounds.origin.y + adjustedBounds.height > scrollView.contentSize.height {
|
||||
adjustedBounds.origin.y = scrollView.contentSize.height - adjustedBounds.height
|
||||
}
|
||||
}
|
||||
}
|
||||
self.scrollNode.bounds = adjustedBounds
|
||||
|
||||
if let reactionContextNode = self.reactionContextNode {
|
||||
let isIntersectingContent = scrollView.contentOffset.y >= 10.0
|
||||
let isIntersectingContent = adjustedBounds.minY >= 10.0
|
||||
reactionContextNode.updateIsIntersectingContent(isIntersectingContent: isIntersectingContent, transition: .animated(duration: 0.25, curve: .easeInOut))
|
||||
|
||||
if !reactionContextNode.isExpanded && reactionContextNode.canBeExpanded {
|
||||
if topOverscroll > 60.0 && self.scroller.isDragging {
|
||||
self.scroller.panGestureRecognizer.state = .cancelled
|
||||
reactionContextNode.expand()
|
||||
} else {
|
||||
reactionContextNode.updateExtension(distance: topOverscroll)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -341,7 +405,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
}
|
||||
|
||||
private func getCurrentScrollingState() -> CGFloat {
|
||||
return self.scrollNode.view.contentOffset.y
|
||||
return self.scrollNode.bounds.minY
|
||||
}
|
||||
|
||||
private func getActionsStackPositionLock() -> CGFloat? {
|
||||
@ -410,6 +474,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
transition.updateFrame(node: self.clippingNode, frame: CGRect(origin: CGPoint(), size: layout.size), beginWithCurrentState: true)
|
||||
if self.scrollNode.frame != CGRect(origin: CGPoint(), size: layout.size) {
|
||||
transition.updateFrame(node: self.scrollNode, frame: CGRect(origin: CGPoint(), size: layout.size), beginWithCurrentState: true)
|
||||
transition.updateFrame(view: self.scroller, frame: CGRect(origin: CGPoint(), size: layout.size), beginWithCurrentState: true)
|
||||
}
|
||||
|
||||
if let current = self.contentNode {
|
||||
@ -684,16 +749,16 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
}
|
||||
let contentSize = CGSize(width: layout.size.width, height: contentHeight)
|
||||
|
||||
if self.scrollNode.view.contentSize != contentSize {
|
||||
let previousContentOffset = self.scrollNode.view.contentOffset
|
||||
self.scrollNode.view.contentSize = contentSize
|
||||
if self.scroller.contentSize != contentSize {
|
||||
let previousContentOffset = self.scroller.contentOffset
|
||||
self.scroller.contentSize = contentSize
|
||||
if let storedScrollingState = self.actionsStackNode.storedScrollingState {
|
||||
self.actionsStackNode.clearStoredScrollingState()
|
||||
|
||||
self.scrollNode.view.contentOffset = CGPoint(x: 0.0, y: storedScrollingState)
|
||||
self.scroller.contentOffset = CGPoint(x: 0.0, y: storedScrollingState)
|
||||
}
|
||||
if case .none = stateTransition, transition.isAnimated {
|
||||
let contentOffset = self.scrollNode.view.contentOffset
|
||||
let contentOffset = self.scroller.contentOffset
|
||||
transition.animateOffsetAdditive(layer: self.scrollNode.layer, offset: previousContentOffset.y - contentOffset.y)
|
||||
}
|
||||
}
|
||||
@ -718,7 +783,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
let duration: Double = 0.42
|
||||
let springDamping: CGFloat = 104.0
|
||||
|
||||
self.scrollNode.view.contentOffset = CGPoint(x: 0.0, y: defaultScrollY)
|
||||
self.scroller.contentOffset = CGPoint(x: 0.0, y: defaultScrollY)
|
||||
|
||||
self.backgroundNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
|
||||
|
@ -112,7 +112,7 @@ private final class ExpandItemView: UIView {
|
||||
self.tintView.layer.cornerRadius = size.width / 2.0
|
||||
|
||||
if let image = self.arrowView.image {
|
||||
transition.updateFrame(view: self.arrowView, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - image.size.width) / 2.0), y: floorToScreenPixels((size.height - image.size.height) / 2.0)), size: image.size))
|
||||
transition.updateFrame(view: self.arrowView, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - image.size.width) / 2.0), y: floorToScreenPixels(size.height - size.width + (size.width - image.size.height) / 2.0)), size: image.size))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -168,6 +168,10 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
|
||||
public private(set) var currentContentHeight: CGFloat = 46.0
|
||||
public private(set) var isExpanded: Bool = false
|
||||
public private(set) var canBeExpanded: Bool = false
|
||||
|
||||
private var animateFromExtensionDistance: CGFloat = 0.0
|
||||
private var extensionDistance: CGFloat = 0.0
|
||||
|
||||
private var emojiContent: EmojiPagerContentComponent?
|
||||
private var emojiContentDisposable: Disposable?
|
||||
@ -252,6 +256,8 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
|
||||
self.contentContainer.view.addSubview(expandItemView)
|
||||
self.contentTintContainer.view.addSubview(expandItemView.tintView)
|
||||
|
||||
self.canBeExpanded = true
|
||||
} else {
|
||||
self.expandItemView = nil
|
||||
}
|
||||
@ -289,6 +295,16 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.backgroundNode.updateIsIntersectingContent(isIntersectingContent: isIntersectingContent, transition: transition)
|
||||
}
|
||||
|
||||
public func updateExtension(distance: CGFloat) {
|
||||
if self.extensionDistance != distance {
|
||||
self.extensionDistance = distance
|
||||
|
||||
if let (size, insets, anchorRect) = self.validLayout {
|
||||
self.updateLayout(size: size, insets: insets, anchorRect: anchorRect, isAnimatingOut: false, transition: .immediate, animateInFromAnchorRect: nil, animateOutToAnchorRect: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func calculateBackgroundFrame(containerSize: CGSize, insets: UIEdgeInsets, anchorRect: CGRect, contentSize: CGSize) -> (backgroundFrame: CGRect, visualBackgroundFrame: CGRect, isLeftAligned: Bool, cloudSourcePoint: CGFloat) {
|
||||
var contentSize = contentSize
|
||||
contentSize.width = max(46.0, contentSize.width)
|
||||
@ -325,7 +341,8 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
cloudSourcePoint = max(rect.minX + 46.0 / 2.0, anchorRect.minX)
|
||||
}
|
||||
|
||||
let visualRect = rect
|
||||
var visualRect = rect
|
||||
visualRect.size.height += self.extensionDistance
|
||||
|
||||
return (rect, visualRect, isLeftAligned, cloudSourcePoint)
|
||||
}
|
||||
@ -478,7 +495,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
}
|
||||
|
||||
if let expandItemView = self.expandItemView {
|
||||
let baseNextFrame = CGRect(origin: CGPoint(x: nextX + 3.0, y: containerHeight - contentHeight + floor((contentHeight - 30.0) / 2.0) + (self.isExpanded ? 46.0 : 0.0)), size: CGSize(width: 30.0, height: 30.0))
|
||||
let baseNextFrame = CGRect(origin: CGPoint(x: nextX + 3.0, y: containerHeight - contentHeight + floor((contentHeight - 30.0) / 2.0) + (self.isExpanded ? 46.0 : 0.0)), size: CGSize(width: 30.0, height: 30.0 + self.extensionDistance))
|
||||
|
||||
transition.updateFrame(view: expandItemView, frame: baseNextFrame)
|
||||
transition.updateFrame(view: expandItemView.tintView, frame: baseNextFrame)
|
||||
@ -488,10 +505,10 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
|
||||
if let currentMaskFrame = currentMaskFrame {
|
||||
let transition = maskTransition ?? transition
|
||||
transition.updateFrame(node: self.leftBackgroundMaskNode, frame: CGRect(x: -1000.0 + currentMaskFrame.minX, y: 0.0, width: 1000.0, height: self.currentContentHeight))
|
||||
transition.updateFrame(node: self.rightBackgroundMaskNode, frame: CGRect(x: currentMaskFrame.maxX, y: 0.0, width: 1000.0, height: self.currentContentHeight))
|
||||
transition.updateFrame(node: self.leftBackgroundMaskNode, frame: CGRect(x: -1000.0 + currentMaskFrame.minX, y: 0.0, width: 1000.0, height: self.currentContentHeight + self.extensionDistance))
|
||||
transition.updateFrame(node: self.rightBackgroundMaskNode, frame: CGRect(x: currentMaskFrame.maxX, y: 0.0, width: 1000.0, height: self.currentContentHeight + self.extensionDistance))
|
||||
} else {
|
||||
self.leftBackgroundMaskNode.frame = CGRect(x: 0.0, y: 0.0, width: 1000.0, height: self.currentContentHeight)
|
||||
self.leftBackgroundMaskNode.frame = CGRect(x: 0.0, y: 0.0, width: 1000.0, height: self.currentContentHeight + self.extensionDistance)
|
||||
self.rightBackgroundMaskNode.frame = CGRect(origin: .zero, size: .zero)
|
||||
}
|
||||
|
||||
@ -569,12 +586,15 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.isLeftAligned = isLeftAligned
|
||||
self.visibleItemCount = itemCount
|
||||
|
||||
var scrollFrame = CGRect(origin: CGPoint(x: 0.0, y: self.isExpanded ? 46.0 : 0.0), size: actualBackgroundFrame.size)
|
||||
scrollFrame.origin.y += floorToScreenPixels(self.extensionDistance / 2.0)
|
||||
|
||||
transition.updateFrame(node: self.contentContainer, frame: visualBackgroundFrame, beginWithCurrentState: true)
|
||||
transition.updateFrame(node: self.contentTintContainer, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: visualBackgroundFrame.size), beginWithCurrentState: true)
|
||||
transition.updateFrame(view: self.contentContainerMask, frame: CGRect(origin: CGPoint(), size: visualBackgroundFrame.size), beginWithCurrentState: true)
|
||||
transition.updateFrame(node: self.scrollNode, frame: CGRect(origin: CGPoint(x: 0.0, y: self.isExpanded ? 46.0 : 0.0), size: actualBackgroundFrame.size), beginWithCurrentState: true)
|
||||
transition.updateFrame(node: self.scrollNode, frame: scrollFrame, beginWithCurrentState: true)
|
||||
transition.updateFrame(node: self.previewingItemContainer, frame: visualBackgroundFrame, beginWithCurrentState: true)
|
||||
self.scrollNode.view.contentSize = CGSize(width: completeContentWidth, height: visualBackgroundFrame.size.height)
|
||||
self.scrollNode.view.contentSize = CGSize(width: completeContentWidth, height: scrollFrame.size.height)
|
||||
|
||||
self.updateScrolling(transition: transition)
|
||||
|
||||
@ -607,9 +627,23 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
||||
strongSelf.emojiContent = emojiContent
|
||||
if let (size, insets, anchorRect) = strongSelf.validLayout {
|
||||
strongSelf.updateLayout(size: size, insets: insets, anchorRect: anchorRect, isAnimatingOut: false, transition: .immediate, animateInFromAnchorRect: nil, animateOutToAnchorRect: nil)
|
||||
|
||||
if let reactionSelectionComponentHost = strongSelf.reactionSelectionComponentHost, let componentView = reactionSelectionComponentHost.view {
|
||||
let _ = reactionSelectionComponentHost.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(EmojiStatusSelectionComponent(
|
||||
theme: strongSelf.presentationData.theme,
|
||||
strings: strongSelf.presentationData.strings,
|
||||
deviceMetrics: DeviceMetrics.iPhone13,
|
||||
emojiContent: emojiContent,
|
||||
backgroundColor: .clear,
|
||||
separatorColor: strongSelf.presentationData.theme.list.itemPlainSeparatorColor.withMultipliedAlpha(0.5)
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: componentView.bounds.width, height: 300.0)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -754,7 +788,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
componentTransition.setFrame(view: componentView, frame: CGRect(origin: componentFrame.origin, size: CGSize(width: componentFrame.width, height: componentFrame.height)))
|
||||
|
||||
if animateIn {
|
||||
transition.animatePositionAdditive(layer: componentView.layer, offset: CGPoint(x: 0.0, y: -46.0))
|
||||
transition.animatePositionAdditive(layer: componentView.layer, offset: CGPoint(x: 0.0, y: -46.0 + floorToScreenPixels(self.animateFromExtensionDistance / 2.0)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1250,6 +1284,14 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
public func expand() {
|
||||
self.animateFromExtensionDistance = self.extensionDistance
|
||||
self.extensionDistance = 0.0
|
||||
self.currentContentHeight = 300.0
|
||||
self.isExpanded = true
|
||||
self.isExpandedUpdated(.animated(duration: 0.4, curve: .spring))
|
||||
}
|
||||
|
||||
public func highlightGestureMoved(location: CGPoint, hover: Bool) {
|
||||
let highlightedReaction = self.previewReaction(at: location)?.reaction
|
||||
if self.highlightedReaction != highlightedReaction {
|
||||
|
@ -170,6 +170,28 @@ func _internal_reportPeerMessages(account: Account, messageIds: [MessageId], rea
|
||||
} |> switchToLatest
|
||||
}
|
||||
|
||||
func _internal_reportPeerReaction(account: Account, authorId: PeerId, messageId: MessageId) -> Signal<Never, NoError> {
|
||||
return account.postbox.transaction { transaction -> (Api.InputPeer, Api.InputUser)? in
|
||||
guard let peer = transaction.getPeer(messageId.peerId).flatMap(apiInputPeer) else {
|
||||
return nil
|
||||
}
|
||||
guard let author = transaction.getPeer(authorId).flatMap(apiInputUser) else {
|
||||
return nil
|
||||
}
|
||||
return (peer, author)
|
||||
}
|
||||
|> mapToSignal { inputData -> Signal<Never, NoError> in
|
||||
guard let (inputPeer, inputUser) = inputData else {
|
||||
return .complete()
|
||||
}
|
||||
return account.network.request(Api.functions.messages.reportReaction(peer: inputPeer, id: messageId.id, userId: inputUser))
|
||||
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
||||
return .single(.boolFalse)
|
||||
}
|
||||
|> ignoreValues
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_dismissPeerStatusOptions(account: Account, peerId: PeerId) -> Signal<Void, NoError> {
|
||||
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
|
||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
||||
|
@ -160,7 +160,11 @@ public extension TelegramEngine {
|
||||
}
|
||||
|
||||
public func reportPeerMessages(messageIds: [MessageId], reason: ReportReason, message: String) -> Signal<Void, NoError> {
|
||||
return _internal_reportPeerMessages(account: account, messageIds: messageIds, reason: reason, message: message)
|
||||
return _internal_reportPeerMessages(account: self.account, messageIds: messageIds, reason: reason, message: message)
|
||||
}
|
||||
|
||||
public func reportPeerReaction(authorId: PeerId, messageId: MessageId) -> Signal<Never, NoError> {
|
||||
return _internal_reportPeerReaction(account: self.account, authorId: authorId, messageId: messageId)
|
||||
}
|
||||
|
||||
public func dismissPeerStatusOptions(peerId: PeerId) -> Signal<Void, NoError> {
|
||||
|
@ -408,7 +408,7 @@ final class ChatBotInfoItemNode: ListViewItemNode {
|
||||
case let .url(url, concealed):
|
||||
self.item?.controllerInteraction.openUrl(url, concealed, nil, nil)
|
||||
case let .peerMention(peerId, _):
|
||||
self.item?.controllerInteraction.openPeer(peerId, .chat(textInputState: nil, subject: nil, peekData: nil), nil, nil)
|
||||
self.item?.controllerInteraction.openPeer(peerId, .chat(textInputState: nil, subject: nil, peekData: nil), nil, false, nil)
|
||||
case let .textMention(name):
|
||||
self.item?.controllerInteraction.openPeerMention(name)
|
||||
case let .botCommand(command):
|
||||
|
@ -247,7 +247,7 @@ final class ChatButtonKeyboardInputNode: ChatInputNode {
|
||||
peerId = message.id.peerId
|
||||
}
|
||||
if let botPeer = botPeer, let addressName = botPeer.addressName {
|
||||
self.controllerInteraction.openPeer(peerId, .chat(textInputState: ChatTextInputState(inputText: NSAttributedString(string: "@\(addressName) \(query)")), subject: nil, peekData: nil), nil, nil)
|
||||
self.controllerInteraction.openPeer(peerId, .chat(textInputState: ChatTextInputState(inputText: NSAttributedString(string: "@\(addressName) \(query)")), subject: nil, peekData: nil), nil, false, nil)
|
||||
}
|
||||
}
|
||||
case .payment:
|
||||
@ -259,7 +259,7 @@ final class ChatButtonKeyboardInputNode: ChatInputNode {
|
||||
case let .setupPoll(isQuiz):
|
||||
self.controllerInteraction.openPollCreation(isQuiz)
|
||||
case let .openUserProfile(peerId):
|
||||
self.controllerInteraction.openPeer(peerId, .info, nil, nil)
|
||||
self.controllerInteraction.openPeer(peerId, .info, nil, false, nil)
|
||||
case let .openWebView(url, simple):
|
||||
self.controllerInteraction.openWebView(markupButton.title, url, simple, false)
|
||||
}
|
||||
|
@ -881,7 +881,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
}, openPeer: { [weak self] peerId in
|
||||
if let strongSelf = self {
|
||||
strongSelf.controllerInteraction?.openPeer(peerId, .default, nil, nil)
|
||||
strongSelf.controllerInteraction?.openPeer(peerId, .default, nil, false, nil)
|
||||
}
|
||||
}, openHashtag: { [weak self] peerName, hashtag in
|
||||
if let strongSelf = self {
|
||||
@ -948,8 +948,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
})
|
||||
})))
|
||||
}, openPeer: { [weak self] id, navigation, fromMessage, _ in
|
||||
self?.openPeer(peerId: id, navigation: navigation, fromMessage: fromMessage)
|
||||
}, openPeer: { [weak self] id, navigation, fromMessage, isReaction, _ in
|
||||
self?.openPeer(peerId: id, navigation: navigation, fromMessage: fromMessage, fromReactionMessageId: isReaction ? fromMessage?.id : nil)
|
||||
}, openPeerMention: { [weak self] name in
|
||||
self?.openPeerMention(name)
|
||||
}, openMessageContextMenu: { [weak self] message, selectAll, node, frame, anyRecognizer, location in
|
||||
@ -1437,7 +1437,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return
|
||||
}
|
||||
|
||||
strongSelf.openPeer(peerId: id, navigation: .default, fromMessage: MessageReference(message))
|
||||
strongSelf.openPeer(peerId: id, navigation: .default, fromMessage: MessageReference(message), fromReactionMessageId: message.id)
|
||||
})
|
||||
})))
|
||||
|
||||
@ -1552,7 +1552,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
),
|
||||
file: items.first?.file,
|
||||
action: action)
|
||||
return .single(tip) |> delay(1.0, queue: .mainQueue())
|
||||
return .single(tip)
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
@ -12707,7 +12707,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
case let .mention(peerId, mention):
|
||||
switch action {
|
||||
case .tap:
|
||||
strongSelf.controllerInteraction?.openPeer(peerId, .default, nil, nil)
|
||||
strongSelf.controllerInteraction?.openPeer(peerId, .default, nil, false, nil)
|
||||
case .longTap:
|
||||
strongSelf.controllerInteraction?.longTap(.peerMention(peerId, mention), nil)
|
||||
}
|
||||
@ -12795,7 +12795,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
case let .mention(peerId, mention):
|
||||
switch action {
|
||||
case .tap:
|
||||
strongSelf.controllerInteraction?.openPeer(peerId, .default, nil, nil)
|
||||
strongSelf.controllerInteraction?.openPeer(peerId, .default, nil, false, nil)
|
||||
case .longTap:
|
||||
strongSelf.controllerInteraction?.longTap(.peerMention(peerId, mention), nil)
|
||||
}
|
||||
@ -12904,7 +12904,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
case let .mention(peerId, mention):
|
||||
switch action {
|
||||
case .tap:
|
||||
strongSelf.controllerInteraction?.openPeer(peerId, .default, nil, nil)
|
||||
strongSelf.controllerInteraction?.openPeer(peerId, .default, nil, false, nil)
|
||||
case .longTap:
|
||||
strongSelf.controllerInteraction?.longTap(.peerMention(peerId, mention), nil)
|
||||
}
|
||||
@ -14887,7 +14887,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
})
|
||||
}
|
||||
|
||||
private func openPeer(peerId: PeerId?, navigation: ChatControllerInteractionNavigateToPeer, fromMessage: MessageReference?, expandAvatar: Bool = false) {
|
||||
private func openPeer(peerId: PeerId?, navigation: ChatControllerInteractionNavigateToPeer, fromMessage: MessageReference?, fromReactionMessageId: MessageId? = nil, expandAvatar: Bool = false) {
|
||||
let _ = self.presentVoiceMessageDiscardAlert(action: {
|
||||
if case let .peer(currentPeerId) = self.chatLocation, peerId == currentPeerId {
|
||||
switch navigation {
|
||||
@ -14936,6 +14936,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
if let _ = fromMessage, let chatPeerId = chatPeerId {
|
||||
mode = .group(chatPeerId)
|
||||
}
|
||||
if let fromReactionMessageId = fromReactionMessageId {
|
||||
mode = .reaction(fromReactionMessageId)
|
||||
}
|
||||
var expandAvatar = expandAvatar
|
||||
if peer.smallProfileImage == nil {
|
||||
expandAvatar = false
|
||||
|
@ -59,7 +59,7 @@ struct UnreadMessageRangeKey: Hashable {
|
||||
|
||||
public final class ChatControllerInteraction {
|
||||
let openMessage: (Message, ChatControllerInteractionOpenMessageMode) -> Bool
|
||||
let openPeer: (PeerId?, ChatControllerInteractionNavigateToPeer, MessageReference?, Peer?) -> Void
|
||||
let openPeer: (PeerId?, ChatControllerInteractionNavigateToPeer, MessageReference?, Bool, Peer?) -> Void
|
||||
let openPeerMention: (String) -> Void
|
||||
let openMessageContextMenu: (Message, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?, CGPoint?) -> Void
|
||||
let updateMessageReaction: (Message, ChatControllerInteractionReaction) -> Void
|
||||
@ -164,7 +164,7 @@ public final class ChatControllerInteraction {
|
||||
|
||||
init(
|
||||
openMessage: @escaping (Message, ChatControllerInteractionOpenMessageMode) -> Bool,
|
||||
openPeer: @escaping (PeerId?, ChatControllerInteractionNavigateToPeer, MessageReference?, Peer?) -> Void,
|
||||
openPeer: @escaping (PeerId?, ChatControllerInteractionNavigateToPeer, MessageReference?, Bool, Peer?) -> Void,
|
||||
openPeerMention: @escaping (String) -> Void,
|
||||
openMessageContextMenu: @escaping (Message, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?, CGPoint?) -> Void,
|
||||
openMessageReactionContextMenu: @escaping (Message, ContextExtractedContentContainingView, ContextGesture?, MessageReaction.Reaction) -> Void,
|
||||
|
@ -1584,7 +1584,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
actions.insert(.custom(ChatReadReportContextItem(context: context, message: message, stats: readStats, action: { c, f, stats, customReactionEmojiPacks, firstCustomEmojiReaction in
|
||||
if reactionCount == 0, let stats = stats, stats.peers.count == 1 {
|
||||
c.dismiss(completion: {
|
||||
controllerInteraction.openPeer(stats.peers[0].id, .default, nil, nil)
|
||||
controllerInteraction.openPeer(stats.peers[0].id, .default, nil, false, nil)
|
||||
})
|
||||
} else if (stats != nil && !stats!.peers.isEmpty) || reactionCount != 0 {
|
||||
var tip: ContextController.Tip?
|
||||
@ -1625,7 +1625,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
},
|
||||
openPeer: { [weak c] id in
|
||||
c?.dismiss(completion: {
|
||||
controllerInteraction.openPeer(id, .default, nil, nil)
|
||||
controllerInteraction.openPeer(id, .default, MessageReference(message), true, nil)
|
||||
})
|
||||
}
|
||||
)), tip: tip)))
|
||||
|
@ -1941,7 +1941,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId)
|
||||
} else if let peer = forwardInfo.source ?? forwardInfo.author {
|
||||
item.controllerInteraction.openPeer(peer.id, peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, nil)
|
||||
item.controllerInteraction.openPeer(peer.id, peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, false, nil)
|
||||
} else if let _ = forwardInfo.authorSignature {
|
||||
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil)
|
||||
}
|
||||
|
@ -3221,7 +3221,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
})
|
||||
} else {
|
||||
return .optionalAction({
|
||||
item.controllerInteraction.openPeer(peerId, .chat(textInputState: nil, subject: nil, peekData: nil), nil, item.message.peers[peerId])
|
||||
item.controllerInteraction.openPeer(peerId, .chat(textInputState: nil, subject: nil, peekData: nil), nil, false, item.message.peers[peerId])
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -3253,7 +3253,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
}
|
||||
item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId)
|
||||
} else if let peer = forwardInfo.source ?? forwardInfo.author {
|
||||
item.controllerInteraction.openPeer(peer.id, peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, nil)
|
||||
item.controllerInteraction.openPeer(peer.id, peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, false, nil)
|
||||
} else if let _ = forwardInfo.authorSignature {
|
||||
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil)
|
||||
}
|
||||
@ -3292,7 +3292,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
})
|
||||
case let .peerMention(peerId, _):
|
||||
return .action({
|
||||
self.item?.controllerInteraction.openPeer(peerId, .chat(textInputState: nil, subject: nil, peekData: nil), nil, nil)
|
||||
self.item?.controllerInteraction.openPeer(peerId, .chat(textInputState: nil, subject: nil, peekData: nil), nil, false, nil)
|
||||
})
|
||||
case let .textMention(name):
|
||||
return .action({
|
||||
|
@ -612,9 +612,9 @@ final class ChatMessageAvatarHeaderNode: ListViewItemHeaderNode {
|
||||
self.controllerInteraction.displayMessageTooltip(id, self.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, self.avatarNode.frame)
|
||||
} else {
|
||||
if let channel = self.peer as? TelegramChannel, case .broadcast = channel.info {
|
||||
self.controllerInteraction.openPeer(self.peerId, .chat(textInputState: nil, subject: nil, peekData: nil), self.messageReference, nil)
|
||||
self.controllerInteraction.openPeer(self.peerId, .chat(textInputState: nil, subject: nil, peekData: nil), self.messageReference, false, nil)
|
||||
} else {
|
||||
self.controllerInteraction.openPeer(self.peerId, .info, self.messageReference, nil)
|
||||
self.controllerInteraction.openPeer(self.peerId, .info, self.messageReference, false, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -918,7 +918,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
|
||||
}
|
||||
item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId)
|
||||
} else if let peer = forwardInfo.source ?? forwardInfo.author {
|
||||
item.controllerInteraction.openPeer(peer.id, peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, nil)
|
||||
item.controllerInteraction.openPeer(peer.id, peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, false, nil)
|
||||
} else if let _ = forwardInfo.authorSignature {
|
||||
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil)
|
||||
}
|
||||
|
@ -847,7 +847,7 @@ public class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol
|
||||
case .setupPoll:
|
||||
break
|
||||
case let .openUserProfile(peerId):
|
||||
item.controllerInteraction.openPeer(peerId, .info, nil, nil)
|
||||
item.controllerInteraction.openPeer(peerId, .info, nil, false, nil)
|
||||
case let .openWebView(url, simple):
|
||||
item.controllerInteraction.openWebView(button.title, url, simple, false)
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
}
|
||||
navigationData = .chat(textInputState: nil, subject: subject, peekData: nil)
|
||||
}
|
||||
item.controllerInteraction.openPeer(id, navigationData, nil, nil)
|
||||
item.controllerInteraction.openPeer(id, navigationData, nil, false, nil)
|
||||
case let .join(_, joinHash):
|
||||
item.controllerInteraction.openJoinLink(joinHash)
|
||||
}
|
||||
|
@ -851,7 +851,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
case .setupPoll:
|
||||
break
|
||||
case let .openUserProfile(peerId):
|
||||
controllerInteraction.openPeer(peerId, .info, nil, nil)
|
||||
controllerInteraction.openPeer(peerId, .info, nil, false, nil)
|
||||
case let .openWebView(url, simple):
|
||||
controllerInteraction.openWebView(button.title, url, simple, false)
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
}, gallerySource: gallerySource))
|
||||
}
|
||||
return false
|
||||
}, openPeer: { [weak self] peerId, _, message, peer in
|
||||
}, openPeer: { [weak self] peerId, _, message, _, peer in
|
||||
if let peerId = peerId, peerId != context.account.peerId {
|
||||
self?.openPeer(peerId: peerId, peer: peer)
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
|
||||
var selectStickerImpl: ((FileMediaReference, UIView, CGRect) -> Bool)?
|
||||
|
||||
self.controllerInteraction = ChatControllerInteraction(openMessage: { _, _ in
|
||||
return false }, openPeer: { _, _, _, _ in }, openPeerMention: { _ in }, openMessageContextMenu: { _, _, _, _, _, _ in }, openMessageReactionContextMenu: { _, _, _, _ in
|
||||
return false }, openPeer: { _, _, _, _, _ in }, openPeerMention: { _ in }, openMessageContextMenu: { _, _, _, _, _, _ in }, openMessageReactionContextMenu: { _, _, _, _ in
|
||||
}, updateMessageReaction: { _, _ in }, activateMessagePinch: { _ in
|
||||
}, openMessageContextActions: { _, _, _, _ in }, navigateToMessage: { _, _ in }, navigateToMessageStandalone: { _ in
|
||||
}, tapMessage: nil, clickThroughMessage: { }, toggleMessagesSelection: { _, _ in }, sendCurrentMessage: { _ in }, sendMessage: { _ in }, sendSticker: { fileReference, _, _, _, _, node, rect, _ in return selectStickerImpl?(fileReference, node, rect) ?? false }, sendGif: { _, _, _, _, _ in return false }, sendBotContextResultAsGif: { _, _, _, _, _ in return false }, requestMessageActionCallback: { _, _, _, _ in }, requestMessageActionUrlAuth: { _, _ in }, activateSwitchInline: { _, _ in }, openUrl: { _, _, _, _ in }, shareCurrentLocation: {}, shareAccountContact: {}, sendBotCommand: { _, _ in }, openInstantPage: { _, _ in }, openWallpaper: { _ in }, openTheme: { _ in }, openHashtag: { _, _ in }, updateInputState: { _ in }, updateInputMode: { _ in }, openMessageShareMenu: { _ in
|
||||
|
@ -67,7 +67,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}, openPeer: { _, _, _, _ in
|
||||
}, openPeer: { _, _, _, _, _ in
|
||||
}, openPeerMention: { _ in
|
||||
}, openMessageContextMenu: { _, _, _, _, _, _ in
|
||||
}, openMessageReactionContextMenu: { _, _, _, _ in
|
||||
|
@ -186,7 +186,7 @@ final class PeerInfoGroupsInCommonPaneNode: ASDisplayNode, PeerInfoPaneNode {
|
||||
}
|
||||
}
|
||||
let transaction = preparedTransition(from: self.currentEntries, to: entries, context: self.context, presentationData: presentationData, openPeer: { [weak self] peer in
|
||||
self?.chatControllerInteraction.openPeer(peer.id, .default, nil, nil)
|
||||
self?.chatControllerInteraction.openPeer(peer.id, .default, nil, false, nil)
|
||||
}, openPeerContextAction: { [weak self] peer, node, gesture in
|
||||
self?.openPeerContextAction(peer, node, gesture)
|
||||
})
|
||||
|
@ -449,6 +449,12 @@ private enum PeerInfoSettingsSection {
|
||||
case emojiStatus
|
||||
}
|
||||
|
||||
private enum PeerInfoReportType {
|
||||
case `default`
|
||||
case user
|
||||
case reaction(MessageId)
|
||||
}
|
||||
|
||||
private final class PeerInfoInteraction {
|
||||
let openChat: () -> Void
|
||||
let openUsername: (String) -> Void
|
||||
@ -459,7 +465,7 @@ private final class PeerInfoInteraction {
|
||||
let requestDeleteContact: () -> Void
|
||||
let openAddContact: () -> Void
|
||||
let updateBlocked: (Bool) -> Void
|
||||
let openReport: (Bool) -> Void
|
||||
let openReport: (PeerInfoReportType) -> Void
|
||||
let openShareBot: () -> Void
|
||||
let openAddBotToGroup: () -> Void
|
||||
let performBotCommand: (PeerInfoBotCommand) -> Void
|
||||
@ -503,7 +509,7 @@ private final class PeerInfoInteraction {
|
||||
openChat: @escaping () -> Void,
|
||||
openAddContact: @escaping () -> Void,
|
||||
updateBlocked: @escaping (Bool) -> Void,
|
||||
openReport: @escaping (Bool) -> Void,
|
||||
openReport: @escaping (PeerInfoReportType) -> Void,
|
||||
openShareBot: @escaping () -> Void,
|
||||
openAddBotToGroup: @escaping () -> Void,
|
||||
performBotCommand: @escaping (PeerInfoBotCommand) -> Void,
|
||||
@ -900,7 +906,7 @@ private func settingsEditingItems(data: PeerInfoScreenData?, state: PeerInfoStat
|
||||
return result
|
||||
}
|
||||
|
||||
private func infoItems(data: PeerInfoScreenData?, context: AccountContext, presentationData: PresentationData, interaction: PeerInfoInteraction, nearbyPeerDistance: Int32?, callMessages: [Message]) -> [(AnyHashable, [PeerInfoScreenItem])] {
|
||||
private func infoItems(data: PeerInfoScreenData?, context: AccountContext, presentationData: PresentationData, interaction: PeerInfoInteraction, nearbyPeerDistance: Int32?, reactionSourceMessageId: MessageId?, callMessages: [Message]) -> [(AnyHashable, [PeerInfoScreenItem])] {
|
||||
guard let data = data else {
|
||||
return []
|
||||
}
|
||||
@ -965,13 +971,21 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
||||
}))
|
||||
}
|
||||
}
|
||||
if let _ = nearbyPeerDistance {
|
||||
if let reactionSourceMessageId = reactionSourceMessageId {
|
||||
items[.peerInfo]!.append(PeerInfoScreenActionItem(id: 3, text: presentationData.strings.UserInfo_SendMessage, action: {
|
||||
interaction.openChat()
|
||||
}))
|
||||
|
||||
items[.peerInfo]!.append(PeerInfoScreenActionItem(id: 4, text: presentationData.strings.ReportPeer_Report, color: .destructive, action: {
|
||||
interaction.openReport(true)
|
||||
interaction.openReport(.reaction(reactionSourceMessageId))
|
||||
}))
|
||||
} else if let _ = nearbyPeerDistance {
|
||||
items[.peerInfo]!.append(PeerInfoScreenActionItem(id: 3, text: presentationData.strings.UserInfo_SendMessage, action: {
|
||||
interaction.openChat()
|
||||
}))
|
||||
|
||||
items[.peerInfo]!.append(PeerInfoScreenActionItem(id: 4, text: presentationData.strings.ReportPeer_Report, color: .destructive, action: {
|
||||
interaction.openReport(.user)
|
||||
}))
|
||||
} else {
|
||||
if !data.isContact {
|
||||
@ -1010,7 +1024,7 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
||||
|
||||
if user.botInfo != nil, !user.isVerified {
|
||||
items[.peerInfo]!.append(PeerInfoScreenActionItem(id: 6, text: presentationData.strings.ReportPeer_Report, action: {
|
||||
interaction.openReport(false)
|
||||
interaction.openReport(.default)
|
||||
}))
|
||||
}
|
||||
|
||||
@ -1717,6 +1731,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
highlightedButton: nil
|
||||
)
|
||||
private let nearbyPeerDistance: Int32?
|
||||
private let reactionSourceMessageId: MessageId?
|
||||
private var dataDisposable: Disposable?
|
||||
|
||||
private let activeActionDisposable = MetaDisposable()
|
||||
@ -1757,7 +1772,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
private var didSetReady = false
|
||||
|
||||
init(controller: PeerInfoScreenImpl, context: AccountContext, peerId: PeerId, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, nearbyPeerDistance: Int32?, callMessages: [Message], isSettings: Bool, hintGroupInCommon: PeerId?, requestsContext: PeerInvitationImportersContext?) {
|
||||
init(controller: PeerInfoScreenImpl, context: AccountContext, peerId: PeerId, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, nearbyPeerDistance: Int32?, reactionSourceMessageId: MessageId?, callMessages: [Message], isSettings: Bool, hintGroupInCommon: PeerId?, requestsContext: PeerInvitationImportersContext?) {
|
||||
self.controller = controller
|
||||
self.context = context
|
||||
self.peerId = peerId
|
||||
@ -1765,6 +1780,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
self.videoCallsEnabled = true
|
||||
self.presentationData = controller.presentationData
|
||||
self.nearbyPeerDistance = nearbyPeerDistance
|
||||
self.reactionSourceMessageId = reactionSourceMessageId
|
||||
self.callMessages = callMessages
|
||||
self.isSettings = isSettings
|
||||
self.isMediaOnly = context.account.peerId == peerId && !isSettings
|
||||
@ -1808,8 +1824,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
updateBlocked: { [weak self] block in
|
||||
self?.updateBlocked(block: block)
|
||||
},
|
||||
openReport: { [weak self] user in
|
||||
self?.openReport(user: user, contextController: nil, backAction: nil)
|
||||
openReport: { [weak self] type in
|
||||
self?.openReport(type: type, contextController: nil, backAction: nil)
|
||||
},
|
||||
openShareBot: { [weak self] in
|
||||
self?.openShareBot()
|
||||
@ -1914,7 +1930,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
return false
|
||||
}
|
||||
return strongSelf.openMessage(id: message.id)
|
||||
}, openPeer: { [weak self] id, navigation, _, _ in
|
||||
}, openPeer: { [weak self] id, navigation, _, _, _ in
|
||||
if let id = id {
|
||||
self?.openPeer(peerId: id, navigation: navigation)
|
||||
}
|
||||
@ -2443,7 +2459,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
let items: [ContextMenuItem] = [
|
||||
.action(ContextMenuActionItem(text: presentationData.strings.Conversation_LinkDialogOpen, icon: { _ in nil }, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
self?.chatInterfaceInteraction.openPeer(peer.id, .default, nil, nil)
|
||||
self?.chatInterfaceInteraction.openPeer(peer.id, .default, nil, false, nil)
|
||||
}))
|
||||
]
|
||||
let contextController = ContextController(account: strongSelf.context.account, presentationData: presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture)
|
||||
@ -4296,7 +4312,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.ReportPeer_Report, icon: { theme in
|
||||
generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Report"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] c, f in
|
||||
self?.openReport(user: false, contextController: c, backAction: { c in
|
||||
self?.openReport(type: .default, contextController: c, backAction: { c in
|
||||
if let mainItemsImpl = mainItemsImpl {
|
||||
c.setItems(mainItemsImpl() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil)
|
||||
}
|
||||
@ -5354,26 +5370,37 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
})
|
||||
}
|
||||
|
||||
private func openReport(user: Bool, contextController: ContextControllerProtocol?, backAction: ((ContextControllerProtocol) -> Void)?) {
|
||||
private func openReport(type: PeerInfoReportType, contextController: ContextControllerProtocol?, backAction: ((ContextControllerProtocol) -> Void)?) {
|
||||
guard let controller = self.controller else {
|
||||
return
|
||||
}
|
||||
self.view.endEditing(true)
|
||||
|
||||
let options: [PeerReportOption]
|
||||
if user {
|
||||
options = [.spam, .fake, .violence, .pornography, .childAbuse]
|
||||
} else {
|
||||
options = [.spam, .fake, .violence, .pornography, .childAbuse, .copyright, .other]
|
||||
}
|
||||
|
||||
presentPeerReportOptions(context: self.context, parent: controller, contextController: contextController, backAction: backAction, subject: .peer(self.peerId), options: options, passthrough: true, completion: { [weak self] reason, _ in
|
||||
if let reason = reason {
|
||||
DispatchQueue.main.async {
|
||||
self?.openChatForReporting(reason)
|
||||
switch type {
|
||||
case let .reaction(sourceMessageId):
|
||||
let _ = (self.context.engine.peers.reportPeerReaction(authorId: self.peerId, messageId: sourceMessageId)
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .emoji(name: "PoliceCar", text: strongSelf.presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), in: .current)
|
||||
})
|
||||
default:
|
||||
let options: [PeerReportOption]
|
||||
if case .user = type {
|
||||
options = [.spam, .fake, .violence, .pornography, .childAbuse]
|
||||
} else {
|
||||
options = [.spam, .fake, .violence, .pornography, .childAbuse, .copyright, .other]
|
||||
}
|
||||
})
|
||||
|
||||
presentPeerReportOptions(context: self.context, parent: controller, contextController: contextController, backAction: backAction, subject: .peer(self.peerId), options: options, passthrough: true, completion: { [weak self] reason, _ in
|
||||
if let reason = reason {
|
||||
DispatchQueue.main.async {
|
||||
self?.openChatForReporting(reason)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private func openEncryptionKey() {
|
||||
@ -7258,7 +7285,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
insets.left += sectionInset
|
||||
insets.right += sectionInset
|
||||
|
||||
let items = self.isSettings ? settingsItems(data: self.data, context: self.context, presentationData: self.presentationData, interaction: self.interaction, isExpanded: self.headerNode.isAvatarExpanded) : infoItems(data: self.data, context: self.context, presentationData: self.presentationData, interaction: self.interaction, nearbyPeerDistance: self.nearbyPeerDistance, callMessages: self.callMessages)
|
||||
let items = self.isSettings ? settingsItems(data: self.data, context: self.context, presentationData: self.presentationData, interaction: self.interaction, isExpanded: self.headerNode.isAvatarExpanded) : infoItems(data: self.data, context: self.context, presentationData: self.presentationData, interaction: self.interaction, nearbyPeerDistance: self.nearbyPeerDistance, reactionSourceMessageId: self.reactionSourceMessageId, callMessages: self.callMessages)
|
||||
|
||||
contentHeight += headerHeight
|
||||
if !(self.isSettings && self.state.isEditing) {
|
||||
@ -7873,6 +7900,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
|
||||
private let avatarInitiallyExpanded: Bool
|
||||
private let isOpenedFromChat: Bool
|
||||
private let nearbyPeerDistance: Int32?
|
||||
private let reactionSourceMessageId: MessageId?
|
||||
private let callMessages: [Message]
|
||||
private let isSettings: Bool
|
||||
private let hintGroupInCommon: PeerId?
|
||||
@ -7911,13 +7939,14 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
|
||||
|
||||
private var validLayout: (layout: ContainerViewLayout, navigationHeight: CGFloat)?
|
||||
|
||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: PeerId, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, nearbyPeerDistance: Int32?, callMessages: [Message], isSettings: Bool = false, hintGroupInCommon: PeerId? = nil, requestsContext: PeerInvitationImportersContext? = nil) {
|
||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: PeerId, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, nearbyPeerDistance: Int32?, reactionSourceMessageId: MessageId?, callMessages: [Message], isSettings: Bool = false, hintGroupInCommon: PeerId? = nil, requestsContext: PeerInvitationImportersContext? = nil) {
|
||||
self.context = context
|
||||
self.updatedPresentationData = updatedPresentationData
|
||||
self.peerId = peerId
|
||||
self.avatarInitiallyExpanded = avatarInitiallyExpanded
|
||||
self.isOpenedFromChat = isOpenedFromChat
|
||||
self.nearbyPeerDistance = nearbyPeerDistance
|
||||
self.reactionSourceMessageId = reactionSourceMessageId
|
||||
self.callMessages = callMessages
|
||||
self.isSettings = isSettings
|
||||
self.hintGroupInCommon = hintGroupInCommon
|
||||
@ -8204,7 +8233,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
|
||||
}
|
||||
|
||||
override public func loadDisplayNode() {
|
||||
self.displayNode = PeerInfoScreenNode(controller: self, context: self.context, peerId: self.peerId, avatarInitiallyExpanded: self.avatarInitiallyExpanded, isOpenedFromChat: self.isOpenedFromChat, nearbyPeerDistance: self.nearbyPeerDistance, callMessages: self.callMessages, isSettings: self.isSettings, hintGroupInCommon: self.hintGroupInCommon, requestsContext: requestsContext)
|
||||
self.displayNode = PeerInfoScreenNode(controller: self, context: self.context, peerId: self.peerId, avatarInitiallyExpanded: self.avatarInitiallyExpanded, isOpenedFromChat: self.isOpenedFromChat, nearbyPeerDistance: self.nearbyPeerDistance, reactionSourceMessageId: self.reactionSourceMessageId, callMessages: self.callMessages, isSettings: self.isSettings, hintGroupInCommon: self.hintGroupInCommon, requestsContext: requestsContext)
|
||||
self.controllerNode.accountsAndPeers.set(self.accountsAndPeers.get() |> map { $0.1 })
|
||||
self.controllerNode.activeSessionsContextAndCount.set(self.activeSessionsContextAndCount.get())
|
||||
self.cachedDataPromise.set(self.controllerNode.cachedDataPromise.get())
|
||||
|
@ -1274,7 +1274,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
let controllerInteraction: ChatControllerInteraction
|
||||
|
||||
controllerInteraction = ChatControllerInteraction(openMessage: { _, _ in
|
||||
return false }, openPeer: { _, _, _, _ in }, openPeerMention: { _ in }, openMessageContextMenu: { _, _, _, _, _, _ in }, openMessageReactionContextMenu: { _, _, _, _ in
|
||||
return false }, openPeer: { _, _, _, _, _ in }, openPeerMention: { _ in }, openMessageContextMenu: { _, _, _, _, _, _ in }, openMessageReactionContextMenu: { _, _, _, _ in
|
||||
}, updateMessageReaction: { _, _ in }, activateMessagePinch: { _ in
|
||||
}, openMessageContextActions: { _, _, _, _ in }, navigateToMessage: { _, _ in }, navigateToMessageStandalone: { _ in
|
||||
}, tapMessage: { message in
|
||||
@ -1514,11 +1514,12 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
|
||||
private func peerInfoControllerImpl(context: AccountContext, updatedPresentationData: (PresentationData, Signal<PresentationData, NoError>)?, peer: Peer, mode: PeerInfoControllerMode, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, requestsContext: PeerInvitationImportersContext? = nil) -> ViewController? {
|
||||
if let _ = peer as? TelegramGroup {
|
||||
return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nil, callMessages: [])
|
||||
return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nil, reactionSourceMessageId: nil, callMessages: [])
|
||||
} else if let _ = peer as? TelegramChannel {
|
||||
return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nil, callMessages: [])
|
||||
return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nil, reactionSourceMessageId: nil, callMessages: [])
|
||||
} else if peer is TelegramUser {
|
||||
var nearbyPeerDistance: Int32?
|
||||
var reactionSourceMessageId: MessageId?
|
||||
var callMessages: [Message] = []
|
||||
var hintGroupInCommon: PeerId?
|
||||
switch mode {
|
||||
@ -1530,10 +1531,12 @@ private func peerInfoControllerImpl(context: AccountContext, updatedPresentation
|
||||
break
|
||||
case let .group(id):
|
||||
hintGroupInCommon = id
|
||||
case let .reaction(messageId):
|
||||
reactionSourceMessageId = messageId
|
||||
}
|
||||
return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nearbyPeerDistance, callMessages: callMessages, hintGroupInCommon: hintGroupInCommon)
|
||||
return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nearbyPeerDistance, reactionSourceMessageId: reactionSourceMessageId, callMessages: callMessages, hintGroupInCommon: hintGroupInCommon)
|
||||
} else if peer is TelegramSecretChat {
|
||||
return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nil, callMessages: [])
|
||||
return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nil, reactionSourceMessageId: nil, callMessages: [])
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ public final class TelegramRootController: NavigationController {
|
||||
sharedContext.switchingData = (nil, nil, nil)
|
||||
}
|
||||
|
||||
let accountSettingsController = PeerInfoScreenImpl(context: self.context, updatedPresentationData: nil, peerId: self.context.account.peerId, avatarInitiallyExpanded: false, isOpenedFromChat: false, nearbyPeerDistance: nil, callMessages: [], isSettings: true)
|
||||
let accountSettingsController = PeerInfoScreenImpl(context: self.context, updatedPresentationData: nil, peerId: self.context.account.peerId, avatarInitiallyExpanded: false, isOpenedFromChat: false, nearbyPeerDistance: nil, reactionSourceMessageId: nil, callMessages: [], isSettings: true)
|
||||
accountSettingsController.tabBarItemDebugTapAction = { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
|
Loading…
x
Reference in New Issue
Block a user