Add reply action in gallery

This commit is contained in:
Ilya Laktyushin 2024-07-03 21:43:18 +04:00
parent 4224ec0cec
commit 39598deb04
34 changed files with 207 additions and 152 deletions

View File

@ -774,7 +774,7 @@ public enum ChatControllerSubject: Equatable {
}
}
case message(id: MessageSubject, highlight: MessageHighlight?, timecode: Double?)
case message(id: MessageSubject, highlight: MessageHighlight?, timecode: Double?, setupReply: Bool)
case scheduledMessages
case pinnedMessages(id: EngineMessage.Id?)
case messageOptions(peerIds: [EnginePeer.Id], ids: [EngineMessage.Id], info: MessageOptionsInfo)
@ -782,8 +782,8 @@ public enum ChatControllerSubject: Equatable {
public static func ==(lhs: ChatControllerSubject, rhs: ChatControllerSubject) -> Bool {
switch lhs {
case let .message(lhsId, lhsHighlight, lhsTimecode):
if case let .message(rhsId, rhsHighlight, rhsTimecode) = rhs, lhsId == rhsId && lhsHighlight == rhsHighlight && lhsTimecode == rhsTimecode {
case let .message(lhsId, lhsHighlight, lhsTimecode, lhsSetupReply):
if case let .message(rhsId, rhsHighlight, rhsTimecode, rhsSetupReply) = rhs, lhsId == rhsId && lhsHighlight == rhsHighlight && lhsTimecode == rhsTimecode && lhsSetupReply == rhsSetupReply {
return true
} else {
return false

View File

@ -20,10 +20,12 @@ public struct MessageHistoryScrollToSubject: Equatable {
public var index: MessageHistoryAnchorIndex
public var quote: Quote?
public var setupReply: Bool
public init(index: MessageHistoryAnchorIndex, quote: Quote?) {
public init(index: MessageHistoryAnchorIndex, quote: Quote?, setupReply: Bool = false) {
self.index = index
self.quote = quote
self.setupReply = setupReply
}
}
@ -49,9 +51,9 @@ public struct MessageHistoryInitialSearchSubject: Equatable {
public enum ChatHistoryLocation: Equatable {
case Initial(count: Int)
case InitialSearch(subject: MessageHistoryInitialSearchSubject, count: Int, highlight: Bool)
case InitialSearch(subject: MessageHistoryInitialSearchSubject, count: Int, highlight: Bool, setupReply: Bool)
case Navigation(index: MessageHistoryAnchorIndex, anchorIndex: MessageHistoryAnchorIndex, count: Int, highlight: Bool)
case Scroll(subject: MessageHistoryScrollToSubject, anchorIndex: MessageHistoryAnchorIndex, sourceIndex: MessageHistoryAnchorIndex, scrollPosition: ListViewScrollPosition, animated: Bool, highlight: Bool)
case Scroll(subject: MessageHistoryScrollToSubject, anchorIndex: MessageHistoryAnchorIndex, sourceIndex: MessageHistoryAnchorIndex, scrollPosition: ListViewScrollPosition, animated: Bool, highlight: Bool, setupReply: Bool)
}
public struct ChatHistoryLocationInput: Equatable {

View File

@ -1204,7 +1204,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if case let .channel(channel) = actualPeer, channel.flags.contains(.isForum), let threadId {
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: messageId, navigationController: navigationController, activateInput: nil, scrollToEndIfExists: false, keepStack: .never).startStandalone()
} else {
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(actualPeer), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil), purposefulAction: {
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(actualPeer), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false), purposefulAction: {
if deactivateOnAction {
self?.deactivateSearch(animated: false)
}
@ -1465,7 +1465,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
} else {
var subject: ChatControllerSubject?
if case let .search(messageId) = source, let id = messageId {
subject = .message(id: .id(id), highlight: nil, timecode: nil)
subject = .message(id: .id(id), highlight: nil, timecode: nil, setupReply: false)
}
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peer.id), subject: subject, botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)

View File

@ -3742,7 +3742,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
strongSelf.interaction.dismissInput()
strongSelf.interaction.present(controller, nil)
} else if case let .messages(chatLocation, _, _) = playlistLocation {
let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(id.messageId), quote: nil), count: 60, highlight: true), id: 0), context: strongSelf.context, chatLocation: chatLocation, subject: nil, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), tag: .tag(EngineMessage.Tags.music))
let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(id.messageId), quote: nil), count: 60, highlight: true, setupReply: false), id: 0), context: strongSelf.context, chatLocation: chatLocation, subject: nil, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), tag: .tag(EngineMessage.Tags.music))
var cancelImpl: (() -> Void)?
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }

View File

