chore: migrate to new version + fixed several critical bugs

- Migrated project to latest Telegram iOS base (v12.3.2+)
- Fixed circular dependency between GhostModeManager and MiscSettingsManager
- Fixed multiple Bazel build configuration errors (select() default conditions)
- Fixed duplicate type definitions in PeerInfoScreen
- Fixed swiftmodule directory resolution in build scripts
- Added Ghostgram Settings tab in main Settings menu with all 5 features
- Cleared sensitive credentials from config.json (template-only now)
- Excluded bazel-cache from version control
This commit is contained in:
ichmagmaus 812
2026-02-23 23:04:32 +01:00
parent 703e291bcb
commit db53826061
1017 changed files with 62337 additions and 40559 deletions
@@ -15,7 +15,7 @@ final class MutableDeletedMessagesView: MutablePostboxView {
for operation in operations {
switch operation {
case let .Remove(indices):
for (index, _) in indices {
for (index, _, _) in indices {
testMessageIds.append(index.id)
}
default:
@@ -32,7 +32,7 @@ final class MutableHistoryTagInfoView: MutablePostboxView {
}
case let .Remove(indicesAndTags):
if self.currentIndex != nil {
for (index, tags) in indicesAndTags {
for (index, tags, _) in indicesAndTags {
if tags.contains(self.tag) {
if index == self.currentIndex {
self.currentIndex = nil
@@ -2,7 +2,7 @@ import Foundation
enum MessageHistoryOperation {
case InsertMessage(IntermediateMessage)
case Remove([(MessageIndex, MessageTags)])
case Remove([(MessageIndex, MessageTags, Int64?)])
case UpdateReadState(PeerId, CombinedPeerReadState)
case UpdateEmbeddedMedia(MessageIndex, ReadBuffer)
case UpdateTimestamp(MessageIndex, Int32)
@@ -197,19 +197,19 @@ final class MessageHistoryTable: Table {
let buckets = self.continuousIndexIntervalsForRemoving(accumulatedRemoveIndices)
for bucket in buckets {
var indicesWithMetadata: [(MessageIndex, MessageTags)] = []
var indicesWithMetadata: [(MessageIndex, MessageTags, Int64?)] = []
var globalIndicesWithMetadata: [(GlobalMessageTags, MessageIndex)] = []
for index in bucket {
let tagsAndGlobalTags = self.justRemove(index, unsentMessageOperations: &unsentMessageOperations, pendingActionsOperations: &pendingActionsOperations, updatedMessageActionsSummaries: &updatedMessageActionsSummaries, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, localTagsOperations: &localTagsOperations, timestampBasedMessageAttributesOperations: &timestampBasedMessageAttributesOperations)
if let (tags, globalTags) = tagsAndGlobalTags {
indicesWithMetadata.append((index, tags))
if let (tags, globalTags, threadId) = tagsAndGlobalTags {
indicesWithMetadata.append((index, tags, threadId))
if !globalTags.isEmpty {
globalIndicesWithMetadata.append((globalTags, index))
}
} else {
indicesWithMetadata.append((index, MessageTags()))
indicesWithMetadata.append((index, MessageTags(), nil))
}
}
assert(bucket.count == indicesWithMetadata.count)
@@ -352,8 +352,8 @@ final class MessageHistoryTable: Table {
processIndexOperationsCommitAccumulatedRemoveIndices(peerId: peerId, accumulatedRemoveIndices: &accumulatedRemoveIndices, updatedCombinedState: &updatedCombinedState, invalidateReadState: &invalidateReadState, unsentMessageOperations: &unsentMessageOperations, outputOperations: &outputOperations, globalTagsOperations: &globalTagsOperations, pendingActionsOperations: &pendingActionsOperations, updatedMessageActionsSummaries: &updatedMessageActionsSummaries, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, localTagsOperations: &localTagsOperations, timestampBasedMessageAttributesOperations: &timestampBasedMessageAttributesOperations)
var updatedGroupInfos: [MessageId: MessageGroupInfo] = [:]
if let (message, previousTags) = self.justUpdate(storeMessage.index, message: storeMessage, keepLocalTags: true, sharedKey: sharedKey, sharedBuffer: sharedBuffer, sharedEncoder: sharedEncoder, unsentMessageOperations: &unsentMessageOperations, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, updatedGroupInfos: &updatedGroupInfos, localTagsOperations: &localTagsOperations, timestampBasedMessageAttributesOperations: &timestampBasedMessageAttributesOperations, updatedMedia: &updatedMedia) {
outputOperations.append(.Remove([(storeMessage.index, previousTags)]))
if let (message, previousTags, previousThreadId) = self.justUpdate(storeMessage.index, message: storeMessage, keepLocalTags: true, sharedKey: sharedKey, sharedBuffer: sharedBuffer, sharedEncoder: sharedEncoder, unsentMessageOperations: &unsentMessageOperations, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, updatedGroupInfos: &updatedGroupInfos, localTagsOperations: &localTagsOperations, timestampBasedMessageAttributesOperations: &timestampBasedMessageAttributesOperations, updatedMedia: &updatedMedia) {
outputOperations.append(.Remove([(storeMessage.index, previousTags, previousThreadId)]))
outputOperations.append(.InsertMessage(message))
if !updatedGroupInfos.isEmpty {
outputOperations.append(.UpdateGroupInfos(updatedGroupInfos))
@@ -367,8 +367,8 @@ final class MessageHistoryTable: Table {
processIndexOperationsCommitAccumulatedRemoveIndices(peerId: peerId, accumulatedRemoveIndices: &accumulatedRemoveIndices, updatedCombinedState: &updatedCombinedState, invalidateReadState: &invalidateReadState, unsentMessageOperations: &unsentMessageOperations, outputOperations: &outputOperations, globalTagsOperations: &globalTagsOperations, pendingActionsOperations: &pendingActionsOperations, updatedMessageActionsSummaries: &updatedMessageActionsSummaries, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, localTagsOperations: &localTagsOperations, timestampBasedMessageAttributesOperations: &timestampBasedMessageAttributesOperations)
var updatedGroupInfos: [MessageId: MessageGroupInfo] = [:]
if let (message, previousTags) = self.justUpdate(index, message: storeMessage, keepLocalTags: false, sharedKey: sharedKey, sharedBuffer: sharedBuffer, sharedEncoder: sharedEncoder, unsentMessageOperations: &unsentMessageOperations, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, updatedGroupInfos: &updatedGroupInfos, localTagsOperations: &localTagsOperations, timestampBasedMessageAttributesOperations: &timestampBasedMessageAttributesOperations, updatedMedia: &updatedMedia) {
outputOperations.append(.Remove([(index, previousTags)]))
if let (message, previousTags, previousThreadId) = self.justUpdate(index, message: storeMessage, keepLocalTags: false, sharedKey: sharedKey, sharedBuffer: sharedBuffer, sharedEncoder: sharedEncoder, unsentMessageOperations: &unsentMessageOperations, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, updatedGroupInfos: &updatedGroupInfos, localTagsOperations: &localTagsOperations, timestampBasedMessageAttributesOperations: &timestampBasedMessageAttributesOperations, updatedMedia: &updatedMedia) {
outputOperations.append(.Remove([(index, previousTags, previousThreadId)]))
outputOperations.append(.InsertMessage(message))
if !updatedGroupInfos.isEmpty {
outputOperations.append(.UpdateGroupInfos(updatedGroupInfos))
@@ -944,7 +944,7 @@ final class MessageHistoryTable: Table {
self.storeIntermediateMessage(updatedMessage, sharedKey: self.key(MessageIndex.absoluteLowerBound()))
let operations: [MessageHistoryOperation] = [
.Remove([(index, message.tags)]),
.Remove([(index, message.tags, message.threadId)]),
.InsertMessage(updatedMessage)
]
if operationsByPeerId[message.id.peerId] == nil {
@@ -1352,7 +1352,7 @@ final class MessageHistoryTable: Table {
return result
}
private func justRemove(_ index: MessageIndex, unsentMessageOperations: inout [IntermediateMessageHistoryUnsentOperation], pendingActionsOperations: inout [PendingMessageActionsOperation], updatedMessageActionsSummaries: inout [PendingMessageActionsSummaryKey: Int32], updatedMessageTagSummaries: inout [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], invalidateMessageTagSummaries: inout [InvalidatedMessageHistoryTagsSummaryEntryOperation], localTagsOperations: inout [IntermediateMessageHistoryLocalTagsOperation], timestampBasedMessageAttributesOperations: inout [TimestampBasedMessageAttributesOperation]) -> (MessageTags, GlobalMessageTags)? {
private func justRemove(_ index: MessageIndex, unsentMessageOperations: inout [IntermediateMessageHistoryUnsentOperation], pendingActionsOperations: inout [PendingMessageActionsOperation], updatedMessageActionsSummaries: inout [PendingMessageActionsSummaryKey: Int32], updatedMessageTagSummaries: inout [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], invalidateMessageTagSummaries: inout [InvalidatedMessageHistoryTagsSummaryEntryOperation], localTagsOperations: inout [IntermediateMessageHistoryLocalTagsOperation], timestampBasedMessageAttributesOperations: inout [TimestampBasedMessageAttributesOperation]) -> (MessageTags, GlobalMessageTags, Int64?)? {
let key = self.key(index)
if let value = self.valueBox.get(self.table, key: key) {
let resultTags: MessageTags
@@ -1440,7 +1440,7 @@ final class MessageHistoryTable: Table {
resultGlobalTags = message.globalTags
self.valueBox.remove(self.table, key: key, secure: true)
return (resultTags, resultGlobalTags)
return (resultTags, resultGlobalTags, message.threadId)
} else {
return nil
}
@@ -1544,7 +1544,7 @@ final class MessageHistoryTable: Table {
})
}
private func justUpdate(_ index: MessageIndex, message: InternalStoreMessage, keepLocalTags: Bool, sharedKey: ValueBoxKey, sharedBuffer: WriteBuffer, sharedEncoder: PostboxEncoder, unsentMessageOperations: inout [IntermediateMessageHistoryUnsentOperation], updatedMessageTagSummaries: inout [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], invalidateMessageTagSummaries: inout [InvalidatedMessageHistoryTagsSummaryEntryOperation], updatedGroupInfos: inout [MessageId: MessageGroupInfo], localTagsOperations: inout [IntermediateMessageHistoryLocalTagsOperation], timestampBasedMessageAttributesOperations: inout [TimestampBasedMessageAttributesOperation], updatedMedia: inout [MediaId: Media?]) -> (IntermediateMessage, MessageTags)? {
private func justUpdate(_ index: MessageIndex, message: InternalStoreMessage, keepLocalTags: Bool, sharedKey: ValueBoxKey, sharedBuffer: WriteBuffer, sharedEncoder: PostboxEncoder, unsentMessageOperations: inout [IntermediateMessageHistoryUnsentOperation], updatedMessageTagSummaries: inout [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], invalidateMessageTagSummaries: inout [InvalidatedMessageHistoryTagsSummaryEntryOperation], updatedGroupInfos: inout [MessageId: MessageGroupInfo], localTagsOperations: inout [IntermediateMessageHistoryLocalTagsOperation], timestampBasedMessageAttributesOperations: inout [TimestampBasedMessageAttributesOperation], updatedMedia: inout [MediaId: Media?]) -> (IntermediateMessage, MessageTags, Int64?)? {
if let previousMessage = self.getMessage(index) {
var mediaToUpdate: [Media] = []
@@ -2037,7 +2037,7 @@ final class MessageHistoryTable: Table {
self.valueBox.set(self.table, key: self.key(message.index, key: sharedKey), value: sharedBuffer)
let result = (IntermediateMessage(stableId: stableId, stableVersion: stableVersion, id: message.id, globallyUniqueId: message.globallyUniqueId, groupingKey: message.groupingKey, groupInfo: groupInfo, threadId: message.threadId, timestamp: message.timestamp, flags: flags, tags: tags, globalTags: message.globalTags, localTags: updatedLocalTags, customTags: message.customTags, forwardInfo: intermediateForwardInfo, authorId: message.authorId, text: message.text, attributesData: attributesBuffer.makeReadBufferAndReset(), embeddedMediaData: embeddedMediaBuffer.makeReadBufferAndReset(), referencedMedia: referencedMedia), previousMessage.tags)
let result = (IntermediateMessage(stableId: stableId, stableVersion: stableVersion, id: message.id, globallyUniqueId: message.globallyUniqueId, groupingKey: message.groupingKey, groupInfo: groupInfo, threadId: message.threadId, timestamp: message.timestamp, flags: flags, tags: tags, globalTags: message.globalTags, localTags: updatedLocalTags, customTags: message.customTags, forwardInfo: intermediateForwardInfo, authorId: message.authorId, text: message.text, attributesData: attributesBuffer.makeReadBufferAndReset(), embeddedMediaData: embeddedMediaBuffer.makeReadBufferAndReset(), referencedMedia: referencedMedia), previousMessage.tags, previousMessage.threadId)
for media in mediaToUpdate {
if let id = media.id {
@@ -676,7 +676,7 @@ final class MutableMessageHistoryView: MutablePostboxView {
}
}
case let .Remove(indicesAndTags):
for (index, _) in indicesAndTags {
for (index, _, _) in indicesAndTags {
if self.namespaces.contains(index.id.namespace) {
if loadedState.remove(index: index) {
hasChanges = true
@@ -821,7 +821,7 @@ final class MutableMessageHistoryView: MutablePostboxView {
}
case let .Remove(indices):
if !self.topTaggedMessages.isEmpty {
for (index, _) in indices {
for (index, _, _) in indices {
if let maybeCurrentTopMessage = self.topTaggedMessages[index.id.namespace], let currentTopMessage = maybeCurrentTopMessage, index.id == currentTopMessage.id {
let item: MessageHistoryTopTaggedMessage? = nil
self.topTaggedMessages[index.id.namespace] = item
@@ -873,7 +873,7 @@ final class MutableMessageHistoryView: MutablePostboxView {
break findOperation
}
case let .Remove(indices):
for (index, _) in indices {
for (index, _, _) in indices {
if currentIds.contains(index.id) {
updateMessage = true
break findOperation
@@ -956,7 +956,7 @@ final class MutableMessageHistoryView: MutablePostboxView {
break outer
}
case let .Remove(indicesWithTags):
for (index, _) in indicesWithTags {
for (index, _, _) in indicesWithTags {
if cachedData.messageIds.contains(index.id) {
updatedCachedPeerDataMessages = true
break outer
+1 -1
View File
@@ -18,7 +18,7 @@ final class MutableMessageView {
case let .Remove(indices):
if let message = self.message {
let messageIndex = message.index
for (index, _) in indices {
for (index, _, _) in indices {
if index == messageIndex {
self.message = nil
updated = true
@@ -1,7 +1,7 @@
import Foundation
private struct PeerChatTopTaggedUpdateRecord: Equatable, Hashable {
let peerId: PeerId
let peerAndThreadId: PeerAndThreadId
let namespace: MessageId.Namespace
}
@@ -10,71 +10,85 @@ final class PeerChatTopTaggedMessageIdsTable: Table {
return ValueBoxTable(id: id, keyType: .binary, compactValuesOnCreation: true)
}
private var cachedTopIds: [PeerId: [MessageId.Namespace: MessageId?]] = [:]
private var cachedTopIds: [PeerAndThreadId: [MessageId.Namespace: MessageId?]] = [:]
private var updatedPeerIds = Set<PeerChatTopTaggedUpdateRecord>()
private let sharedKey = ValueBoxKey(length: 8 + 4)
private let sharedKeyNoThreadId = ValueBoxKey(length: 8 + 4)
private let sharedKeyWithThreadId = ValueBoxKey(length: 8 + 4 + 8)
private func key(peerId: PeerId, namespace: MessageId.Namespace) -> ValueBoxKey {
self.sharedKey.setInt64(0, value: peerId.toInt64())
self.sharedKey.setInt32(8, value: namespace)
return self.sharedKey
private func key(combinedId: PeerAndThreadId, namespace: MessageId.Namespace) -> ValueBoxKey {
if let threadId = combinedId.threadId {
self.sharedKeyWithThreadId.setInt64(0, value: combinedId.peerId.toInt64())
self.sharedKeyWithThreadId.setInt32(8, value: namespace)
self.sharedKeyWithThreadId.setInt64(8 + 4, value: threadId)
return self.sharedKeyWithThreadId
} else {
self.sharedKeyNoThreadId.setInt64(0, value: combinedId.peerId.toInt64())
self.sharedKeyNoThreadId.setInt32(8, value: namespace)
return self.sharedKeyNoThreadId
}
}
func get(peerId: PeerId, namespace: MessageId.Namespace) -> MessageId? {
if let cachedDict = self.cachedTopIds[peerId] {
func get(peerId: PeerId, threadId: Int64?, namespace: MessageId.Namespace) -> MessageId? {
let combinedId = PeerAndThreadId(peerId: peerId, threadId: threadId)
if let cachedDict = self.cachedTopIds[combinedId] {
if let maybeCachedId = cachedDict[namespace] {
return maybeCachedId
} else {
if let value = self.valueBox.get(self.table, key: self.key(peerId: peerId, namespace: namespace)) {
if let value = self.valueBox.get(self.table, key: self.key(combinedId: combinedId, namespace: namespace)) {
var messageIdId: Int32 = 0
value.read(&messageIdId, offset: 0, length: 4)
self.cachedTopIds[peerId]![namespace] = MessageId(peerId: peerId, namespace: namespace, id: messageIdId)
self.cachedTopIds[combinedId]![namespace] = MessageId(peerId: peerId, namespace: namespace, id: messageIdId)
return MessageId(peerId: peerId, namespace: namespace, id: messageIdId)
} else {
let item: MessageId? = nil
self.cachedTopIds[peerId]![namespace] = item
self.cachedTopIds[combinedId]![namespace] = item
return nil
}
}
} else {
if let value = self.valueBox.get(self.table, key: self.key(peerId: peerId, namespace: namespace)) {
if let value = self.valueBox.get(self.table, key: self.key(combinedId: combinedId, namespace: namespace)) {
var messageIdId: Int32 = 0
value.read(&messageIdId, offset: 0, length: 4)
self.cachedTopIds[peerId] = [namespace: MessageId(peerId: peerId, namespace: namespace, id: messageIdId)]
self.cachedTopIds[combinedId] = [namespace: MessageId(peerId: peerId, namespace: namespace, id: messageIdId)]
return MessageId(peerId: peerId, namespace: namespace, id: messageIdId)
} else {
let item: MessageId? = nil
self.cachedTopIds[peerId] = [namespace: item]
self.cachedTopIds[combinedId] = [namespace: item]
return nil
}
}
}
private func set(peerId: PeerId, namespace: MessageId.Namespace, id: MessageId?) {
if let _ = self.cachedTopIds[peerId] {
self.cachedTopIds[peerId]![namespace] = id
private func set(peerId: PeerId, threadId: Int64?, namespace: MessageId.Namespace, id: MessageId?) {
let combinedId = PeerAndThreadId(peerId: peerId, threadId: threadId)
if let _ = self.cachedTopIds[combinedId] {
self.cachedTopIds[combinedId]![namespace] = id
} else {
self.cachedTopIds[peerId] = [namespace: id]
self.cachedTopIds[combinedId] = [namespace: id]
}
self.updatedPeerIds.insert(PeerChatTopTaggedUpdateRecord(peerId: peerId, namespace: namespace))
self.updatedPeerIds.insert(PeerChatTopTaggedUpdateRecord(peerAndThreadId: combinedId, namespace: namespace))
}
func replay(historyOperationsByPeerId: [PeerId : [MessageHistoryOperation]]) {
func replay(historyOperationsByPeerId: [PeerId: [MessageHistoryOperation]]) {
for (_, operations) in historyOperationsByPeerId {
for operation in operations {
switch operation {
case let .InsertMessage(message):
if message.flags.contains(.TopIndexable) {
let currentTopMessageId = self.get(peerId: message.id.peerId, namespace: message.id.namespace)
let currentTopMessageId = self.get(peerId: message.id.peerId, threadId: message.threadId, namespace: message.id.namespace)
if currentTopMessageId == nil || currentTopMessageId! < message.id {
self.set(peerId: message.id.peerId, namespace: message.id.namespace, id: message.id)
self.set(peerId: message.id.peerId, threadId: message.threadId, namespace: message.id.namespace, id: message.id)
}
}
case let .Remove(indices):
for (index, _) in indices {
if let messageId = self.get(peerId: index.id.peerId, namespace: index.id.namespace), index.id == messageId {
self.set(peerId: index.id.peerId, namespace: index.id.namespace, id: nil)
for (index, _, threadId) in indices {
if let messageId = self.get(peerId: index.id.peerId, threadId: threadId, namespace: index.id.namespace), index.id == messageId {
self.set(peerId: index.id.peerId, threadId: threadId, namespace: index.id.namespace, id: nil)
}
}
default:
@@ -92,12 +106,12 @@ final class PeerChatTopTaggedMessageIdsTable: Table {
override func beforeCommit() {
if !self.updatedPeerIds.isEmpty {
for record in self.updatedPeerIds {
if let cachedDict = self.cachedTopIds[record.peerId], let maybeMessageId = cachedDict[record.namespace] {
if let cachedDict = self.cachedTopIds[record.peerAndThreadId], let maybeMessageId = cachedDict[record.namespace] {
if let maybeMessageId = maybeMessageId {
var messageIdId: Int32 = maybeMessageId.id
self.valueBox.set(self.table, key: self.key(peerId: record.peerId, namespace: record.namespace), value: MemoryBuffer(memory: &messageIdId, capacity: 4, length: 4, freeWhenDone: false))
self.valueBox.set(self.table, key: self.key(combinedId: record.peerAndThreadId, namespace: record.namespace), value: MemoryBuffer(memory: &messageIdId, capacity: 4, length: 4, freeWhenDone: false))
} else {
self.valueBox.remove(self.table, key: self.key(peerId: record.peerId, namespace: record.namespace), secure: false)
self.valueBox.remove(self.table, key: self.key(combinedId: record.peerAndThreadId, namespace: record.namespace), secure: false)
}
}
}
+1 -1
View File
@@ -247,7 +247,7 @@ final class MutablePeerView: MutablePostboxView {
break outer
}
case let .Remove(indicesWithTags):
for (index, _) in indicesWithTags {
for (index, _, _) in indicesWithTags {
if cachedData.messageIds.contains(index.id) {
updateMessages = true
break outer
+7 -7
View File
@@ -3494,20 +3494,20 @@ final class PostboxImpl {
useRootInterfaceStateForThread: Bool
) -> Disposable {
var topTaggedMessages: [MessageId.Namespace: MessageHistoryTopTaggedMessage?] = [:]
var mainPeerIdForTopTaggedMessages: PeerId?
switch peerIds {
var mainPeerIdForTopTaggedMessages: (peerId: PeerId, threadId: Int64?)?
if tag == nil {
switch peerIds {
case let .single(id, threadId):
if threadId == nil {
mainPeerIdForTopTaggedMessages = id
}
mainPeerIdForTopTaggedMessages = (id, threadId)
case let .associated(id, _):
mainPeerIdForTopTaggedMessages = id
mainPeerIdForTopTaggedMessages = (id, nil)
case .external:
mainPeerIdForTopTaggedMessages = nil
}
}
if let peerId = mainPeerIdForTopTaggedMessages {
for namespace in topTaggedMessageIdNamespaces {
if let messageId = self.peerChatTopTaggedMessageIdsTable.get(peerId: peerId, namespace: namespace) {
if let messageId = self.peerChatTopTaggedMessageIdsTable.get(peerId: peerId.peerId, threadId: peerId.threadId, namespace: namespace) {
if let index = self.messageHistoryIndexTable.getIndex(messageId) {
if let message = self.messageHistoryTable.getMessage(index) {
topTaggedMessages[namespace] = MessageHistoryTopTaggedMessage.intermediate(message)