[WIP] Topics

This commit is contained in:
Ali 2022-10-21 16:51:45 +04:00
parent 0378e1c5c4
commit 94d264900f
6 changed files with 89 additions and 33 deletions

View File

@ -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 {

View File

@ -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<ChatListNodePeerInputActivities?>(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 {

View File

@ -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,

View File

@ -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
}

View File

@ -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

View File

@ -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)
}