diff --git a/submodules/AccountContext/Sources/ChatController.swift b/submodules/AccountContext/Sources/ChatController.swift index 03bd0b2a26..2141b1f10c 100644 --- a/submodules/AccountContext/Sources/ChatController.swift +++ b/submodules/AccountContext/Sources/ChatController.swift @@ -329,7 +329,7 @@ public struct ChatTextInputStateText: PostboxCoding, Equatable { } public enum ChatControllerSubject: Equatable { - case message(MessageId) + case message(id: MessageId, highlight: Bool) case scheduledMessages } diff --git a/submodules/AccountContext/Sources/ChatHistoryLocation.swift b/submodules/AccountContext/Sources/ChatHistoryLocation.swift index e4e59fd224..7241d181a7 100644 --- a/submodules/AccountContext/Sources/ChatHistoryLocation.swift +++ b/submodules/AccountContext/Sources/ChatHistoryLocation.swift @@ -9,9 +9,9 @@ public enum ChatHistoryInitialSearchLocation: Equatable { public enum ChatHistoryLocation: Equatable { case Initial(count: Int) - case InitialSearch(location: ChatHistoryInitialSearchLocation, count: Int) - case Navigation(index: MessageHistoryAnchorIndex, anchorIndex: MessageHistoryAnchorIndex, count: Int) - case Scroll(index: MessageHistoryAnchorIndex, anchorIndex: MessageHistoryAnchorIndex, sourceIndex: MessageHistoryAnchorIndex, scrollPosition: ListViewScrollPosition, animated: Bool) + case InitialSearch(location: ChatHistoryInitialSearchLocation, count: Int, highlight: Bool) + case Navigation(index: MessageHistoryAnchorIndex, anchorIndex: MessageHistoryAnchorIndex, count: Int, highlight: Bool) + case Scroll(index: MessageHistoryAnchorIndex, anchorIndex: MessageHistoryAnchorIndex, sourceIndex: MessageHistoryAnchorIndex, scrollPosition: ListViewScrollPosition, animated: Bool, highlight: Bool) } public struct ChatHistoryLocationInput: Equatable { diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index e670713562..d92d95676f 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -669,7 +669,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController, if let layout = strongSelf.validLayout, case .regular = layout.metrics.widthClass { scrollToEndIfExists = true } - strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(actualPeerId), subject: .message(messageId), purposefulAction: { + strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(actualPeerId), subject: .message(id: messageId, highlight: true), purposefulAction: { self?.deactivateSearch(animated: false) }, scrollToEndIfExists: scrollToEndIfExists, options: strongSelf.groupId == PeerGroupId.root ? [.removeOnMasterDetails] : [])) strongSelf.chatListDisplayNode.containerNode.currentItemNode.clearHighlightAnimated(true) @@ -1780,7 +1780,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController, sourceRect = CGRect(x: sourceRect.minX, y: sourceRect.minY + bounds.minY, width: bounds.width, height: bounds.height) sourceRect.size.height -= UIScreenPixel - let chatController = self.context.sharedContext.makeChatController(context: self.context, chatLocation: .peer(messageId.peerId), subject: .message(messageId), botStart: nil, mode: .standard(previewing: true)) + let chatController = self.context.sharedContext.makeChatController(context: self.context, chatLocation: .peer(messageId.peerId), subject: .message(id: messageId, highlight: true), botStart: nil, mode: .standard(previewing: true)) chatController.canReadHistory.set(false) chatController.containerLayoutUpdated(ContainerViewLayout(size: contentSize, metrics: LayoutMetrics(), deviceMetrics: layout.deviceMetrics, intrinsicInsets: UIEdgeInsets(), safeInsets: UIEdgeInsets(), statusBarHeight: nil, inputHeight: nil, inputHeightIsInteractivellyChanging: false, inVoiceOver: false), transition: .immediate) return (chatController, sourceRect) diff --git a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift index c7618f0e20..b33404b960 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift @@ -1726,7 +1726,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode { } if let id = state.id as? PeerMessagesMediaPlaylistItemId { if type == .music { - let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(location: .id(id.messageId), count: 60), id: 0), context: strongSelf.context, chatLocation: .peer(id.messageId.peerId), chatLocationContextHolder: Atomic(value: nil), tagMask: MessageTags.music) + let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(location: .id(id.messageId), count: 60, highlight: true), id: 0), context: strongSelf.context, chatLocation: .peer(id.messageId.peerId), chatLocationContextHolder: Atomic(value: nil), tagMask: MessageTags.music) var cancelImpl: (() -> Void)? let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/HashtagSearchUI/Sources/HashtagSearchController.swift b/submodules/HashtagSearchUI/Sources/HashtagSearchController.swift index e433841dd1..463006184a 100644 --- a/submodules/HashtagSearchUI/Sources/HashtagSearchController.swift +++ b/submodules/HashtagSearchUI/Sources/HashtagSearchController.swift @@ -57,7 +57,7 @@ public final class HashtagSearchController: TelegramBaseController { if let strongSelf = self { strongSelf.openMessageFromSearchDisposable.set((storedMessageFromSearchPeer(account: strongSelf.context.account, peer: peer) |> deliverOnMainQueue).start(next: { actualPeerId in if let strongSelf = self, let navigationController = strongSelf.navigationController as? NavigationController { - strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(actualPeerId), subject: message.id.peerId == actualPeerId ? .message(message.id) : nil, keepStack: .always)) + strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(actualPeerId), subject: message.id.peerId == actualPeerId ? .message(id: message.id, highlight: true) : nil, keepStack: .always)) } })) strongSelf.controllerNode.listNode.clearHighlightAnimated(true) diff --git a/submodules/StatisticsUI/Sources/ChannelStatsController.swift b/submodules/StatisticsUI/Sources/ChannelStatsController.swift index 1e2a2fb821..b413a660a3 100644 --- a/submodules/StatisticsUI/Sources/ChannelStatsController.swift +++ b/submodules/StatisticsUI/Sources/ChannelStatsController.swift @@ -497,7 +497,7 @@ public func channelStatsController(context: AccountContext, peerId: PeerId, cach } navigateToMessageImpl = { [weak controller] messageId in if let navigationController = controller?.navigationController as? NavigationController { - context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(messageId.peerId), subject: .message(messageId), keepStack: .always, useExisting: false, purposefulAction: {}, peekData: nil)) + context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(messageId.peerId), subject: .message(id: messageId, highlight: true), keepStack: .always, useExisting: false, purposefulAction: {}, peekData: nil)) } } return controller diff --git a/submodules/StatisticsUI/Sources/MessageStatsController.swift b/submodules/StatisticsUI/Sources/MessageStatsController.swift index 8db5d7f899..fe20ab3a1f 100644 --- a/submodules/StatisticsUI/Sources/MessageStatsController.swift +++ b/submodules/StatisticsUI/Sources/MessageStatsController.swift @@ -258,7 +258,7 @@ public func messageStatsController(context: AccountContext, messageId: MessageId } navigateToMessageImpl = { [weak controller] messageId in if let navigationController = controller?.navigationController as? NavigationController { - context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(messageId.peerId), subject: .message(messageId), keepStack: .always, useExisting: false, purposefulAction: {}, peekData: nil)) + context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(messageId.peerId), subject: .message(id: messageId, highlight: true), keepStack: .always, useExisting: false, purposefulAction: {}, peekData: nil)) } } return controller diff --git a/submodules/TelegramBaseController/Sources/TelegramBaseController.swift b/submodules/TelegramBaseController/Sources/TelegramBaseController.swift index d248455df0..e97b542b3a 100644 --- a/submodules/TelegramBaseController/Sources/TelegramBaseController.swift +++ b/submodules/TelegramBaseController/Sources/TelegramBaseController.swift @@ -557,7 +557,7 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder { } if let id = state.id as? PeerMessagesMediaPlaylistItemId { if type == .music { - let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(location: .id(id.messageId), count: 60), id: 0), context: strongSelf.context, chatLocation: .peer(id.messageId.peerId), chatLocationContextHolder: Atomic(value: nil), tagMask: MessageTags.music) + let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(location: .id(id.messageId), count: 60, highlight: true), id: 0), context: strongSelf.context, chatLocation: .peer(id.messageId.peerId), chatLocationContextHolder: Atomic(value: nil), tagMask: MessageTags.music) var cancelImpl: (() -> Void)? let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramCore/Sources/Holes.swift b/submodules/TelegramCore/Sources/Holes.swift index 5d4e5e1799..852cb4bd93 100644 --- a/submodules/TelegramCore/Sources/Holes.swift +++ b/submodules/TelegramCore/Sources/Holes.swift @@ -155,6 +155,8 @@ enum FetchMessageHistoryHoleThreadInput: CustomStringConvertible { struct FetchMessageHistoryHoleResult: Equatable { var removedIndices: IndexSet var strictRemovedIndices: IndexSet + var actualPeerId: PeerId? + var actualThreadId: Int64? } func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryHoleSource, postbox: Postbox, peerInput: FetchMessageHistoryHoleThreadInput, namespace: MessageId.Namespace, direction: MessageHistoryViewRelativeHoleDirection, space: MessageHistoryHoleSpace, count rawCount: Int) -> Signal { @@ -180,7 +182,7 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH } |> mapToSignal { (inputPeer, hash) -> Signal in guard let inputPeer = inputPeer else { - return .single(FetchMessageHistoryHoleResult(removedIndices: IndexSet(), strictRemovedIndices: IndexSet())) + return .single(FetchMessageHistoryHoleResult(removedIndices: IndexSet(), strictRemovedIndices: IndexSet(), actualPeerId: nil, actualThreadId: nil)) } print("fetchMessageHistoryHole for \(peerInput) direction \(direction) space \(space)") @@ -537,7 +539,9 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH return FetchMessageHistoryHoleResult( removedIndices: IndexSet(integersIn: Int(filledRange.lowerBound) ... Int(filledRange.upperBound)), - strictRemovedIndices: strictFilledIndices + strictRemovedIndices: strictFilledIndices, + actualPeerId: storeMessages.first?.id.peerId, + actualThreadId: storeMessages.first?.threadId ) }) } diff --git a/submodules/TelegramCore/Sources/PeerUtils.swift b/submodules/TelegramCore/Sources/PeerUtils.swift index 23f84731d4..6ed76ec717 100644 --- a/submodules/TelegramCore/Sources/PeerUtils.swift +++ b/submodules/TelegramCore/Sources/PeerUtils.swift @@ -227,6 +227,9 @@ public extension RenderedPeer { public func isServicePeer(_ peer: Peer) -> Bool { if let peer = peer as? TelegramUser { + if peer.id.isReplies { + return true + } return (peer.id.namespace == Namespaces.Peer.CloudUser && (peer.id.id == 777000 || peer.id.id == 333000)) } return false diff --git a/submodules/TelegramCore/Sources/ReplyThreadHistory.swift b/submodules/TelegramCore/Sources/ReplyThreadHistory.swift index b94ef635fc..75bab2744f 100644 --- a/submodules/TelegramCore/Sources/ReplyThreadHistory.swift +++ b/submodules/TelegramCore/Sources/ReplyThreadHistory.swift @@ -374,9 +374,9 @@ public class ReplyThreadHistoryContext { } public struct ChatReplyThreadMessage: Equatable { - public enum Anchor { + public enum Anchor: Equatable { case automatic - case lowerBound + case lowerBoundMessage(MessageIndex) } public var messageId: MessageId @@ -606,17 +606,13 @@ public func fetchChannelReplyThreadMessage(account: Account, messageId: MessageI } let inputAnchor: HistoryViewInputAnchor - let initialAnchor: ChatReplyThreadMessage.Anchor switch anchor { case .lowerBound: inputAnchor = .lowerBound - initialAnchor = .lowerBound case .upperBound: inputAnchor = .upperBound - initialAnchor = .automatic case let .message(id): inputAnchor = .message(id) - initialAnchor = .automatic } let testView = transaction.getMessagesHistoryViewState( @@ -635,27 +631,57 @@ public func fetchChannelReplyThreadMessage(account: Account, messageId: MessageI namespaces: .not(Namespaces.Message.allScheduled) ) if !testView.isLoading { + let initialAnchor: ChatReplyThreadMessage.Anchor + switch anchor { + case .lowerBound: + if let entry = testView.entries.first { + initialAnchor = .lowerBoundMessage(entry.index) + } else { + initialAnchor = .automatic + } + case .upperBound: + initialAnchor = .automatic + case .message: + initialAnchor = .automatic + } + return .single((FetchMessageHistoryHoleResult(removedIndices: IndexSet(), strictRemovedIndices: IndexSet()), initialAnchor)) } } let direction: MessageHistoryViewRelativeHoleDirection - let initialAnchor: ChatReplyThreadMessage.Anchor switch anchor { case .lowerBound: direction = .range(start: MessageId(peerId: commentsPeerId, namespace: Namespaces.Message.Cloud, id: 1), end: MessageId(peerId: commentsPeerId, namespace: Namespaces.Message.Cloud, id: Int32.max - 1)) - initialAnchor = .lowerBound case .upperBound: direction = .range(start: MessageId(peerId: commentsPeerId, namespace: Namespaces.Message.Cloud, id: Int32.max - 1), end: MessageId(peerId: commentsPeerId, namespace: Namespaces.Message.Cloud, id: 1)) - initialAnchor = .automatic case let .message(id): direction = .aroundId(id) - initialAnchor = .automatic } return fetchMessageHistoryHole(accountPeerId: account.peerId, source: .network(account.network), postbox: account.postbox, peerInput: peerInput, namespace: Namespaces.Message.Cloud, direction: direction, space: .everywhere, count: 40) |> castError(FetchChannelReplyThreadMessageError.self) - |> map { result -> (FetchMessageHistoryHoleResult, ChatReplyThreadMessage.Anchor) in - return (result, initialAnchor) + |> mapToSignal { result -> Signal<(FetchMessageHistoryHoleResult, ChatReplyThreadMessage.Anchor), FetchChannelReplyThreadMessageError> in + return account.postbox.transaction { transaction -> (FetchMessageHistoryHoleResult, ChatReplyThreadMessage.Anchor) in + let initialAnchor: ChatReplyThreadMessage.Anchor + switch anchor { + case .lowerBound: + if let actualPeerId = result.actualPeerId, let actualThreadId = result.actualThreadId { + if let firstMessage = transaction.getMessagesWithThreadId(peerId: actualPeerId, namespace: Namespaces.Message.Cloud, threadId: actualThreadId, from: MessageIndex.lowerBound(peerId: actualPeerId, namespace: Namespaces.Message.Cloud), includeFrom: false, to: MessageIndex.upperBound(peerId: actualPeerId, namespace: Namespaces.Message.Cloud), limit: 1).first { + initialAnchor = .lowerBoundMessage(firstMessage.index) + } else { + initialAnchor = .automatic + } + } else { + initialAnchor = .automatic + } + case .upperBound: + initialAnchor = .automatic + case .message: + initialAnchor = .automatic + } + return (result, initialAnchor) + } + |> castError(FetchChannelReplyThreadMessageError.self) } } |> castError(FetchChannelReplyThreadMessageError.self) diff --git a/submodules/TelegramUI/Sources/ApplicationContext.swift b/submodules/TelegramUI/Sources/ApplicationContext.swift index 0c08fc926f..ceab4ab7b8 100644 --- a/submodules/TelegramUI/Sources/ApplicationContext.swift +++ b/submodules/TelegramUI/Sources/ApplicationContext.swift @@ -702,7 +702,7 @@ final class AuthorizedApplicationContext { } let navigateToMessage = { - strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: strongSelf.rootController, context: strongSelf.context, chatLocation: .peer(messageId.peerId), subject: .message(messageId))) + strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: strongSelf.rootController, context: strongSelf.context, chatLocation: .peer(messageId.peerId), subject: .message(id: messageId, highlight: true))) } if chatIsVisible { @@ -773,7 +773,7 @@ final class AuthorizedApplicationContext { if visiblePeerId != peerId || messageId != nil { if self.rootController.rootTabController != nil { - self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: self.rootController, context: self.context, chatLocation: .peer(peerId), subject: messageId.flatMap { .message($0) }, activateInput: activateInput)) + self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: self.rootController, context: self.context, chatLocation: .peer(peerId), subject: messageId.flatMap { .message(id: $0, highlight: true) }, activateInput: activateInput)) } else { self.scheduledOpenChatWithPeerId = (peerId, messageId, activateInput) } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 26274f8558..847a09c0d7 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -5115,7 +5115,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } if let navigationController = strongSelf.effectiveNavigationController { - let subject: ChatControllerSubject? = sourceMessageId.flatMap(ChatControllerSubject.message) + let subject: ChatControllerSubject? = sourceMessageId.flatMap { ChatControllerSubject.message(id: $0, highlight: true) } strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .replyThread(replyThreadResult), subject: subject, keepStack: .always)) } }, statuses: ChatPanelInterfaceInteractionStatuses(editingMessage: self.editingMessage.get(), startingBot: self.startingBot.get(), unblockingPeer: self.unblockingPeer.get(), searching: self.searching.get(), loadingMessage: self.loadingMessage.get(), inlineSearch: self.performingInlineSearch.get())) @@ -8189,7 +8189,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } func scrollToEndOfHistory() { - let locationInput = ChatHistoryLocationInput(content: .Scroll(index: .upperBound, anchorIndex: .upperBound, sourceIndex: .lowerBound, scrollPosition: .top(0.0), animated: true), id: 0) + let locationInput = ChatHistoryLocationInput(content: .Scroll(index: .upperBound, anchorIndex: .upperBound, sourceIndex: .lowerBound, scrollPosition: .top(0.0), animated: true, highlight: false), id: 0) let historyView = preloadedChatHistoryViewForLocation(locationInput, context: self.context, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tagMask: nil, additionalData: []) let signal = historyView @@ -8253,7 +8253,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } func scrollToStartOfHistory() { - let locationInput = ChatHistoryLocationInput(content: .Scroll(index: .lowerBound, anchorIndex: .lowerBound, sourceIndex: .upperBound, scrollPosition: .bottom(0.0), animated: true), id: 0) + let locationInput = ChatHistoryLocationInput(content: .Scroll(index: .lowerBound, anchorIndex: .lowerBound, sourceIndex: .upperBound, scrollPosition: .bottom(0.0), animated: true, highlight: false), id: 0) let historyView = preloadedChatHistoryViewForLocation(locationInput, context: self.context, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tagMask: nil, additionalData: []) let signal = historyView @@ -8400,9 +8400,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let subject: ChatControllerSubject? if let atMessageId = atMessageId { - subject = .message(atMessageId) - } else if result.scrollToLowerBound { - subject = .message(MessageId(peerId: result.message.messageId.peerId, namespace: Namespaces.Message.Cloud, id: 1)) + subject = .message(id: atMessageId, highlight: true) + } else if let index = result.scrollToLowerBoundMessage { + subject = .message(id: index.id, highlight: false) } else { subject = nil } @@ -8456,7 +8456,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if case let .peer(peerId) = self.chatLocation, let messageId = messageLocation.messageId, (messageId.peerId != peerId && !forceInCurrentChat) || (self.presentationInterfaceState.isScheduledMessages && messageId.id != 0 && !Namespaces.Message.allScheduled.contains(messageId.namespace)) { if let navigationController = self.effectiveNavigationController { - self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(messageId.peerId), subject: .message(messageId), keepStack: .always)) + self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(messageId.peerId), subject: .message(id: messageId, highlight: true), keepStack: .always)) } } else if forceInCurrentChat { if let _ = fromId, let fromIndex = fromIndex, rememberInStack { @@ -8491,7 +8491,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G case .upperBound: searchLocation = .index(MessageIndex.upperBound(peerId: self.chatLocation.peerId)) } - let historyView = preloadedChatHistoryViewForLocation(ChatHistoryLocationInput(content: .InitialSearch(location: searchLocation, count: 50), id: 0), context: self.context, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tagMask: nil, additionalData: []) + let historyView = preloadedChatHistoryViewForLocation(ChatHistoryLocationInput(content: .InitialSearch(location: searchLocation, count: 50, highlight: true), id: 0), context: self.context, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tagMask: nil, additionalData: []) let signal = historyView |> mapToSignal { historyView -> Signal<(MessageIndex?, Bool), NoError> in switch historyView { @@ -8583,7 +8583,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.historyNavigationStack.add(fromIndex) } self.loadingMessage.set(true) - let historyView = preloadedChatHistoryViewForLocation(ChatHistoryLocationInput(content: .InitialSearch(location: searchLocation, count: 50), id: 0), context: self.context, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tagMask: nil, additionalData: []) + let historyView = preloadedChatHistoryViewForLocation(ChatHistoryLocationInput(content: .InitialSearch(location: searchLocation, count: 50, highlight: true), id: 0), context: self.context, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tagMask: nil, additionalData: []) let signal = historyView |> mapToSignal { historyView -> Signal in switch historyView { @@ -8606,7 +8606,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G completion?() } else { if let navigationController = strongSelf.effectiveNavigationController { - strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(messageLocation.peerId), subject: messageLocation.messageId.flatMap { .message($0) })) + strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(messageLocation.peerId), subject: messageLocation.messageId.flatMap { .message(id: $0, highlight: true) })) } completion?() } @@ -8618,7 +8618,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G })) } else { if let navigationController = self.effectiveNavigationController { - self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(messageLocation.peerId), subject: messageLocation.messageId.flatMap { .message($0) })) + self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(messageLocation.peerId), subject: messageLocation.messageId.flatMap { .message(id: $0, highlight: true) })) } completion?() } @@ -9205,7 +9205,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G switch navigation { case let .chat(_, subject, peekData): if case .peer(peerId) = strongSelf.chatLocation { - if let subject = subject, case let .message(messageId) = subject { + if let subject = subject, case let .message(messageId, _) = subject { strongSelf.navigateToMessage(from: nil, to: .id(messageId)) } } else if let navigationController = strongSelf.effectiveNavigationController { diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index 60630a7cdc..cb1c6ce36f 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -83,7 +83,7 @@ public enum ChatHistoryListMode: Equatable { enum ChatHistoryViewScrollPosition { case unread(index: MessageIndex) case positionRestoration(index: MessageIndex, relativeOffset: CGFloat) - case index(index: MessageHistoryAnchorIndex, position: ListViewScrollPosition, directionHint: ListViewScrollToItemDirectionHint, animated: Bool) + case index(index: MessageHistoryAnchorIndex, position: ListViewScrollPosition, directionHint: ListViewScrollToItemDirectionHint, animated: Bool, highlight: Bool) } enum ChatHistoryViewUpdateType { @@ -399,9 +399,9 @@ private func extractAssociatedData(chatLocation: ChatLocation, view: MessageHist private extension ChatHistoryLocationInput { var isAtUpperBound: Bool { switch self.content { - case .Navigation(index: .upperBound, anchorIndex: .upperBound, count: _): + case .Navigation(index: .upperBound, anchorIndex: .upperBound, count: _, highlight: _): return true - case .Scroll(index: .upperBound, anchorIndex: .upperBound, sourceIndex: _, scrollPosition: _, animated: _): + case .Scroll(index: .upperBound, anchorIndex: .upperBound, sourceIndex: _, scrollPosition: _, animated: _, highlight: _): return true default: return false @@ -795,10 +795,10 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { if let filteredEntries = historyView?.filteredEntries, let visibleRange = displayRange.visibleRange { let lastEntry = filteredEntries[filteredEntries.count - 1 - visibleRange.lastIndex] - strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .message(lastEntry.index), anchorIndex: .message(lastEntry.index), count: historyMessageCount), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0) + strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .message(lastEntry.index), anchorIndex: .message(lastEntry.index), count: historyMessageCount, highlight: false), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0) } else { - if let subject = subject, case let .message(messageId) = subject { - strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: .id(messageId), count: 60), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0) + if let subject = subject, case let .message(messageId, highlight) = subject { + strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: .id(messageId), count: 60, highlight: highlight), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0) } else if var chatHistoryLocation = strongSelf.chatHistoryLocationValue { chatHistoryLocation.id += 1 strongSelf.chatHistoryLocationValue = chatHistoryLocation @@ -886,10 +886,10 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { if scrollPosition == nil, let originalScrollPosition = originalScrollPosition { switch originalScrollPosition { - case let .index(index, position, _, _): + case let .index(index, position, _, _, highlight): if case .upperBound = index { if let previous = previous, previous.filteredEntries.isEmpty { - updatedScrollPosition = .index(index: index, position: position, directionHint: .Down, animated: false) + updatedScrollPosition = .index(index: index, position: position, directionHint: .Down, animated: false, highlight: highlight) } } default: @@ -972,8 +972,8 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } }) - if let subject = subject, case let .message(messageId) = subject { - self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: .id(messageId), count: 60), id: 0) + if let subject = subject, case let .message(messageId, highlight) = subject { + self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: .id(messageId), count: 60, highlight: highlight), id: 0) } else { self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Initial(count: 60), id: 0) } @@ -1334,14 +1334,14 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { if let loaded = displayedRange.loadedRange, let firstEntry = historyView.filteredEntries.first, let lastEntry = historyView.filteredEntries.last { if loaded.firstIndex < 5 && historyView.originalView.laterId != nil { - let locationInput: ChatHistoryLocation = .Navigation(index: .message(lastEntry.index), anchorIndex: .message(lastEntry.index), count: historyMessageCount) + let locationInput: ChatHistoryLocation = .Navigation(index: .message(lastEntry.index), anchorIndex: .message(lastEntry.index), count: historyMessageCount, highlight: false) if self.chatHistoryLocationValue?.content != locationInput { self.chatHistoryLocationValue = ChatHistoryLocationInput(content: locationInput, id: self.takeNextHistoryLocationId()) } } else if loaded.firstIndex < 5, historyView.originalView.laterId == nil, !historyView.originalView.holeLater, let chatHistoryLocationValue = self.chatHistoryLocationValue, !chatHistoryLocationValue.isAtUpperBound, historyView.originalView.anchorIndex != .upperBound { - self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .upperBound, anchorIndex: .upperBound, count: historyMessageCount), id: self.takeNextHistoryLocationId()) + self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .upperBound, anchorIndex: .upperBound, count: historyMessageCount, highlight: false), id: self.takeNextHistoryLocationId()) } else if loaded.lastIndex >= historyView.filteredEntries.count - 5 && historyView.originalView.earlierId != nil { - let locationInput: ChatHistoryLocation = .Navigation(index: .message(firstEntry.index), anchorIndex: .message(firstEntry.index), count: historyMessageCount) + let locationInput: ChatHistoryLocation = .Navigation(index: .message(firstEntry.index), anchorIndex: .message(firstEntry.index), count: historyMessageCount, highlight: false) if self.chatHistoryLocationValue?.content != locationInput { self.chatHistoryLocationValue = ChatHistoryLocationInput(content: locationInput, id: self.takeNextHistoryLocationId()) } @@ -1373,7 +1373,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { currentMessage = messages.first?.0 } if let message = currentMessage, let anchorMessage = self.anchorMessageInCurrentHistoryView() { - self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(index: .message(message.index), anchorIndex: .message(message.index), sourceIndex: .upperBound, scrollPosition: .bottom(0.0), animated: true), id: self.takeNextHistoryLocationId()) + self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(index: .message(message.index), anchorIndex: .message(message.index), sourceIndex: .upperBound, scrollPosition: .bottom(0.0), animated: true, highlight: false), id: self.takeNextHistoryLocationId()) } } } @@ -1402,13 +1402,13 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } if let currentMessage = currentMessage { - self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(index: .message(currentMessage.index), anchorIndex: .message(currentMessage.index), sourceIndex: .upperBound, scrollPosition: .top(0.0), animated: true), id: self.takeNextHistoryLocationId()) + self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(index: .message(currentMessage.index), anchorIndex: .message(currentMessage.index), sourceIndex: .upperBound, scrollPosition: .top(0.0), animated: true, highlight: true), id: self.takeNextHistoryLocationId()) } } } public func scrollToStartOfHistory() { - self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(index: .lowerBound, anchorIndex: .lowerBound, sourceIndex: .upperBound, scrollPosition: .bottom(0.0), animated: true), id: self.takeNextHistoryLocationId()) + self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(index: .lowerBound, anchorIndex: .lowerBound, sourceIndex: .upperBound, scrollPosition: .bottom(0.0), animated: true, highlight: false), id: self.takeNextHistoryLocationId()) } public func scrollToEndOfHistory() { @@ -1416,13 +1416,13 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { case .known(0.0): break default: - let locationInput = ChatHistoryLocationInput(content: .Scroll(index: .upperBound, anchorIndex: .upperBound, sourceIndex: .lowerBound, scrollPosition: .top(0.0), animated: true), id: self.takeNextHistoryLocationId()) + let locationInput = ChatHistoryLocationInput(content: .Scroll(index: .upperBound, anchorIndex: .upperBound, sourceIndex: .lowerBound, scrollPosition: .top(0.0), animated: true, highlight: false), id: self.takeNextHistoryLocationId()) self.chatHistoryLocationValue = locationInput } } public func scrollToMessage(from fromIndex: MessageIndex, to toIndex: MessageIndex, animated: Bool, highlight: Bool = true, scrollPosition: ListViewScrollPosition = .center(.bottom)) { - self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(index: .message(toIndex), anchorIndex: .message(toIndex), sourceIndex: .message(fromIndex), scrollPosition: scrollPosition, animated: animated), id: self.takeNextHistoryLocationId()) + self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(index: .message(toIndex), anchorIndex: .message(toIndex), sourceIndex: .message(fromIndex), scrollPosition: scrollPosition, animated: animated, highlight: highlight), id: self.takeNextHistoryLocationId()) } public func anchorMessageInCurrentHistoryView() -> Message? { diff --git a/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift b/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift index 0f6a3a58ad..abe9135fcd 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift @@ -32,9 +32,9 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, context: A if scheduled { var first = true var chatScrollPosition: ChatHistoryViewScrollPosition? - if case let .Scroll(index, _, sourceIndex, position, animated) = location.content { + if case let .Scroll(index, _, sourceIndex, position, animated, highlight) = location.content { let directionHint: ListViewScrollToItemDirectionHint = sourceIndex > index ? .Down : .Up - chatScrollPosition = .index(index: index, position: position, directionHint: directionHint, animated: animated) + chatScrollPosition = .index(index: index, position: position, directionHint: directionHint, animated: animated, highlight: highlight) } return account.viewTracker.scheduledMessagesViewForLocation(context.chatLocationInput(for: chatLocation, contextHolder: chatLocationContextHolder), additionalData: additionalData) |> map { view, updateType, initialData -> ChatHistoryViewUpdate in @@ -146,7 +146,7 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, context: A return .HistoryView(view: view, type: .Initial(fadeIn: fadeIn), scrollPosition: scrollPosition, flashIndicators: false, originalScrollPosition: nil, initialData: ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData), id: location.id) } } - case let .InitialSearch(searchLocation, count): + case let .InitialSearch(searchLocation, count, highlight): var preloaded = false var fadeIn = false @@ -198,10 +198,10 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, context: A } preloaded = true - return .HistoryView(view: view, type: reportUpdateType, scrollPosition: .index(index: anchorIndex, position: .center(.bottom), directionHint: .Down, animated: false), flashIndicators: false, originalScrollPosition: nil, initialData: ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData), id: location.id) + return .HistoryView(view: view, type: reportUpdateType, scrollPosition: .index(index: anchorIndex, position: .center(.bottom), directionHint: .Down, animated: false, highlight: highlight), flashIndicators: false, originalScrollPosition: nil, initialData: ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData), id: location.id) } } - case let .Navigation(index, anchorIndex, count): + case let .Navigation(index, anchorIndex, count, highlight): var first = true return account.viewTracker.aroundMessageHistoryViewForLocation(context.chatLocationInput(for: chatLocation, contextHolder: chatLocationContextHolder), index: index, anchorIndex: anchorIndex, count: count, fixedCombinedReadStates: fixedCombinedReadStates, tagMask: tagMask, orderStatistics: orderStatistics, additionalData: additionalData) |> map { view, updateType, initialData -> ChatHistoryViewUpdate in let (cachedData, cachedDataMessages, readStateData) = extractAdditionalData(view: view, chatLocation: chatLocation) @@ -215,9 +215,9 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, context: A } return .HistoryView(view: view, type: .Generic(type: genericType), scrollPosition: nil, flashIndicators: false, originalScrollPosition: nil, initialData: ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData), id: location.id) } - case let .Scroll(index, anchorIndex, sourceIndex, scrollPosition, animated): + case let .Scroll(index, anchorIndex, sourceIndex, scrollPosition, animated, highlight): let directionHint: ListViewScrollToItemDirectionHint = sourceIndex > index ? .Down : .Up - let chatScrollPosition = ChatHistoryViewScrollPosition.index(index: index, position: scrollPosition, directionHint: directionHint, animated: animated) + let chatScrollPosition = ChatHistoryViewScrollPosition.index(index: index, position: scrollPosition, directionHint: directionHint, animated: animated, highlight: highlight) var first = true return account.viewTracker.aroundMessageHistoryViewForLocation(context.chatLocationInput(for: chatLocation, contextHolder: chatLocationContextHolder), index: index, anchorIndex: anchorIndex, count: 128, fixedCombinedReadStates: fixedCombinedReadStates, tagMask: tagMask, orderStatistics: orderStatistics, additionalData: additionalData) |> map { view, updateType, initialData -> ChatHistoryViewUpdate in @@ -305,7 +305,7 @@ struct ReplyThreadInfo { var message: ChatReplyThreadMessage var isChannelPost: Bool var isEmpty: Bool - var scrollToLowerBound: Bool + var scrollToLowerBoundMessage: MessageIndex? var contextHolder: Atomic } @@ -326,12 +326,12 @@ func fetchAndPreloadReplyThreadInfo(context: AccountContext, subject: ReplyThrea let chatLocationContextHolder = Atomic(value: nil) let input: ChatHistoryLocationInput - let scrollToLowerBound: Bool + var scrollToLowerBoundMessage: MessageIndex? switch replyThreadMessage.initialAnchor { case .automatic: if let atMessageId = atMessageId { input = ChatHistoryLocationInput( - content: .InitialSearch(location: .id(atMessageId), count: 40), + content: .InitialSearch(location: .id(atMessageId), count: 40, highlight: true), id: 0 ) } else { @@ -340,13 +340,12 @@ func fetchAndPreloadReplyThreadInfo(context: AccountContext, subject: ReplyThrea id: 0 ) } - scrollToLowerBound = false - case .lowerBound: + case let .lowerBoundMessage(index): input = ChatHistoryLocationInput( - content: .Navigation(index: .lowerBound, anchorIndex: .lowerBound, count: 40), + content: .Navigation(index: .message(index), anchorIndex: .message(index), count: 40, highlight: false), id: 0 ) - scrollToLowerBound = true + scrollToLowerBoundMessage = index } let preloadSignal = preloadedChatHistoryViewForLocation( @@ -380,7 +379,7 @@ func fetchAndPreloadReplyThreadInfo(context: AccountContext, subject: ReplyThrea message: replyThreadMessage, isChannelPost: replyThreadMessage.isChannelPost, isEmpty: isEmpty, - scrollToLowerBound: scrollToLowerBound, + scrollToLowerBoundMessage: scrollToLowerBoundMessage, contextHolder: chatLocationContextHolder ) } diff --git a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift index 21c8427ac4..b6701149c9 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift @@ -1127,7 +1127,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { for attribute in item.content.firstMessage.attributes { if let attribute = attribute as? SourceReferenceMessageAttribute { openPeerId = attribute.messageId.peerId - navigate = .chat(textInputState: nil, subject: .message(attribute.messageId), peekData: nil) + navigate = .chat(textInputState: nil, subject: .message(id: attribute.messageId, highlight: true), peekData: nil) } } @@ -1259,7 +1259,9 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } } - if item.content.firstMessage.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) { + if item.content.firstMessage.id.peerId.isReplies { + item.controllerInteraction.openReplyThreadOriginalMessage(item.content.firstMessage) + } else if item.content.firstMessage.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) { for attribute in item.content.firstMessage.attributes { if let attribute = attribute as? SourceReferenceMessageAttribute { item.controllerInteraction.navigateToMessage(item.content.firstMessage.id, attribute.messageId) diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index 373d88b05f..c9b2a4f71e 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -2502,7 +2502,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode for attribute in item.content.firstMessage.attributes { if let attribute = attribute as? SourceReferenceMessageAttribute { openPeerId = attribute.messageId.peerId - navigate = .chat(textInputState: nil, subject: .message(attribute.messageId), peekData: nil) + navigate = .chat(textInputState: nil, subject: .message(id: attribute.messageId, highlight: true), peekData: nil) } } diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift index a353a141a0..49b7868aa3 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift @@ -672,7 +672,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { for attribute in item.content.firstMessage.attributes { if let attribute = attribute as? SourceReferenceMessageAttribute { openPeerId = attribute.messageId.peerId - navigate = .chat(textInputState: nil, subject: .message(attribute.messageId), peekData: nil) + navigate = .chat(textInputState: nil, subject: .message(id: attribute.messageId, highlight: true), peekData: nil) } } @@ -754,7 +754,9 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { } } - if item.content.firstMessage.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) { + if item.content.firstMessage.id.peerId.isReplies { + item.controllerInteraction.openReplyThreadOriginalMessage(item.content.firstMessage) + } else if item.content.firstMessage.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) { for attribute in item.content.firstMessage.attributes { if let attribute = attribute as? SourceReferenceMessageAttribute { item.controllerInteraction.navigateToMessage(item.content.firstMessage.id, attribute.messageId) diff --git a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift index 6516c1f007..25b0a27f45 100644 --- a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift @@ -735,7 +735,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { for attribute in item.content.firstMessage.attributes { if let attribute = attribute as? SourceReferenceMessageAttribute { openPeerId = attribute.messageId.peerId - navigate = .chat(textInputState: nil, subject: .message(attribute.messageId), peekData: nil) + navigate = .chat(textInputState: nil, subject: .message(id: attribute.messageId, highlight: true), peekData: nil) } } @@ -820,7 +820,9 @@ class ChatMessageStickerItemNode: ChatMessageItemView { } } - if item.content.firstMessage.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) { + if item.content.firstMessage.id.peerId.isReplies { + item.controllerInteraction.openReplyThreadOriginalMessage(item.content.firstMessage) + } else if item.content.firstMessage.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) { for attribute in item.content.firstMessage.attributes { if let attribute = attribute as? SourceReferenceMessageAttribute { item.controllerInteraction.navigateToMessage(item.content.firstMessage.id, attribute.messageId) diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift index 0f1631d1ac..e73b020249 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift @@ -815,11 +815,11 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { break case let .channelMessage(peerId, messageId): if let navigationController = strongSelf.getNavigationController() { - strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peerId), subject: .message(messageId))) + strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peerId), subject: .message(id: messageId, highlight: true))) } case let .replyThreadMessage(replyThreadMessage, messageId): if let navigationController = strongSelf.getNavigationController() { - strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .replyThread(replyThreadMessage), subject: .message(messageId))) + strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .replyThread(replyThreadMessage), subject: .message(id: messageId, highlight: true))) } case let .stickerPack(name): let packReference: StickerPackReference = .name(name) diff --git a/submodules/TelegramUI/Sources/ChatSearchResultsContollerNode.swift b/submodules/TelegramUI/Sources/ChatSearchResultsContollerNode.swift index a69e9c64c8..93a5f73095 100644 --- a/submodules/TelegramUI/Sources/ChatSearchResultsContollerNode.swift +++ b/submodules/TelegramUI/Sources/ChatSearchResultsContollerNode.swift @@ -196,7 +196,7 @@ class ChatSearchResultsControllerNode: ViewControllerTracingNode, UIScrollViewDe switch item.content { case let .peer(peer): if let message = peer.messages.first { - let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(peer.peer.peerId), subject: .message(message.id), botStart: nil, mode: .standard(previewing: true)) + let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(peer.peer.peerId), subject: .message(id: message.id, highlight: true), botStart: nil, mode: .standard(previewing: true)) chatController.canReadHistory.set(false) let contextController = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: .single([]), reactionItems: [], gesture: gesture) presentInGlobalOverlay(contextController) diff --git a/submodules/TelegramUI/Sources/NavigateToChatController.swift b/submodules/TelegramUI/Sources/NavigateToChatController.swift index 233d8cd066..22848f2286 100644 --- a/submodules/TelegramUI/Sources/NavigateToChatController.swift +++ b/submodules/TelegramUI/Sources/NavigateToChatController.swift @@ -20,7 +20,7 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam if let updateTextInputState = params.updateTextInputState { controller.updateTextInputState(updateTextInputState) } - if let subject = params.subject, case let .message(messageId) = subject { + if let subject = params.subject, case let .message(messageId, _) = subject { let navigationController = params.navigationController let animated = params.animated controller.navigateToMessage(messageLocation: .id(messageId), animated: isFirst, completion: { [weak navigationController, weak controller] in diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index 8ddbdc9500..b10f952798 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -89,7 +89,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur dismissInput() navigationController?.pushViewController(controller) case let .channelMessage(peerId, messageId): - openPeer(peerId, .chat(textInputState: nil, subject: .message(messageId), peekData: nil)) + openPeer(peerId, .chat(textInputState: nil, subject: .message(id: messageId, highlight: true), peekData: nil)) case let .replyThreadMessage(replyThreadMessage, messageId): if let navigationController = navigationController { let _ = ChatControllerImpl.openMessageReplies(context: context, navigationController: navigationController, present: { c, a in diff --git a/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift b/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift index 3bc0f9691d..f0d348eaad 100644 --- a/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift +++ b/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift @@ -165,7 +165,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu let chatLocationContextHolder = Atomic(value: nil) - self.historyNode = ChatHistoryListNode(context: context, chatLocation: .peer(peerId), chatLocationContextHolder: chatLocationContextHolder, tagMask: tagMask, subject: .message(initialMessageId), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, displayHeaders: .none, hintLinks: false, isGlobalSearch: isGlobalSearch)) + self.historyNode = ChatHistoryListNode(context: context, chatLocation: .peer(peerId), chatLocationContextHolder: chatLocationContextHolder, tagMask: tagMask, subject: .message(id: initialMessageId, highlight: true), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, displayHeaders: .none, hintLinks: false, isGlobalSearch: isGlobalSearch)) super.init() @@ -496,7 +496,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu } let chatLocationContextHolder = Atomic(value: nil) - let historyNode = ChatHistoryListNode(context: self.context, chatLocation: .peer(self.peerId), chatLocationContextHolder: chatLocationContextHolder, tagMask: tagMask, subject: .message(messageId), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, displayHeaders: .none, hintLinks: false, isGlobalSearch: self.isGlobalSearch)) + let historyNode = ChatHistoryListNode(context: self.context, chatLocation: .peer(self.peerId), chatLocationContextHolder: chatLocationContextHolder, tagMask: tagMask, subject: .message(id: messageId, highlight: true), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, displayHeaders: .none, hintLinks: false, isGlobalSearch: self.isGlobalSearch)) historyNode.preloadPages = true historyNode.stackFromBottom = true historyNode.updateFloatingHeaderOffset = { [weak self] offset, _ in diff --git a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift index de270ceb40..ea63e93b1d 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift @@ -256,7 +256,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode { } if let id = state.id as? PeerMessagesMediaPlaylistItemId { if type == .music { - let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(location: .id(id.messageId), count: 60), id: 0), context: strongSelf.context, chatLocation: .peer(id.messageId.peerId), chatLocationContextHolder: Atomic(value: nil), tagMask: MessageTags.music) + let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(location: .id(id.messageId), count: 60, highlight: true), id: 0), context: strongSelf.context, chatLocation: .peer(id.messageId.peerId), chatLocationContextHolder: Atomic(value: nil), tagMask: MessageTags.music) var cancelImpl: (() -> Void)? let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index a9e53fa223..6873b25754 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -1600,7 +1600,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.SharedMedia_ViewInChat, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/GoToMessage"), color: theme.contextMenu.primaryColor) }, action: { c, _ in c.dismiss(completion: { if let strongSelf = self, let navigationController = strongSelf.controller?.navigationController as? NavigationController { - strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(strongSelf.peerId), subject: .message(message.id))) + strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(strongSelf.peerId), subject: .message(id: message.id, highlight: true))) } }) }))) @@ -1703,7 +1703,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD items.append(.action(ContextMenuActionItem(text: strings.SharedMedia_ViewInChat, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/GoToMessage"), color: theme.contextMenu.primaryColor) }, action: { c, f in c.dismiss(completion: { if let strongSelf = self, let navigationController = strongSelf.controller?.navigationController as? NavigationController { - strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(strongSelf.peerId), subject: .message(message.id))) + strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(strongSelf.peerId), subject: .message(id: message.id, highlight: true))) } }) }))) diff --git a/submodules/TelegramUI/Sources/PreparedChatHistoryViewTransition.swift b/submodules/TelegramUI/Sources/PreparedChatHistoryViewTransition.swift index 1efca4fc26..cdc8293c66 100644 --- a/submodules/TelegramUI/Sources/PreparedChatHistoryViewTransition.swift +++ b/submodules/TelegramUI/Sources/PreparedChatHistoryViewTransition.swift @@ -143,8 +143,8 @@ func preparedChatHistoryViewTransition(from fromView: ChatHistoryView?, to toVie index += 1 } } - case let .index(scrollIndex, position, directionHint, animated): - if case .center = position { + case let .index(scrollIndex, position, directionHint, animated, highlight): + if case .center = position, highlight { scrolledToIndex = scrollIndex } var index = toView.filteredEntries.count - 1 diff --git a/submodules/TelegramUI/Sources/TextLinkHandling.swift b/submodules/TelegramUI/Sources/TextLinkHandling.swift index fbabf1690d..e981b5c7cd 100644 --- a/submodules/TelegramUI/Sources/TextLinkHandling.swift +++ b/submodules/TelegramUI/Sources/TextLinkHandling.swift @@ -57,7 +57,7 @@ func handleTextLinkActionImpl(context: AccountContext, peerId: PeerId?, navigate openResolvedPeerImpl(peerId, .default) case let .channelMessage(peerId, messageId): if let navigationController = controller.navigationController as? NavigationController { - context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId), subject: .message(messageId))) + context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId), subject: .message(id: messageId, highlight: true))) } case let .replyThreadMessage(replyThreadMessage, messageId): if let navigationController = controller.navigationController as? NavigationController { diff --git a/submodules/UrlHandling/Sources/UrlHandling.swift b/submodules/UrlHandling/Sources/UrlHandling.swift index 75a45279eb..42576e6876 100644 --- a/submodules/UrlHandling/Sources/UrlHandling.swift +++ b/submodules/UrlHandling/Sources/UrlHandling.swift @@ -383,7 +383,7 @@ private func resolveInternalUrl(account: Account, url: ParsedInternalUrl) -> Sig return .replyThreadMessage(replyThreadMessage: result, messageId: messageId) } } else { - return .single(.peer(foundPeer.id, .chat(textInputState: nil, subject: .message(messageId), peekData: nil))) + return .single(.peer(foundPeer.id, .chat(textInputState: nil, subject: .message(id: messageId, highlight: true), peekData: nil))) } } else { return .single(.inaccessiblePeer)