@ -532,59 +532,78 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode {
}
private func contextMenuMainItems() -> Signal<[ContextMenuItem], NoError> {
var items: [ContextMenuItem] = []
let peer: Signal<EnginePeer?, NoError>
if let message = self.message {
let context = self.context
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.SharedMedia_ViewInChat, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/GoToMessage"), color: theme.contextMenu.primaryColor)}, action: { [weak self] _, f in
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: message.id.peerId))
|> deliverOnMainQueue).start(next: { [weak self] peer in
guard let strongSelf = self, let peer = peer else {
return
}
if let navigationController = strongSelf.baseNavigationController() {
strongSelf.beginCustomDismiss(true)
peer = self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: message.id.peerId))
} else {
peer = .single(nil)
}
let context = self.context
return peer
|> map { [weak self] peer -> [ContextMenuItem] in
guard let self else {
return []
}
var items: [ContextMenuItem] = []
if let message = self.message {
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.SharedMedia_ViewInChat, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/GoToMessage"), color: theme.contextMenu.primaryColor)}, action: { [weak self] _, f in
if let self, let peer, let navigationController = self.baseNavigationController() {
self.beginCustomDismiss(true)
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil)))
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false)))
Queue.mainQueue().after(0.3) {
strongSelf.completeCustomDismiss()
self.completeCustomDismiss()
}
}
f(.default)
})
})))
})))
if !message.isCopyProtected() && !self.peerIsCopyProtected && message.paidContent == nil, let media = self.contextAndMedia?.1 {
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.Gallery_SaveImage, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Download"), color: theme.actionSheet.primaryTextColor) }, action: { [weak self] _, f in
f(.default)
let _ = (SaveToCameraRoll.saveToCameraRoll(context: context, postbox: context.account.postbox, userLocation: .peer(message.id.peerId), mediaReference: media)
|> deliverOnMainQueue).start(completed: { [weak self] in
guard let strongSelf = self else {
return
}
guard let controller = strongSelf.galleryController() else {
return
}
controller.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .mediaSaved(text: strongSelf.presentationData.strings.Gallery_ImageSaved), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
})
})))
}
}
if !message.isCopyProtected() && !self.peerIsCopyProtected && message.paidContent == nil, let media = self.contextAndMedia?.1 {
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.Gallery_SaveImage, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Download"), color: theme.actionSheet.primaryTextColor) }, action: { [weak self] _, f in
if let peer, let message = self.message, canSendMessagesToPeer(peer._asPeer()) {
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.Conversation_ContextMenuReply, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Reply"), color: theme.contextMenu.primaryColor)}, action: { [weak self] _, f in
if let self, let navigationController = self.baseNavigationController() {
self.beginCustomDismiss(true)
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: true)))
Queue.mainQueue().after(0.3) {
self.completeCustomDismiss()
}
}
f(.default)
let _ = (SaveToCameraRoll.saveToCameraRoll(context: context, postbox: context.account.postbox, userLocation: .peer(message.id.peerId), mediaReference: media)
|> deliverOnMainQueue).start(completed: { [weak self] in
guard let strongSelf = self else {
return
}
guard let controller = strongSelf.galleryController() else {
return
}
controller.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .mediaSaved(text: strongSelf.presentationData.strings.Gallery_ImageSaved), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
})
})))
}
}
if self.canDelete() {
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.Common_Delete, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak self] _, f in
f(.default)
if self.canDelete() {
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.Common_Delete, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak self] _, f in
f(.default)
if let strongSelf = self {
strongSelf.footerContentNode.deleteButtonPressed()
}
})))
if let strongSelf = self {
strongSelf.footerContentNode.deleteButtonPressed()
}
})))
}
return items
}
return .single(items)
}
private func openMoreMenu(sourceNode: ASDisplayNode, gesture: ContextGesture?) {

View File

@ -2509,11 +2509,17 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
guard let videoNode = self.videoNode, let item = self.item else {
return .single([])
}
let peer: Signal<EnginePeer?, NoError>
if let (message, _, _) = self.contentInfo() {
peer = self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: message.id.peerId))
} else {
peer = .single(nil)
}
return videoNode.status
return combineLatest(queue: Queue.mainQueue(), videoNode.status, peer)
|> take(1)
|> deliverOnMainQueue
|> map { [weak self] status -> [ContextMenuItem] in
|> map { [weak self] status, peer -> [ContextMenuItem] in
guard let status = status, let strongSelf = self else {
return []
}
@ -2552,23 +2558,19 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
if let (message, _, _) = strongSelf.contentInfo() {
let context = strongSelf.context
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: { [weak self] _, f in
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: message.id.peerId))
|> deliverOnMainQueue).start(next: { [weak self] peer in
guard let strongSelf = self, let peer = peer else {
return
guard let strongSelf = self, let peer = peer else {
return
}
if let navigationController = strongSelf.baseNavigationController() {
strongSelf.beginCustomDismiss(true)
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false)))
Queue.mainQueue().after(0.3) {
strongSelf.completeCustomDismiss()
}
if let navigationController = strongSelf.baseNavigationController() {
strongSelf.beginCustomDismiss(true)
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil)))
Queue.mainQueue().after(0.3) {
strongSelf.completeCustomDismiss()
}
}
f(.default)
})
}
f(.default)
})))
}
@ -2637,6 +2639,22 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
}
})))
}
if let peer, let (message, _, _) = strongSelf.contentInfo(), canSendMessagesToPeer(peer._asPeer()) {
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_ContextMenuReply, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Reply"), color: theme.contextMenu.primaryColor)}, action: { [weak self] _, f in
if let self, let navigationController = self.baseNavigationController() {
self.beginCustomDismiss(true)
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: true)))
Queue.mainQueue().after(0.3) {
self.completeCustomDismiss()
}
}
f(.default)
})))
}
if strongSelf.canDelete() {
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Common_Delete, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { _, f in
f(.default)

View File

@ -2291,7 +2291,7 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
}
if let navigationController = controller?.navigationController as? NavigationController {
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil)))
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false)))
}
})
})
@ -2338,7 +2338,7 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
return
}
if let navigationController = controller?.navigationController as? NavigationController {
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil), keepStack: .always, useExisting: false, purposefulAction: {}, peekData: nil))
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false), keepStack: .always, useExisting: false, purposefulAction: {}, peekData: nil))
}
})
}

View File

@ -450,7 +450,7 @@ public func messageStatsController(context: AccountContext, updatedPresentationD
return
}
if let navigationController = controller?.navigationController as? NavigationController {
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil), keepStack: .always, useExisting: false, purposefulAction: {}, peekData: nil))
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false), keepStack: .always, useExisting: false, purposefulAction: {}, peekData: nil))
}
})
}

View File

@ -829,7 +829,7 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
strongSelf.displayNode.view.window?.endEditing(true)
strongSelf.present(controller, in: .window(.root))
} else if case let .messages(chatLocation, _, _) = playlistLocation {
let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(id.messageId), quote: nil), count: 60, highlight: true), id: 0), context: strongSelf.context, chatLocation: chatLocation, subject: nil, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), tag: .tag(MessageTags.music))
let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(id.messageId), quote: nil), count: 60, highlight: true, setupReply: false), id: 0), context: strongSelf.context, chatLocation: chatLocation, subject: nil, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), tag: .tag(MessageTags.music))
var cancelImpl: (() -> Void)?
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }

View File

@ -1179,11 +1179,11 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
break
case let .channelMessage(peer, messageId, timecode):
if let navigationController = strongSelf.getNavigationController() {
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(peer)), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: timecode)))
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(peer)), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: timecode, setupReply: false)))
}
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(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil)))
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .replyThread(replyThreadMessage), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false)))
}
case let .replyThread(messageId):
if let navigationController = strongSelf.getNavigationController() {

View File

@ -98,12 +98,14 @@ public struct NavigateToMessageParams {
public var quote: Quote?
public var progress: Promise<Bool>?
public var forceNew: Bool
public var setupReply: Bool
public init(timestamp: Double?, quote: Quote?, progress: Promise<Bool>? = nil, forceNew: Bool = false) {
public init(timestamp: Double?, quote: Quote?, progress: Promise<Bool>? = nil, forceNew: Bool = false, setupReply: Bool = false) {
self.timestamp = timestamp
self.quote = quote
self.progress = progress
self.forceNew = forceNew
self.setupReply = setupReply
}
}

View File

@ -368,7 +368,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode {
}
if let id = state.id as? PeerMessagesMediaPlaylistItemId, let playlistLocation = strongSelf.playlistLocation as? PeerMessagesPlaylistLocation, case let .messages(chatLocation, _, _) = playlistLocation {
if type == .music {
let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(id.messageId), quote: nil), count: 60, highlight: true), id: 0), context: strongSelf.context, chatLocation: .peer(id: id.messageId.peerId), subject: nil, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), tag: .tag(MessageTags.music))
let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(id.messageId), quote: nil), count: 60, highlight: true, setupReply: false), id: 0), context: strongSelf.context, chatLocation: .peer(id: id.messageId.peerId), subject: nil, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), tag: .tag(MessageTags.music))
var cancelImpl: (() -> Void)?
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }

View File

