diff --git a/submodules/Postbox/Sources/AdditionalChatListItemsView.swift b/submodules/Postbox/Sources/AdditionalChatListItemsView.swift index 4c54a00236..6bf80cc6c9 100644 --- a/submodules/Postbox/Sources/AdditionalChatListItemsView.swift +++ b/submodules/Postbox/Sources/AdditionalChatListItemsView.swift @@ -14,6 +14,10 @@ final class MutableAdditionalChatListItemsView: MutablePostboxView { } return false } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } func immutableView() -> PostboxView { return AdditionalChatListItemsView(self) diff --git a/submodules/Postbox/Sources/AllChatListHolesView.swift b/submodules/Postbox/Sources/AllChatListHolesView.swift index 4e582e9ed6..3cadfe60a7 100644 --- a/submodules/Postbox/Sources/AllChatListHolesView.swift +++ b/submodules/Postbox/Sources/AllChatListHolesView.swift @@ -48,6 +48,10 @@ final class MutableAllChatListHolesView: MutablePostboxView { return false } } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } func immutableView() -> PostboxView { return AllChatListHolesView(self) diff --git a/submodules/Postbox/Sources/CachedItemView.swift b/submodules/Postbox/Sources/CachedItemView.swift index cbaefed63d..6da64b46ed 100644 --- a/submodules/Postbox/Sources/CachedItemView.swift +++ b/submodules/Postbox/Sources/CachedItemView.swift @@ -16,6 +16,10 @@ final class MutableCachedItemView: MutablePostboxView { } return false } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } func immutableView() -> PostboxView { return CachedItemView(self) diff --git a/submodules/Postbox/Sources/CachedPeerDataView.swift b/submodules/Postbox/Sources/CachedPeerDataView.swift index c3cb02ac7b..9e432d5f25 100644 --- a/submodules/Postbox/Sources/CachedPeerDataView.swift +++ b/submodules/Postbox/Sources/CachedPeerDataView.swift @@ -17,6 +17,10 @@ final class MutableCachedPeerDataView: MutablePostboxView { return false } } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } func immutableView() -> PostboxView { return CachedPeerDataView(self) diff --git a/submodules/Postbox/Sources/ContactPeersView.swift b/submodules/Postbox/Sources/ContactPeersView.swift index 341646e179..b48fe93722 100644 --- a/submodules/Postbox/Sources/ContactPeersView.swift +++ b/submodules/Postbox/Sources/ContactPeersView.swift @@ -70,6 +70,10 @@ final class MutableContactPeersView: MutablePostboxView { return updated } + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } + func immutableView() -> PostboxView { return ContactPeersView(self) } diff --git a/submodules/Postbox/Sources/DeletedMessagesView.swift b/submodules/Postbox/Sources/DeletedMessagesView.swift index 95c8e2d528..7f3b4edaaf 100644 --- a/submodules/Postbox/Sources/DeletedMessagesView.swift +++ b/submodules/Postbox/Sources/DeletedMessagesView.swift @@ -33,6 +33,10 @@ final class MutableDeletedMessagesView: MutablePostboxView { return updated } + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } + func immutableView() -> PostboxView { return DeletedMessagesView(self) } diff --git a/submodules/Postbox/Sources/GlobalMessageTagsView.swift b/submodules/Postbox/Sources/GlobalMessageTagsView.swift index 941f6c8096..6733a52339 100644 --- a/submodules/Postbox/Sources/GlobalMessageTagsView.swift +++ b/submodules/Postbox/Sources/GlobalMessageTagsView.swift @@ -202,6 +202,25 @@ final class MutableGlobalMessageTagsView: MutablePostboxView { return hasChanges } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + let (entries, lower, upper) = postbox.messageHistoryTable.entriesAround(globalTagMask: globalTag, index: position, count: count) + + self.entries = entries.map { entry -> InternalGlobalMessageTagsEntry in + switch entry { + case let .message(message): + return .intermediateMessage(message) + case let .hole(index): + return .hole(index) + } + } + self.earlier = lower + self.later = upper + + self.render(postbox: postbox) + + return true + } private func add(_ entry: InternalGlobalMessageTagsEntry) -> Bool { if self.entries.count == 0 { diff --git a/submodules/Postbox/Sources/HistoryTagInfoView.swift b/submodules/Postbox/Sources/HistoryTagInfoView.swift index d3bd9de9a6..7892353518 100644 --- a/submodules/Postbox/Sources/HistoryTagInfoView.swift +++ b/submodules/Postbox/Sources/HistoryTagInfoView.swift @@ -61,6 +61,22 @@ final class MutableHistoryTagInfoView: MutablePostboxView { return false } } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + var currentIndex: MessageIndex? + for namespace in postbox.messageHistoryIndexTable.existingNamespaces(peerId: self.peerId) { + if let index = postbox.messageHistoryTagsTable.latestIndex(tag: self.tag, peerId: self.peerId, namespace: namespace) { + currentIndex = index + break + } + } + if self.currentIndex != currentIndex { + self.currentIndex = currentIndex + return true + } else { + return false + } + } func immutableView() -> PostboxView { return HistoryTagInfoView(self) diff --git a/submodules/Postbox/Sources/InvalidatedMessageHistoryTagSummariesView.swift b/submodules/Postbox/Sources/InvalidatedMessageHistoryTagSummariesView.swift index 7e082850ff..13224a2502 100644 --- a/submodules/Postbox/Sources/InvalidatedMessageHistoryTagSummariesView.swift +++ b/submodules/Postbox/Sources/InvalidatedMessageHistoryTagSummariesView.swift @@ -37,6 +37,19 @@ final class MutableInvalidatedMessageHistoryTagSummariesView: MutablePostboxView } return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + var entries = Set() + for entry in postbox.invalidatedMessageHistoryTagsSummaryTable.get(tagMask: tagMask, namespace: namespace) { + entries.insert(entry) + } + if self.entries != entries { + self.entries = entries + return true + } else { + return false + } + } func immutableView() -> PostboxView { return InvalidatedMessageHistoryTagSummariesView(self) diff --git a/submodules/Postbox/Sources/ItemCollectionIdsView.swift b/submodules/Postbox/Sources/ItemCollectionIdsView.swift index fed265431f..232419de61 100644 --- a/submodules/Postbox/Sources/ItemCollectionIdsView.swift +++ b/submodules/Postbox/Sources/ItemCollectionIdsView.swift @@ -40,6 +40,20 @@ final class MutableItemCollectionIdsView: MutablePostboxView { } return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + var idsByNamespace: [ItemCollectionId.Namespace: Set] = [:] + for namespace in namespaces { + let ids = postbox.itemCollectionInfoTable.getIds(namespace: namespace) + idsByNamespace[namespace] = Set(ids) + } + if self.idsByNamespace != idsByNamespace { + self.idsByNamespace = idsByNamespace + return true + } else { + return false + } + } func immutableView() -> PostboxView { return ItemCollectionIdsView(self) diff --git a/submodules/Postbox/Sources/ItemCollectionInfoView.swift b/submodules/Postbox/Sources/ItemCollectionInfoView.swift index 7ce6008419..6eb601595f 100644 --- a/submodules/Postbox/Sources/ItemCollectionInfoView.swift +++ b/submodules/Postbox/Sources/ItemCollectionInfoView.swift @@ -48,6 +48,10 @@ final class MutableItemCollectionInfoView: MutablePostboxView { } return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } func immutableView() -> PostboxView { return ItemCollectionInfoView(self) diff --git a/submodules/Postbox/Sources/ItemCollectionInfosView.swift b/submodules/Postbox/Sources/ItemCollectionInfosView.swift index d82b6af593..c39cbe7164 100644 --- a/submodules/Postbox/Sources/ItemCollectionInfosView.swift +++ b/submodules/Postbox/Sources/ItemCollectionInfosView.swift @@ -90,12 +90,14 @@ final class MutableItemCollectionInfosView: MutablePostboxView { } return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } func immutableView() -> PostboxView { return ItemCollectionInfosView(self) } - - } public final class ItemCollectionInfosView: PostboxView { diff --git a/submodules/Postbox/Sources/LocalMessageTagsView.swift b/submodules/Postbox/Sources/LocalMessageTagsView.swift index 356f6c8efb..10ec9cc8fa 100644 --- a/submodules/Postbox/Sources/LocalMessageTagsView.swift +++ b/submodules/Postbox/Sources/LocalMessageTagsView.swift @@ -50,6 +50,10 @@ final class MutableLocalMessageTagsView: MutablePostboxView { } return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } func immutableView() -> PostboxView { return LocalMessageTagsView(self) diff --git a/submodules/Postbox/Sources/MessageHistoryTagSummaryView.swift b/submodules/Postbox/Sources/MessageHistoryTagSummaryView.swift index b56759162c..4e62e434cf 100644 --- a/submodules/Postbox/Sources/MessageHistoryTagSummaryView.swift +++ b/submodules/Postbox/Sources/MessageHistoryTagSummaryView.swift @@ -25,6 +25,16 @@ final class MutableMessageHistoryTagSummaryView: MutablePostboxView { return hasChanges } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + let count = postbox.messageHistoryTagsSummaryTable.get(MessageHistoryTagsSummaryKey(tag: self.tag, peerId: self.peerId, namespace: self.namespace))?.count + if self.count != count { + self.count = count + return true + } else { + return false + } + } func immutableView() -> PostboxView { return MessageHistoryTagSummaryView(self) diff --git a/submodules/Postbox/Sources/MessageHistoryView.swift b/submodules/Postbox/Sources/MessageHistoryView.swift index 7543827b81..280bdb4bf0 100644 --- a/submodules/Postbox/Sources/MessageHistoryView.swift +++ b/submodules/Postbox/Sources/MessageHistoryView.swift @@ -739,7 +739,7 @@ final class MutableMessageHistoryView { } case let .peerChatState(peerId, _): if transaction.currentUpdatedPeerChatStates.contains(peerId) { - updated[i] = .peerChatState(peerId, postbox.peerChatStateTable.get(peerId) as? PeerChatState) + updated[i] = .peerChatState(peerId, postbox.peerChatStateTable.get(peerId)?.getLegacy() as? PeerChatState) hasChanges = true } case .totalUnreadState: diff --git a/submodules/Postbox/Sources/MessageOfInterestHolesView.swift b/submodules/Postbox/Sources/MessageOfInterestHolesView.swift index ea2e2dbb41..033d9fec90 100644 --- a/submodules/Postbox/Sources/MessageOfInterestHolesView.swift +++ b/submodules/Postbox/Sources/MessageOfInterestHolesView.swift @@ -171,6 +171,10 @@ final class MutableMessageOfInterestHolesView: MutablePostboxView { return false } } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } func immutableView() -> PostboxView { return MessageOfInterestHolesView(self) diff --git a/submodules/Postbox/Sources/MessagesView.swift b/submodules/Postbox/Sources/MessagesView.swift index ae4a1b4d94..91808bb160 100644 --- a/submodules/Postbox/Sources/MessagesView.swift +++ b/submodules/Postbox/Sources/MessagesView.swift @@ -51,6 +51,10 @@ final class MutableMessagesView: MutablePostboxView { return false } } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } func immutableView() -> PostboxView { return MessagesView(self) diff --git a/submodules/Postbox/Sources/MutableBasicPeerView.swift b/submodules/Postbox/Sources/MutableBasicPeerView.swift index a2f30f8f6b..0236960e1d 100644 --- a/submodules/Postbox/Sources/MutableBasicPeerView.swift +++ b/submodules/Postbox/Sources/MutableBasicPeerView.swift @@ -42,6 +42,10 @@ final class MutableBasicPeerView: MutablePostboxView { return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } func immutableView() -> PostboxView { return BasicPeerView(self) diff --git a/submodules/Postbox/Sources/MutablePeerChatInclusionView.swift b/submodules/Postbox/Sources/MutablePeerChatInclusionView.swift index 9b7d5d1952..5c5daec04e 100644 --- a/submodules/Postbox/Sources/MutablePeerChatInclusionView.swift +++ b/submodules/Postbox/Sources/MutablePeerChatInclusionView.swift @@ -22,6 +22,10 @@ final class MutablePeerChatInclusionView: MutablePostboxView { return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } func immutableView() -> PostboxView { return PeerChatInclusionView(self) diff --git a/submodules/Postbox/Sources/OrderedItemListView.swift b/submodules/Postbox/Sources/OrderedItemListView.swift index bdd066a8fc..d8bf403a00 100644 --- a/submodules/Postbox/Sources/OrderedItemListView.swift +++ b/submodules/Postbox/Sources/OrderedItemListView.swift @@ -51,6 +51,10 @@ final class MutableOrderedItemListView: MutablePostboxView { return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } func immutableView() -> PostboxView { return OrderedItemListView(self) diff --git a/submodules/Postbox/Sources/PeerChatStateTable.swift b/submodules/Postbox/Sources/PeerChatStateTable.swift index b0f059fc17..716d025d4b 100644 --- a/submodules/Postbox/Sources/PeerChatStateTable.swift +++ b/submodules/Postbox/Sources/PeerChatStateTable.swift @@ -5,7 +5,7 @@ final class PeerChatStateTable: Table { return ValueBoxTable(id: id, keyType: .int64, compactValuesOnCreation: false) } - private var cachedPeerChatStates: [PeerId: PostboxCoding?] = [:] + private var cachedPeerChatStates: [PeerId: CodableEntry?] = [:] private var updatedPeerIds = Set() private let sharedKey = ValueBoxKey(length: 8) @@ -15,11 +15,12 @@ final class PeerChatStateTable: Table { return self.sharedKey } - func get(_ id: PeerId) -> PostboxCoding? { + func get(_ id: PeerId) -> CodableEntry? { if let state = self.cachedPeerChatStates[id] { return state } else { - if let value = self.valueBox.get(self.table, key: self.key(id)), let state = PostboxDecoder(buffer: value).decodeRootObject() { + if let value = self.valueBox.get(self.table, key: self.key(id)) { + let state = CodableEntry(data: value.makeData()) self.cachedPeerChatStates[id] = state return state } else { @@ -29,7 +30,7 @@ final class PeerChatStateTable: Table { } } - func set(_ id: PeerId, state: PostboxCoding?) { + func set(_ id: PeerId, state: CodableEntry?) { self.cachedPeerChatStates[id] = state self.updatedPeerIds.insert(id) } @@ -41,12 +42,9 @@ final class PeerChatStateTable: Table { override func beforeCommit() { if !self.updatedPeerIds.isEmpty { - let sharedEncoder = PostboxEncoder() for id in self.updatedPeerIds { if let wrappedState = self.cachedPeerChatStates[id], let state = wrappedState { - sharedEncoder.reset() - sharedEncoder.encodeRootObject(state) - self.valueBox.set(self.table, key: self.key(id), value: sharedEncoder.readBufferNoCopy()) + self.valueBox.set(self.table, key: self.key(id), value: ReadBuffer(data: state.data)) } else { self.valueBox.remove(self.table, key: self.key(id), secure: false) } diff --git a/submodules/Postbox/Sources/PeerChatStateView.swift b/submodules/Postbox/Sources/PeerChatStateView.swift index 3c0edec8d6..df81cba5b3 100644 --- a/submodules/Postbox/Sources/PeerChatStateView.swift +++ b/submodules/Postbox/Sources/PeerChatStateView.swift @@ -2,7 +2,7 @@ import Foundation final class MutablePeerChatStateView: MutablePostboxView { let peerId: PeerId - var chatState: PostboxCoding? + var chatState: CodableEntry? init(postbox: PostboxImpl, peerId: PeerId) { self.peerId = peerId @@ -17,6 +17,16 @@ final class MutablePeerChatStateView: MutablePostboxView { return false } } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + let chatState = postbox.peerChatStateTable.get(self.peerId) + if self.chatState != chatState { + self.chatState = chatState + return true + } else { + return false + } + } func immutableView() -> PostboxView { return PeerChatStateView(self) @@ -25,7 +35,7 @@ final class MutablePeerChatStateView: MutablePostboxView { public final class PeerChatStateView: PostboxView { public let peerId: PeerId - public let chatState: PostboxCoding? + public let chatState: CodableEntry? init(_ view: MutablePeerChatStateView) { self.peerId = view.peerId diff --git a/submodules/Postbox/Sources/PeerNotificationSettingsBehaviorTimestampView.swift b/submodules/Postbox/Sources/PeerNotificationSettingsBehaviorTimestampView.swift index dd6448f5b8..a00d2b33b6 100644 --- a/submodules/Postbox/Sources/PeerNotificationSettingsBehaviorTimestampView.swift +++ b/submodules/Postbox/Sources/PeerNotificationSettingsBehaviorTimestampView.swift @@ -19,6 +19,16 @@ final class MutablePeerNotificationSettingsBehaviorTimestampView: MutablePostbox return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + let earliestTimestamp = postbox.peerNotificationSettingsBehaviorTable.getEarliest()?.1 + if self.earliestTimestamp != earliestTimestamp { + self.earliestTimestamp = earliestTimestamp + return true + } else { + return false + } + } func immutableView() -> PostboxView { return PeerNotificationSettingsBehaviorTimestampView(self) diff --git a/submodules/Postbox/Sources/PeerNotificationSettingsView.swift b/submodules/Postbox/Sources/PeerNotificationSettingsView.swift index a1521e17a0..2d85dcf466 100644 --- a/submodules/Postbox/Sources/PeerNotificationSettingsView.swift +++ b/submodules/Postbox/Sources/PeerNotificationSettingsView.swift @@ -36,6 +36,43 @@ final class MutablePeerNotificationSettingsView: MutablePostboxView { return false } } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + var notificationSettings: [PeerId: PeerNotificationSettings] = [:] + for peerId in self.peerIds { + var notificationPeerId = peerId + if let peer = postbox.peerTable.get(peerId), let associatedPeerId = peer.associatedPeerId { + notificationPeerId = associatedPeerId + } + if let settings = postbox.peerNotificationSettingsTable.getEffective(notificationPeerId) { + notificationSettings[peerId] = settings + } + } + + var updated = false + if self.notificationSettings.count != notificationSettings.count { + updated = true + } else { + for (key, value) in self.notificationSettings { + if let other = notificationSettings[key] { + if !other.isEqual(to: value) { + updated = true + break + } + } else { + updated = true + break + } + } + } + + if updated { + self.notificationSettings = notificationSettings + return true + } else { + return false + } + } func immutableView() -> PostboxView { return PeerNotificationSettingsView(self) diff --git a/submodules/Postbox/Sources/PeerPresencesView.swift b/submodules/Postbox/Sources/PeerPresencesView.swift index 4f280d944b..51f4a32c03 100644 --- a/submodules/Postbox/Sources/PeerPresencesView.swift +++ b/submodules/Postbox/Sources/PeerPresencesView.swift @@ -26,6 +26,40 @@ final class MutablePeerPresencesView: MutablePostboxView { return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + var presences: [PeerId: PeerPresence] = [:] + + for id in self.ids { + if let presence = postbox.peerPresenceTable.get(id) { + presences[id] = presence + } + } + + var updated = false + if self.presences.count != presences.count { + updated = true + } else { + for (key, value) in self.presences { + if let other = presences[key] { + if !other.isEqual(to: value) { + updated = true + break + } + } else { + updated = true + break + } + } + } + + if updated { + self.presences = presences + return true + } else { + return false + } + } func immutableView() -> PostboxView { return PeerPresencesView(self) diff --git a/submodules/Postbox/Sources/PeerView.swift b/submodules/Postbox/Sources/PeerView.swift index 9fb5046de6..6db9f56c81 100644 --- a/submodules/Postbox/Sources/PeerView.swift +++ b/submodules/Postbox/Sources/PeerView.swift @@ -253,6 +253,10 @@ final class MutablePeerView: MutablePostboxView { return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } func immutableView() -> PostboxView { return PeerView(self) diff --git a/submodules/Postbox/Sources/PendingMessageActionsSummaryView.swift b/submodules/Postbox/Sources/PendingMessageActionsSummaryView.swift index dbfa7c7e56..79161a526d 100644 --- a/submodules/Postbox/Sources/PendingMessageActionsSummaryView.swift +++ b/submodules/Postbox/Sources/PendingMessageActionsSummaryView.swift @@ -16,6 +16,10 @@ final class MutablePendingMessageActionsSummaryView: MutablePostboxView { } return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } func immutableView() -> PostboxView { return PendingMessageActionsSummaryView(self) diff --git a/submodules/Postbox/Sources/PendingMessageActionsView.swift b/submodules/Postbox/Sources/PendingMessageActionsView.swift index 87662edaef..1b24f63f63 100644 --- a/submodules/Postbox/Sources/PendingMessageActionsView.swift +++ b/submodules/Postbox/Sources/PendingMessageActionsView.swift @@ -38,6 +38,10 @@ final class MutablePendingMessageActionsView: MutablePostboxView { } return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } func immutableView() -> PostboxView { return PendingMessageActionsView(self) diff --git a/submodules/Postbox/Sources/PendingPeerNotificationSettingsView.swift b/submodules/Postbox/Sources/PendingPeerNotificationSettingsView.swift index dfc7e22d22..d7da2420e9 100644 --- a/submodules/Postbox/Sources/PendingPeerNotificationSettingsView.swift +++ b/submodules/Postbox/Sources/PendingPeerNotificationSettingsView.swift @@ -25,6 +25,10 @@ final class MutablePendingPeerNotificationSettingsView: MutablePostboxView { } return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + return false + } func immutableView() -> PostboxView { return PendingPeerNotificationSettingsView(self) diff --git a/submodules/Postbox/Sources/Postbox.swift b/submodules/Postbox/Sources/Postbox.swift index ea1b24e9da..321edd1ef9 100644 --- a/submodules/Postbox/Sources/Postbox.swift +++ b/submodules/Postbox/Sources/Postbox.swift @@ -2212,7 +2212,7 @@ final class PostboxImpl { } fileprivate func setPeerChatState(_ id: PeerId, state: PeerChatState) { - self.peerChatStateTable.set(id, state: state) + self.peerChatStateTable.set(id, state: CodableEntry(legacyValue: state)) self.currentUpdatedPeerChatStates.insert(id) } diff --git a/submodules/Postbox/Sources/PostboxView.swift b/submodules/Postbox/Sources/PostboxView.swift index effaf9752c..710fb0b21a 100644 --- a/submodules/Postbox/Sources/PostboxView.swift +++ b/submodules/Postbox/Sources/PostboxView.swift @@ -5,6 +5,7 @@ public protocol PostboxView { protocol MutablePostboxView { func replay(postbox: PostboxImpl, transaction: PostboxTransaction) -> Bool + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool func immutableView() -> PostboxView } @@ -24,6 +25,16 @@ final class CombinedMutableView { } return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + var updated = false + for (_, view) in self.views { + if view.refreshDueToExternalTransaction(postbox: postbox) { + updated = true + } + } + return updated + } func immutableView() -> CombinedView { var result: [PostboxViewKey: PostboxView] = [:] diff --git a/submodules/Postbox/Sources/PreferencesEntry.swift b/submodules/Postbox/Sources/PreferencesEntry.swift index a38f5cae4b..125a6ed5ae 100644 --- a/submodules/Postbox/Sources/PreferencesEntry.swift +++ b/submodules/Postbox/Sources/PreferencesEntry.swift @@ -13,11 +13,37 @@ public final class CodableEntry: Equatable { self.data = encoder.makeData() } + public init(legacyValue: PostboxCoding) { + let encoder = PostboxEncoder() + encoder.encodeRootObject(legacyValue) + self.data = encoder.makeData() + } + public func get(_ type: T.Type) -> T? { let decoder = PostboxDecoder(buffer: MemoryBuffer(data: self.data)) return decoder.decode(T.self, forKey: "_") } + public func getLegacy(_ type: T.Type) -> T? { + let decoder = PostboxDecoder(buffer: MemoryBuffer(data: self.data)) + let object = decoder.decodeRootObject() + if let object = object as? T { + return object + } else { + return nil + } + } + + public func getLegacy() -> PostboxCoding? { + let decoder = PostboxDecoder(buffer: MemoryBuffer(data: self.data)) + let object = decoder.decodeRootObject() + if let object = object { + return object + } else { + return nil + } + } + public static func ==(lhs: CodableEntry, rhs: CodableEntry) -> Bool { return lhs.data == rhs.data } diff --git a/submodules/Postbox/Sources/PreferencesView.swift b/submodules/Postbox/Sources/PreferencesView.swift index 1fa4b3f348..faec5ead7c 100644 --- a/submodules/Postbox/Sources/PreferencesView.swift +++ b/submodules/Postbox/Sources/PreferencesView.swift @@ -44,6 +44,21 @@ final class MutablePreferencesView: MutablePostboxView { return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + var values: [ValueBoxKey: PreferencesEntry] = [:] + for key in self.keys { + if let value = postbox.preferencesTable.get(key: key) { + values[key] = value + } + } + if self.values != values { + self.values = values + return true + } else { + return false + } + } func immutableView() -> PostboxView { return PreferencesView(self) diff --git a/submodules/Postbox/Sources/SynchronizeGroupMessageStatsView.swift b/submodules/Postbox/Sources/SynchronizeGroupMessageStatsView.swift index a2865e2b50..af39f00534 100644 --- a/submodules/Postbox/Sources/SynchronizeGroupMessageStatsView.swift +++ b/submodules/Postbox/Sources/SynchronizeGroupMessageStatsView.swift @@ -26,6 +26,16 @@ final class MutableSynchronizeGroupMessageStatsView: MutablePostboxView { } return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + let groupsAndNamespaces = postbox.synchronizeGroupMessageStatsTable.get() + if self.groupsAndNamespaces != groupsAndNamespaces { + self.groupsAndNamespaces = groupsAndNamespaces + return true + } else { + return false + } + } func immutableView() -> PostboxView { return SynchronizeGroupMessageStatsView(self) diff --git a/submodules/Postbox/Sources/TopChatMessageView.swift b/submodules/Postbox/Sources/TopChatMessageView.swift index 9f276873f9..d348c6dfb1 100644 --- a/submodules/Postbox/Sources/TopChatMessageView.swift +++ b/submodules/Postbox/Sources/TopChatMessageView.swift @@ -29,6 +29,41 @@ final class MutableTopChatMessageView: MutablePostboxView { return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + var messages: [PeerId: Message] = [:] + + for peerId in self.peerIds { + if let index = postbox.chatListIndexTable.get(peerId: peerId).topMessageIndex { + messages[peerId] = postbox.getMessage(index.id) + } + } + + var updated = false + + if self.messages.count != messages.count { + updated = true + } else { + for (key, value) in self.messages { + if let other = messages[key] { + if other.stableId != value.stableId || other.stableVersion != value.stableVersion { + updated = true + break + } + } else { + updated = true + break + } + } + } + + if updated { + self.messages = messages + return true + } else { + return false + } + } func immutableView() -> PostboxView { return TopChatMessageView(self) diff --git a/submodules/Postbox/Sources/UnreadMessageCountsView.swift b/submodules/Postbox/Sources/UnreadMessageCountsView.swift index 8fe50bc914..8e2d19a12b 100644 --- a/submodules/Postbox/Sources/UnreadMessageCountsView.swift +++ b/submodules/Postbox/Sources/UnreadMessageCountsView.swift @@ -6,10 +6,42 @@ public enum UnreadMessageCountsItem: Equatable { case peer(PeerId) } -private enum MutableUnreadMessageCountsItemEntry { +private enum MutableUnreadMessageCountsItemEntry: Equatable { case total((ValueBoxKey, PreferencesEntry?)?, ChatListTotalUnreadState) case totalInGroup(PeerGroupId, ChatListTotalUnreadState) case peer(PeerId, CombinedPeerReadState?) + + static func ==(lhs: MutableUnreadMessageCountsItemEntry, rhs: MutableUnreadMessageCountsItemEntry) -> Bool { + switch lhs { + case let .total(lhsKeyAndEntry, lhsUnreadState): + if case let .total(rhsKeyAndEntry, rhsUnreadState) = rhs { + if lhsKeyAndEntry?.0 != rhsKeyAndEntry?.0 { + return false + } + if lhsKeyAndEntry?.1 != rhsKeyAndEntry?.1 { + return false + } + if lhsUnreadState != rhsUnreadState { + return false + } + return true + } else { + return false + } + case let .totalInGroup(groupId, state): + if case .totalInGroup(groupId, state) = rhs { + return true + } else { + return false + } + case let .peer(peerId, readState): + if case .peer(peerId, readState) = rhs { + return true + } else { + return false + } + } + } } public enum UnreadMessageCountsItemEntry { @@ -19,9 +51,12 @@ public enum UnreadMessageCountsItemEntry { } final class MutableUnreadMessageCountsView: MutablePostboxView { + private let items: [UnreadMessageCountsItem] fileprivate var entries: [MutableUnreadMessageCountsItemEntry] init(postbox: PostboxImpl, items: [UnreadMessageCountsItem]) { + self.items = items + self.entries = items.map { item in switch item { case let .total(preferencesKey): @@ -80,6 +115,25 @@ final class MutableUnreadMessageCountsView: MutablePostboxView { return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + let entries: [MutableUnreadMessageCountsItemEntry] = self.items.map { item -> MutableUnreadMessageCountsItemEntry in + switch item { + case let .total(preferencesKey): + return .total(preferencesKey.flatMap({ ($0, postbox.preferencesTable.get(key: $0)) }), postbox.messageHistoryMetadataTable.getTotalUnreadState(groupId: .root)) + case let .totalInGroup(groupId): + return .totalInGroup(groupId, postbox.messageHistoryMetadataTable.getTotalUnreadState(groupId: groupId)) + case let .peer(peerId): + return .peer(peerId, postbox.readStateTable.getCombinedState(peerId)) + } + } + if self.entries != entries { + self.entries = entries + return true + } else { + return false + } + } func immutableView() -> PostboxView { return UnreadMessageCountsView(self) @@ -151,6 +205,16 @@ final class MutableCombinedReadStateView: MutablePostboxView { return updated } + + func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { + let state = postbox.readStateTable.getCombinedState(self.peerId) + if state != self.state { + self.state = state + return true + } else { + return false + } + } func immutableView() -> PostboxView { return CombinedReadStateView(self)