diff --git a/submodules/AccountContext/Sources/ChatListController.swift b/submodules/AccountContext/Sources/ChatListController.swift index 83360ec5c5..e46041d20e 100644 --- a/submodules/AccountContext/Sources/ChatListController.swift +++ b/submodules/AccountContext/Sources/ChatListController.swift @@ -6,7 +6,7 @@ import TelegramCore public enum ChatListControllerLocation: Equatable { case chatList(groupId: EngineChatList.Group) case forum(peerId: EnginePeer.Id) - case savedMessagesChats + case savedMessagesChats(peerId: EnginePeer.Id) } public protocol ChatListController: ViewController { diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index 052e707e58..3a0b455703 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -1030,9 +1030,20 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController guard let self else { return } - let _ = (self.context.account.postbox.combinedView(keys: [.cachedPeerData(peerId: peer.id)]) - |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] combinedView in + + var forumSourcePeer: Signal = .single(nil) + if case let .savedMessagesChats(peerId) = self.location, peerId != self.context.account.peerId { + forumSourcePeer = self.context.engine.data.get( + TelegramEngine.EngineData.Item.Peer.Peer(id: peerId) + ) + } + + let _ = (combineLatest(queue: .mainQueue(), + self.context.account.postbox.combinedView(keys: [.cachedPeerData(peerId: peer.id)]) + |> take(1), + forumSourcePeer + ) + |> deliverOnMainQueue).start(next: { [weak self] combinedView, forumSourcePeer in guard let self, let cachedDataView = combinedView.views[.cachedPeerData(peerId: peer.id)] as? CachedPeerDataView else { return } @@ -1040,19 +1051,30 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController return } + var peer = peer + var threadId = threadId + if let forumSourcePeer { + threadId = peer.id.toInt64() + peer = forumSourcePeer + } + var scrollToEndIfExists = false if let layout = self.validLayout, case .regular = layout.metrics.widthClass { scrollToEndIfExists = true } var openAsInlineForum = true - if let cachedData = cachedDataView.cachedPeerData as? CachedChannelData, case let .known(viewForumAsMessages) = cachedData.viewForumAsMessages, viewForumAsMessages { + + if case let .channel(channel) = peer, channel.flags.contains(.isMonoforum) { openAsInlineForum = false + } else { + if let cachedData = cachedDataView.cachedPeerData as? CachedChannelData, case let .known(viewForumAsMessages) = cachedData.viewForumAsMessages, viewForumAsMessages { + openAsInlineForum = false + } } if openAsInlineForum, case let .channel(channel) = peer, channel.flags.contains(.isForum), threadId == nil { self.chatListDisplayNode.clearHighlightAnimated(true) - if self.chatListDisplayNode.inlineStackContainerNode?.location == .forum(peerId: channel.id) { self.setInlineChatList(location: nil) } else { @@ -1062,7 +1084,28 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController } if case let .channel(channel) = peer, channel.flags.contains(.isForum), let threadId { - let _ = self.context.sharedContext.navigateToForumThread(context: self.context, peerId: peer.id, threadId: threadId, messageId: nil, navigationController: navigationController, activateInput: nil, scrollToEndIfExists: scrollToEndIfExists, keepStack: .never).startStandalone() + self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams( + navigationController: navigationController, + context: self.context, + chatLocation: .replyThread(ChatReplyThreadMessage( + peerId: peer.id, + threadId: threadId, + channelMessageId: nil, + isChannelPost: false, + isForumPost: true, + isMonoforum: channel.flags.contains(.isMonoforum), + maxMessage: nil, + maxReadIncomingMessageId: nil, + maxReadOutgoingMessageId: nil, + unreadCount: 0, + initialFilledHoles: IndexSet(), + initialAnchor: .automatic, + isNotAvailable: false + )), + subject: nil, + keepStack: .always + )) + self.chatListDisplayNode.clearHighlightAnimated(true) } else { var navigationAnimationOptions: NavigationAnimationOptions = [] @@ -1476,7 +1519,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController if let threadId = threadId { let source: ContextContentSource let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .replyThread(message: ChatReplyThreadMessage( - peerId: peer.peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false + peerId: peer.peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false )), subject: nil, botStart: nil, mode: .standard(.previewing), params: nil) chatController.canReadHistory.set(false) source = .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController)) @@ -1545,7 +1588,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController } let source: ContextContentSource let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .replyThread(message: ChatReplyThreadMessage( - peerId: peer.peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false + peerId: peer.peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false )), subject: nil, botStart: nil, mode: .standard(.previewing), params: nil) chatController.canReadHistory.set(false) source = .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController)) diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index 7205b7d450..9a884915cf 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -3137,7 +3137,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { } if case let .peer(peerData) = item.content, peerData.customMessageListData?.hidePeerStatus == true { currentCredibilityIconContent = nil - } else if case .savedMessagesChats = item.chatListLocation, peer.id == item.context.account.peerId { + } else if case let .savedMessagesChats(peerId) = item.chatListLocation, peer.id == peerId { currentCredibilityIconContent = nil } else if peer.isScam { currentCredibilityIconContent = .text(color: item.presentationData.theme.chat.message.incoming.scamColor, string: item.presentationData.strings.Message_ScamAccount.uppercased()) @@ -3273,6 +3273,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { var isFirstForumThreadSelectable = false var forumThreads: [(id: Int64, title: NSAttributedString, iconId: Int64?, iconColor: Int32)] = [] if case .savedMessagesChats = item.chatListLocation { + } else if case let .peer(peer) = item.content, case let .channel(channel) = peer.peer.peer, channel.flags.contains(.isMonoforum) { } else if forumThread != nil || !topForumTopicItems.isEmpty { if let forumThread = forumThread { isFirstForumThreadSelectable = forumThread.isUnread diff --git a/submodules/ChatListUI/Sources/Node/ChatListNode.swift b/submodules/ChatListUI/Sources/Node/ChatListNode.swift index 5f679acdc0..b0d0a5b92a 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNode.swift @@ -1535,9 +1535,9 @@ public final class ChatListNode: ListView { } } }, setItemPinned: { [weak self] itemId, _ in - if case .savedMessagesChats = location { + if case let .savedMessagesChats(peerId) = location { if case let .peer(itemPeerId) = itemId { - let _ = (context.engine.peers.toggleForumChannelTopicPinned(id: context.account.peerId, threadId: itemPeerId.toInt64()) + let _ = (context.engine.peers.toggleForumChannelTopicPinned(id: peerId, threadId: itemPeerId.toInt64()) |> deliverOnMainQueue).start(error: { error in guard let self else { return diff --git a/submodules/ChatListUI/Sources/Node/ChatListNodeLocation.swift b/submodules/ChatListUI/Sources/Node/ChatListNodeLocation.swift index 7b67cae1b2..dea1d3d354 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNodeLocation.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNodeLocation.swift @@ -319,9 +319,9 @@ func chatListViewForLocation(chatListLocation: ChatListControllerLocation, locat isFirst = false return ChatListNodeViewUpdate(list: list, type: type, scrollPosition: nil) } - case .savedMessagesChats: - let viewKey: PostboxViewKey = .savedMessagesIndex(peerId: account.peerId) - let interfaceStateKey: PostboxViewKey = .chatInterfaceState(peerId: account.peerId) + case let .savedMessagesChats(peerId): + let viewKey: PostboxViewKey = .savedMessagesIndex(peerId: peerId) + let interfaceStateKey: PostboxViewKey = .chatInterfaceState(peerId: peerId) var isFirst = true return account.postbox.combinedView(keys: [viewKey, interfaceStateKey]) diff --git a/submodules/TelegramApi/Sources/Api38.swift b/submodules/TelegramApi/Sources/Api38.swift index d01310f41a..8459b8722e 100644 --- a/submodules/TelegramApi/Sources/Api38.swift +++ b/submodules/TelegramApi/Sources/Api38.swift @@ -6833,16 +6833,17 @@ public extension Api.functions.messages { } } public extension Api.functions.messages { - static func getSavedDialogs(flags: Int32, offsetDate: Int32, offsetId: Int32, offsetPeer: Api.InputPeer, limit: Int32, hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func getSavedDialogs(flags: Int32, parentPeer: Api.InputPeer?, offsetDate: Int32, offsetId: Int32, offsetPeer: Api.InputPeer, limit: Int32, hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(1401016858) + buffer.appendInt32(512883865) serializeInt32(flags, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 1) != 0 {parentPeer!.serialize(buffer, true)} serializeInt32(offsetDate, buffer: buffer, boxed: false) serializeInt32(offsetId, buffer: buffer, boxed: false) offsetPeer.serialize(buffer, true) serializeInt32(limit, buffer: buffer, boxed: false) serializeInt64(hash, buffer: buffer, boxed: false) - return (FunctionDescription(name: "messages.getSavedDialogs", parameters: [("flags", String(describing: flags)), ("offsetDate", String(describing: offsetDate)), ("offsetId", String(describing: offsetId)), ("offsetPeer", String(describing: offsetPeer)), ("limit", String(describing: limit)), ("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.SavedDialogs? in + return (FunctionDescription(name: "messages.getSavedDialogs", parameters: [("flags", String(describing: flags)), ("parentPeer", String(describing: parentPeer)), ("offsetDate", String(describing: offsetDate)), ("offsetId", String(describing: offsetId)), ("offsetPeer", String(describing: offsetPeer)), ("limit", String(describing: limit)), ("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.SavedDialogs? in let reader = BufferReader(buffer) var result: Api.messages.SavedDialogs? if let signature = reader.readInt32() { @@ -6868,9 +6869,11 @@ public extension Api.functions.messages { } } public extension Api.functions.messages { - static func getSavedHistory(peer: Api.InputPeer, offsetId: Int32, offsetDate: Int32, addOffset: Int32, limit: Int32, maxId: Int32, minId: Int32, hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func getSavedHistory(flags: Int32, parentPeer: Api.InputPeer?, peer: Api.InputPeer, offsetId: Int32, offsetDate: Int32, addOffset: Int32, limit: Int32, maxId: Int32, minId: Int32, hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(1033519437) + buffer.appendInt32(-1718964215) + serializeInt32(flags, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 0) != 0 {parentPeer!.serialize(buffer, true)} peer.serialize(buffer, true) serializeInt32(offsetId, buffer: buffer, boxed: false) serializeInt32(offsetDate, buffer: buffer, boxed: false) @@ -6879,7 +6882,7 @@ public extension Api.functions.messages { serializeInt32(maxId, buffer: buffer, boxed: false) serializeInt32(minId, buffer: buffer, boxed: false) serializeInt64(hash, buffer: buffer, boxed: false) - return (FunctionDescription(name: "messages.getSavedHistory", parameters: [("peer", String(describing: peer)), ("offsetId", String(describing: offsetId)), ("offsetDate", String(describing: offsetDate)), ("addOffset", String(describing: addOffset)), ("limit", String(describing: limit)), ("maxId", String(describing: maxId)), ("minId", String(describing: minId)), ("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.Messages? in + return (FunctionDescription(name: "messages.getSavedHistory", parameters: [("flags", String(describing: flags)), ("parentPeer", String(describing: parentPeer)), ("peer", String(describing: peer)), ("offsetId", String(describing: offsetId)), ("offsetDate", String(describing: offsetDate)), ("addOffset", String(describing: addOffset)), ("limit", String(describing: limit)), ("maxId", String(describing: maxId)), ("minId", String(describing: minId)), ("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.Messages? in let reader = BufferReader(buffer) var result: Api.messages.Messages? if let signature = reader.readInt32() { diff --git a/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift b/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift index 27ee6e65f7..0726313806 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift @@ -802,7 +802,7 @@ extension StoreMessage { } } - if peerId == accountPeerId, let savedPeerId = savedPeerId { + if let savedPeerId { threadId = savedPeerId.peerId.toInt64() } diff --git a/submodules/TelegramCore/Sources/ForumChannels.swift b/submodules/TelegramCore/Sources/ForumChannels.swift index 8b8a9fccce..865f85b9ff 100644 --- a/submodules/TelegramCore/Sources/ForumChannels.swift +++ b/submodules/TelegramCore/Sources/ForumChannels.swift @@ -684,218 +684,105 @@ public func _internal_fillSavedMessageHistory(accountPeerId: PeerId, postbox: Po } func _internal_requestMessageHistoryThreads(accountPeerId: PeerId, postbox: Postbox, network: Network, peerId: PeerId, query: String?, offsetIndex: StoredPeerThreadCombinedState.Index?, limit: Int) -> Signal { - if peerId == accountPeerId { - var flags: Int32 = 0 - flags = 0 + return postbox.transaction { transaction -> Peer? in + return transaction.getPeer(peerId) + } + |> castError(LoadMessageHistoryThreadsError.self) + |> mapToSignal { peer -> Signal in + guard let peer else { + return .fail(.generic) + } - var offsetDate: Int32 = 0 - var offsetId: Int32 = 0 - var offsetPeer: Api.InputPeer = .inputPeerEmpty - if let offsetIndex = offsetIndex { - offsetDate = offsetIndex.timestamp - offsetId = offsetIndex.messageId - //TODO:api - offsetPeer = .inputPeerEmpty + var isSavedThreads = false + if peer.id == accountPeerId { + isSavedThreads = true + } else if let channel = peer as? TelegramChannel, channel.flags.contains(.isMonoforum) { + isSavedThreads = true } - let signal: Signal = network.request(Api.functions.messages.getSavedDialogs( - flags: flags, - offsetDate: offsetDate, - offsetId: offsetId, - offsetPeer: offsetPeer, - limit: Int32(limit), - hash: 0 - )) - |> `catch` { error -> Signal in - if error.errorDescription == "SAVED_DIALOGS_UNSUPPORTED" { - return .never() - } else { - return .fail(.generic) - } - } - |> mapToSignal { result -> Signal in - switch result { - case .savedDialogs(let dialogs, let messages, let chats, let users), .savedDialogsSlice(_, let dialogs, let messages, let chats, let users): - var items: [LoadMessageHistoryThreadsResult.Item] = [] - var pinnedIds: [Int64] = [] - - let addedMessages = messages.compactMap { message -> StoreMessage? in - return StoreMessage(apiMessage: message, accountPeerId: accountPeerId, peerIsForum: false) - } - - var minIndex: StoredPeerThreadCombinedState.Index? - - for dialog in dialogs { - switch dialog { - case let .savedDialog(flags, peer, topMessage): - if (flags & (1 << 2)) != 0 { - pinnedIds.append(peer.peerId.toInt64()) - } - - let data = MessageHistoryThreadData( - creationDate: 0, - isOwnedByMe: true, - author: peer.peerId, - info: EngineMessageHistoryThread.Info( - title: "", - icon: nil, - iconColor: 0 - ), - incomingUnreadCount: 0, - maxIncomingReadId: 0, - maxKnownMessageId: topMessage, - maxOutgoingReadId: 0, - isClosed: false, - isHidden: false, - notificationSettings: TelegramPeerNotificationSettings.defaultSettings - ) - - var topTimestamp: Int32 = 1 - for message in addedMessages { - if message.id.peerId == peerId && message.threadId == peer.peerId.toInt64() { - topTimestamp = max(topTimestamp, message.timestamp) - } - } - - let topicIndex = StoredPeerThreadCombinedState.Index(timestamp: topTimestamp, threadId: peer.peerId.toInt64(), messageId: topMessage) - if let minIndexValue = minIndex { - if topicIndex < minIndexValue { - minIndex = topicIndex - } - } else { - minIndex = topicIndex - } - - items.append(LoadMessageHistoryThreadsResult.Item( - threadId: peer.peerId.toInt64(), - data: data, - topMessage: topMessage, - unreadMentionsCount: 0, - unreadReactionsCount: 0, - index: topicIndex - )) - } - } - - var pinnedThreadIds: [Int64]? - if offsetIndex == nil { - pinnedThreadIds = pinnedIds - } - - var nextIndex: StoredPeerThreadCombinedState.Index - if dialogs.count != 0 { - nextIndex = minIndex ?? StoredPeerThreadCombinedState.Index(timestamp: 0, threadId: 0, messageId: 1) - } else { - nextIndex = StoredPeerThreadCombinedState.Index(timestamp: 0, threadId: 0, messageId: 1) - } - if let offsetIndex = offsetIndex, nextIndex == offsetIndex { - nextIndex = StoredPeerThreadCombinedState.Index(timestamp: 0, threadId: 0, messageId: 1) - } - - let combinedState = PeerThreadCombinedState(validIndexBoundary: nextIndex) - - return .single(LoadMessageHistoryThreadsResult( - peerId: peerId, - items: items, - messages: addedMessages, - pinnedThreadIds: pinnedThreadIds, - combinedState: combinedState, - users: users, - chats: chats - )) - case .savedDialogsNotModified: - return .complete() - } - } - return signal - } else { - let signal: Signal = postbox.transaction { transaction -> Api.InputChannel? in - guard let channel = transaction.getPeer(peerId) as? TelegramChannel else { - return nil - } - if !channel.flags.contains(.isForum) { - return nil - } - return apiInputChannel(channel) - } - |> castError(LoadMessageHistoryThreadsError.self) - |> mapToSignal { inputChannel -> Signal in - guard let inputChannel = inputChannel else { - return .fail(.generic) - } + + if isSavedThreads { var flags: Int32 = 0 - - if query != nil { - flags |= 1 << 0 - } + flags = 0 var offsetDate: Int32 = 0 var offsetId: Int32 = 0 - var offsetTopic: Int32 = 0 + var offsetPeer: Api.InputPeer = .inputPeerEmpty if let offsetIndex = offsetIndex { offsetDate = offsetIndex.timestamp offsetId = offsetIndex.messageId - offsetTopic = Int32(clamping: offsetIndex.threadId) + offsetPeer = .inputPeerEmpty } - let signal: Signal = network.request(Api.functions.channels.getForumTopics( + + var parentPeer: Api.InputPeer? + if peerId != accountPeerId { + guard let inputChannel = apiInputPeer(peer) else { + return .fail(.generic) + } + flags |= 1 << 1 + parentPeer = inputChannel + } + + let signal: Signal = network.request(Api.functions.messages.getSavedDialogs( flags: flags, - channel: inputChannel, - q: query, + parentPeer: parentPeer, offsetDate: offsetDate, offsetId: offsetId, - offsetTopic: offsetTopic, - limit: Int32(limit) + offsetPeer: offsetPeer, + limit: Int32(limit), + hash: 0 )) - |> mapError { _ -> LoadMessageHistoryThreadsError in - return .generic + |> `catch` { error -> Signal in + if error.errorDescription == "SAVED_DIALOGS_UNSUPPORTED" { + return .never() + } else { + return .fail(.generic) + } } |> mapToSignal { result -> Signal in switch result { - case let .forumTopics(_, _, topics, messages, chats, users, pts): + case .savedDialogs(let dialogs, let messages, let chats, let users), .savedDialogsSlice(_, let dialogs, let messages, let chats, let users): var items: [LoadMessageHistoryThreadsResult.Item] = [] var pinnedIds: [Int64] = [] let addedMessages = messages.compactMap { message -> StoreMessage? in - return StoreMessage(apiMessage: message, accountPeerId: accountPeerId, peerIsForum: true) + return StoreMessage(apiMessage: message, accountPeerId: accountPeerId, peerIsForum: false) } - let _ = pts var minIndex: StoredPeerThreadCombinedState.Index? - for topic in topics { - switch topic { - case let .forumTopic(flags, id, date, title, iconColor, iconEmojiId, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, unreadReactionsCount, fromId, notifySettings, draft): - let _ = draft - - if (flags & (1 << 3)) != 0 { - pinnedIds.append(Int64(id)) + for dialog in dialogs { + switch dialog { + case let .savedDialog(flags, peer, topMessage): + if (flags & (1 << 2)) != 0 { + pinnedIds.append(peer.peerId.toInt64()) } let data = MessageHistoryThreadData( - creationDate: date, - isOwnedByMe: (flags & (1 << 1)) != 0, - author: fromId.peerId, + creationDate: 0, + isOwnedByMe: true, + author: peer.peerId, info: EngineMessageHistoryThread.Info( - title: title, - icon: iconEmojiId == 0 ? nil : iconEmojiId, - iconColor: iconColor + title: "", + icon: nil, + iconColor: 0 ), - incomingUnreadCount: unreadCount, - maxIncomingReadId: readInboxMaxId, + incomingUnreadCount: 0, + maxIncomingReadId: 0, maxKnownMessageId: topMessage, - maxOutgoingReadId: readOutboxMaxId, - isClosed: (flags & (1 << 2)) != 0, - isHidden: (flags & (1 << 6)) != 0, - notificationSettings: TelegramPeerNotificationSettings(apiSettings: notifySettings) + maxOutgoingReadId: 0, + isClosed: false, + isHidden: false, + notificationSettings: TelegramPeerNotificationSettings.defaultSettings ) - var topTimestamp = date + var topTimestamp: Int32 = 1 for message in addedMessages { - if message.id.peerId == peerId && message.threadId == Int64(id) { + if message.id.peerId == peerId && message.threadId == peer.peerId.toInt64() { topTimestamp = max(topTimestamp, message.timestamp) } } - let topicIndex = StoredPeerThreadCombinedState.Index(timestamp: topTimestamp, threadId: Int64(id), messageId: topMessage) + let topicIndex = StoredPeerThreadCombinedState.Index(timestamp: topTimestamp, threadId: peer.peerId.toInt64(), messageId: topMessage) if let minIndexValue = minIndex { if topicIndex < minIndexValue { minIndex = topicIndex @@ -905,15 +792,13 @@ func _internal_requestMessageHistoryThreads(accountPeerId: PeerId, postbox: Post } items.append(LoadMessageHistoryThreadsResult.Item( - threadId: Int64(id), + threadId: peer.peerId.toInt64(), data: data, topMessage: topMessage, - unreadMentionsCount: unreadMentionsCount, - unreadReactionsCount: unreadReactionsCount, + unreadMentionsCount: 0, + unreadReactionsCount: 0, index: topicIndex )) - case .forumTopicDeleted: - break } } @@ -923,7 +808,7 @@ func _internal_requestMessageHistoryThreads(accountPeerId: PeerId, postbox: Post } var nextIndex: StoredPeerThreadCombinedState.Index - if topics.count != 0 { + if dialogs.count != 0 { nextIndex = minIndex ?? StoredPeerThreadCombinedState.Index(timestamp: 0, threadId: 0, messageId: 1) } else { nextIndex = StoredPeerThreadCombinedState.Index(timestamp: 0, threadId: 0, messageId: 1) @@ -943,12 +828,154 @@ func _internal_requestMessageHistoryThreads(accountPeerId: PeerId, postbox: Post users: users, chats: chats )) + case .savedDialogsNotModified: + return .complete() } } + return signal + } else { + let signal: Signal = postbox.transaction { transaction -> Api.InputChannel? in + guard let channel = transaction.getPeer(peerId) as? TelegramChannel else { + return nil + } + if !channel.flags.contains(.isForum) { + return nil + } + return apiInputChannel(channel) + } + |> castError(LoadMessageHistoryThreadsError.self) + |> mapToSignal { inputChannel -> Signal in + guard let inputChannel = inputChannel else { + return .fail(.generic) + } + var flags: Int32 = 0 + + if query != nil { + flags |= 1 << 0 + } + + var offsetDate: Int32 = 0 + var offsetId: Int32 = 0 + var offsetTopic: Int32 = 0 + if let offsetIndex = offsetIndex { + offsetDate = offsetIndex.timestamp + offsetId = offsetIndex.messageId + offsetTopic = Int32(clamping: offsetIndex.threadId) + } + let signal: Signal = network.request(Api.functions.channels.getForumTopics( + flags: flags, + channel: inputChannel, + q: query, + offsetDate: offsetDate, + offsetId: offsetId, + offsetTopic: offsetTopic, + limit: Int32(limit) + )) + |> mapError { _ -> LoadMessageHistoryThreadsError in + return .generic + } + |> mapToSignal { result -> Signal in + switch result { + case let .forumTopics(_, _, topics, messages, chats, users, pts): + var items: [LoadMessageHistoryThreadsResult.Item] = [] + var pinnedIds: [Int64] = [] + + let addedMessages = messages.compactMap { message -> StoreMessage? in + return StoreMessage(apiMessage: message, accountPeerId: accountPeerId, peerIsForum: true) + } + + let _ = pts + var minIndex: StoredPeerThreadCombinedState.Index? + + for topic in topics { + switch topic { + case let .forumTopic(flags, id, date, title, iconColor, iconEmojiId, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, unreadReactionsCount, fromId, notifySettings, draft): + let _ = draft + + if (flags & (1 << 3)) != 0 { + pinnedIds.append(Int64(id)) + } + + let data = MessageHistoryThreadData( + creationDate: date, + isOwnedByMe: (flags & (1 << 1)) != 0, + author: fromId.peerId, + info: EngineMessageHistoryThread.Info( + title: title, + icon: iconEmojiId == 0 ? nil : iconEmojiId, + iconColor: iconColor + ), + incomingUnreadCount: unreadCount, + maxIncomingReadId: readInboxMaxId, + maxKnownMessageId: topMessage, + maxOutgoingReadId: readOutboxMaxId, + isClosed: (flags & (1 << 2)) != 0, + isHidden: (flags & (1 << 6)) != 0, + notificationSettings: TelegramPeerNotificationSettings(apiSettings: notifySettings) + ) + + var topTimestamp = date + for message in addedMessages { + if message.id.peerId == peerId && message.threadId == Int64(id) { + topTimestamp = max(topTimestamp, message.timestamp) + } + } + + let topicIndex = StoredPeerThreadCombinedState.Index(timestamp: topTimestamp, threadId: Int64(id), messageId: topMessage) + if let minIndexValue = minIndex { + if topicIndex < minIndexValue { + minIndex = topicIndex + } + } else { + minIndex = topicIndex + } + + items.append(LoadMessageHistoryThreadsResult.Item( + threadId: Int64(id), + data: data, + topMessage: topMessage, + unreadMentionsCount: unreadMentionsCount, + unreadReactionsCount: unreadReactionsCount, + index: topicIndex + )) + case .forumTopicDeleted: + break + } + } + + var pinnedThreadIds: [Int64]? + if offsetIndex == nil { + pinnedThreadIds = pinnedIds + } + + var nextIndex: StoredPeerThreadCombinedState.Index + if topics.count != 0 { + nextIndex = minIndex ?? StoredPeerThreadCombinedState.Index(timestamp: 0, threadId: 0, messageId: 1) + } else { + nextIndex = StoredPeerThreadCombinedState.Index(timestamp: 0, threadId: 0, messageId: 1) + } + if let offsetIndex = offsetIndex, nextIndex == offsetIndex { + nextIndex = StoredPeerThreadCombinedState.Index(timestamp: 0, threadId: 0, messageId: 1) + } + + let combinedState = PeerThreadCombinedState(validIndexBoundary: nextIndex) + + return .single(LoadMessageHistoryThreadsResult( + peerId: peerId, + items: items, + messages: addedMessages, + pinnedThreadIds: pinnedThreadIds, + combinedState: combinedState, + users: users, + chats: chats + )) + } + } + return signal + } + return signal } - - return signal } } diff --git a/submodules/TelegramCore/Sources/State/AccountViewTracker.swift b/submodules/TelegramCore/Sources/State/AccountViewTracker.swift index 4b7b8db719..569a026238 100644 --- a/submodules/TelegramCore/Sources/State/AccountViewTracker.swift +++ b/submodules/TelegramCore/Sources/State/AccountViewTracker.swift @@ -2161,16 +2161,24 @@ public final class AccountViewTracker { if let account = self.account { let signal: Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> if let peerId = chatLocation.peerId, let threadId = chatLocation.threadId, tag == nil { - signal = account.postbox.transaction { transaction -> (MessageHistoryThreadData?, MessageIndex?) in + signal = account.postbox.transaction { transaction -> (Peer?, MessageHistoryThreadData?, MessageIndex?) in let interfaceState = transaction.getPeerChatThreadInterfaceState(peerId, threadId: threadId) return ( + transaction.getPeer(peerId), transaction.getMessageHistoryThreadInfo(peerId: peerId, threadId: threadId)?.data.get(MessageHistoryThreadData.self), interfaceState?.historyScrollMessageIndex ) } - |> mapToSignal { threadInfo, scrollRestorationIndex -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> in + |> mapToSignal { peer, threadInfo, scrollRestorationIndex -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> in + var isSimpleThread = false if peerId == account.peerId { + isSimpleThread = true + } else if let channel = peer as? TelegramChannel, channel.flags.contains(.isMonoforum) { + isSimpleThread = true + } + + if isSimpleThread { let anchor: HistoryViewInputAnchor if let scrollRestorationIndex { anchor = .index(scrollRestorationIndex) diff --git a/submodules/TelegramCore/Sources/State/Holes.swift b/submodules/TelegramCore/Sources/State/Holes.swift index 16de04770f..54b25a0bfb 100644 --- a/submodules/TelegramCore/Sources/State/Holes.swift +++ b/submodules/TelegramCore/Sources/State/Holes.swift @@ -339,9 +339,12 @@ enum FetchMessageHistoryHoleThreadInput: CustomStringConvertible { } } - func requestThreadId(accountPeerId: PeerId) -> Int64? { + func requestThreadId(accountPeerId: PeerId, peer: Peer) -> Int64? { switch self { case let .direct(peerId, threadId): + if let channel = peer as? TelegramChannel, channel.flags.contains(.isMonoforum) { + return nil + } if let threadId = threadId, peerId != accountPeerId { return threadId } else { @@ -352,10 +355,12 @@ enum FetchMessageHistoryHoleThreadInput: CustomStringConvertible { } } - func requestSubPeerId(accountPeerId: PeerId) -> PeerId? { + func requestSubPeerId(accountPeerId: PeerId, peer: Peer) -> PeerId? { switch self { case let .direct(peerId, threadId): - if let threadId = threadId, peerId == accountPeerId { + if let threadId, peerId == accountPeerId { + return PeerId(threadId) + } else if let threadId, let channel = peer as? TelegramChannel, channel.flags.contains(.isMonoforum) { return PeerId(threadId) } else { return nil @@ -390,7 +395,12 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH return postbox.transaction { transaction -> (Peer?, Int64, Peer?) in switch peerInput { case let .direct(peerId, _): - return (transaction.getPeer(peerId), 0, peerInput.requestSubPeerId(accountPeerId: accountPeerId).flatMap(transaction.getPeer)) + let peer = transaction.getPeer(peerId) + var subPeerId: PeerId? + if let peer { + subPeerId = peerInput.requestSubPeerId(accountPeerId: accountPeerId, peer: peer) + } + return (peer, 0, subPeerId.flatMap(transaction.getPeer)) case let .threadFromChannel(channelMessageId): return (transaction.getPeer(channelMessageId.peerId), 0, nil) } @@ -411,7 +421,7 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH switch space { case .everywhere: - if let requestThreadId = peerInput.requestThreadId(accountPeerId: accountPeerId) { + if let requestThreadId = peerInput.requestThreadId(accountPeerId: accountPeerId, peer: peer) { let offsetId: Int32 let addOffset: Int32 let selectedLimit = count @@ -459,7 +469,7 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH } request = source.request(Api.functions.messages.getReplies(peer: inputPeer, msgId: Int32(clamping: requestThreadId), offsetId: offsetId, offsetDate: 0, addOffset: addOffset, limit: Int32(selectedLimit), maxId: maxId, minId: minId, hash: hash)) - } else if let subPeerId = peerInput.requestSubPeerId(accountPeerId: accountPeerId) { + } else if let subPeerId = peerInput.requestSubPeerId(accountPeerId: accountPeerId, peer: peer) { guard let subPeer, subPeer.id == subPeerId, let inputSubPeer = apiInputPeer(subPeer) else { Logger.shared.log("fetchMessageHistoryHole", "subPeer not available") return .never() @@ -511,7 +521,14 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH minMaxRange = 1 ... (Int32.max - 1) } - request = source.request(Api.functions.messages.getSavedHistory(peer: inputSubPeer, offsetId: offsetId, offsetDate: 0, addOffset: addOffset, limit: Int32(selectedLimit), maxId: maxId, minId: minId, hash: hash)) + var getSavedHistoryFlags: Int32 = 0 + var parentPeer: Api.InputPeer? + if peer.id != accountPeerId { + getSavedHistoryFlags |= 1 << 0 + parentPeer = inputPeer + } + + request = source.request(Api.functions.messages.getSavedHistory(flags: getSavedHistoryFlags, parentPeer: parentPeer, peer: inputSubPeer, offsetId: offsetId, offsetDate: 0, addOffset: addOffset, limit: Int32(selectedLimit), maxId: maxId, minId: minId, hash: hash)) } else { let offsetId: Int32 let addOffset: Int32 @@ -611,7 +628,7 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH var flags: Int32 = 0 var topMsgId: Int32? - if let threadId = peerInput.requestThreadId(accountPeerId: accountPeerId) { + if let threadId = peerInput.requestThreadId(accountPeerId: accountPeerId, peer: peer) { flags |= (1 << 1) topMsgId = Int32(clamping: threadId) } @@ -666,7 +683,7 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH var flags: Int32 = 0 var topMsgId: Int32? - if let threadId = peerInput.requestThreadId(accountPeerId: accountPeerId) { + if let threadId = peerInput.requestThreadId(accountPeerId: accountPeerId, peer: peer) { flags |= (1 << 0) topMsgId = Int32(clamping: threadId) } @@ -730,13 +747,13 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH var flags: Int32 = 0 var topMsgId: Int32? - if let threadId = peerInput.requestThreadId(accountPeerId: accountPeerId) { + if let threadId = peerInput.requestThreadId(accountPeerId: accountPeerId, peer: peer) { flags |= (1 << 1) topMsgId = Int32(clamping: threadId) } var savedPeerId: Api.InputPeer? - if let subPeerId = peerInput.requestSubPeerId(accountPeerId: accountPeerId), let subPeer = subPeer, subPeer.id == subPeerId { + if let subPeerId = peerInput.requestSubPeerId(accountPeerId: accountPeerId, peer: peer), let subPeer = subPeer, subPeer.id == subPeerId { if let inputPeer = apiInputPeer(subPeer) { flags |= 1 << 2 savedPeerId = inputPeer @@ -799,13 +816,13 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH var flags: Int32 = 0 var topMsgId: Int32? - if let threadId = peerInput.requestThreadId(accountPeerId: accountPeerId) { + if let threadId = peerInput.requestThreadId(accountPeerId: accountPeerId, peer: peer) { flags |= (1 << 1) topMsgId = Int32(clamping: threadId) } var savedPeerId: Api.InputPeer? - if let subPeerId = peerInput.requestSubPeerId(accountPeerId: accountPeerId), let subPeer = subPeer, subPeer.id == subPeerId { + if let subPeerId = peerInput.requestSubPeerId(accountPeerId: accountPeerId, peer: peer), let subPeer = subPeer, subPeer.id == subPeerId { if let inputPeer = apiInputPeer(subPeer) { flags |= 1 << 2 savedPeerId = inputPeer @@ -960,9 +977,6 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH } print("fetchMessageHistoryHole for \(peerInput) space \(space) done") - if peerInput.requestThreadId(accountPeerId: accountPeerId) != nil, case .everywhere = space, case .aroundId = direction { - assert(true) - } if ids.count == 0 || implicitelyFillHole { filledRange = minMaxRange @@ -974,7 +988,7 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH filledRange = min(aroundId.id, messageRange.lowerBound) ... max(aroundId.id, messageRange.upperBound) strictFilledIndices = IndexSet(integersIn: Int(min(aroundId.id, messageRange.lowerBound)) ... Int(max(aroundId.id, messageRange.upperBound))) var shouldFillAround = false - if peerInput.requestThreadId(accountPeerId: accountPeerId) != nil { + if peerInput.requestThreadId(accountPeerId: accountPeerId, peer: peer) != nil || peerInput.requestSubPeerId(accountPeerId: accountPeerId, peer: peer) != nil { shouldFillAround = true } if case .customTag = space { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/ReplyThreadHistory.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/ReplyThreadHistory.swift index 2d02461232..093db67ef1 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/ReplyThreadHistory.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/ReplyThreadHistory.swift @@ -565,6 +565,7 @@ public struct ChatReplyThreadMessage: Equatable { public var channelMessageId: MessageId? public var isChannelPost: Bool public var isForumPost: Bool + public var isMonoforum: Bool public var maxMessage: MessageId? public var maxReadIncomingMessageId: MessageId? public var maxReadOutgoingMessageId: MessageId? @@ -581,12 +582,13 @@ public struct ChatReplyThreadMessage: Equatable { } } - public init(peerId: PeerId, threadId: Int64, channelMessageId: MessageId?, isChannelPost: Bool, isForumPost: Bool, maxMessage: MessageId?, maxReadIncomingMessageId: MessageId?, maxReadOutgoingMessageId: MessageId?, unreadCount: Int, initialFilledHoles: IndexSet, initialAnchor: Anchor, isNotAvailable: Bool) { + public init(peerId: PeerId, threadId: Int64, channelMessageId: MessageId?, isChannelPost: Bool, isForumPost: Bool, isMonoforum: Bool, maxMessage: MessageId?, maxReadIncomingMessageId: MessageId?, maxReadOutgoingMessageId: MessageId?, unreadCount: Int, initialFilledHoles: IndexSet, initialAnchor: Anchor, isNotAvailable: Bool) { self.peerId = peerId self.threadId = threadId self.channelMessageId = channelMessageId self.isChannelPost = isChannelPost self.isForumPost = isForumPost + self.isMonoforum = isMonoforum self.maxMessage = maxMessage self.maxReadIncomingMessageId = maxReadIncomingMessageId self.maxReadOutgoingMessageId = maxReadOutgoingMessageId @@ -598,7 +600,7 @@ public struct ChatReplyThreadMessage: Equatable { public var normalized: ChatReplyThreadMessage { if self.isForumPost { - return ChatReplyThreadMessage(peerId: self.peerId, threadId: self.threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false) + return ChatReplyThreadMessage(peerId: self.peerId, threadId: self.threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false) } else { return self } @@ -931,6 +933,7 @@ func _internal_fetchChannelReplyThreadMessage(account: Account, messageId: Messa channelMessageId: discussionMessage.channelMessageId, isChannelPost: discussionMessage.isChannelPost, isForumPost: discussionMessage.isForumPost, + isMonoforum: false, maxMessage: discussionMessage.maxMessage, maxReadIncomingMessageId: discussionMessage.maxReadIncomingMessageId, maxReadOutgoingMessageId: discussionMessage.maxReadOutgoingMessageId, diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift index 83b1d94507..ff1dfd86c7 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift @@ -827,7 +827,13 @@ func _internal_searchMessageIdByTimestamp(account: Account, peerId: PeerId, thre guard let subPeer = transaction.getPeer(PeerId(threadId)), let inputSubPeer = apiInputPeer(subPeer) else { return .single(nil) } - let primaryIndex = account.network.request(Api.functions.messages.getSavedHistory(peer: inputSubPeer, offsetId: 0, offsetDate: timestamp, addOffset: -1, limit: 1, maxId: 0, minId: 0, hash: 0)) + var getSavedHistoryFlags: Int32 = 0 + var parentPeer: Api.InputPeer? + if peer.id != account.peerId { + getSavedHistoryFlags |= 1 << 0 + parentPeer = inputPeer + } + let primaryIndex = account.network.request(Api.functions.messages.getSavedHistory(flags: getSavedHistoryFlags, parentPeer: parentPeer, peer: inputSubPeer, offsetId: 0, offsetDate: timestamp, addOffset: -1, limit: 1, maxId: 0, minId: 0, hash: 0)) |> map { result -> MessageIndex? in let messages: [Api.Message] switch result { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChannelMembers.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChannelMembers.swift index 22e59346e3..a1d943cf0a 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChannelMembers.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChannelMembers.swift @@ -29,6 +29,9 @@ func _internal_channelMembers(postbox: Postbox, network: Network, accountPeerId: return .single(nil) } } + if peer.flags.contains(.isMonoforum) { + return .single(nil) + } let apiFilter: Api.ChannelParticipantsFilter switch category { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift index 8ea009967d..298fc080ab 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift @@ -30,6 +30,10 @@ func fetchAndUpdateSupplementalCachedPeerData(peerId rawPeerId: PeerId, accountP } else { peer = rawPeer } + + if let channel = peer as? TelegramChannel, channel.flags.contains(.isMonoforum) { + return .single(false) + } let cachedData = transaction.getPeerCachedData(peerId: peer.id) @@ -579,6 +583,9 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee } } } else if let inputChannel = maybePeer.flatMap(apiInputChannel) { + if let channel = maybePeer as? TelegramChannel, channel.flags.contains(.isMonoforum) { + return .single(false) + } let fullChannelSignal = network.request(Api.functions.channels.getFullChannel(channel: inputChannel)) |> map(Optional.init) |> `catch` { error -> Signal in diff --git a/submodules/TelegramUI/Components/Chat/ChatInlineSearchResultsListComponent/Sources/ChatInlineSearchResultsListComponent.swift b/submodules/TelegramUI/Components/Chat/ChatInlineSearchResultsListComponent/Sources/ChatInlineSearchResultsListComponent.swift index 193e1f6040..105ce3a39c 100644 --- a/submodules/TelegramUI/Components/Chat/ChatInlineSearchResultsListComponent/Sources/ChatInlineSearchResultsListComponent.swift +++ b/submodules/TelegramUI/Components/Chat/ChatInlineSearchResultsListComponent/Sources/ChatInlineSearchResultsListComponent.swift @@ -804,7 +804,7 @@ public final class ChatInlineSearchResultsListComponent: Component { return ChatListItem( presentationData: chatListPresentationData, context: component.context, - chatListLocation: component.peerId == component.context.account.peerId ? .savedMessagesChats : .chatList(groupId: .root), + chatListLocation: component.peerId == component.context.account.peerId ? .savedMessagesChats(peerId: component.context.account.peerId) : .chatList(groupId: .root), filterData: nil, index: .forum( pinnedIndex: .none, diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoChatListPaneNode/Sources/PeerInfoChatListPaneNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoChatListPaneNode/Sources/PeerInfoChatListPaneNode.swift index 6a191d60a3..9602ad62c4 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoChatListPaneNode/Sources/PeerInfoChatListPaneNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoChatListPaneNode/Sources/PeerInfoChatListPaneNode.swift @@ -149,7 +149,7 @@ public final class PeerInfoChatListPaneNode: ASDisplayNode, PeerInfoPaneNode, AS self.chatListNode = ChatListNode( context: self.context, - location: .savedMessagesChats, + location: .savedMessagesChats(peerId: context.account.peerId), chatListFilter: nil, previewing: false, fillPreloadItems: false, @@ -210,6 +210,7 @@ public final class PeerInfoChatListPaneNode: ASDisplayNode, PeerInfoPaneNode, AS channelMessageId: nil, isChannelPost: false, isForumPost: false, + isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, @@ -378,7 +379,7 @@ public final class PeerInfoChatListPaneNode: ASDisplayNode, PeerInfoPaneNode, AS if case let .peer(peerData) = item.content { let threadId = peerData.peer.peerId.toInt64() let chatController = self.context.sharedContext.makeChatController(context: self.context, chatLocation: .replyThread(message: ChatReplyThreadMessage( - peerId: self.context.account.peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false + peerId: self.context.account.peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: false, isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false )), subject: nil, botStart: nil, mode: .standard(.previewing), params: nil) chatController.canReadHistory.set(false) let source: ContextContentSource = .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, navigationController: parentController.navigationController as? NavigationController)) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoChatPaneNode/Sources/PeerInfoChatPaneNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoChatPaneNode/Sources/PeerInfoChatPaneNode.swift index 1e10096d4d..bd23911577 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoChatPaneNode/Sources/PeerInfoChatPaneNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoChatPaneNode/Sources/PeerInfoChatPaneNode.swift @@ -149,7 +149,7 @@ public final class PeerInfoChatPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScro self.coveringView = UIView() - self.chatController = context.sharedContext.makeChatController(context: context, chatLocation: .replyThread(message: ChatReplyThreadMessage(peerId: context.account.peerId, threadId: peerId.toInt64(), channelMessageId: nil, isChannelPost: false, isForumPost: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false)), subject: nil, botStart: nil, mode: .standard(.embedded(invertDirection: true)), params: nil) + self.chatController = context.sharedContext.makeChatController(context: context, chatLocation: .replyThread(message: ChatReplyThreadMessage(peerId: context.account.peerId, threadId: peerId.toInt64(), channelMessageId: nil, isChannelPost: false, isForumPost: false, isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false)), subject: nil, botStart: nil, mode: .standard(.embedded(invertDirection: true)), params: nil) self.chatController.navigation_setNavigationController(navigationController()) super.init() diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index aed5af4e78..df451f4693 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -11016,7 +11016,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro self?.deactivateSearch() }) } else if let currentPaneKey = self.paneContainerNode.currentPaneKey, case .savedMessagesChats = currentPaneKey { - let contentNode = ChatListSearchContainerNode(context: self.context, animationCache: self.context.animationCache, animationRenderer: self.context.animationRenderer, filter: [.removeSearchHeader], requestPeerType: nil, location: .savedMessagesChats, displaySearchFilters: false, hasDownloads: false, initialFilter: .chats, openPeer: { [weak self] peer, _, _, _ in + let contentNode = ChatListSearchContainerNode(context: self.context, animationCache: self.context.animationCache, animationRenderer: self.context.animationRenderer, filter: [.removeSearchHeader], requestPeerType: nil, location: .savedMessagesChats(peerId: self.context.account.peerId), displaySearchFilters: false, hasDownloads: false, initialFilter: .chats, openPeer: { [weak self] peer, _, _, _ in guard let self else { return } @@ -11032,6 +11032,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro channelMessageId: nil, isChannelPost: false, isForumPost: false, + isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, @@ -11061,6 +11062,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro channelMessageId: nil, isChannelPost: false, isForumPost: false, + isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, @@ -13374,7 +13376,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc let navigateChatLocation: NavigateToChatControllerParams.Location if let threadId = item.threadId { navigateChatLocation = .replyThread(ChatReplyThreadMessage( - peerId: item.peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false + peerId: item.peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, isMonoforum: false,maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false )) } else { navigateChatLocation = .peer(itemPeer) diff --git a/submodules/TelegramUI/Components/StorageUsageScreen/Sources/StorageUsageScreen.swift b/submodules/TelegramUI/Components/StorageUsageScreen/Sources/StorageUsageScreen.swift index 6994ba3d69..39be124675 100644 --- a/submodules/TelegramUI/Components/StorageUsageScreen/Sources/StorageUsageScreen.swift +++ b/submodules/TelegramUI/Components/StorageUsageScreen/Sources/StorageUsageScreen.swift @@ -2586,7 +2586,7 @@ final class StorageUsageScreenComponent: Component { var chatLocation: NavigateToChatControllerParams.Location = .peer(peer) if case let .channel(channel) = peer, channel.flags.contains(.isForum), let threadId = message.threadId { - chatLocation = .replyThread(ChatReplyThreadMessage(peerId: peer.id, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false)) + chatLocation = .replyThread(ChatReplyThreadMessage(peerId: peer.id, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false)) } component.context.sharedContext.navigateToChatController(NavigateToChatControllerParams( @@ -2689,7 +2689,7 @@ final class StorageUsageScreenComponent: Component { var chatLocation: NavigateToChatControllerParams.Location = .peer(peer) if case let .channel(channel) = peer, channel.flags.contains(.isForum), let threadId = message.threadId { - chatLocation = .replyThread(ChatReplyThreadMessage(peerId: peer.id, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false)) + chatLocation = .replyThread(ChatReplyThreadMessage(peerId: peer.id, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false)) } component.context.sharedContext.navigateToChatController(NavigateToChatControllerParams( diff --git a/submodules/TelegramUI/Sources/ApplicationContext.swift b/submodules/TelegramUI/Sources/ApplicationContext.swift index f27d52dbb9..7b72a6c677 100644 --- a/submodules/TelegramUI/Sources/ApplicationContext.swift +++ b/submodules/TelegramUI/Sources/ApplicationContext.swift @@ -325,7 +325,7 @@ final class AuthorizedApplicationContext { let chatLocation: NavigateToChatControllerParams.Location if let _ = threadData, let threadId = firstMessage.threadId { chatLocation = .replyThread(ChatReplyThreadMessage( - peerId: firstMessage.id.peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false + peerId: firstMessage.id.peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false ).normalized) } else { guard let peer = firstMessage.peers[firstMessage.id.peerId] else { @@ -941,7 +941,7 @@ final class AuthorizedApplicationContext { let chatLocation: NavigateToChatControllerParams.Location if let threadId = threadId { chatLocation = .replyThread(ChatReplyThreadMessage( - peerId: peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false + peerId: peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false )) } else { chatLocation = .peer(peer) diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift index 3ee5265fbb..6223b0d385 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift @@ -6231,14 +6231,23 @@ extension ChatControllerImpl { guard let peerId = self.chatLocation.peerId else { return } + guard let peer = self.presentationInterfaceState.renderedPeer?.chatMainPeer else { + return + } let updatedChatLocation: ChatLocation if let threadId { + var isMonoforum = false + if let channel = peer as? TelegramChannel, channel.flags.contains(.isMonoforum) { + isMonoforum = true + } + updatedChatLocation = .replyThread(message: ChatReplyThreadMessage( peerId: peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, + isMonoforum: isMonoforum, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, @@ -6709,6 +6718,7 @@ extension ChatControllerImpl { channelMessageId: nil, isChannelPost: false, isForumPost: true, + isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerNavigateToMessage.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerNavigateToMessage.swift index eba9090dd9..ebd1d447e5 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerNavigateToMessage.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerNavigateToMessage.swift @@ -144,7 +144,7 @@ extension ChatControllerImpl { let navigateToLocation: NavigateToChatControllerParams.Location if let message = messages.first, let threadId = message.threadId, let channel = message.peers[message.id.peerId] as? TelegramChannel, channel.flags.contains(.isForum) { - navigateToLocation = .replyThread(ChatReplyThreadMessage(peerId: peer.id, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false)) + navigateToLocation = .replyThread(ChatReplyThreadMessage(peerId: peer.id, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, isMonoforum: false,maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false)) } else { navigateToLocation = .peer(peer) } @@ -179,7 +179,7 @@ extension ChatControllerImpl { var displayMessageNotFoundToast = false if case let .channel(channel) = peer, channel.flags.contains(.isForum) { if let message = message, let threadId = message.threadId { - let replyThreadMessage = ChatReplyThreadMessage(peerId: peer.id, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false) + let replyThreadMessage = ChatReplyThreadMessage(peerId: peer.id, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false) chatLocation = .replyThread(replyThreadMessage) preloadChatLocation = .replyThread(message: replyThreadMessage) } else { diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 26c5695745..afba1eb742 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -6131,7 +6131,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let chatLocation: ChatLocation if let threadId { - chatLocation = .replyThread(message: ChatReplyThreadMessage(peerId: peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false)) + chatLocation = .replyThread(message: ChatReplyThreadMessage(peerId: peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false)) } else { chatLocation = .peer(id: peerId) } diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index f106ab6e35..072ca9beef 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -2964,6 +2964,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { channelMessageId: nil, isChannelPost: false, isForumPost: false, + isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index 75cfa1e9ea..8c1a5f8e09 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -1647,8 +1647,18 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto let topicAuthorId: Signal if let peerId = chatLocation.peerId, let threadId = chatLocation.threadId { - topicAuthorId = context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.ThreadData(id: peerId, threadId: threadId)) - |> map { data -> EnginePeer.Id? in + topicAuthorId = context.engine.data.subscribe( + TelegramEngine.EngineData.Item.Peer.Peer(id: peerId), + TelegramEngine.EngineData.Item.Peer.ThreadData(id: peerId, threadId: threadId) + ) + |> map { peer, data -> EnginePeer.Id? in + guard let peer else { + return nil + } + if case let .channel(channel) = peer, channel.flags.contains(.isMonoforum) { + return nil + } + return data?.author } |> distinctUntilChanged diff --git a/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift b/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift index e70ce3a7bd..017d71066c 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift @@ -102,7 +102,7 @@ func chatHistoryViewForLocation( if tag != nil { requestAroundId = true } - if case let .replyThread(message) = chatLocation, message.peerId == context.account.peerId { + if case let .replyThread(message) = chatLocation, (message.peerId == context.account.peerId || message.isMonoforum) { preFixedReadState = .peer([:]) } diff --git a/submodules/TelegramUI/Sources/ChatSearchResultsContollerNode.swift b/submodules/TelegramUI/Sources/ChatSearchResultsContollerNode.swift index a0264aeec2..70b66ef646 100644 --- a/submodules/TelegramUI/Sources/ChatSearchResultsContollerNode.swift +++ b/submodules/TelegramUI/Sources/ChatSearchResultsContollerNode.swift @@ -185,7 +185,7 @@ class ChatSearchResultsControllerNode: ViewControllerTracingNode, ASScrollViewDe self.searchState = searchState if case let .peer(peerId, _, _, _, _, _, _) = location, peerId == context.account.peerId { - self.mappedLocation = .savedMessagesChats + self.mappedLocation = .savedMessagesChats(peerId: peerId) } else { self.mappedLocation = .chatList(groupId: .root) } diff --git a/submodules/TelegramUI/Sources/NavigateToChatController.swift b/submodules/TelegramUI/Sources/NavigateToChatController.swift index be4908991d..3e628f8d9f 100644 --- a/submodules/TelegramUI/Sources/NavigateToChatController.swift +++ b/submodules/TelegramUI/Sources/NavigateToChatController.swift @@ -27,7 +27,9 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam } var viewForumAsMessages: Signal = .single(false) - if case let .peer(peer) = params.chatLocation, case let .channel(channel) = peer, channel.flags.contains(.isForum) { + if case let .peer(peer) = params.chatLocation, case let .channel(channel) = peer, channel.flags.contains(.isMonoforum) { + viewForumAsMessages = .single(false) + } else if case let .peer(peer) = params.chatLocation, case let .channel(channel) = peer, channel.flags.contains(.isForum) { viewForumAsMessages = params.context.account.postbox.combinedView(keys: [.cachedPeerData(peerId: peer.id)]) |> take(1) |> map { combinedView in @@ -52,6 +54,11 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam let _ = (viewForumAsMessages |> take(1) |> deliverOnMainQueue).start(next: { viewForumAsMessages in + var viewForumAsMessages = viewForumAsMessages + if case let .peer(peer) = params.chatLocation, case let .channel(channel) = peer, channel.flags.contains(.isMonoforum), channel.adminRights == nil { + viewForumAsMessages = true + } + if case let .peer(peer) = params.chatLocation, case let .channel(channel) = peer, channel.flags.contains(.isForum), !viewForumAsMessages { for controller in params.navigationController.viewControllers.reversed() { var chatListController: ChatListControllerImpl? @@ -65,6 +72,8 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam var matches = false if case let .forum(peerId) = chatListController.location, peer.id == peerId { matches = true + } else if case let .savedMessagesChats(peerId) = chatListController.location, peer.id == peerId { + matches = true } else if case let .forum(peerId) = chatListController.effectiveLocation, peer.id == peerId { matches = true } @@ -79,7 +88,14 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam } } - let controller = ChatListControllerImpl(context: params.context, location: .forum(peerId: peer.id), controlsHistoryPreload: false, enableDebugActions: false) + let chatListLocation: ChatListControllerLocation + if case let .peer(peer) = params.chatLocation, case let .channel(channel) = peer, channel.flags.contains(.isMonoforum) { + chatListLocation = .savedMessagesChats(peerId: peer.id) + } else { + chatListLocation = .forum(peerId: peer.id) + } + + let controller = ChatListControllerImpl(context: params.context, location: chatListLocation, controlsHistoryPreload: false, enableDebugActions: false) let activateMessageSearch = params.activateMessageSearch let chatListCompletion = params.chatListCompletion diff --git a/submodules/TranslateUI/Sources/ChatTranslation.swift b/submodules/TranslateUI/Sources/ChatTranslation.swift index 8c03916535..8370e509f0 100644 --- a/submodules/TranslateUI/Sources/ChatTranslation.swift +++ b/submodules/TranslateUI/Sources/ChatTranslation.swift @@ -76,10 +76,14 @@ public struct ChatTranslationState: Codable { } private func cachedChatTranslationState(engine: TelegramEngine, peerId: EnginePeer.Id, threadId: Int64?) -> Signal { - let key = EngineDataBuffer(length: 8) - key.setInt64(0, value: peerId.id._internalGetInt64Value()) + let key: EngineDataBuffer if let threadId { + key = EngineDataBuffer(length: 8 + 8) + key.setInt64(0, value: peerId.id._internalGetInt64Value()) key.setInt64(8, value: threadId) + } else { + key = EngineDataBuffer(length: 8) + key.setInt64(0, value: peerId.id._internalGetInt64Value()) } return engine.data.subscribe(TelegramEngine.EngineData.Item.ItemCache.Item(collectionId: ApplicationSpecificItemCacheCollectionId.translationState, id: key)) @@ -89,10 +93,14 @@ private func cachedChatTranslationState(engine: TelegramEngine, peerId: EnginePe } private func updateChatTranslationState(engine: TelegramEngine, peerId: EnginePeer.Id, threadId: Int64?, state: ChatTranslationState?) -> Signal { - let key = EngineDataBuffer(length: 8) - key.setInt64(0, value: peerId.id._internalGetInt64Value()) + let key: EngineDataBuffer if let threadId { + key = EngineDataBuffer(length: 8 + 8) + key.setInt64(0, value: peerId.id._internalGetInt64Value()) key.setInt64(8, value: threadId) + } else { + key = EngineDataBuffer(length: 8) + key.setInt64(0, value: peerId.id._internalGetInt64Value()) } if let state { diff --git a/submodules/UrlHandling/Sources/UrlHandling.swift b/submodules/UrlHandling/Sources/UrlHandling.swift index 006982c311..9318261517 100644 --- a/submodules/UrlHandling/Sources/UrlHandling.swift +++ b/submodules/UrlHandling/Sources/UrlHandling.swift @@ -841,7 +841,7 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl) return .progress case let .result(info): if let _ = info { - return .result(.replyThreadMessage(replyThreadMessage: ChatReplyThreadMessage(peerId: channel.id, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false), messageId: messageId)) + return .result(.replyThreadMessage(replyThreadMessage: ChatReplyThreadMessage(peerId: channel.id, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false), messageId: messageId)) } else { return .result(.peer(peer._asPeer(), .chat(textInputState: nil, subject: nil, peekData: nil))) } @@ -866,7 +866,7 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl) return .progress case let .result(info): if let _ = info { - return .result(.replyThreadMessage(replyThreadMessage: ChatReplyThreadMessage(peerId: channel.id, threadId: Int64(replyThreadMessageId.id), channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false), messageId: MessageId(peerId: channel.id, namespace: Namespaces.Message.Cloud, id: replyId))) + return .result(.replyThreadMessage(replyThreadMessage: ChatReplyThreadMessage(peerId: channel.id, threadId: Int64(replyThreadMessageId.id), channelMessageId: nil, isChannelPost: false, isForumPost: true, isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false), messageId: MessageId(peerId: channel.id, namespace: Namespaces.Message.Cloud, id: replyId))) } else { return .result(.peer(peer._asPeer(), .chat(textInputState: nil, subject: nil, peekData: nil))) } @@ -956,7 +956,7 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl) return .progress case let .result(info): if let _ = info { - return .result(.replyThreadMessage(replyThreadMessage: ChatReplyThreadMessage(peerId: channel.id, threadId: Int64(threadId), channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false), messageId: messageId)) + return .result(.replyThreadMessage(replyThreadMessage: ChatReplyThreadMessage(peerId: channel.id, threadId: Int64(threadId), channelMessageId: nil, isChannelPost: false, isForumPost: true, isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false), messageId: messageId)) } else { return .result(.peer(peer?._asPeer(), .chat(textInputState: nil, subject: nil, peekData: nil))) } @@ -980,7 +980,7 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl) return .progress case let .result(info): if let _ = info { - return .result(.replyThreadMessage(replyThreadMessage: ChatReplyThreadMessage(peerId: channel.id, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false), messageId: messageId)) + return .result(.replyThreadMessage(replyThreadMessage: ChatReplyThreadMessage(peerId: channel.id, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, isMonoforum: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false), messageId: messageId)) } else { return .result(.peer(peer?._asPeer(), .chat(textInputState: nil, subject: nil, peekData: nil))) }