@ -2882,7 +2882,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
}
let currentPeerId = strongSelf.peerId
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: targetLocation, subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil), keepStack: .always, useExisting: false, purposefulAction: {
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: targetLocation, subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false), keepStack: .always, useExisting: false, purposefulAction: {
var viewControllers = navigationController.viewControllers
var indexesToRemove = Set<Int>()
var keptCurrentChatController = false
@ -3044,7 +3044,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
}
let currentPeerId = strongSelf.peerId
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: targetLocation, subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil), keepStack: .always, useExisting: false, purposefulAction: {
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: targetLocation, subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false), keepStack: .always, useExisting: false, purposefulAction: {
var viewControllers = navigationController.viewControllers
var indexesToRemove = Set<Int>()
var keptCurrentChatController = false
@ -10908,7 +10908,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
chatController: nil,
context: strongSelf.context,
chatLocation: .peer(EnginePeer(peer)),
subject: .message(id: .id(index.id), highlight: nil, timecode: nil),
subject: .message(id: .id(index.id), highlight: nil, timecode: nil, setupReply: false),
botStart: nil,
updateTextInputState: nil,
keepStack: .never,
@ -10929,7 +10929,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
))
})))
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: strongSelf.peerId), subject: .message(id: .id(index.id), highlight: nil, timecode: nil), botStart: nil, mode: .standard(.previewing), params: nil)
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: strongSelf.peerId), subject: .message(id: .id(index.id), highlight: nil, timecode: nil, setupReply: false), botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
let contextController = ContextController(presentationData: strongSelf.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: sourceNode, sourceRect: sourceRect, passthroughTouches: true)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture)
strongSelf.controller?.presentInGlobalOverlay(contextController)

View File

@ -843,7 +843,7 @@ public class StarsTransactionScreen: ViewControllerComponentContainer {
return
}
if let navigationController = self.navigationController as? NavigationController {
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil), keepStack: .always, useExisting: false, purposefulAction: {}, peekData: nil))
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false), keepStack: .always, useExisting: false, purposefulAction: {}, peekData: nil))
}
})
}

View File

@ -2571,7 +2571,7 @@ final class StorageUsageScreenComponent: Component {
navigationController: navigationController,
context: component.context,
chatLocation: chatLocation,
subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil),
subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false),
keepStack: .always
))
})
@ -2674,7 +2674,7 @@ final class StorageUsageScreenComponent: Component {
navigationController: navigationController,
context: component.context,
chatLocation: chatLocation,
subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil),
subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false),
keepStack: .always
))
})

View File

@ -3388,7 +3388,7 @@ public final class StoryItemSetContainerComponent: Component {
guard let self else {
return
}
self.navigateToPeer(peer: peer, chat: true, subject: .message(id: .id(messageId), highlight: nil, timecode: nil))
self.navigateToPeer(peer: peer, chat: true, subject: .message(id: .id(messageId), highlight: nil, timecode: nil, setupReply: false))
},
peerContextAction: { [weak self] peer, sourceView, gesture in
guard let self, let component = self.component else {
@ -4644,7 +4644,7 @@ public final class StoryItemSetContainerComponent: Component {
presentationData: presentationData,
content: .sticker(context: context, file: animation, loop: false, title: nil, text: component.strings.Story_ToastReactionSent, undoText: component.strings.Story_ToastViewInChat, customAction: { [weak self] in
if let messageId = messageIds.first, let self {
self.navigateToPeer(peer: peer, chat: true, subject: messageId.flatMap { .message(id: .id($0), highlight: nil, timecode: nil) })
self.navigateToPeer(peer: peer, chat: true, subject: messageId.flatMap { .message(id: .id($0), highlight: nil, timecode: nil, setupReply: false) })
}
}),
elevatedLayout: false,

View File

@ -377,7 +377,7 @@ final class StoryItemSetContainerSendMessage {
animateInAsReplacement: false,
action: { [weak view, weak self] action in
if case .undo = action, let messageId {
view?.navigateToPeer(peer: peer, chat: true, subject: isScheduled ? .scheduledMessages : .message(id: .id(messageId), highlight: nil, timecode: nil))
view?.navigateToPeer(peer: peer, chat: true, subject: isScheduled ? .scheduledMessages : .message(id: .id(messageId), highlight: nil, timecode: nil, setupReply: false))
}
self?.tooltipScreen = nil
view?.updateIsProgressPaused()
@ -2768,7 +2768,7 @@ final class StoryItemSetContainerSendMessage {
return
}
if let navigationController = controller.navigationController as? NavigationController {
component.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: component.context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil)))
component.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: component.context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false)))
}
completion?()
})

View File

@ -823,7 +823,7 @@ final class AuthorizedApplicationContext {
return
}
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: strongSelf.rootController, context: strongSelf.context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil)))
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: strongSelf.rootController, context: strongSelf.context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false)))
})
}
@ -942,7 +942,7 @@ final class AuthorizedApplicationContext {
chatLocation = .peer(peer)
}
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: self.rootController, context: self.context, chatLocation: chatLocation, subject: isOutgoingMessage ? messageId.flatMap { .message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil) } : nil, activateInput: activateInput ? .text : nil))
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: self.rootController, context: self.context, chatLocation: chatLocation, subject: isOutgoingMessage ? messageId.flatMap { .message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false) } : nil, activateInput: activateInput ? .text : nil))
})
}
}

View File

