diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index 65a6898af3..55958e98fd 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -1797,8 +1797,14 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { var inputActivitiesSize: CGSize? var inputActivitiesApply: (() -> Void)? - if let inputActivities = inputActivities, !inputActivities.isEmpty, case let .chatList(index) = item.index { - let (size, apply) = inputActivitiesLayout(CGSize(width: rawContentWidth - badgeSize, height: 40.0), item.presentationData, item.presentationData.theme.chatList.messageTextColor, index.messageIndex.id.peerId, inputActivities) + var chatPeerId: EnginePeer.Id? + if case let .chatList(index) = item.index { + chatPeerId = index.messageIndex.id.peerId + } else if case let .forum(peerId) = item.chatListLocation { + chatPeerId = peerId + } + if let inputActivities = inputActivities, !inputActivities.isEmpty, let chatPeerId { + let (size, apply) = inputActivitiesLayout(CGSize(width: rawContentWidth - badgeSize, height: 40.0), item.presentationData, item.presentationData.theme.chatList.messageTextColor, chatPeerId, inputActivities) inputActivitiesSize = size inputActivitiesApply = apply } else { diff --git a/submodules/ChatListUI/Sources/Node/ChatListNode.swift b/submodules/ChatListUI/Sources/Node/ChatListNode.swift index 4152ffa1af..4c60cd7f91 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNode.swift @@ -142,9 +142,19 @@ public final class ChatListNodeInteraction { } public final class ChatListNodePeerInputActivities { - public let activities: [EnginePeer.Id: [(EnginePeer, PeerInputActivity)]] + public struct ItemId: Hashable { + public var peerId: EnginePeer.Id + public var threadId: Int64? + + public init(peerId: EnginePeer.Id, threadId: Int64?) { + self.peerId = peerId + self.threadId = threadId + } + } - public init(activities: [EnginePeer.Id: [(EnginePeer, PeerInputActivity)]]) { + public let activities: [ItemId: [(EnginePeer, PeerInputActivity)]] + + public init(activities: [ItemId: [(EnginePeer, PeerInputActivity)]]) { self.activities = activities } } @@ -1114,7 +1124,7 @@ public final class ChatListNode: ListView { let previousHideArchivedFolderByDefaultValue = previousHideArchivedFolderByDefault.swap(hideArchivedFolderByDefault) - let (rawEntries, isLoading) = chatListNodeEntriesForView(update.list, state: state, savedMessagesPeer: savedMessagesPeer, foundPeers: state.foundPeers, hideArchivedFolderByDefault: hideArchivedFolderByDefault, displayArchiveIntro: displayArchiveIntro, mode: mode) + let (rawEntries, isLoading) = chatListNodeEntriesForView(update.list, state: state, savedMessagesPeer: savedMessagesPeer, foundPeers: state.foundPeers, hideArchivedFolderByDefault: hideArchivedFolderByDefault, displayArchiveIntro: displayArchiveIntro, mode: mode, chatListLocation: location) let entries = rawEntries.filter { entry in switch entry { case let .PeerEntry(_, _, _, _, _, _, peer, _, _, _, _, _, _, _, _, _, _, _, _): @@ -1447,7 +1457,7 @@ public final class ChatListNode: ListView { let previousPeerCache = Atomic<[EnginePeer.Id: EnginePeer]>(value: [:]) let previousActivities = Atomic(value: nil) self.activityStatusesDisposable = (context.account.allPeerInputActivities() - |> mapToSignal { activitiesByPeerId -> Signal<[EnginePeer.Id: [(EnginePeer, PeerInputActivity)]], NoError> in + |> mapToSignal { activitiesByPeerId -> Signal<[ChatListNodePeerInputActivities.ItemId: [(EnginePeer, PeerInputActivity)]], NoError> in var activitiesByPeerId = activitiesByPeerId for key in activitiesByPeerId.keys { activitiesByPeerId[key]?.removeAll(where: { _, activity in @@ -1463,11 +1473,23 @@ public final class ChatListNode: ListView { } var foundAllPeers = true - var cachedResult: [EnginePeer.Id: [(EnginePeer, PeerInputActivity)]] = [:] + var cachedResult: [ChatListNodePeerInputActivities.ItemId: [(EnginePeer, PeerInputActivity)]] = [:] previousPeerCache.with { dict -> Void in for (chatPeerId, activities) in activitiesByPeerId { - guard case .global = chatPeerId.category else { - continue + var threadId: Int64? + switch location { + case .chatList: + guard case .global = chatPeerId.category else { + continue + } + case let .forum(peerId): + if chatPeerId.peerId != peerId { + continue + } + guard case let .thread(threadIdValue) = chatPeerId.category else { + continue + } + threadId = threadIdValue } var cachedChatResult: [(EnginePeer, PeerInputActivity)] = [] for (peerId, activity) in activities { @@ -1477,31 +1499,46 @@ public final class ChatListNode: ListView { foundAllPeers = false break } - cachedResult[chatPeerId.peerId] = cachedChatResult + cachedResult[ChatListNodePeerInputActivities.ItemId(peerId: chatPeerId.peerId, threadId: threadId)] = cachedChatResult } } } if foundAllPeers { return .single(cachedResult) } else { + var dataKeys: [EnginePeer.Id] = [] + for (peerId, activities) in activitiesByPeerId { + dataKeys.append(peerId.peerId) + for activity in activities { + dataKeys.append(activity.0) + } + } return engine.data.get(EngineDataMap( - activitiesByPeerId.keys.filter { key in - if case .global = key.category { - return true - } else { - return false - } - }.map { key in - return TelegramEngine.EngineData.Item.Peer.Peer(id: key.peerId) + Set(dataKeys).map { + TelegramEngine.EngineData.Item.Peer.Peer(id: $0) } )) - |> map { peerMap -> [EnginePeer.Id: [(EnginePeer, PeerInputActivity)]] in - var result: [EnginePeer.Id: [(EnginePeer, PeerInputActivity)]] = [:] + |> map { peerMap -> [ChatListNodePeerInputActivities.ItemId: [(EnginePeer, PeerInputActivity)]] in + var result: [ChatListNodePeerInputActivities.ItemId: [(EnginePeer, PeerInputActivity)]] = [:] var peerCache: [EnginePeer.Id: EnginePeer] = [:] for (chatPeerId, activities) in activitiesByPeerId { - guard case .global = chatPeerId.category else { - continue + let itemId: ChatListNodePeerInputActivities.ItemId + switch location { + case .chatList: + guard case .global = chatPeerId.category else { + continue + } + itemId = ChatListNodePeerInputActivities.ItemId(peerId: chatPeerId.peerId, threadId: nil) + case let .forum(peerId): + if chatPeerId.peerId != peerId { + continue + } + guard case let .thread(threadIdValue) = chatPeerId.category else { + continue + } + itemId = ChatListNodePeerInputActivities.ItemId(peerId: chatPeerId.peerId, threadId: threadIdValue) } + var chatResult: [(EnginePeer, PeerInputActivity)] = [] for (peerId, activity) in activities { @@ -1511,7 +1548,7 @@ public final class ChatListNode: ListView { } } - result[chatPeerId.peerId] = chatResult + result[itemId] = chatResult } let _ = previousPeerCache.swap(peerCache) return result @@ -1521,7 +1558,7 @@ public final class ChatListNode: ListView { |> map { activities -> ChatListNodePeerInputActivities? in return previousActivities.modify { current in var updated = false - let currentList: [EnginePeer.Id: [(EnginePeer, PeerInputActivity)]] = current?.activities ?? [:] + let currentList: [ChatListNodePeerInputActivities.ItemId: [(EnginePeer, PeerInputActivity)]] = current?.activities ?? [:] if currentList.count != activities.count { updated = true } else { diff --git a/submodules/ChatListUI/Sources/Node/ChatListNodeEntries.swift b/submodules/ChatListUI/Sources/Node/ChatListNodeEntries.swift index 7bf30c2f05..b66bf18d96 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNodeEntries.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNodeEntries.swift @@ -316,7 +316,7 @@ private func offsetPinnedIndex(_ index: EngineChatList.Item.Index, offset: UInt1 } } -func chatListNodeEntriesForView(_ view: EngineChatList, state: ChatListNodeState, savedMessagesPeer: EnginePeer?, foundPeers: [(EnginePeer, EnginePeer?)], hideArchivedFolderByDefault: Bool, displayArchiveIntro: Bool, mode: ChatListNodeMode) -> (entries: [ChatListNodeEntry], loading: Bool) { +func chatListNodeEntriesForView(_ view: EngineChatList, state: ChatListNodeState, savedMessagesPeer: EnginePeer?, foundPeers: [(EnginePeer, EnginePeer?)], hideArchivedFolderByDefault: Bool, displayArchiveIntro: Bool, mode: ChatListNodeMode, chatListLocation: ChatListControllerLocation) -> (entries: [ChatListNodeEntry], loading: Bool) { var result: [ChatListNodeEntry] = [] var pinnedIndexOffset: UInt16 = 0 @@ -343,8 +343,13 @@ func chatListNodeEntriesForView(_ view: EngineChatList, state: ChatListNodeState } loop: for entry in view.items { var peerId: EnginePeer.Id? + var activityItemId: ChatListNodePeerInputActivities.ItemId? if case let .chatList(index) = entry.index { peerId = index.messageIndex.id.peerId + activityItemId = ChatListNodePeerInputActivities.ItemId(peerId: index.messageIndex.id.peerId, threadId: nil) + } else if case let .forum(_, _, threadId, _, _) = entry.index, case let .forum(peerIdValue) = chatListLocation { + peerId = peerIdValue + activityItemId = ChatListNodePeerInputActivities.ItemId(peerId: peerIdValue, threadId: threadId) } if let savedMessagesPeer = savedMessagesPeer, let peerId = peerId, savedMessagesPeer.id == peerId || foundPeerIds.contains(peerId) { @@ -374,8 +379,8 @@ func chatListNodeEntriesForView(_ view: EngineChatList, state: ChatListNodeState isSelected = state.selectedPeerIds.contains(peerId) } var inputActivities: [(EnginePeer, PeerInputActivity)]? - if let peerId { - inputActivities = state.peerInputActivities?.activities[peerId] + if let activityItemId { + inputActivities = state.peerInputActivities?.activities[activityItemId] } var threadId: Int64 = 0 @@ -471,7 +476,7 @@ func chatListNodeEntriesForView(_ view: EngineChatList, state: ChatListNodeState editing: state.editing, hasActiveRevealControls: peerId == state.peerIdWithRevealedOptions, selected: isSelected, - inputActivities: state.peerInputActivities?.activities[peerId], + inputActivities: state.peerInputActivities?.activities[ChatListNodePeerInputActivities.ItemId(peerId: peerId, threadId: nil)], promoInfo: promoInfo, hasFailedMessages: item.item.hasFailed, isContact: item.item.isContact, diff --git a/submodules/Postbox/Sources/MessageHistoryMetadataTable.swift b/submodules/Postbox/Sources/MessageHistoryMetadataTable.swift index 1e2517bb89..ec03eeae0a 100644 --- a/submodules/Postbox/Sources/MessageHistoryMetadataTable.swift +++ b/submodules/Postbox/Sources/MessageHistoryMetadataTable.swift @@ -81,7 +81,7 @@ final class MessageHistoryMetadataTable: Table { private func peerThreadHoleIndexInitializedKey(peerId: PeerId, threadId: Int64) -> ValueBoxKey { self.sharedPeerThreadHoleIndexInitializedKey.setInt64(0, value: peerId.toInt64()) self.sharedPeerThreadHoleIndexInitializedKey.setInt8(8, value: MetadataPrefix.PeerHistoryThreadHoleIndexInitialized.rawValue) - self.sharedPeerThreadHoleIndexInitializedKey.setInt64(0, value: threadId) + self.sharedPeerThreadHoleIndexInitializedKey.setInt64(8 + 1, value: threadId) return self.sharedPeerThreadHoleIndexInitializedKey } diff --git a/submodules/Postbox/Sources/Postbox.swift b/submodules/Postbox/Sources/Postbox.swift index 873e742f05..ca5add8f93 100644 --- a/submodules/Postbox/Sources/Postbox.swift +++ b/submodules/Postbox/Sources/Postbox.swift @@ -1267,7 +1267,7 @@ public func openPostbox(basePath: String, seedConfiguration: SeedConfiguration, } #if DEBUG - debugSaveState(basePath: basePath, name: "previous1") + //debugSaveState(basePath: basePath, name: "previous1") //debugRestoreState(basePath: basePath, name: "previous1") #endif diff --git a/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift b/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift index cdcd4e4a5b..c227ba7d60 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift @@ -94,6 +94,10 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, ignoreMess let combinedInitialData = ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData) if preloaded { + if tagMask == nil && view.entries.isEmpty { + print("") + } + return .HistoryView(view: view, type: .Generic(type: updateType), scrollPosition: nil, flashIndicators: false, originalScrollPosition: nil, initialData: combinedInitialData, id: location.id) } else { if view.isLoading { @@ -102,7 +106,7 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, ignoreMess var scrollPosition: ChatHistoryViewScrollPosition? let canScrollToRead: Bool - if case .replyThread = chatLocation { + if case let .replyThread(message) = chatLocation, !message.isForumPost { canScrollToRead = true } else if view.isAddedToChatList { canScrollToRead = true @@ -114,7 +118,7 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, ignoreMess let aroundIndex = maxReadIndex scrollPosition = .unread(index: maxReadIndex) - if case .peer = chatLocation { + if let _ = chatLocation.peerId { var targetIndex = 0 for i in 0 ..< view.entries.count { if view.entries[i].index >= aroundIndex { @@ -152,7 +156,7 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, ignoreMess } else if view.isAddedToChatList, tagMask == nil, let historyScrollState = (initialData?.storedInterfaceState).flatMap(_internal_decodeStoredChatInterfaceState).flatMap(ChatInterfaceState.parse)?.historyScrollState { scrollPosition = .positionRestoration(index: historyScrollState.messageIndex, relativeOffset: CGFloat(historyScrollState.relativeOffset)) } else { - if case .peer = chatLocation, !view.isAddedToChatList { + if let _ = chatLocation.peerId, !view.isAddedToChatList { if view.holeEarlier && view.entries.count <= 2 { fadeIn = true return .Loading(initialData: combinedInitialData, type: .Generic(type: updateType)) @@ -164,6 +168,10 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, ignoreMess } } + if tagMask == nil && view.entries.isEmpty { + print("") + } + preloaded = true 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) }