Monoforums

This commit is contained in:
Isaac 2025-05-27 13:13:53 +08:00
parent 0d56fcc294
commit e2bc739c7f
7 changed files with 102 additions and 18 deletions

View File

@ -679,13 +679,16 @@ final class MutableMessageHistoryView: MutablePostboxView {
hasChanges = true hasChanges = true
} }
case let .UpdateReadState(peerId, combinedReadState): case let .UpdateReadState(peerId, combinedReadState):
hasChanges = true if case let .single(_, threadId) = self.peerIds, threadId != nil {
if let transientReadStates = self.transientReadStates { } else {
switch transientReadStates { hasChanges = true
case let .peer(states): if let transientReadStates = self.transientReadStates {
var updatedStates = states switch transientReadStates {
updatedStates[peerId] = combinedReadState case let .peer(states):
self.transientReadStates = .peer(updatedStates) var updatedStates = states
updatedStates[peerId] = combinedReadState
self.transientReadStates = .peer(updatedStates)
}
} }
} }
case let .UpdateTimestamp(index, timestamp): case let .UpdateTimestamp(index, timestamp):
@ -698,8 +701,15 @@ final class MutableMessageHistoryView: MutablePostboxView {
var currentThreadId: Int64? var currentThreadId: Int64?
switch self.peerIds { switch self.peerIds {
case let .single(_, threadIdValue): case let .single(peerId, threadIdValue):
currentThreadId = threadIdValue currentThreadId = threadIdValue
if let threadIdValue, transaction.updatedPeerThreadInfos.contains(MessageHistoryThreadsTable.ItemId(peerId: peerId, threadId: threadIdValue)) {
if let threadData = postbox.messageHistoryThreadIndexTable.get(peerId: peerId, threadId: threadIdValue) {
hasChanges = true
self.transientReadStates = .peer([peerId: CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 0, maxOutgoingReadId: threadData.summary.maxOutgoingReadId, maxKnownId: 0, count: 0, markedUnread: false))])])
}
}
case .associated: case .associated:
break break
case .external: case .external:

View File