@ -1023,7 +1023,7 @@ extension ChatControllerImpl {
self.chatDisplayNode.historyNode.scrolledToIndex = { [weak self] toSubject, initial in
if let strongSelf = self, case let .message(index) = toSubject.index {
if case let .message(messageSubject, _, _) = strongSelf.subject, initial, case let .id(messageId) = messageSubject, messageId != index.id {
if case let .message(messageSubject, _, _, _) = strongSelf.subject, initial, case let .id(messageId) = messageSubject, messageId != index.id {
if messageId.peerId == index.id.peerId {
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .info(title: nil, text: strongSelf.presentationData.strings.Conversation_MessageDoesntExist, timeout: nil, customUndoText: nil), elevatedLayout: false, action: { _ in return true }), in: .current)
}
@ -1036,6 +1036,12 @@ extension ChatControllerImpl {
}
if let message = strongSelf.chatDisplayNode.historyNode.messageInCurrentHistoryView(mappedId) {
if toSubject.setupReply {
Queue.mainQueue().after(0.1) {
strongSelf.interfaceInteraction?.setupReplyMessage(mappedId, { _, f in f() })
}
}
let highlightedState = ChatInterfaceHighlightedState(messageStableId: message.stableId, quote: toSubject.quote.flatMap { quote in ChatInterfaceHighlightedState.Quote(string: quote.string, offset: quote.offset) })
controllerInteraction.highlightedState = highlightedState
strongSelf.updateItemNodesHighlightedStates(animated: initial)
@ -1066,7 +1072,7 @@ extension ChatControllerImpl {
let _ = strongSelf.controllerInteraction?.openMessage(message, OpenMessageParams(mode: .timecode(timecode)))
}
}
} else if case let .message(_, _, maybeTimecode) = strongSelf.subject, let timecode = maybeTimecode, initial {
} else if case let .message(_, _, maybeTimecode, _) = strongSelf.subject, let timecode = maybeTimecode, initial {
Queue.mainQueue().after(0.2) {
let _ = strongSelf.controllerInteraction?.openMessage(message, OpenMessageParams(mode: .timecode(timecode)))
}
@ -3854,7 +3860,7 @@ extension ChatControllerImpl {
}
if let navigationController = strongSelf.effectiveNavigationController {
let subject: ChatControllerSubject? = sourceMessageId.flatMap { ChatControllerSubject.message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil) }
let subject: ChatControllerSubject? = sourceMessageId.flatMap { ChatControllerSubject.message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false) }
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .replyThread(replyThreadResult), subject: subject, keepStack: .always))
}
}, activatePinnedListPreview: { [weak self] node, gesture in

View File

@ -147,7 +147,7 @@ extension ChatControllerImpl {
} else {
navigateToLocation = .peer(peer)
}
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: navigateToLocation, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil), keepStack: .always))
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: navigateToLocation, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false), keepStack: .always))
completion?()
})
@ -177,7 +177,7 @@ extension ChatControllerImpl {
}
let context = self.context
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: chatLocation, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: quote), timecode: nil), keepStack: .always, chatListCompletion: { chatListController in
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: chatLocation, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: quote), timecode: nil, setupReply: false), keepStack: .always, chatListCompletion: { chatListController in
if displayMessageNotFoundToast {
let presentationData = context.sharedContext.currentPresentationData.with({ $0 })
chatListController.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.Conversation_MessageDoesntExist, timeout: nil, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in
@ -214,11 +214,13 @@ extension ChatControllerImpl {
}
var quote: (string: String, offset: Int?)?
var setupReply = false
if case let .id(_, params) = messageLocation {
quote = params.quote.flatMap { quote in (string: quote.string, offset: quote.offset) }
setupReply = params.setupReply
}
self.chatDisplayNode.historyNode.scrollToMessage(from: scrollFromIndex, to: message.index, animated: animated, quote: quote, scrollPosition: scrollPosition)
self.chatDisplayNode.historyNode.scrollToMessage(from: scrollFromIndex, to: message.index, animated: animated, quote: quote, scrollPosition: scrollPosition, setupReply: setupReply)
if delayCompletion {
Queue.mainQueue().after(0.25, {
@ -236,12 +238,14 @@ extension ChatControllerImpl {
} else if case let .index(index) = messageLocation, index.id.id == 0, index.timestamp > 0, case .scheduledMessages = self.presentationInterfaceState.subject {
self.chatDisplayNode.historyNode.scrollToMessage(from: scrollFromIndex, to: index, animated: animated, scrollPosition: scrollPosition)
} else {
var setupReply = false
var quote: (string: String, offset: Int?)?
if case let .id(messageId, params) = messageLocation {
if params.timestamp != nil {
self.scheduledScrollToMessageId = (messageId, params)
}
quote = params.quote.flatMap { ($0.string, $0.offset) }
setupReply = params.setupReply
}
var progress: Promise<Bool>?
if case let .id(_, params) = messageLocation {
@ -267,7 +271,7 @@ extension ChatControllerImpl {
}
}
var historyView: Signal<ChatHistoryViewUpdate, NoError>
historyView = preloadedChatHistoryViewForLocation(ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: searchLocation, quote: nil), count: 50, highlight: true), id: 0), context: self.context, chatLocation: self.chatLocation, subject: self.subject, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tag: nil, additionalData: [])
historyView = preloadedChatHistoryViewForLocation(ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: searchLocation, quote: nil), count: 50, highlight: true, setupReply: setupReply), id: 0), context: self.context, chatLocation: self.chatLocation, subject: self.subject, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tag: nil, additionalData: [])
var signal: Signal<(MessageIndex?, Bool), NoError>
signal = historyView
@ -338,7 +342,7 @@ extension ChatControllerImpl {
}
|> deliverOnMainQueue).startStrict(next: { [weak self] index in
if let strongSelf = self, let index = index.0 {
strongSelf.chatDisplayNode.historyNode.scrollToMessage(from: scrollFromIndex, to: index, animated: animated, quote: quote, scrollPosition: scrollPosition)
strongSelf.chatDisplayNode.historyNode.scrollToMessage(from: scrollFromIndex, to: index, animated: animated, quote: quote, scrollPosition: scrollPosition, setupReply: setupReply)
} else if index.1 {
if !progressStarted {
progressStarted = true
@ -380,11 +384,13 @@ extension ChatControllerImpl {
self.loadingMessage.set(.single(statusSubject) |> delay(0.1, queue: .mainQueue()))
var quote: ChatControllerSubject.MessageHighlight.Quote?
var setupReply = false
if case let .id(_, params) = messageLocation {
quote = params.quote.flatMap { quote in ChatControllerSubject.MessageHighlight.Quote(string: quote.string, offset: quote.offset) }
setupReply = params.setupReply
}
let historyView = preloadedChatHistoryViewForLocation(ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: searchLocation, quote: quote.flatMap { quote in MessageHistoryInitialSearchSubject.Quote(string: quote.string, offset: quote.offset) }), count: 50, highlight: true), id: 0), context: self.context, chatLocation: self.chatLocation, subject: self.subject, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tag: nil, additionalData: [])
let historyView = preloadedChatHistoryViewForLocation(ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: searchLocation, quote: quote.flatMap { quote in MessageHistoryInitialSearchSubject.Quote(string: quote.string, offset: quote.offset) }), count: 50, highlight: true, setupReply: setupReply), id: 0), context: self.context, chatLocation: self.chatLocation, subject: self.subject, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tag: nil, additionalData: [])
var signal: Signal<MessageIndex?, NoError>
signal = historyView
|> mapToSignal { historyView -> Signal<MessageIndex?, NoError> in
@ -416,11 +422,13 @@ extension ChatControllerImpl {
if let navigationController = strongSelf.effectiveNavigationController {
var quote: ChatControllerSubject.MessageHighlight.Quote?
var setupReply = false
if case let .id(_, params) = messageLocation {
quote = params.quote.flatMap { quote in ChatControllerSubject.MessageHighlight.Quote(string: quote.string, offset: quote.offset) }
setupReply = params.setupReply
}
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), subject: messageLocation.messageId.flatMap { .message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: quote), timecode: nil) }, keepStack: .always))
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), subject: messageLocation.messageId.flatMap { .message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: quote), timecode: nil, setupReply: setupReply) }, keepStack: .always))
}
})
completion?()
@ -438,7 +446,7 @@ extension ChatControllerImpl {
return
}
if let navigationController = self.effectiveNavigationController {
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), subject: messageLocation.messageId.flatMap { .message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil) }))
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), subject: messageLocation.messageId.flatMap { .message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false) }))
}
completion?()
})

View File

