From 5c0851bb152cf0218558c7730112419a65502e94 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Wed, 25 Oct 2023 22:22:27 +0400 Subject: [PATCH 1/3] Add special case for embeds without preview --- submodules/TelegramUI/Sources/ChatController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 02051f5906..0412bc1bb6 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -17994,7 +17994,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } } - } else if let embedUrl = content.embedUrl, !embedUrl.isEmpty { + } else if content.file == nil, (content.image == nil || content.isMediaLargeByDefault == true || content.isMediaLargeByDefault == nil), let embedUrl = content.embedUrl, !embedUrl.isEmpty { progress?.set(.single(false)) if let controllerInteraction = self.controllerInteraction { if controllerInteraction.openMessage(message, .default) { From 6fab49a22904db7ffe45b619d73d971a4c792070 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Wed, 25 Oct 2023 22:22:45 +0400 Subject: [PATCH 2/3] Fix async quote positioning --- submodules/Display/Source/ListView.swift | 3 --- .../Source/ListViewIntermediateState.swift | 27 ++++++++++++------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/submodules/Display/Source/ListView.swift b/submodules/Display/Source/ListView.swift index edc62d5d9b..18a5294fe7 100644 --- a/submodules/Display/Source/ListView.swift +++ b/submodules/Display/Source/ListView.swift @@ -2953,9 +2953,6 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture offset = (self.visibleSize.height - insets.bottom) - itemNode.apparentFrame.maxY + itemNode.insets.top offset += overflow offset -= floor((self.visibleSize.height - insets.bottom - insets.top) * 0.5) - //offset += 100.0 - - //offset = (self.visibleSize.height - insets.bottom) - itemNode.apparentFrame.maxY + getOverflow(itemNode) } } case .visible: diff --git a/submodules/Display/Source/ListViewIntermediateState.swift b/submodules/Display/Source/ListViewIntermediateState.swift index fa220dedab..9a0a1d1862 100644 --- a/submodules/Display/Source/ListViewIntermediateState.swift +++ b/submodules/Display/Source/ListViewIntermediateState.swift @@ -240,12 +240,12 @@ struct PendingNode { } enum ListViewStateNode { - case Node(index: Int, frame: CGRect, referenceNode: QueueLocalObject?) + case Node(index: Int, frame: CGRect, referenceNode: QueueLocalObject?, newNode: QueueLocalObject?) case Placeholder(frame: CGRect) var index: Int? { switch self { - case .Node(let index, _, _): + case let .Node(index, _, _, _): return index case .Placeholder(_): return nil @@ -255,15 +255,15 @@ enum ListViewStateNode { var frame: CGRect { get { switch self { - case .Node(_, let frame, _): + case let .Node(_, frame, _, _): return frame case .Placeholder(let frame): return frame } } set(value) { switch self { - case let .Node(index, _, referenceNode): - self = .Node(index: index, frame: value, referenceNode: referenceNode) + case let .Node(index, _, referenceNode, newNode): + self = .Node(index: index, frame: value, referenceNode: referenceNode, newNode: newNode) case .Placeholder(_): self = .Placeholder(frame: value) } @@ -313,7 +313,7 @@ struct ListViewState { if let (fixedIndex, fixedPosition) = self.scrollPosition { for node in self.nodes { if let index = node.index, index == fixedIndex { - let offset: CGFloat + var offset: CGFloat switch fixedPosition { case let .bottom(additionalOffset): offset = (self.visibleSize.height - self.insets.bottom) - node.frame.maxY + additionalOffset @@ -327,8 +327,17 @@ struct ListViewState { switch overflow { case .top: offset = self.insets.top - node.frame.minY - case .bottom, .custom: + case .bottom: offset = (self.visibleSize.height - self.insets.bottom) - node.frame.maxY + case let .custom(getOverflow): + if Thread.isMainThread, case let .Node(_, _, referenceNode, newNode) = node, let listNode = referenceNode?.syncWith({ $0 }) ?? newNode?.syncWith({ $0 }) { + let overflow = getOverflow(listNode) + offset = (self.visibleSize.height - self.insets.bottom) - node.frame.maxY + offset += overflow + offset -= floor((self.visibleSize.height - self.insets.bottom - self.insets.top) * 0.5) + } else { + offset = self.insets.top - node.frame.minY + } } } case .visible: @@ -741,7 +750,7 @@ struct ListViewState { let nodeFrame = CGRect(origin: nodeOrigin, size: CGSize(width: layout.size.width, height: animated ? 0.0 : layout.size.height)) operations.append(.InsertNode(index: insertionIndex, offsetDirection: offsetDirection, animated: animated, node: node, layout: layout, apply: apply)) - self.nodes.insert(.Node(index: itemIndex, frame: nodeFrame, referenceNode: nil), at: insertionIndex) + self.nodes.insert(.Node(index: itemIndex, frame: nodeFrame, referenceNode: nil, newNode: node), at: insertionIndex) if !animated { switch offsetDirection { @@ -786,7 +795,7 @@ struct ListViewState { mutating func removeNodeAtIndex(_ index: Int, direction: ListViewItemOperationDirectionHint?, animated: Bool, operations: inout [ListViewStateOperation]) { let node = self.nodes[index] - if case let .Node(_, _, referenceNode) = node { + if case let .Node(_, _, referenceNode, _) = node { let nodeFrame = node.frame self.nodes.remove(at: index) let offsetDirection: ListViewInsertionOffsetDirection From 25624f2ce160d0fa9a2435abeaa720309de378c7 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Wed, 25 Oct 2023 23:57:58 +0400 Subject: [PATCH 3/3] Various improvements --- submodules/Display/Source/ListView.swift | 22 +++--- .../Source/ListViewIntermediateState.swift | 10 ++- .../Sources/PhotoResources.swift | 53 +++++++------ ...yncCore_TextEntitiesMessageAttribute.swift | 2 +- .../Sources/ReplyAccessoryPanelNode.swift | 6 +- .../Chat/ChatMessageActionOptions.swift | 75 ++++++++++--------- .../Sources/ChatHistoryListNode.swift | 2 +- .../Sources/NavigateToChatController.swift | 4 +- 8 files changed, 98 insertions(+), 76 deletions(-) diff --git a/submodules/Display/Source/ListView.swift b/submodules/Display/Source/ListView.swift index 18a5294fe7..54f6030996 100644 --- a/submodules/Display/Source/ListView.swift +++ b/submodules/Display/Source/ListView.swift @@ -1819,7 +1819,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture if let index = node.index { nodes.append(.Node(index: index, frame: node.apparentFrame, referenceNode: QueueLocalObject(queue: Queue.mainQueue(), generate: { return node - }))) + }), newNode: nil)) } else { nodes.append(.Placeholder(frame: node.apparentFrame)) } @@ -2000,10 +2000,10 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture } switch state.nodes[i] { - case let .Node(_, frame, referenceNode): - state.nodes[i] = .Node(index: updatedIndex, frame: frame, referenceNode: referenceNode) - case .Placeholder: - break + case let .Node(_, frame, referenceNode, newNode): + state.nodes[i] = .Node(index: updatedIndex, frame: frame, referenceNode: referenceNode, newNode: newNode) + case .Placeholder: + break } i += 1 } @@ -2039,10 +2039,10 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture } switch state.nodes[i] { - case let .Node(_, frame, referenceNode): - state.nodes[i] = .Node(index: updatedIndex, frame: frame, referenceNode: referenceNode) - case .Placeholder: - break + case let .Node(_, frame, referenceNode, newNode): + state.nodes[i] = .Node(index: updatedIndex, frame: frame, referenceNode: referenceNode, newNode: newNode) + case .Placeholder: + break } } } @@ -2097,7 +2097,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture var updateIndices = updateAdjacentItemsIndices if widthUpdated { - for case let .Node(index, _, _) in updatedState.nodes { + for case let .Node(index, _, _, _) in updatedState.nodes { updateIndices.insert(index) } } @@ -2205,7 +2205,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture var i = 0 for node in state.nodes { - if case let .Node(index, _, referenceNode) = node , index == nodeIndex { + if case let .Node(index, _, referenceNode, _) = node, index == nodeIndex { if let referenceNode = referenceNode { continueWithoutNode = false var controlledTransition: ControlledTransition? diff --git a/submodules/Display/Source/ListViewIntermediateState.swift b/submodules/Display/Source/ListViewIntermediateState.swift index 9a0a1d1862..70680497eb 100644 --- a/submodules/Display/Source/ListViewIntermediateState.swift +++ b/submodules/Display/Source/ListViewIntermediateState.swift @@ -332,9 +332,13 @@ struct ListViewState { case let .custom(getOverflow): if Thread.isMainThread, case let .Node(_, _, referenceNode, newNode) = node, let listNode = referenceNode?.syncWith({ $0 }) ?? newNode?.syncWith({ $0 }) { let overflow = getOverflow(listNode) - offset = (self.visibleSize.height - self.insets.bottom) - node.frame.maxY - offset += overflow - offset -= floor((self.visibleSize.height - self.insets.bottom - self.insets.top) * 0.5) + if overflow == 0.0 { + offset = self.insets.top - node.frame.minY + } else { + offset = (self.visibleSize.height - self.insets.bottom) - node.frame.maxY + offset += overflow + offset -= floor((self.visibleSize.height - self.insets.bottom - self.insets.top) * 0.5) + } } else { offset = self.insets.top - node.frame.minY } diff --git a/submodules/PhotoResources/Sources/PhotoResources.swift b/submodules/PhotoResources/Sources/PhotoResources.swift index 74e3b57260..6a8c165c6f 100644 --- a/submodules/PhotoResources/Sources/PhotoResources.swift +++ b/submodules/PhotoResources/Sources/PhotoResources.swift @@ -804,7 +804,7 @@ public func chatMessagePhotoInternal(photoData: Signal Signal, NoError> { +private func chatMessagePhotoThumbnailDatas(account: Account, userLocation: MediaResourceUserLocation, photoReference: ImageMediaReference, onlyFullSize: Bool = false, forceThumbnail: Bool = false) -> Signal, NoError> { let fullRepresentationSize: CGSize = CGSize(width: 1280.0, height: 1280.0) if let smallestRepresentation = smallestImageRepresentation(photoReference.media.representations), let largestRepresentation = photoReference.media.representationForDisplayAtSize(PixelDimensions(width: Int32(fullRepresentationSize.width), height: Int32(fullRepresentationSize.height))) { @@ -813,17 +813,23 @@ private func chatMessagePhotoThumbnailDatas(account: Account, userLocation: Medi let signal = maybeFullSize |> take(1) - |> mapToSignal { maybeData -> Signal, NoError> in + |> mapToSignal { maybeData -> Signal, NoError> in if maybeData.complete, !forceThumbnail { let loadedData: Data? = try? Data(contentsOf: URL(fileURLWithPath: maybeData.path), options: []) return .single(Tuple(nil, loadedData, true)) } else { let fetchedThumbnail = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: userLocation, userContentType: .image, reference: photoReference.resourceReference(smallestRepresentation.resource), statsCategory: .image) - let thumbnail = Signal { subscriber in + let thumbnail = Signal<(Data, Bool)?, NoError> { subscriber in let fetchedDisposable = fetchedThumbnail.start() let thumbnailDisposable = account.postbox.mediaBox.resourceData(smallestRepresentation.resource).start(next: { next in - subscriber.putNext(next.size == 0 ? nil : try? Data(contentsOf: URL(fileURLWithPath: next.path), options: [])) + if next.size == 0 { + subscriber.putNext(nil) + } else if let data = try? Data(contentsOf: URL(fileURLWithPath: next.path), options: []) { + subscriber.putNext((data, false)) + } else { + subscriber.putNext(nil) + } }, error: subscriber.putError, completed: subscriber.putCompletion) return ActionDisposable { @@ -858,7 +864,8 @@ public func chatMessagePhotoThumbnail(account: Account, userLocation: MediaResou let signal = chatMessagePhotoThumbnailDatas(account: account, userLocation: userLocation, photoReference: photoReference, onlyFullSize: onlyFullSize, forceThumbnail: blurred) return signal |> map { value in - let thumbnailData = value._0 + let thumbnailData: Data? = value._0?.0 + let thumbnailIsBlurred: Bool = value._0?.1 ?? false let fullSizeData = value._1 let fullSizeComplete = value._2 return { arguments in @@ -905,23 +912,27 @@ public func chatMessagePhotoThumbnail(account: Account, userLocation: MediaResou thumbnailImage = image } - var blurredThumbnailImage: UIImage? + var blurredThumbnailImage: CGImage? if let thumbnailImage = thumbnailImage { - let thumbnailSize = CGSize(width: thumbnailImage.width, height: thumbnailImage.height) - let thumbnailContextSize = thumbnailSize.aspectFitted(blurred ? CGSize(width: 50.0, height: 50.0) : CGSize(width: 150.0, height: 150.0)) - if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { - thumbnailContext.withFlippedContext { c in - c.interpolationQuality = .none - c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) - } - imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - if blurred { + if thumbnailIsBlurred { + let thumbnailSize = CGSize(width: thumbnailImage.width, height: thumbnailImage.height) + let thumbnailContextSize = thumbnailSize.aspectFitted(blurred ? CGSize(width: 50.0, height: 50.0) : CGSize(width: 150.0, height: 150.0)) + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { + thumbnailContext.withFlippedContext { c in + c.interpolationQuality = .none + c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + } imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - adjustSaturationInContext(context: thumbnailContext, saturation: 1.7) + + if blurred { + imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + adjustSaturationInContext(context: thumbnailContext, saturation: 1.7) + } + + blurredThumbnailImage = thumbnailContext.generateImage()?.cgImage } - - blurredThumbnailImage = thumbnailContext.generateImage() + } else { + blurredThumbnailImage = thumbnailImage } } @@ -933,9 +944,9 @@ public func chatMessagePhotoThumbnail(account: Account, userLocation: MediaResou } c.setBlendMode(.copy) - if let blurredThumbnailImage = blurredThumbnailImage, let cgImage = blurredThumbnailImage.cgImage { + if let blurredThumbnailImage { c.interpolationQuality = .low - drawImage(context: c, image: cgImage, orientation: imageOrientation, in: fittedRect) + drawImage(context: c, image: blurredThumbnailImage, orientation: imageOrientation, in: fittedRect) c.setBlendMode(.normal) } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TextEntitiesMessageAttribute.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TextEntitiesMessageAttribute.swift index 178fbdb22e..424fbfc7b8 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TextEntitiesMessageAttribute.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TextEntitiesMessageAttribute.swift @@ -359,7 +359,7 @@ public func trimStringWithEntities(string: String, entities: [MessageTextEntity] } while range.upperBound > range.lowerBound { - let c = nsString.character(at: range.lowerBound) + let c = nsString.character(at: range.upperBound - 1) if c == 0x0a || c == 0x20 { range = range.lowerBound ..< (range.upperBound - 1) } else { diff --git a/submodules/TelegramUI/Components/Chat/ReplyAccessoryPanelNode/Sources/ReplyAccessoryPanelNode.swift b/submodules/TelegramUI/Components/Chat/ReplyAccessoryPanelNode/Sources/ReplyAccessoryPanelNode.swift index 28ebc31ffb..61ef685756 100644 --- a/submodules/TelegramUI/Components/Chat/ReplyAccessoryPanelNode/Sources/ReplyAccessoryPanelNode.swift +++ b/submodules/TelegramUI/Components/Chat/ReplyAccessoryPanelNode/Sources/ReplyAccessoryPanelNode.swift @@ -240,7 +240,7 @@ public final class ReplyAccessoryPanelNode: AccessoryPanelNode { var titleText: [CompositeTextNode.Component] = [] if let peer = message?.peers[strongSelf.messageId.peerId] as? TelegramChannel, case .broadcast = peer.info { let icon: UIImage? - icon = UIImage(bundleImageName: "Chat/Input/Accessory Panels/PanelTextChannelIcon")?.withRenderingMode(.alwaysTemplate) + icon = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/PanelTextChannelIcon"), color: theme.chat.inputPanel.panelControlAccentColor) if let icon { let rawString: PresentationStrings.FormattedString @@ -279,9 +279,9 @@ public final class ReplyAccessoryPanelNode: AccessoryPanelNode { if let peer = message?.peers[strongSelf.messageId.peerId], (peer is TelegramChannel || peer is TelegramGroup) { let icon: UIImage? if let channel = peer as? TelegramChannel, case .broadcast = channel.info { - icon = UIImage(bundleImageName: "Chat/Input/Accessory Panels/PanelTextChannelIcon")?.withRenderingMode(.alwaysTemplate) + icon = UIImage(bundleImageName: "Chat/Input/Accessory Panels/PanelTextChannelIcon") } else { - icon = UIImage(bundleImageName: "Chat/Input/Accessory Panels/PanelTextGroupIcon")?.withRenderingMode(.alwaysTemplate) + icon = UIImage(bundleImageName: "Chat/Input/Accessory Panels/PanelTextGroupIcon") } if let iconImage = generateTintedImage(image: icon, color: strongSelf.theme.chat.inputPanel.panelControlAccentColor) { titleText.append(.icon(iconImage)) diff --git a/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift b/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift index cc72586e4a..ca59798691 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift @@ -273,6 +273,41 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch return .complete() } + let applyCurrentQuoteSelection: () -> Void = { [weak selfController, weak chatController] in + guard let selfController, let chatController else { + return + } + var messageItemNode: ChatMessageItemView? + chatController.chatDisplayNode.historyNode.enumerateItemNodes { itemNode in + if let itemNode = itemNode as? ChatMessageItemView, let item = itemNode.item, item.message.id == replySubject.messageId { + messageItemNode = itemNode + } + return true + } + var targetContentNode: ChatMessageTextBubbleContentNode? + if let messageItemNode = messageItemNode as? ChatMessageBubbleItemNode { + for contentNode in messageItemNode.contentNodes { + if let contentNode = contentNode as? ChatMessageTextBubbleContentNode { + targetContentNode = contentNode + break + } + } + } + guard let contentNode = targetContentNode else { + return + } + guard let textSelection = contentNode.getCurrentTextSelection() else { + return + } + var quote: EngineMessageReplyQuote? + let trimmedText = trimStringWithEntities(string: textSelection.text, entities: textSelection.entities, maxLength: quoteMaxLength(appConfig: selfController.context.currentAppConfiguration.with({ $0 }))) + if !trimmedText.string.isEmpty { + quote = EngineMessageReplyQuote(text: trimmedText.string, entities: trimmedText.entities, media: nil) + } + + selfController.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withUpdatedReplyMessageSubject(ChatInterfaceState.ReplyMessageSubject(messageId: replySubject.messageId, quote: quote)).withoutSelectionState() }) }) + } + let items = combineLatest(queue: .mainQueue(), selfController.context.account.postbox.messagesAtIds([replySubject.messageId]), ApplicationSpecificNotice.getReplyQuoteTextSelectionTips(accountManager: selfController.context.sharedContext.accountManager) @@ -288,40 +323,8 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch if replySubject.quote != nil { items.append(.action(ContextMenuActionItem(text: selfController.presentationData.strings.Conversation_MessageOptionsQuoteSelectedPart, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/QuoteSelected"), color: theme.contextMenu.primaryColor) - }, action: { [weak selfController, weak chatController] _, f in - guard let selfController, let chatController else { - return - } - - var messageItemNode: ChatMessageItemView? - chatController.chatDisplayNode.historyNode.enumerateItemNodes { itemNode in - if let itemNode = itemNode as? ChatMessageItemView, let item = itemNode.item, item.message.id == replySubject.messageId { - messageItemNode = itemNode - } - return true - } - var targetContentNode: ChatMessageTextBubbleContentNode? - if let messageItemNode = messageItemNode as? ChatMessageBubbleItemNode { - for contentNode in messageItemNode.contentNodes { - if let contentNode = contentNode as? ChatMessageTextBubbleContentNode { - targetContentNode = contentNode - break - } - } - } - guard let contentNode = targetContentNode else { - return - } - guard let textSelection = contentNode.getCurrentTextSelection() else { - return - } - var quote: EngineMessageReplyQuote? - let trimmedText = trimStringWithEntities(string: textSelection.text, entities: textSelection.entities, maxLength: quoteMaxLength(appConfig: selfController.context.currentAppConfiguration.with({ $0 }))) - if !trimmedText.string.isEmpty { - quote = EngineMessageReplyQuote(text: trimmedText.string, entities: trimmedText.entities, media: nil) - } - - selfController.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withUpdatedReplyMessageSubject(ChatInterfaceState.ReplyMessageSubject(messageId: replySubject.messageId, quote: quote)).withoutSelectionState() }) }) + }, action: { _, f in + applyCurrentQuoteSelection() f(.default) }))) @@ -418,6 +421,8 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch if canReplyInAnotherChat { items.append(.action(ContextMenuActionItem(text: selfController.presentationData.strings.Conversation_MessageOptionsReplyInAnotherChat, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Replace"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController] c, f in + applyCurrentQuoteSelection() + f(.default) guard let selfController else { @@ -434,6 +439,8 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch items.append(.separator) items.append(.action(ContextMenuActionItem(text: selfController.presentationData.strings.Conversation_MessageOptionsApplyChanges, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Select"), color: theme.contextMenu.primaryColor) }, action: { _, f in + applyCurrentQuoteSelection() + f(.default) }))) } diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index d1ee5742b6..ce191a497c 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -1375,7 +1375,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { initialSearchLocation = .index(.absoluteUpperBound()) } } - strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: initialSearchLocation, quote: nil), count: historyMessageCount, highlight: highlight != nil), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0) + strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: initialSearchLocation, quote: highlight?.quote), count: historyMessageCount, highlight: highlight != nil), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0) } else if let subject = subject, case let .pinnedMessages(maybeMessageId) = subject, let messageId = maybeMessageId { strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(messageId), quote: nil), count: historyMessageCount, highlight: true), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0) } else if var chatHistoryLocation = strongSelf.chatHistoryLocationValue { diff --git a/submodules/TelegramUI/Sources/NavigateToChatController.swift b/submodules/TelegramUI/Sources/NavigateToChatController.swift index 1dbe38bd8a..7782fe6a07 100644 --- a/submodules/TelegramUI/Sources/NavigateToChatController.swift +++ b/submodules/TelegramUI/Sources/NavigateToChatController.swift @@ -73,11 +73,11 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam controller.updateTextInputState(updateTextInputState) } var popAndComplete = true - if let subject = params.subject, case let .message(messageSubject, _, timecode) = subject { + if let subject = params.subject, case let .message(messageSubject, highlight, timecode) = subject { if case let .id(messageId) = messageSubject { let navigationController = params.navigationController let animated = params.animated - controller.navigateToMessage(messageLocation: .id(messageId, NavigateToMessageParams(timestamp: timecode, quote: nil)), animated: isFirst, completion: { [weak navigationController, weak controller] in + controller.navigateToMessage(messageLocation: .id(messageId, NavigateToMessageParams(timestamp: timecode, quote: highlight?.quote)), animated: isFirst, completion: { [weak navigationController, weak controller] in if let navigationController = navigationController, let controller = controller { let _ = navigationController.popToViewController(controller, animated: animated) }