@ -5,17 +5,20 @@ public struct StoredMessageHistoryThreadInfo: Equatable, PostboxCoding {
public var totalUnreadCount: Int32 public var totalUnreadCount: Int32
public var isMarkedUnread: Bool public var isMarkedUnread: Bool
public var mutedUntil: Int32? public var mutedUntil: Int32?
public var maxOutgoingReadId: Int32
public init(totalUnreadCount: Int32, isMarkedUnread: Bool, mutedUntil: Int32?) { public init(totalUnreadCount: Int32, isMarkedUnread: Bool, mutedUntil: Int32?, maxOutgoingReadId: Int32) {
self.totalUnreadCount = totalUnreadCount self.totalUnreadCount = totalUnreadCount
self.isMarkedUnread = isMarkedUnread self.isMarkedUnread = isMarkedUnread
self.mutedUntil = mutedUntil self.mutedUntil = mutedUntil
self.maxOutgoingReadId = maxOutgoingReadId
} }
public init(decoder: PostboxDecoder) { public init(decoder: PostboxDecoder) {
self.totalUnreadCount = decoder.decodeInt32ForKey("u", orElse: 0) self.totalUnreadCount = decoder.decodeInt32ForKey("u", orElse: 0)
self.mutedUntil = decoder.decodeOptionalInt32ForKey("m") self.mutedUntil = decoder.decodeOptionalInt32ForKey("m")
self.isMarkedUnread = decoder.decodeBoolForKey("mu", orElse: false) self.isMarkedUnread = decoder.decodeBoolForKey("mu", orElse: false)
self.maxOutgoingReadId = decoder.decodeInt32ForKey("or", orElse: 0)
} }
public func encode(_ encoder: PostboxEncoder) { public func encode(_ encoder: PostboxEncoder) {
@ -26,6 +29,7 @@ public struct StoredMessageHistoryThreadInfo: Equatable, PostboxCoding {
} else { } else {
encoder.encodeNil(forKey: "m") encoder.encodeNil(forKey: "m")
} }
encoder.encodeInt32(self.maxOutgoingReadId, forKey: "or")
} }
} }
@ -112,7 +116,7 @@ class MessageHistoryThreadIndexTable: Table {
return ValueBoxTable(id: id, keyType: .binary, compactValuesOnCreation: true) return ValueBoxTable(id: id, keyType: .binary, compactValuesOnCreation: true)
} }
private struct UpdatedEntry { struct UpdatedEntry {
var value: StoredMessageHistoryThreadInfo? var value: StoredMessageHistoryThreadInfo?
} }
@ -127,7 +131,7 @@ class MessageHistoryThreadIndexTable: Table {
private let sharedKey = ValueBoxKey(length: 8 + 4 + 8 + 4 + 4) private let sharedKey = ValueBoxKey(length: 8 + 4 + 8 + 4 + 4)
private var updatedInfoItems: [MessageHistoryThreadsTable.ItemId: UpdatedEntry] = [:] private(set) var updatedInfoItems: [MessageHistoryThreadsTable.ItemId: UpdatedEntry] = [:]
init(valueBox: ValueBox, table: ValueBoxTable, reverseIndexTable: MessageHistoryThreadReverseIndexTable, seedConfiguration: SeedConfiguration, useCaches: Bool) { init(valueBox: ValueBox, table: ValueBoxTable, reverseIndexTable: MessageHistoryThreadReverseIndexTable, seedConfiguration: SeedConfiguration, useCaches: Bool) {
self.reverseIndexTable = reverseIndexTable self.reverseIndexTable = reverseIndexTable

View File

@ -2456,6 +2456,7 @@ final class PostboxImpl {
let transactionParticipationInTotalUnreadCountUpdates = self.peerNotificationSettingsTable.transactionParticipationInTotalUnreadCountUpdates(postbox: self, transaction: currentTransaction) let transactionParticipationInTotalUnreadCountUpdates = self.peerNotificationSettingsTable.transactionParticipationInTotalUnreadCountUpdates(postbox: self, transaction: currentTransaction)
let updatedMessageThreadPeerIds = self.messageHistoryThreadIndexTable.replay(threadsTable: self.messageHistoryThreadsTable, namespaces: self.seedConfiguration.chatMessagesNamespaces, updatedIds: self.messageHistoryThreadsTable.updatedIds) let updatedMessageThreadPeerIds = self.messageHistoryThreadIndexTable.replay(threadsTable: self.messageHistoryThreadsTable, namespaces: self.seedConfiguration.chatMessagesNamespaces, updatedIds: self.messageHistoryThreadsTable.updatedIds)
let updatedPeerThreadInfos = Set(self.messageHistoryThreadIndexTable.updatedInfoItems.keys)
let alteredInitialPeerThreadsSummaries = self.peerThreadsSummaryTable.update(peerIds: updatedMessageThreadPeerIds.union(self.currentUpdatedPeerThreadCombinedStates), indexTable: self.messageHistoryThreadIndexTable, combinedStateTable: self.peerThreadCombinedStateTable, tagsSummaryTable: self.messageHistoryTagsSummaryTable) let alteredInitialPeerThreadsSummaries = self.peerThreadsSummaryTable.update(peerIds: updatedMessageThreadPeerIds.union(self.currentUpdatedPeerThreadCombinedStates), indexTable: self.messageHistoryThreadIndexTable, combinedStateTable: self.peerThreadCombinedStateTable, tagsSummaryTable: self.messageHistoryTagsSummaryTable)
self.chatListIndexTable.commitWithTransaction( self.chatListIndexTable.commitWithTransaction(
@ -2479,7 +2480,62 @@ final class PostboxImpl {
let updatedPeerTimeoutAttributes = self.peerTimeoutPropertiesTable.hasUpdates let updatedPeerTimeoutAttributes = self.peerTimeoutPropertiesTable.hasUpdates
let transaction = PostboxTransaction(currentUpdatedState: self.currentUpdatedState, currentPeerHoleOperations: self.currentPeerHoleOperations, currentOperationsByPeerId: self.currentOperationsByPeerId, chatListOperations: self.currentChatListOperations, currentUpdatedChatListInclusions: self.currentUpdatedChatListInclusions, currentUpdatedPeers: self.currentUpdatedPeers, currentUpdatedPeerNotificationSettings: self.currentUpdatedPeerNotificationSettings, currentUpdatedPeerNotificationBehaviorTimestamps: self.currentUpdatedPeerNotificationBehaviorTimestamps, currentUpdatedCachedPeerData: self.currentUpdatedCachedPeerData, currentUpdatedPeerPresences: currentUpdatedPeerPresences, currentUpdatedPeerChatListEmbeddedStates: self.currentUpdatedPeerChatListEmbeddedStates, currentUpdatedTotalUnreadStates: self.currentUpdatedTotalUnreadStates, currentUpdatedTotalUnreadSummaries: self.currentUpdatedGroupTotalUnreadSummaries, alteredInitialPeerCombinedReadStates: alteredInitialPeerCombinedReadStates, currentPeerMergedOperationLogOperations: self.currentPeerMergedOperationLogOperations, currentTimestampBasedMessageAttributesOperations: self.currentTimestampBasedMessageAttributesOperations, unsentMessageOperations: self.currentUnsentOperations, updatedSynchronizePeerReadStateOperations: self.currentUpdatedSynchronizeReadStateOperations, currentUpdatedGroupSummarySynchronizeOperations: self.currentUpdatedGroupSummarySynchronizeOperations, currentPreferencesOperations: self.currentPreferencesOperations, currentOrderedItemListOperations: self.currentOrderedItemListOperations, currentItemCollectionItemsOperations: self.currentItemCollectionItemsOperations, currentItemCollectionInfosOperations: self.currentItemCollectionInfosOperations, currentUpdatedPeerChatStates: self.currentUpdatedPeerChatStates, currentGlobalTagsOperations: self.currentGlobalTagsOperations, currentLocalTagsOperations: self.currentLocalTagsOperations, updatedMedia: self.currentUpdatedMedia, replaceRemoteContactCount: self.currentReplaceRemoteContactCount, replaceContactPeerIds: self.currentReplacedContactPeerIds, currentPendingMessageActionsOperations: self.currentPendingMessageActionsOperations, currentUpdatedMessageActionsSummaries: self.currentUpdatedMessageActionsSummaries, currentUpdatedMessageTagSummaries: self.currentUpdatedMessageTagSummaries, currentInvalidateMessageTagSummaries: self.currentInvalidateMessageTagSummaries, currentUpdatedPendingPeerNotificationSettings: self.currentUpdatedPendingPeerNotificationSettings, replacedAdditionalChatListItems: self.currentReplacedAdditionalChatListItems, updatedNoticeEntryKeys: self.currentUpdatedNoticeEntryKeys, updatedCacheEntryKeys: self.currentUpdatedCacheEntryKeys, currentUpdatedMasterClientId: currentUpdatedMasterClientId, updatedFailedMessagePeerIds: self.messageHistoryFailedTable.updatedPeerIds, updatedFailedMessageIds: self.messageHistoryFailedTable.updatedMessageIds, updatedGlobalNotificationSettings: self.currentNeedsReindexUnreadCounters, updatedPeerTimeoutAttributes: updatedPeerTimeoutAttributes, updatedMessageThreadPeerIds: updatedMessageThreadPeerIds, updatedPeerThreadCombinedStates: self.currentUpdatedPeerThreadCombinedStates, updatedPeerThreadsSummaries: Set(alteredInitialPeerThreadsSummaries.keys), updatedPinnedThreads: self.currentUpdatedPinnedThreads, updatedHiddenPeerIds: self.currentUpdatedHiddenPeerIds, storyGeneralStatesEvents: self.currentStoryGeneralStatesEvents, storyPeerStatesEvents: self.currentStoryPeerStatesEvents, storySubscriptionsEvents: self.currentStorySubscriptionsEvents, storyItemsEvents: self.currentStoryItemsEvents, currentStoryTopItemEvents: self.currentStoryTopItemEvents, storyEvents: self.currentStoryEvents) let transaction = PostboxTransaction(
currentUpdatedState: self.currentUpdatedState,
currentPeerHoleOperations: self.currentPeerHoleOperations,
currentOperationsByPeerId: self.currentOperationsByPeerId,
chatListOperations: self.currentChatListOperations,
currentUpdatedChatListInclusions: self.currentUpdatedChatListInclusions,
currentUpdatedPeers: self.currentUpdatedPeers,
currentUpdatedPeerNotificationSettings: self.currentUpdatedPeerNotificationSettings,
currentUpdatedPeerNotificationBehaviorTimestamps: self.currentUpdatedPeerNotificationBehaviorTimestamps,
currentUpdatedCachedPeerData: self.currentUpdatedCachedPeerData,
currentUpdatedPeerPresences: currentUpdatedPeerPresences,
currentUpdatedPeerChatListEmbeddedStates: self.currentUpdatedPeerChatListEmbeddedStates,
currentUpdatedTotalUnreadStates: self.currentUpdatedTotalUnreadStates,
currentUpdatedTotalUnreadSummaries: self.currentUpdatedGroupTotalUnreadSummaries,
alteredInitialPeerCombinedReadStates: alteredInitialPeerCombinedReadStates,
currentPeerMergedOperationLogOperations: self.currentPeerMergedOperationLogOperations,
currentTimestampBasedMessageAttributesOperations: self.currentTimestampBasedMessageAttributesOperations,
unsentMessageOperations: self.currentUnsentOperations,
updatedSynchronizePeerReadStateOperations: self.currentUpdatedSynchronizeReadStateOperations,
currentUpdatedGroupSummarySynchronizeOperations: self.currentUpdatedGroupSummarySynchronizeOperations,
currentPreferencesOperations: self.currentPreferencesOperations,
currentOrderedItemListOperations: self.currentOrderedItemListOperations,
currentItemCollectionItemsOperations: self.currentItemCollectionItemsOperations,
currentItemCollectionInfosOperations: self.currentItemCollectionInfosOperations,
currentUpdatedPeerChatStates: self.currentUpdatedPeerChatStates,
currentGlobalTagsOperations: self.currentGlobalTagsOperations,
currentLocalTagsOperations: self.currentLocalTagsOperations,
updatedMedia: self.currentUpdatedMedia,
replaceRemoteContactCount: self.currentReplaceRemoteContactCount,
replaceContactPeerIds: self.currentReplacedContactPeerIds,
currentPendingMessageActionsOperations: self.currentPendingMessageActionsOperations,
currentUpdatedMessageActionsSummaries: self.currentUpdatedMessageActionsSummaries,
currentUpdatedMessageTagSummaries: self.currentUpdatedMessageTagSummaries,
currentInvalidateMessageTagSummaries: self.currentInvalidateMessageTagSummaries,
currentUpdatedPendingPeerNotificationSettings: self.currentUpdatedPendingPeerNotificationSettings,
replacedAdditionalChatListItems: self.currentReplacedAdditionalChatListItems,
updatedNoticeEntryKeys: self.currentUpdatedNoticeEntryKeys,
updatedCacheEntryKeys: self.currentUpdatedCacheEntryKeys,
currentUpdatedMasterClientId: currentUpdatedMasterClientId,
updatedFailedMessagePeerIds: self.messageHistoryFailedTable.updatedPeerIds,
updatedFailedMessageIds: self.messageHistoryFailedTable.updatedMessageIds,
updatedGlobalNotificationSettings: self.currentNeedsReindexUnreadCounters,
updatedPeerTimeoutAttributes: updatedPeerTimeoutAttributes,
updatedMessageThreadPeerIds: updatedMessageThreadPeerIds,
updatedPeerThreadCombinedStates: self.currentUpdatedPeerThreadCombinedStates,
updatedPeerThreadsSummaries: Set(alteredInitialPeerThreadsSummaries.keys),
updatedPeerThreadInfos: updatedPeerThreadInfos,
updatedPinnedThreads: self.currentUpdatedPinnedThreads,
updatedHiddenPeerIds: self.currentUpdatedHiddenPeerIds,
storyGeneralStatesEvents: self.currentStoryGeneralStatesEvents,
storyPeerStatesEvents: self.currentStoryPeerStatesEvents,
storySubscriptionsEvents: self.currentStorySubscriptionsEvents,
storyItemsEvents: self.currentStoryItemsEvents,
currentStoryTopItemEvents: self.currentStoryTopItemEvents,
storyEvents: self.currentStoryEvents
)
var updatedTransactionState: Int64? var updatedTransactionState: Int64?
var updatedMasterClientId: Int64? var updatedMasterClientId: Int64?
if !transaction.isEmpty { if !transaction.isEmpty {
@ -3131,6 +3187,7 @@ final class PostboxImpl {
let signal: Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> = self.transactionSignal(userInteractive: true, { subscriber, transaction in let signal: Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> = self.transactionSignal(userInteractive: true, { subscriber, transaction in
let peerIds = self.peerIdsForLocation(chatLocation, ignoreRelatedChats: false) let peerIds = self.peerIdsForLocation(chatLocation, ignoreRelatedChats: false)
//TODO:release jump to unread
var anchor: HistoryViewInputAnchor = .upperBound var anchor: HistoryViewInputAnchor = .upperBound
switch peerIds { switch peerIds {
case let .single(peerId, threadId): case let .single(peerId, threadId):
@ -3334,8 +3391,14 @@ final class PostboxImpl {
var transientReadStates: MessageHistoryViewReadState? var transientReadStates: MessageHistoryViewReadState?
switch peerIds { switch peerIds {
case let .single(peerId, threadId): case let .single(peerId, threadId):
if threadId == nil, let readState = self.readStateTable.getCombinedState(peerId) { if let threadId {
transientReadStates = .peer([peerId: readState]) if let threadData = self.messageHistoryThreadIndexTable.get(peerId: peerId, threadId: threadId) {
transientReadStates = .peer([peerId: CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 0, maxOutgoingReadId: threadData.summary.maxOutgoingReadId, maxKnownId: 0, count: 0, markedUnread: false))])])
}
} else {
if let readState = self.readStateTable.getCombinedState(peerId) {
transientReadStates = .peer([peerId: readState])
}
} }
case let .associated(peerId, _): case let .associated(peerId, _):
if let readState = self.readStateTable.getCombinedState(peerId) { if let readState = self.readStateTable.getCombinedState(peerId) {

View File

@ -47,6 +47,7 @@ final class PostboxTransaction {
let updatedMessageThreadPeerIds: Set<PeerId> let updatedMessageThreadPeerIds: Set<PeerId>
let updatedPeerThreadCombinedStates: Set<PeerId> let updatedPeerThreadCombinedStates: Set<PeerId>
let updatedPeerThreadsSummaries: Set<PeerId> let updatedPeerThreadsSummaries: Set<PeerId>
let updatedPeerThreadInfos: Set<MessageHistoryThreadsTable.ItemId>
let updatedPinnedThreads: Set<PeerId> let updatedPinnedThreads: Set<PeerId>
let updatedHiddenPeerIds: Bool let updatedHiddenPeerIds: Bool
let storyGeneralStatesEvents: [StoryGeneralStatesTable.Event] let storyGeneralStatesEvents: [StoryGeneralStatesTable.Event]
@ -195,6 +196,9 @@ final class PostboxTransaction {
if !self.updatedPeerThreadsSummaries.isEmpty { if !self.updatedPeerThreadsSummaries.isEmpty {
return false return false
} }
if !self.updatedPeerThreadInfos.isEmpty {
return false
}
if !self.updatedPinnedThreads.isEmpty { if !self.updatedPinnedThreads.isEmpty {
return false return false
} }
@ -269,6 +273,7 @@ final class PostboxTransaction {
updatedMessageThreadPeerIds: Set<PeerId>, updatedMessageThreadPeerIds: Set<PeerId>,
updatedPeerThreadCombinedStates: Set<PeerId>, updatedPeerThreadCombinedStates: Set<PeerId>,
updatedPeerThreadsSummaries: Set<PeerId>, updatedPeerThreadsSummaries: Set<PeerId>,
updatedPeerThreadInfos: Set<MessageHistoryThreadsTable.ItemId>,
updatedPinnedThreads: Set<PeerId>, updatedPinnedThreads: Set<PeerId>,
updatedHiddenPeerIds: Bool, updatedHiddenPeerIds: Bool,
storyGeneralStatesEvents: [StoryGeneralStatesTable.Event], storyGeneralStatesEvents: [StoryGeneralStatesTable.Event],
@ -323,6 +328,7 @@ final class PostboxTransaction {
self.updatedMessageThreadPeerIds = updatedMessageThreadPeerIds self.updatedMessageThreadPeerIds = updatedMessageThreadPeerIds
self.updatedPeerThreadCombinedStates = updatedPeerThreadCombinedStates self.updatedPeerThreadCombinedStates = updatedPeerThreadCombinedStates
self.updatedPeerThreadsSummaries = updatedPeerThreadsSummaries self.updatedPeerThreadsSummaries = updatedPeerThreadsSummaries
self.updatedPeerThreadInfos = updatedPeerThreadInfos
self.updatedPinnedThreads = updatedPinnedThreads self.updatedPinnedThreads = updatedPinnedThreads
self.updatedHiddenPeerIds = updatedHiddenPeerIds self.updatedHiddenPeerIds = updatedHiddenPeerIds
self.storyGeneralStatesEvents = storyGeneralStatesEvents self.storyGeneralStatesEvents = storyGeneralStatesEvents

View File

@ -161,7 +161,8 @@ extension StoredMessageHistoryThreadInfo {
self.init(data: entry, summary: Summary( self.init(data: entry, summary: Summary(
totalUnreadCount: data.incomingUnreadCount, totalUnreadCount: data.incomingUnreadCount,
isMarkedUnread: data.isMarkedUnread, isMarkedUnread: data.isMarkedUnread,
mutedUntil: mutedUntil mutedUntil: mutedUntil,
maxOutgoingReadId: data.maxOutgoingReadId
)) ))
} }
} }

View File

@ -4262,7 +4262,7 @@ func replayFinalState(
} else { } else {
updatedIncomingThreadReadStates[peerAndThreadId] = readMaxId updatedIncomingThreadReadStates[peerAndThreadId] = readMaxId
} }
if let channel = transaction.getPeer(peerAndThreadId.peerId) as? TelegramChannel, case .group = channel.info, channel.flags.contains(.isForum) { if let channel = transaction.getPeer(peerAndThreadId.peerId) as? TelegramChannel, case .group = channel.info, (channel.flags.contains(.isForum) || channel.flags.contains(.isMonoforum)) {
let threadId = peerAndThreadId.threadId let threadId = peerAndThreadId.threadId
if var data = transaction.getMessageHistoryThreadInfo(peerId: peerAndThreadId.peerId, threadId: threadId)?.data.get(MessageHistoryThreadData.self) { if var data = transaction.getMessageHistoryThreadInfo(peerId: peerAndThreadId.peerId, threadId: threadId)?.data.get(MessageHistoryThreadData.self) {
if readMaxId > data.maxIncomingReadId { if readMaxId > data.maxIncomingReadId {
@ -4315,7 +4315,7 @@ func replayFinalState(
} else { } else {
updatedOutgoingThreadReadStates[peerAndThreadId] = readMaxId updatedOutgoingThreadReadStates[peerAndThreadId] = readMaxId
} }
if let channel = transaction.getPeer(peerAndThreadId.peerId) as? TelegramChannel, case .group = channel.info, channel.flags.contains(.isForum) { if let channel = transaction.getPeer(peerAndThreadId.peerId) as? TelegramChannel, case .group = channel.info, (channel.flags.contains(.isForum) || channel.flags.contains(.isMonoforum)) {
if var data = transaction.getMessageHistoryThreadInfo(peerId: peerAndThreadId.peerId, threadId: peerAndThreadId.threadId)?.data.get(MessageHistoryThreadData.self) { if var data = transaction.getMessageHistoryThreadInfo(peerId: peerAndThreadId.peerId, threadId: peerAndThreadId.threadId)?.data.get(MessageHistoryThreadData.self) {
if readMaxId >= data.maxOutgoingReadId { if readMaxId >= data.maxOutgoingReadId {
data.maxOutgoingReadId = readMaxId data.maxOutgoingReadId = readMaxId

View File

@ -194,7 +194,7 @@ public let telegramPostboxSeedConfiguration: SeedConfiguration = {
}, },
automaticThreadIndexInfo: { peerId, _ in automaticThreadIndexInfo: { peerId, _ in
if peerId.namespace == Namespaces.Peer.CloudUser { if peerId.namespace == Namespaces.Peer.CloudUser {
return StoredMessageHistoryThreadInfo(data: CodableEntry(data: Data()), summary: StoredMessageHistoryThreadInfo.Summary(totalUnreadCount: 0, isMarkedUnread: false, mutedUntil: nil)) return StoredMessageHistoryThreadInfo(data: CodableEntry(data: Data()), summary: StoredMessageHistoryThreadInfo.Summary(totalUnreadCount: 0, isMarkedUnread: false, mutedUntil: nil, maxOutgoingReadId: 0))
} else { } else {
return nil return nil
} }