@ -6767,7 +6767,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
func pinnedHistorySignal(anchorMessageId: MessageId?, count: Int) -> Signal<ChatHistoryViewUpdate, NoError> {
let location: ChatHistoryLocation
if let anchorMessageId = anchorMessageId {
location = .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(anchorMessageId), quote: nil), count: count, highlight: false)
location = .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(anchorMessageId), quote: nil), count: count, highlight: false, setupReply: false)
} else {
location = .Initial(count: count)
}
@ -9126,7 +9126,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
case let .chat(textInputState, subject, peekData):
dismissWebAppControllers()
if case .peer(peerId.id) = strongSelf.chatLocation {
if let subject = subject, case let .message(messageSubject, _, timecode) = subject {
if let subject = subject, case let .message(messageSubject, _, timecode, _) = subject {
if case let .id(messageId) = messageSubject {
strongSelf.navigateToMessage(from: sourceMessageId, to: .id(messageId, NavigateToMessageParams(timestamp: timecode, quote: nil)))
}

View File

@ -128,7 +128,7 @@ extension ChatControllerImpl {
})))
}
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerId), subject: .message(id: .timestamp(timestamp), highlight: nil, timecode: nil), botStart: nil, mode: .standard(.previewing), params: nil)
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerId), subject: .message(id: .timestamp(timestamp), highlight: nil, timecode: nil, setupReply: false), botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
strongSelf.chatDisplayNode.messageTransitionNode.dismissMessageReactionContexts()

View File

@ -81,9 +81,9 @@ extension ChatControllerImpl {
let subject: ChatControllerSubject?
if let atMessageId = atMessageId {
subject = .message(id: .id(atMessageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil)
subject = .message(id: .id(atMessageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false)
} else if let index = result.scrollToLowerBoundMessage {
subject = .message(id: .id(index.id), highlight: nil, timecode: nil)
subject = .message(id: .id(index.id), highlight: nil, timecode: nil, setupReply: false)
} else {
subject = nil
}

View File

@ -11,7 +11,7 @@ import PresentationDataUtils
extension ChatControllerImpl {
func scrollToEndOfHistory() {
let locationInput = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .upperBound, quote: nil), anchorIndex: .upperBound, sourceIndex: .lowerBound, scrollPosition: .top(0.0), animated: true, highlight: false), id: 0)
let locationInput = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .upperBound, quote: nil), anchorIndex: .upperBound, sourceIndex: .lowerBound, scrollPosition: .top(0.0), animated: true, highlight: false, setupReply: false), id: 0)
let historyView = preloadedChatHistoryViewForLocation(locationInput, context: self.context, chatLocation: self.chatLocation, subject: self.subject, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tag: nil, additionalData: [])
let signal = historyView
@ -75,7 +75,7 @@ extension ChatControllerImpl {
}
func scrollToStartOfHistory() {
let locationInput = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .lowerBound, quote: nil), anchorIndex: .lowerBound, sourceIndex: .upperBound, scrollPosition: .bottom(0.0), animated: true, highlight: false), id: 0)
let locationInput = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .lowerBound, quote: nil), anchorIndex: .lowerBound, sourceIndex: .upperBound, scrollPosition: .bottom(0.0), animated: true, highlight: false, setupReply: false), id: 0)
let historyView = preloadedChatHistoryViewForLocation(locationInput, context: self.context, chatLocation: self.chatLocation, subject: self.subject, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tag: nil, additionalData: [])
let signal = historyView

View File

