diff --git a/submodules/ChatListUI/Sources/Node/ChatListNodeLocation.swift b/submodules/ChatListUI/Sources/Node/ChatListNodeLocation.swift index b17a211e28..1634e3d88e 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNodeLocation.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNodeLocation.swift @@ -256,7 +256,7 @@ func chatListViewForLocation(chatListLocation: ChatListControllerLocation, locat additionalItems: [], hasEarlier: false, hasLater: false, - isLoading: false + isLoading: view.isLoading ) let type: ViewUpdateType diff --git a/submodules/Postbox/Sources/MessageHistoryThreadIndexView.swift b/submodules/Postbox/Sources/MessageHistoryThreadIndexView.swift index bcf4a201b7..a92e58394f 100644 --- a/submodules/Postbox/Sources/MessageHistoryThreadIndexView.swift +++ b/submodules/Postbox/Sources/MessageHistoryThreadIndexView.swift @@ -30,6 +30,7 @@ final class MutableMessageHistoryThreadIndexView: MutablePostboxView { fileprivate let summaryComponents: ChatListEntrySummaryComponents fileprivate var peer: Peer? fileprivate var items: [Item] = [] + fileprivate var isLoading: Bool = false init(postbox: PostboxImpl, peerId: PeerId, summaryComponents: ChatListEntrySummaryComponents) { self.peerId = peerId @@ -43,68 +44,73 @@ final class MutableMessageHistoryThreadIndexView: MutablePostboxView { self.peer = postbox.peerTable.get(self.peerId) - let pinnedThreadIds = postbox.messageHistoryThreadPinnedTable.get(peerId: self.peerId) - var nextPinnedIndex = 0 + let validIndexBoundary = postbox.peerThreadCombinedStateTable.get(peerId: peerId)?.validIndexBoundary + self.isLoading = validIndexBoundary == nil - for item in postbox.messageHistoryThreadIndexTable.getAll(peerId: self.peerId) { - var pinnedIndex: Int? - if pinnedThreadIds.contains(item.threadId) { - pinnedIndex = nextPinnedIndex - nextPinnedIndex += 1 + if !self.isLoading { + let pinnedThreadIds = postbox.messageHistoryThreadPinnedTable.get(peerId: self.peerId) + var nextPinnedIndex = 0 + + for item in postbox.messageHistoryThreadIndexTable.getAll(peerId: self.peerId) { + var pinnedIndex: Int? + if pinnedThreadIds.contains(item.threadId) { + pinnedIndex = nextPinnedIndex + nextPinnedIndex += 1 + } + + var tagSummaryInfo: [ChatListEntryMessageTagSummaryKey: ChatListMessageTagSummaryInfo] = [:] + for (key, component) in self.summaryComponents.components { + var tagSummaryCount: Int32? + var actionsSummaryCount: Int32? + + if let tagSummary = component.tagSummary { + let key = MessageHistoryTagsSummaryKey(tag: key.tag, peerId: self.peerId, threadId: item.threadId, namespace: tagSummary.namespace) + if let summary = postbox.messageHistoryTagsSummaryTable.get(key) { + tagSummaryCount = summary.count + } + } + + if let actionsSummary = component.actionsSummary { + let key = PendingMessageActionsSummaryKey(type: key.actionType, peerId: self.peerId, namespace: actionsSummary.namespace) + actionsSummaryCount = postbox.pendingMessageActionsMetadataTable.getCount(.peerNamespaceAction(key.peerId, key.namespace, key.type)) + } + + tagSummaryInfo[key] = ChatListMessageTagSummaryInfo( + tagSummaryCount: tagSummaryCount, + actionsSummaryCount: actionsSummaryCount + ) + } + + self.items.append(Item( + id: item.threadId, + pinnedIndex: pinnedIndex, + index: item.index, + info: item.info.data, + tagSummaryInfo: tagSummaryInfo, + topMessage: postbox.getMessage(item.index.id) + )) } - var tagSummaryInfo: [ChatListEntryMessageTagSummaryKey: ChatListMessageTagSummaryInfo] = [:] - for (key, component) in self.summaryComponents.components { - var tagSummaryCount: Int32? - var actionsSummaryCount: Int32? - - if let tagSummary = component.tagSummary { - let key = MessageHistoryTagsSummaryKey(tag: key.tag, peerId: self.peerId, threadId: item.threadId, namespace: tagSummary.namespace) - if let summary = postbox.messageHistoryTagsSummaryTable.get(key) { - tagSummaryCount = summary.count + self.items.sort(by: { lhs, rhs in + if let lhsPinnedIndex = lhs.pinnedIndex, let rhsPinnedIndex = rhs.pinnedIndex { + return lhsPinnedIndex < rhsPinnedIndex + } else if (lhs.pinnedIndex == nil) != (rhs.pinnedIndex == nil) { + if lhs.pinnedIndex != nil { + return true + } else { + return false } } - if let actionsSummary = component.actionsSummary { - let key = PendingMessageActionsSummaryKey(type: key.actionType, peerId: self.peerId, namespace: actionsSummary.namespace) - actionsSummaryCount = postbox.pendingMessageActionsMetadataTable.getCount(.peerNamespaceAction(key.peerId, key.namespace, key.type)) - } - - tagSummaryInfo[key] = ChatListMessageTagSummaryInfo( - tagSummaryCount: tagSummaryCount, - actionsSummaryCount: actionsSummaryCount - ) - } - - self.items.append(Item( - id: item.threadId, - pinnedIndex: pinnedIndex, - index: item.index, - info: item.info.data, - tagSummaryInfo: tagSummaryInfo, - topMessage: postbox.getMessage(item.index.id) - )) + return lhs.index > rhs.index + }) } - - self.items.sort(by: { lhs, rhs in - if let lhsPinnedIndex = lhs.pinnedIndex, let rhsPinnedIndex = rhs.pinnedIndex { - return lhsPinnedIndex < rhsPinnedIndex - } else if (lhs.pinnedIndex == nil) != (rhs.pinnedIndex == nil) { - if lhs.pinnedIndex != nil { - return true - } else { - return false - } - } - - return lhs.index > rhs.index - }) } func replay(postbox: PostboxImpl, transaction: PostboxTransaction) -> Bool { var updated = false - if transaction.updatedMessageThreadPeerIds.contains(self.peerId) || transaction.updatedPinnedThreads.contains(self.peerId) || transaction.currentUpdatedMessageTagSummaries.contains(where: { $0.key.peerId == self.peerId }) || transaction.currentUpdatedMessageActionsSummaries.contains(where: { $0.key.peerId == self.peerId }) { + if transaction.updatedMessageThreadPeerIds.contains(self.peerId) || transaction.updatedPinnedThreads.contains(self.peerId) || transaction.updatedPeerThreadCombinedStates.contains(self.peerId) || transaction.currentUpdatedMessageTagSummaries.contains(where: { $0.key.peerId == self.peerId }) || transaction.currentUpdatedMessageActionsSummaries.contains(where: { $0.key.peerId == self.peerId }) { self.reload(postbox: postbox) updated = true } @@ -181,6 +187,7 @@ public final class EngineMessageHistoryThread { public final class MessageHistoryThreadIndexView: PostboxView { public let peer: Peer? public let items: [EngineMessageHistoryThread.Item] + public let isLoading: Bool init(_ view: MutableMessageHistoryThreadIndexView) { self.peer = view.peer @@ -197,6 +204,8 @@ public final class MessageHistoryThreadIndexView: PostboxView { )) } self.items = items + + self.isLoading = view.isLoading } } diff --git a/submodules/Postbox/Sources/PeerThreadCombinedStateTable.swift b/submodules/Postbox/Sources/PeerThreadCombinedStateTable.swift index 98f7f269b5..edc428389b 100644 --- a/submodules/Postbox/Sources/PeerThreadCombinedStateTable.swift +++ b/submodules/Postbox/Sources/PeerThreadCombinedStateTable.swift @@ -34,8 +34,13 @@ public struct StoredPeerThreadCombinedState: Equatable, Codable { case validIndexBoundary = "r" } - var data: CodableEntry - var validIndexBoundary: Index? + public var data: CodableEntry + public var validIndexBoundary: Index? + + public init(data: CodableEntry, validIndexBoundary: Index?) { + self.data = data + self.validIndexBoundary = validIndexBoundary + } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) diff --git a/submodules/TelegramCore/Sources/ForumChannels.swift b/submodules/TelegramCore/Sources/ForumChannels.swift index bb69d19d55..cf11ce5164 100644 --- a/submodules/TelegramCore/Sources/ForumChannels.swift +++ b/submodules/TelegramCore/Sources/ForumChannels.swift @@ -160,6 +160,23 @@ struct StoreMessageHistoryThreadData { var unreadReactionCount: Int32 } +struct PeerThreadCombinedState: Equatable, Codable { + var validIndexBoundary: StoredPeerThreadCombinedState.Index? + + init(validIndexBoundary: StoredPeerThreadCombinedState.Index?) { + self.validIndexBoundary = validIndexBoundary + } +} + +extension StoredPeerThreadCombinedState { + init?(_ state: PeerThreadCombinedState) { + guard let entry = CodableEntry(state) else { + return nil + } + self.init(data: entry, validIndexBoundary: state.validIndexBoundary) + } +} + public enum CreateForumChannelTopicError { case generic } @@ -500,6 +517,12 @@ func _internal_loadMessageHistoryThreads(account: Account, peerId: PeerId) -> Si } else { transaction.setPeerPinnedThreads(peerId: peerId, threadIds: []) } + + if let entry = StoredPeerThreadCombinedState(PeerThreadCombinedState( + validIndexBoundary: StoredPeerThreadCombinedState.Index(timestamp: Int32.max, threadId: Int64(Int32.max), messageId: Int32.max) + )) { + transaction.setPeerThreadCombinedState(peerId: peerId, state: entry) + } } } |> castError(LoadMessageHistoryThreadsError.self)