@ -48,7 +48,7 @@ private let historyMessageCount: Int = 44
enum ChatHistoryViewScrollPosition {
case unread(index: MessageIndex)
case positionRestoration(index: MessageIndex, relativeOffset: CGFloat)
case index(subject: MessageHistoryScrollToSubject, position: ListViewScrollPosition, directionHint: ListViewScrollToItemDirectionHint, animated: Bool, highlight: Bool, displayLink: Bool)
case index(subject: MessageHistoryScrollToSubject, position: ListViewScrollPosition, directionHint: ListViewScrollToItemDirectionHint, animated: Bool, highlight: Bool, displayLink: Bool, setupReply: Bool)
}
enum ChatHistoryViewUpdateType {
@ -413,7 +413,7 @@ private extension ChatHistoryLocationInput {
switch self.content {
case .Navigation(index: .upperBound, anchorIndex: .upperBound, count: _, highlight: _):
return true
case let .Scroll(subject, anchorIndex, _, _, _, _):
case let .Scroll(subject, anchorIndex, _, _, _, _, _):
if case .upperBound = anchorIndex, case .upperBound = subject.index {
return true
} else {
@ -874,7 +874,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
self.beginReadHistoryManagement()
if let subject = subject, case let .message(messageSubject, highlight, _) = subject {
if let subject = subject, case let .message(messageSubject, highlight, _, setupReply) = subject {
let initialSearchLocation: ChatHistoryInitialSearchLocation
switch messageSubject {
case let .id(id):
@ -887,9 +887,9 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
initialSearchLocation = .index(MessageIndex.absoluteUpperBound())
}
}
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: initialSearchLocation, quote: (highlight?.quote).flatMap { quote in MessageHistoryInitialSearchSubject.Quote(string: quote.string, offset: quote.offset) }), count: historyMessageCount, highlight: highlight != nil), id: 0)
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: initialSearchLocation, quote: (highlight?.quote).flatMap { quote in MessageHistoryInitialSearchSubject.Quote(string: quote.string, offset: quote.offset) }), count: historyMessageCount, highlight: highlight != nil, setupReply: setupReply), id: 0)
} else if let subject = subject, case let .pinnedMessages(maybeMessageId) = subject, let messageId = maybeMessageId {
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(messageId), quote: nil), count: historyMessageCount, highlight: true), id: 0)
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(messageId), quote: nil), count: historyMessageCount, highlight: true, setupReply: false), id: 0)
} else {
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Initial(count: historyMessageCount), id: 0)
}
@ -1220,7 +1220,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
}
if let resetScrollingMessageId {
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .message(resetScrollingMessageId.index), quote: nil), anchorIndex: .message(resetScrollingMessageId.index), sourceIndex: .message(resetScrollingMessageId.index), scrollPosition: .top(resetScrollingMessageId.offset), animated: false, highlight: false), id: (self.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0)
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .message(resetScrollingMessageId.index), quote: nil), anchorIndex: .message(resetScrollingMessageId.index), sourceIndex: .message(resetScrollingMessageId.index), scrollPosition: .top(resetScrollingMessageId.offset), animated: false, highlight: false, setupReply: false), id: (self.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0)
} else {
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Initial(count: historyMessageCount), id: (self.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0)
}
@ -1291,7 +1291,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
let scrollPosition: ChatHistoryViewScrollPosition?
if isFirstTime, let messageIndex = messages.first(where: { $0.id == at })?.index {
scrollPosition = .index(subject: MessageHistoryScrollToSubject(index: .message(messageIndex), quote: quote.flatMap { quote in MessageHistoryScrollToSubject.Quote(string: quote.text, offset: quote.offset) }), position: .center(.bottom), directionHint: .Down, animated: false, highlight: false, displayLink: false)
scrollPosition = .index(subject: MessageHistoryScrollToSubject(index: .message(messageIndex), quote: quote.flatMap { quote in MessageHistoryScrollToSubject.Quote(string: quote.text, offset: quote.offset) }), position: .center(.bottom), directionHint: .Down, animated: false, highlight: false, displayLink: false, setupReply: false)
isFirstTime = false
} else {
scrollPosition = nil
@ -1337,8 +1337,8 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
var scrollPositionValue: ChatHistoryViewScrollPosition?
if let location {
switch location.content {
case let .Scroll(subject, _, _, scrollPosition, animated, highlight):
scrollPositionValue = .index(subject: subject, position: scrollPosition, directionHint: .Up, animated: animated, highlight: highlight, displayLink: false)
case let .Scroll(subject, _, _, scrollPosition, animated, highlight, setupReply):
scrollPositionValue = .index(subject: subject, position: scrollPosition, directionHint: .Up, animated: animated, highlight: highlight, displayLink: false, setupReply: setupReply)
default:
break
}
@ -1673,7 +1673,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .message(anchorIndex), anchorIndex: .message(anchorIndex), count: historyMessageCount, highlight: false), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0)
}
} else {
if let subject = subject, case let .message(messageSubject, highlight, _) = subject {
if let subject = subject, case let .message(messageSubject, highlight, _, setupReply) = subject {
let initialSearchLocation: ChatHistoryInitialSearchLocation
switch messageSubject {
case let .id(id):
@ -1686,9 +1686,9 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
initialSearchLocation = .index(.absoluteUpperBound())
}
}
strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: initialSearchLocation, quote: (highlight?.quote).flatMap { quote in MessageHistoryInitialSearchSubject.Quote(string: quote.string, offset: quote.offset) }), 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).flatMap { quote in MessageHistoryInitialSearchSubject.Quote(string: quote.string, offset: quote.offset) }), count: historyMessageCount, highlight: highlight != nil, setupReply: setupReply), 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)
strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(messageId), quote: nil), count: historyMessageCount, highlight: true, setupReply: false), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0)
} else if var chatHistoryLocation = strongSelf.chatHistoryLocationValue {
chatHistoryLocation.id += 1
strongSelf.chatHistoryLocationValue = chatHistoryLocation
@ -1895,10 +1895,10 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
if scrollPosition == nil, let originalScrollPosition = originalScrollPosition {
switch originalScrollPosition {
case let .index(subject, position, _, _, highlight, displayLink):
case let .index(subject, position, _, _, highlight, displayLink, setupReply):
if case .upperBound = subject.index {
if let previous = previous, previous.filteredEntries.isEmpty {
updatedScrollPosition = .index(subject: subject, position: position, directionHint: .Down, animated: false, highlight: highlight, displayLink: displayLink)
updatedScrollPosition = .index(subject: subject, position: position, directionHint: .Down, animated: false, highlight: highlight, displayLink: displayLink, setupReply: setupReply)
}
}
default:
@ -1948,7 +1948,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
if let strongSelf = self, case .default = source {
strongSelf.toLang = translateToLanguage
if strongSelf.appliedScrollToMessageId == nil, let scrollToMessageId = scrollToMessageId {
updatedScrollPosition = .index(subject: MessageHistoryScrollToSubject(index: .message(scrollToMessageId), quote: nil), position: .center(.top), directionHint: .Up, animated: true, highlight: false, displayLink: true)
updatedScrollPosition = .index(subject: MessageHistoryScrollToSubject(index: .message(scrollToMessageId), quote: nil), position: .center(.top), directionHint: .Up, animated: true, highlight: false, displayLink: true, setupReply: false)
scrollAnimationCurve = .Spring(duration: 0.4)
} else {
let wasPlaying = strongSelf.appliedPlayingMessageId != nil
@ -1978,7 +1978,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
}
})
if currentIsVisible && nextIsVisible && currentlyPlayingVideo {
updatedScrollPosition = .index(subject: MessageHistoryScrollToSubject(index: .message(currentlyPlayingMessageId), quote: nil), position: .center(.bottom), directionHint: .Up, animated: true, highlight: true, displayLink: true)
updatedScrollPosition = .index(subject: MessageHistoryScrollToSubject(index: .message(currentlyPlayingMessageId), quote: nil), position: .center(.bottom), directionHint: .Up, animated: true, highlight: true, displayLink: true, setupReply: false)
scrollAnimationCurve = .Spring(duration: 0.4)
}
}
@ -2040,7 +2040,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
}
if fillsScreen, let firstNonAdIndex = firstNonAdIndex, previousNumAds == 0, updatedNumAds != 0 {
updatedScrollPosition = .index(subject: MessageHistoryScrollToSubject(index: .message(firstNonAdIndex), quote: nil), position: .top(0.0), directionHint: .Up, animated: false, highlight: false, displayLink: false)
updatedScrollPosition = .index(subject: MessageHistoryScrollToSubject(index: .message(firstNonAdIndex), quote: nil), position: .top(0.0), directionHint: .Up, animated: false, highlight: false, displayLink: false, setupReply: false)
disableAnimations = true
}
}
@ -2064,7 +2064,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
if case let .MessageEntry(message, _, _, _, _, _) = entry {
if message.adAttribute == nil {
if let action = message.media.first(where: { $0 is TelegramMediaAction }) as? TelegramMediaAction, case .joinedChannel = action.action {
updatedScrollPosition = .index(subject: MessageHistoryScrollToSubject(index: .message(message.index), quote: nil), position: .top(0.0), directionHint: .Up, animated: true, highlight: false, displayLink: false)
updatedScrollPosition = .index(subject: MessageHistoryScrollToSubject(index: .message(message.index), quote: nil), position: .top(0.0), directionHint: .Up, animated: true, highlight: false, displayLink: false, setupReply: false)
}
break
}
@ -3124,7 +3124,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
currentMessage = messages.first?.0
}
if let message = currentMessage, let _ = self.anchorMessageInCurrentHistoryView() {
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .message(message.index), quote: nil), anchorIndex: .message(message.index), sourceIndex: .upperBound, scrollPosition: .bottom(0.0), animated: true, highlight: false), id: self.takeNextHistoryLocationId())
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .message(message.index), quote: nil), anchorIndex: .message(message.index), sourceIndex: .upperBound, scrollPosition: .bottom(0.0), animated: true, highlight: false, setupReply: false), id: self.takeNextHistoryLocationId())
}
}
}
@ -3153,14 +3153,14 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
}
if let currentMessage = currentMessage {
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .message(currentMessage.index), quote: nil), anchorIndex: .message(currentMessage.index), sourceIndex: .upperBound, scrollPosition: .top(0.0), animated: true, highlight: true), id: self.takeNextHistoryLocationId())
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .message(currentMessage.index), quote: nil), anchorIndex: .message(currentMessage.index), sourceIndex: .upperBound, scrollPosition: .top(0.0), animated: true, highlight: true, setupReply: false), id: self.takeNextHistoryLocationId())
}
}
}
public func scrollToStartOfHistory() {
self.beganDragging?()
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .lowerBound, quote: nil), anchorIndex: .lowerBound, sourceIndex: .upperBound, scrollPosition: .bottom(0.0), animated: true, highlight: false), id: self.takeNextHistoryLocationId())
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .lowerBound, quote: nil), anchorIndex: .lowerBound, sourceIndex: .upperBound, scrollPosition: .bottom(0.0), animated: true, highlight: false, setupReply: false), id: self.takeNextHistoryLocationId())
}
public func scrollToEndOfHistory() {
@ -3169,13 +3169,13 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
case let .known(value) where value <= CGFloat.ulpOfOne:
break
default:
let locationInput = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .upperBound, quote: nil), anchorIndex: .upperBound, sourceIndex: .lowerBound, scrollPosition: .top(0.0), animated: true, highlight: false), id: self.takeNextHistoryLocationId())
let locationInput = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .upperBound, quote: nil), anchorIndex: .upperBound, sourceIndex: .lowerBound, scrollPosition: .top(0.0), animated: true, highlight: false, setupReply: false), id: self.takeNextHistoryLocationId())
self.chatHistoryLocationValue = locationInput
}
}
public func scrollToMessage(from fromIndex: MessageIndex, to toIndex: MessageIndex, animated: Bool, highlight: Bool = true, quote: (string: String, offset: Int?)? = nil, scrollPosition: ListViewScrollPosition = .center(.bottom)) {
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .message(toIndex), quote: quote.flatMap { quote in MessageHistoryScrollToSubject.Quote(string: quote.string, offset: quote.offset) }), anchorIndex: .message(toIndex), sourceIndex: .message(fromIndex), scrollPosition: scrollPosition, animated: animated, highlight: highlight), id: self.takeNextHistoryLocationId())
public func scrollToMessage(from fromIndex: MessageIndex, to toIndex: MessageIndex, animated: Bool, highlight: Bool = true, quote: (string: String, offset: Int?)? = nil, scrollPosition: ListViewScrollPosition = .center(.bottom), setupReply: Bool = false) {
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .message(toIndex), quote: quote.flatMap { quote in MessageHistoryScrollToSubject.Quote(string: quote.string, offset: quote.offset) }, setupReply: setupReply), anchorIndex: .message(toIndex), sourceIndex: .message(fromIndex), scrollPosition: scrollPosition, animated: animated, highlight: highlight, setupReply: setupReply), id: self.takeNextHistoryLocationId())
}
public func anchorMessageInCurrentHistoryView() -> Message? {

View File

@ -55,9 +55,9 @@ func chatHistoryViewForLocation(
if scheduled {
var first = true
var chatScrollPosition: ChatHistoryViewScrollPosition?
if case let .Scroll(subject, _, sourceIndex, position, animated, highlight) = location.content {
if case let .Scroll(subject, _, sourceIndex, position, animated, highlight, setupReply) = location.content {
let directionHint: ListViewScrollToItemDirectionHint = sourceIndex > subject.index ? .Down : .Up
chatScrollPosition = .index(subject: subject, position: position, directionHint: directionHint, animated: animated, highlight: highlight, displayLink: false)
chatScrollPosition = .index(subject: subject, position: position, directionHint: directionHint, animated: animated, highlight: highlight, displayLink: false, setupReply: setupReply)
}
return account.viewTracker.scheduledMessagesViewForLocation(context.chatLocationInput(for: chatLocation, contextHolder: chatLocationContextHolder), additionalData: additionalData)
|> map { view, updateType, initialData -> ChatHistoryViewUpdate in
@ -165,7 +165,7 @@ func chatHistoryViewForLocation(
if tag == nil, case let .replyThread(message) = chatLocation, message.isForumPost, view.maxReadIndex == nil {
if case let .message(index) = view.anchorIndex {
scrollPosition = .index(subject: MessageHistoryScrollToSubject(index: .message(index), quote: nil), position: .bottom(0.0), directionHint: .Up, animated: false, highlight: false, displayLink: false)
scrollPosition = .index(subject: MessageHistoryScrollToSubject(index: .message(index), quote: nil), position: .bottom(0.0), directionHint: .Up, animated: false, highlight: false, displayLink: false, setupReply: false)
}
}
@ -227,7 +227,7 @@ func chatHistoryViewForLocation(
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(searchLocationSubject, count, highlight):
case let .InitialSearch(searchLocationSubject, count, highlight, setupReply):
var preloaded = false
var fadeIn = false
@ -280,7 +280,7 @@ func chatHistoryViewForLocation(
preloaded = true
return .HistoryView(view: view, type: reportUpdateType, scrollPosition: .index(subject: MessageHistoryScrollToSubject(index: anchorIndex, quote: searchLocationSubject.quote.flatMap { quote in MessageHistoryScrollToSubject.Quote(string: quote.string, offset: quote.offset) }), position: .center(.bottom), directionHint: .Down, animated: false, highlight: highlight, displayLink: 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(subject: MessageHistoryScrollToSubject(index: anchorIndex, quote: searchLocationSubject.quote.flatMap { quote in MessageHistoryScrollToSubject.Quote(string: quote.string, offset: quote.offset) }, setupReply: setupReply), position: .center(.bottom), directionHint: .Down, animated: false, highlight: highlight, displayLink: false, setupReply: setupReply), 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, _):
@ -297,9 +297,9 @@ func chatHistoryViewForLocation(
}
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(subject, anchorIndex, sourceIndex, scrollPosition, animated, highlight):
case let .Scroll(subject, anchorIndex, sourceIndex, scrollPosition, animated, highlight, setupReply):
let directionHint: ListViewScrollToItemDirectionHint = sourceIndex > subject.index ? .Down : .Up
let chatScrollPosition = ChatHistoryViewScrollPosition.index(subject: subject, position: scrollPosition, directionHint: directionHint, animated: animated, highlight: highlight, displayLink: false)
let chatScrollPosition = ChatHistoryViewScrollPosition.index(subject: subject, position: scrollPosition, directionHint: directionHint, animated: animated, highlight: highlight, displayLink: false, setupReply: setupReply)
var first = true
return account.viewTracker.aroundMessageHistoryViewForLocation(context.chatLocationInput(for: chatLocation, contextHolder: chatLocationContextHolder), ignoreMessagesInTimestampRange: ignoreMessagesInTimestampRange, ignoreMessageIds: ignoreMessageIds, index: subject.index, anchorIndex: anchorIndex, count: 128, ignoreRelatedChats: ignoreRelatedChats, fixedCombinedReadStates: fixedCombinedReadStates, tag: tag, appendMessagesFromTheSameGroup: appendMessagesFromTheSameGroup, orderStatistics: orderStatistics, additionalData: additionalData, useRootInterfaceStateForThread: useRootInterfaceStateForThread)
|> map { view, updateType, initialData -> ChatHistoryViewUpdate in
@ -413,7 +413,7 @@ func fetchAndPreloadReplyThreadInfo(context: AccountContext, subject: ReplyThrea
case .automatic:
if let atMessageId = atMessageId {
input = ChatHistoryLocationInput(
content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(atMessageId), quote: nil), count: 40, highlight: true),
content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(atMessageId), quote: nil), count: 40, highlight: true, setupReply: false),
id: 0
)
} else {

View File

@ -1767,7 +1767,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
guard let peer = messages[0].peers[messages[0].id.peerId] else {
return
}
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(EnginePeer(peer)), subject: .message(id: .id(messages[0].id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil), useExisting: true))
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(EnginePeer(peer)), subject: .message(id: .id(messages[0].id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false), useExisting: true))
})
})))
}

View File

@ -267,7 +267,7 @@ class ChatSearchResultsControllerNode: ViewControllerTracingNode, ASScrollViewDe
switch item.content {
case let .peer(peerData):
if let message = peerData.messages.first {
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerData.peer.peerId), subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil), botStart: nil, mode: .standard(.previewing), params: nil)
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerData.peer.peerId), subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false), botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
let contextController = ContextController(presentationData: strongSelf.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: .single(ContextController.Items(content: .list([]))), gesture: gesture)
presentInGlobalOverlay(contextController)

View File

@ -121,11 +121,11 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam
controller.updateTextInputState(updateTextInputState)
}
var popAndComplete = true
if let subject = params.subject, case let .message(messageSubject, highlight, timecode) = subject {
if let subject = params.subject, case let .message(messageSubject, highlight, timecode, setupReply) = subject {
if case let .id(messageId) = messageSubject {
let navigationController = params.navigationController
let animated = params.animated
controller.navigateToMessage(messageLocation: .id(messageId, NavigateToMessageParams(timestamp: timecode, quote: (highlight?.quote).flatMap { quote in NavigateToMessageParams.Quote(string: quote.string, offset: quote.offset) })), animated: isFirst, completion: { [weak navigationController, weak controller] in
controller.navigateToMessage(messageLocation: .id(messageId, NavigateToMessageParams(timestamp: timecode, quote: (highlight?.quote).flatMap { quote in NavigateToMessageParams.Quote(string: quote.string, offset: quote.offset) }, setupReply: setupReply)), animated: isFirst, completion: { [weak navigationController, weak controller] in
if let navigationController = navigationController, let controller = controller {
let _ = navigationController.popToViewController(controller, animated: animated)
}
@ -373,7 +373,7 @@ public func navigateToForumThreadImpl(context: AccountContext, peerId: EnginePee
context: context,
chatLocation: .replyThread(result.message),
chatLocationContextHolder: result.contextHolder,
subject: messageId.flatMap { .message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil) },
subject: messageId.flatMap { .message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false) },
activateInput: actualActivateInput,
keepStack: keepStack,
scrollToEndIfExists: scrollToEndIfExists,

View File

@ -207,7 +207,7 @@ func openResolvedUrlImpl(
dismissInput()
navigationController?.pushViewController(controller)
case let .channelMessage(peer, messageId, timecode):
openPeer(EnginePeer(peer), .chat(textInputState: nil, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: timecode), peekData: nil))
openPeer(EnginePeer(peer), .chat(textInputState: nil, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: timecode, setupReply: false), peekData: nil))
case let .replyThreadMessage(replyThreadMessage, messageId):
if let navigationController = navigationController, let effectiveMessageId = replyThreadMessage.effectiveMessageId {
let _ = ChatControllerImpl.openMessageReplies(context: context, navigationController: navigationController, present: { c, a in
@ -1076,7 +1076,7 @@ func openResolvedUrlImpl(
guard let peer else {
return
}
openPeer(peer, .chat(textInputState: nil, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil), peekData: nil))
openPeer(peer, .chat(textInputState: nil, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false), peekData: nil))
if case let .chat(peerId, _, _) = urlContext, peerId == messageId.peerId {
dismissImpl?()
}

View File

@ -223,7 +223,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, ASGestu
self.isGlobalSearch = false
}
self.historyNode = ChatHistoryListNodeImpl(context: context, updatedPresentationData: (context.sharedContext.currentPresentationData.with({ $0 }), context.sharedContext.presentationData), chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, tag: .tag(tagMask), source: source, subject: .message(id: .id(initialMessageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, reverseGroups: !self.currentIsReversed, displayHeaders: .none, hintLinks: false, isGlobalSearch: self.isGlobalSearch), isChatPreview: false, messageTransitionNode: { return nil })
self.historyNode = ChatHistoryListNodeImpl(context: context, updatedPresentationData: (context.sharedContext.currentPresentationData.with({ $0 }), context.sharedContext.presentationData), chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, tag: .tag(tagMask), source: source, subject: .message(id: .id(initialMessageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, reverseGroups: !self.currentIsReversed, displayHeaders: .none, hintLinks: false, isGlobalSearch: self.isGlobalSearch), isChatPreview: false, messageTransitionNode: { return nil })
self.historyNode.clipsToBounds = true
super.init()
@ -565,7 +565,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, ASGestu
}
let chatLocationContextHolder = Atomic<ChatLocationContextHolder?>(value: nil)
let historyNode = ChatHistoryListNodeImpl(context: self.context, updatedPresentationData: (self.context.sharedContext.currentPresentationData.with({ $0 }), self.context.sharedContext.presentationData), chatLocation: self.chatLocation, chatLocationContextHolder: chatLocationContextHolder, tag: .tag(tagMask), source: .default, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, reverseGroups: !self.currentIsReversed, displayHeaders: .none, hintLinks: false, isGlobalSearch: self.isGlobalSearch), isChatPreview: false, messageTransitionNode: { return nil })
let historyNode = ChatHistoryListNodeImpl(context: self.context, updatedPresentationData: (self.context.sharedContext.currentPresentationData.with({ $0 }), self.context.sharedContext.presentationData), chatLocation: self.chatLocation, chatLocationContextHolder: chatLocationContextHolder, tag: .tag(tagMask), source: .default, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, reverseGroups: !self.currentIsReversed, displayHeaders: .none, hintLinks: false, isGlobalSearch: self.isGlobalSearch), isChatPreview: false, messageTransitionNode: { return nil })
historyNode.clipsToBounds = true
historyNode.preloadPages = true
historyNode.stackFromBottom = true

View File

@ -194,7 +194,7 @@ func preparedChatHistoryViewTransition(from fromView: ChatHistoryView?, to toVie
index += 1
}
}
case let .index(scrollSubject, position, directionHint, animated, highlight, displayLink):
case let .index(scrollSubject, position, directionHint, animated, highlight, displayLink, _):
let scrollIndex = scrollSubject
var position = position
if case .center = position, highlight {

View File

@ -72,7 +72,7 @@ func handleTextLinkActionImpl(context: AccountContext, peerId: EnginePeer.Id?, n
openResolvedPeerImpl(EnginePeer(peer), .withBotStartPayload(ChatControllerInitialBotStart(payload: payload, behavior: .interactive)))
case let .channelMessage(peer, messageId, timecode):
if let navigationController = controller.navigationController as? NavigationController {
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(EnginePeer(peer)), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: timecode)))
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(EnginePeer(peer)), subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: timecode, setupReply: false)))
}
case let .replyThreadMessage(replyThreadMessage, messageId):
if let navigationController = controller.navigationController as? NavigationController, let effectiveMessageId = replyThreadMessage.effectiveMessageId {

View File

@ -924,7 +924,7 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl)
return .result(.replyThreadMessage(replyThreadMessage: result, messageId: messageId))
})
} else {
return .single(.result(.peer(foundPeer._asPeer(), .chat(textInputState: nil, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: timecode), peekData: nil))))
return .single(.result(.peer(foundPeer._asPeer(), .chat(textInputState: nil, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: timecode, setupReply: false), peekData: nil))))
}
} else {
return .single(.result(.inaccessiblePeer))