no message

This commit is contained in:
Peter Iakovlev 2018-02-21 01:47:23 +04:00
parent a319509c0c
commit 640865d83c
19 changed files with 607 additions and 140 deletions

View File

@ -61,6 +61,8 @@
D04614312004E24600EC0EF2 /* LocalMessageHistoryTagsTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D046142F2004E24600EC0EF2 /* LocalMessageHistoryTagsTable.swift */; };
D04614332004F2CC00EC0EF2 /* LocalMessageTagsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04614322004F2CC00EC0EF2 /* LocalMessageTagsView.swift */; };
D04614342004F2CC00EC0EF2 /* LocalMessageTagsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04614322004F2CC00EC0EF2 /* LocalMessageTagsView.swift */; };
D048B33D203C838500038D05 /* PostboxUpgrade_15to16.swift in Sources */ = {isa = PBXBuildFile; fileRef = D048B33C203C838500038D05 /* PostboxUpgrade_15to16.swift */; };
D048B33E203C838500038D05 /* PostboxUpgrade_15to16.swift in Sources */ = {isa = PBXBuildFile; fileRef = D048B33C203C838500038D05 /* PostboxUpgrade_15to16.swift */; };
D049EAF01E44D9B900A2CD3A /* PostboxStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D049EAEF1E44D9B900A2CD3A /* PostboxStateView.swift */; };
D049EAF11E44D9B900A2CD3A /* PostboxStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D049EAEF1E44D9B900A2CD3A /* PostboxStateView.swift */; };
D050F2651E4A5B4800988324 /* fts3_tokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = D07516741B2EC90400AE42E0 /* fts3_tokenizer.h */; };
@ -404,6 +406,7 @@
D044E1621B2AD677001EE087 /* MurMurHash32.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MurMurHash32.m; sourceTree = "<group>"; };
D046142F2004E24600EC0EF2 /* LocalMessageHistoryTagsTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalMessageHistoryTagsTable.swift; sourceTree = "<group>"; };
D04614322004F2CC00EC0EF2 /* LocalMessageTagsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalMessageTagsView.swift; sourceTree = "<group>"; };
D048B33C203C838500038D05 /* PostboxUpgrade_15to16.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostboxUpgrade_15to16.swift; sourceTree = "<group>"; };
D049EAEF1E44D9B900A2CD3A /* PostboxStateView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostboxStateView.swift; sourceTree = "<group>"; };
D055BD321B7D3D2D00F06C0A /* MediaBox.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaBox.swift; sourceTree = "<group>"; };
D0575AE21E9ECBB2006F2541 /* AccessChallengeDataView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccessChallengeDataView.swift; sourceTree = "<group>"; };
@ -660,6 +663,7 @@
D0F02CE11E9922F50065DEE2 /* PostboxUpgrade_12to13.swift */,
D0CE8CF21F70249400AA2DB0 /* PostboxUpgrade_13to14.swift */,
D0943B011FDB01D8001522CC /* PostboxUpgrade_14to15.swift */,
D048B33C203C838500038D05 /* PostboxUpgrade_15to16.swift */,
);
name = Upgrade;
sourceTree = "<group>";
@ -1167,6 +1171,7 @@
D073CEA01DCBF3C1007511FD /* ItemCollectionsView.swift in Sources */,
D0BE383A1E7C1FD4000079AF /* ItemCollectionInfoView.swift in Sources */,
D0B418491D7DFE20004562A4 /* ChatListView.swift in Sources */,
D048B33E203C838500038D05 /* PostboxUpgrade_15to16.swift in Sources */,
D0F7B1D61E045C6A007EB8A5 /* ContactTable.swift in Sources */,
D0943B031FDB01D8001522CC /* PostboxUpgrade_14to15.swift in Sources */,
D0F7B1D11E045C6A007EB8A5 /* PeerTable.swift in Sources */,
@ -1341,6 +1346,7 @@
D0C26D6F1FE2E737004ABF18 /* GroupFeedReadState.swift in Sources */,
D0FA0AC71E77F0A2005BB9B7 /* ItemCollectionInfosView.swift in Sources */,
D0F019FD1E1DA0CC00F05AB3 /* PeerMergedOperationLogView.swift in Sources */,
D048B33D203C838500038D05 /* PostboxUpgrade_15to16.swift in Sources */,
D0F9E8651C58CB7F00037222 /* ChatListTable.swift in Sources */,
D0E1D30C1ECA1F5500FCEEF1 /* GlobalMessageHistoryTagsTable.swift in Sources */,
D0F9E8711C5A0E9B00037222 /* PeerTable.swift in Sources */,

View File

@ -3,7 +3,7 @@ public protocol CachedPeerData: PostboxCoding {
var peerIds: Set<PeerId> { get }
var messageIds: Set<MessageId> { get }
var associatedHistoryPeerId: PeerId? { get }
var associatedHistoryMessageId: MessageId? { get }
func isEqual(to: CachedPeerData) -> Bool
}

View File

@ -253,7 +253,7 @@ final class ChatListIndexTable: Table {
assert(self.updatedPreviousGroupCachedIndices.isEmpty)
}
func commitWithTransactionUnreadCountDeltas(_ deltas: [PeerId: Int32], transactionParticipationInTotalUnreadCountUpdates: (added: Set<PeerId>, removed: Set<PeerId>), getPeer: (PeerId) -> Peer?, updatedTotalUnreadCount: inout Int32?) {
func commitWithTransactionUnreadCountDeltas(_ deltas: [PeerId: Int32], transactionParticipationInTotalUnreadCountUpdates: (added: Set<PeerId>, removed: Set<PeerId>), getPeer: (PeerId) -> Peer?, updatedTotalUnreadState: inout ChatListTotalUnreadState?) {
if !self.updatedPreviousPeerCachedIndices.isEmpty || !deltas.isEmpty || !transactionParticipationInTotalUnreadCountUpdates.added.isEmpty || !transactionParticipationInTotalUnreadCountUpdates.removed.isEmpty {
var addedChatListPeerIds = Set<PeerId>()
var removedChatListPeerIds = Set<PeerId>()
@ -326,7 +326,7 @@ final class ChatListIndexTable: Table {
let addedUnreadCountPeerIds = addedChatListPeerIds.union(transactionParticipationInTotalUnreadCountUpdates.added)
let removedUnreadCountPeerIds = removedChatListPeerIds.union(transactionParticipationInTotalUnreadCountUpdates.removed)
var totalUnreadCount = self.metadataTable.getChatListTotalUnreadCount()
var totalUnreadState = self.metadataTable.getChatListTotalUnreadState()
for (peerId, delta) in deltas {
if !addedUnreadCountPeerIds.contains(peerId) && !removedUnreadCountPeerIds.contains(peerId) {
var notificationSettings: PeerNotificationSettings?
@ -337,8 +337,11 @@ final class ChatListIndexTable: Table {
notificationSettings = self.notificationSettingsTable.getEffective(peerId)
}
}
if let _ = self.get(peerId: peerId).includedIndex(peerId: peerId), let notificationSettings = notificationSettings, !notificationSettings.isRemovedFromTotalUnreadCount {
totalUnreadCount += delta
if let _ = self.get(peerId: peerId).includedIndex(peerId: peerId) {
totalUnreadState.absoluteCounters.messageCount += delta
if let notificationSettings = notificationSettings, !notificationSettings.isRemovedFromTotalUnreadCount {
totalUnreadState.filteredCounters.messageCount += delta
}
}
}
}
@ -353,7 +356,8 @@ final class ChatListIndexTable: Table {
if addedToList && startedParticipationInUnreadCount {
if let combinedState = self.readStateTable.getCombinedState(peerId) {
totalUnreadCount += combinedState.count
totalUnreadState.absoluteCounters.messageCount += combinedState.count
totalUnreadState.filteredCounters.messageCount += combinedState.count
}
} else if addedToList {
var notificationSettings: PeerNotificationSettings?
@ -364,15 +368,16 @@ final class ChatListIndexTable: Table {
notificationSettings = self.notificationSettingsTable.getEffective(peerId)
}
}
if let notificationSettings = notificationSettings, !notificationSettings.isRemovedFromTotalUnreadCount {
if let combinedState = self.readStateTable.getCombinedState(peerId) {
totalUnreadCount += combinedState.count
if let combinedState = self.readStateTable.getCombinedState(peerId) {
totalUnreadState.absoluteCounters.messageCount += combinedState.count
if let notificationSettings = notificationSettings, !notificationSettings.isRemovedFromTotalUnreadCount {
totalUnreadState.filteredCounters.messageCount += combinedState.count
}
}
} else if startedParticipationInUnreadCount {
if let _ = self.get(peerId: peerId).includedIndex(peerId: peerId) {
if let combinedState = self.readStateTable.getCombinedState(peerId) {
totalUnreadCount += combinedState.count
totalUnreadState.filteredCounters.messageCount += combinedState.count
}
}
} else {
@ -397,7 +402,8 @@ final class ChatListIndexTable: Table {
let removedFromList = removedChatListPeerIds.contains(peerId)
let removedFromParticipationInUnreadCount = transactionParticipationInTotalUnreadCountUpdates.removed.contains(peerId)
if removedFromList && removedFromParticipationInUnreadCount {
totalUnreadCount -= currentPeerUnreadCount
totalUnreadState.absoluteCounters.messageCount -= currentPeerUnreadCount
totalUnreadState.filteredCounters.messageCount -= currentPeerUnreadCount
} else if removedFromList {
var notificationSettings: PeerNotificationSettings?
if let peer = getPeer(peerId) {
@ -407,12 +413,13 @@ final class ChatListIndexTable: Table {
notificationSettings = self.notificationSettingsTable.getEffective(peerId)
}
}
totalUnreadState.absoluteCounters.messageCount -= currentPeerUnreadCount
if let notificationSettings = notificationSettings, !notificationSettings.isRemovedFromTotalUnreadCount {
totalUnreadCount -= currentPeerUnreadCount
totalUnreadState.filteredCounters.messageCount -= currentPeerUnreadCount
}
} else if removedFromParticipationInUnreadCount {
if let _ = self.get(peerId: peerId).includedIndex(peerId: peerId) {
totalUnreadCount -= currentPeerUnreadCount
totalUnreadState.filteredCounters.messageCount -= currentPeerUnreadCount
}
} else {
assertionFailure()
@ -421,9 +428,9 @@ final class ChatListIndexTable: Table {
//assert(totalUnreadCount >= 0)
if self.metadataTable.getChatListTotalUnreadCount() != totalUnreadCount {
self.metadataTable.setChatListTotalUnreadCount(totalUnreadCount)
updatedTotalUnreadCount = totalUnreadCount
if self.metadataTable.getChatListTotalUnreadState() != totalUnreadState {
self.metadataTable.setChatListTotalUnreadState(totalUnreadState)
updatedTotalUnreadState = totalUnreadState
}
}
@ -476,4 +483,30 @@ final class ChatListIndexTable: Table {
assert(self.updatedPreviousPeerCachedIndices.isEmpty)
assert(self.updatedPreviousGroupCachedIndices.isEmpty)
}
func debugReindexUnreadCounts(postbox: Postbox) -> ChatListTotalUnreadState {
var peerIds: [PeerId] = []
self.valueBox.scanInt64(self.table, values: { key, _ in
let peerId = PeerId(key)
if peerId.namespace != Int32.max {
peerIds.append(peerId)
}
return true
})
var state = ChatListTotalUnreadState(absoluteCounters: ChatListTotalUnreadCounters(messageCount: 0), filteredCounters: ChatListTotalUnreadCounters(messageCount: 0))
for peerId in peerIds {
let inclusion = self.get(peerId: peerId)
if inclusion.includedIndex(peerId: peerId) != nil {
if let combinedState = postbox.readStateTable.getCombinedState(peerId) {
state.absoluteCounters.messageCount += combinedState.count
if let notificationSettings = postbox.peerNotificationSettingsTable.getEffective(peerId), !notificationSettings.isRemovedFromTotalUnreadCount {
state.filteredCounters.messageCount += combinedState.count
}
}
}
}
return state
}
}

View File

@ -1,6 +1,6 @@
import Foundation
func fileSize(_ path: String) -> Int? {
public func fileSize(_ path: String) -> Int? {
var value = stat()
if stat(path, &value) == 0 {
return Int(value.st_size)

View File

@ -173,6 +173,13 @@ public final class MediaBox {
}
}
public func moveResourceData(_ id: MediaResourceId, fromTempPath: String) {
self.dataQueue.async {
let paths = self.storePathsForId(id)
let _ = try? FileManager.default.moveItem(at: URL(fileURLWithPath: fromTempPath), to: URL(fileURLWithPath: paths.complete))
}
}
public func moveResourceData(from: MediaResourceId, to: MediaResourceId) {
self.dataQueue.async {
let pathsFrom = self.storePathsForId(from)
@ -241,9 +248,9 @@ public final class MediaBox {
}
}
disposable.set(ActionDisposable {
disposable.set(ActionDisposable { [weak statusContext] in
self.statusQueue.async {
if let current = self.statusContexts[WrappedMediaResourceId(resource.id)] {
if let current = self.statusContexts[WrappedMediaResourceId(resource.id)], current === statusContext {
current.subscribers.remove(index)
if current.subscribers.isEmpty {
self.statusContexts.removeValue(forKey: WrappedMediaResourceId(resource.id))

View File

@ -396,7 +396,9 @@ final class MediaBoxPartialFile {
self.statusRequests.removeAll()
self.fd.sync()
let linkResult = link(self.path, self.completePath)
assert(linkResult == 0)
if linkResult != 0 {
//assert(linkResult == 0)
}
self.completed(self.fileMap.sum)
}
}

View File

@ -5,12 +5,65 @@ private enum MetadataPrefix: Int8 {
case PeerHistoryInitialized = 1
case PeerNextMessageIdByNamespace = 2
case NextStableMessageId = 3
case ChatListTotalUnreadCount = 4
case ChatListTotalUnreadState = 4
case NextPeerOperationLogIndex = 5
case ChatListGroupInitialized = 6
case GroupFeedIndexInitialized = 7
}
public struct ChatListTotalUnreadCounters: PostboxCoding, Equatable {
public var messageCount: Int32
public init(messageCount: Int32) {
self.messageCount = messageCount
}
public init(decoder: PostboxDecoder) {
self.messageCount = decoder.decodeInt32ForKey("m", orElse: 0)
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt32(self.messageCount, forKey: "m")
}
public static func ==(lhs: ChatListTotalUnreadCounters, rhs: ChatListTotalUnreadCounters) -> Bool {
if lhs.messageCount != rhs.messageCount {
return false
}
return true
}
}
public struct ChatListTotalUnreadState: PostboxCoding, Equatable {
public var absoluteCounters: ChatListTotalUnreadCounters
public var filteredCounters: ChatListTotalUnreadCounters
public init(absoluteCounters: ChatListTotalUnreadCounters, filteredCounters: ChatListTotalUnreadCounters) {
self.absoluteCounters = absoluteCounters
self.filteredCounters = filteredCounters
}
public init(decoder: PostboxDecoder) {
self.absoluteCounters = decoder.decodeObjectForKey("a", decoder: { ChatListTotalUnreadCounters(decoder: $0) }) as! ChatListTotalUnreadCounters
self.filteredCounters = decoder.decodeObjectForKey("f", decoder: { ChatListTotalUnreadCounters(decoder: $0) }) as! ChatListTotalUnreadCounters
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeObject(self.absoluteCounters, forKey: "a")
encoder.encodeObject(self.filteredCounters, forKey: "f")
}
public static func ==(lhs: ChatListTotalUnreadState, rhs: ChatListTotalUnreadState) -> Bool {
if lhs.absoluteCounters != rhs.absoluteCounters {
return false
}
if lhs.filteredCounters != rhs.filteredCounters {
return false
}
return true
}
}
private enum InitializedChatListKey: Hashable {
case global
case group(PeerGroupId)
@ -80,8 +133,8 @@ final class MessageHistoryMetadataTable: Table {
private var nextMessageStableId: UInt32?
private var nextMessageStableIdUpdated = false
private var chatListTotalUnreadCount: Int32?
private var chatListTotalUnreadCountUpdated = false
private var chatListTotalUnreadState: ChatListTotalUnreadState?
private var chatListTotalUnreadStateUpdated = false
private var nextPeerOperationLogIndex: UInt32?
private var nextPeerOperationLogIndexUpdated = false
@ -272,27 +325,28 @@ final class MessageHistoryMetadataTable: Table {
}
}
func getChatListTotalUnreadCount() -> Int32 {
if let cached = self.chatListTotalUnreadCount {
func getChatListTotalUnreadState() -> ChatListTotalUnreadState {
if let cached = self.chatListTotalUnreadState {
return cached
} else {
if let value = self.valueBox.get(self.table, key: self.key(.ChatListTotalUnreadCount)) {
var count: Int32 = 0
value.read(&count, offset: 0, length: 4)
self.chatListTotalUnreadCount = count
return count
if let value = self.valueBox.get(self.table, key: self.key(.ChatListTotalUnreadState)), let state = PostboxDecoder(buffer: value).decodeObjectForKey("_", decoder: {
ChatListTotalUnreadState(decoder: $0)
}) as? ChatListTotalUnreadState {
self.chatListTotalUnreadState = state
return state
} else {
self.chatListTotalUnreadCount = 0
return 0
let state = ChatListTotalUnreadState(absoluteCounters: ChatListTotalUnreadCounters(messageCount: 0), filteredCounters: ChatListTotalUnreadCounters(messageCount: 0))
self.chatListTotalUnreadState = state
return state
}
}
}
func setChatListTotalUnreadCount(_ value: Int32) {
let current = self.getChatListTotalUnreadCount()
if current != value {
self.chatListTotalUnreadCount = value
self.chatListTotalUnreadCountUpdated = true
func setChatListTotalUnreadState(_ state: ChatListTotalUnreadState) {
let current = self.getChatListTotalUnreadState()
if current != state {
self.chatListTotalUnreadState = state
self.chatListTotalUnreadStateUpdated = true
}
}
@ -303,8 +357,8 @@ final class MessageHistoryMetadataTable: Table {
self.updatedPeerNextMessageIdByNamespace.removeAll()
self.nextMessageStableId = nil
self.nextMessageStableIdUpdated = false
self.chatListTotalUnreadCount = nil
self.chatListTotalUnreadCountUpdated = false
self.chatListTotalUnreadState = nil
self.chatListTotalUnreadStateUpdated = false
}
override func beforeCommit() {
@ -339,12 +393,13 @@ final class MessageHistoryMetadataTable: Table {
}
}
if self.chatListTotalUnreadCountUpdated {
if let value = self.chatListTotalUnreadCount {
var count: Int32 = value
self.valueBox.set(self.table, key: self.key(.ChatListTotalUnreadCount), value: MemoryBuffer(memory: &count, capacity: 4, length: 4, freeWhenDone: false))
if self.chatListTotalUnreadStateUpdated {
if let state = self.chatListTotalUnreadState {
let buffer = PostboxEncoder()
buffer.encodeObject(state, forKey: "_")
self.valueBox.set(self.table, key: self.key(.ChatListTotalUnreadState), value: buffer.readBufferNoCopy())
}
self.chatListTotalUnreadCountUpdated = false
self.chatListTotalUnreadStateUpdated = false
}
}
}

View File

@ -228,7 +228,13 @@ final class MessageHistoryReadStateTable: Table {
self.markReadStatesAsUpdated(peerId, namespaces: states.namespaces)
states.namespaces[namespace] = currentState.withAddedCount(Int32(-knownCount))
var updatedState = currentState.withAddedCount(Int32(-knownCount))
if updatedState.count < 0 {
invalidate = true
updatedState = currentState.withAddedCount(-updatedState.count)
}
states.namespaces[namespace] = updatedState
updated = true
} else {
invalidate = true

View File

@ -409,7 +409,7 @@ final class MessageHistoryTable: Table {
private func processIndexOperationsCommitAccumulatedRemoveIndices(peerId: PeerId, accumulatedRemoveIndices: inout [(MessageIndex, Bool)], updatedCombinedState: inout CombinedPeerReadState?, invalidateReadState: inout Bool, unsentMessageOperations: inout [IntermediateMessageHistoryUnsentOperation], outputOperations: inout [MessageHistoryOperation], globalTagsOperations: inout [GlobalMessageHistoryTagsOperation], pendingActionsOperations: inout [PendingMessageActionsOperation], updatedMessageActionsSummaries: inout [PendingMessageActionsSummaryKey: Int32], updatedMessageTagSummaries: inout [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], invalidateMessageTagSummaries: inout [InvalidatedMessageHistoryTagsSummaryEntryOperation], groupFeedOperations: inout [PeerGroupId : [GroupFeedIndexOperation]], localTagsOperations: inout [IntermediateMessageHistoryLocalTagsOperation]) {
if !accumulatedRemoveIndices.isEmpty {
let (combinedState, invalidate) = self.readStateTable.deleteMessages(peerId, indices: accumulatedRemoveIndices.map { $0.0 }, incomingStatsInIndices: { peerId, namespace, indices in
let (combinedState, invalidate) = self.readStateTable.deleteMessages(peerId, indices: accumulatedRemoveIndices.filter({ $0.1 }).map({ $0.0 }), incomingStatsInIndices: { peerId, namespace, indices in
return self.incomingMessageStatsInIndices(peerId, namespace: namespace, indices: indices)
})
if let combinedState = combinedState {
@ -729,7 +729,10 @@ final class MessageHistoryTable: Table {
func clearHistory(peerId: PeerId, operationsByPeerId: inout [PeerId: [MessageHistoryOperation]], updatedMedia: inout [MediaId: Media?], unsentMessageOperations: inout [IntermediateMessageHistoryUnsentOperation], updatedPeerReadStateOperations: inout [PeerId: PeerReadStateSynchronizationOperation?], globalTagsOperations: inout [GlobalMessageHistoryTagsOperation], pendingActionsOperations: inout [PendingMessageActionsOperation], updatedMessageActionsSummaries: inout [PendingMessageActionsSummaryKey: Int32], updatedMessageTagSummaries: inout [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], invalidateMessageTagSummaries: inout [InvalidatedMessageHistoryTagsSummaryEntryOperation], groupFeedOperations: inout [PeerGroupId : [GroupFeedIndexOperation]], localTagsOperations: inout [IntermediateMessageHistoryLocalTagsOperation]) {
let indices = self.allIndices(peerId)
self.removeMessages(indices.map { $0.id }, operationsByPeerId: &operationsByPeerId, updatedMedia: &updatedMedia, unsentMessageOperations: &unsentMessageOperations, updatedPeerReadStateOperations: &updatedPeerReadStateOperations, globalTagsOperations: &globalTagsOperations, pendingActionsOperations: &pendingActionsOperations, updatedMessageActionsSummaries: &updatedMessageActionsSummaries, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, groupFeedOperations: &groupFeedOperations, localTagsOperations: &localTagsOperations)
for index in indices.holes {
self.fillHole(index.id, fillType: HoleFill(complete: true, direction: .UpperToLower(updatedMinIndex: nil, clippingMaxIndex: nil)), tagMask: nil, messages: [], operationsByPeerId: &operationsByPeerId, updatedMedia: &updatedMedia, unsentMessageOperations: &unsentMessageOperations, updatedPeerReadStateOperations: &updatedPeerReadStateOperations, globalTagsOperations: &globalTagsOperations, pendingActionsOperations: &pendingActionsOperations, updatedMessageActionsSummaries: &updatedMessageActionsSummaries, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, groupFeedOperations: &groupFeedOperations, localTagsOperations: &localTagsOperations)
}
self.removeMessages(indices.messages.map { $0.id }, operationsByPeerId: &operationsByPeerId, updatedMedia: &updatedMedia, unsentMessageOperations: &unsentMessageOperations, updatedPeerReadStateOperations: &updatedPeerReadStateOperations, globalTagsOperations: &globalTagsOperations, pendingActionsOperations: &pendingActionsOperations, updatedMessageActionsSummaries: &updatedMessageActionsSummaries, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, groupFeedOperations: &groupFeedOperations, localTagsOperations: &localTagsOperations)
}
func removeAllMessagesWithAuthor(peerId: PeerId, authorId: PeerId, operationsByPeerId: inout [PeerId: [MessageHistoryOperation]], updatedMedia: inout [MediaId: Media?], unsentMessageOperations: inout [IntermediateMessageHistoryUnsentOperation], updatedPeerReadStateOperations: inout [PeerId: PeerReadStateSynchronizationOperation?], globalTagsOperations: inout [GlobalMessageHistoryTagsOperation], pendingActionsOperations: inout [PendingMessageActionsOperation], updatedMessageActionsSummaries: inout [PendingMessageActionsSummaryKey: Int32], updatedMessageTagSummaries: inout [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], invalidateMessageTagSummaries: inout [InvalidatedMessageHistoryTagsSummaryEntryOperation], groupFeedOperations: inout [PeerGroupId : [GroupFeedIndexOperation]], localTagsOperations: inout [IntermediateMessageHistoryLocalTagsOperation]) {
@ -3034,14 +3037,19 @@ final class MessageHistoryTable: Table {
return messageIds
}
func allIndices(_ peerId: PeerId) -> [MessageIndex] {
var indices: [MessageIndex] = []
self.valueBox.range(self.table, start: self.key(MessageIndex.lowerBound(peerId: peerId)).predecessor, end: self.key(MessageIndex.upperBound(peerId: peerId)).successor, keys: { key in
func allIndices(_ peerId: PeerId) -> (messages: [MessageIndex], holes: [MessageIndex]) {
var messages: [MessageIndex] = []
var holes: [MessageIndex] = []
self.valueBox.range(self.table, start: self.key(MessageIndex.lowerBound(peerId: peerId)).predecessor, end: self.key(MessageIndex.upperBound(peerId: peerId)).successor, values: { key, value in
let index = MessageIndex(id: MessageId(peerId: PeerId(key.getInt64(0)), namespace: key.getInt32(8 + 4), id: key.getInt32(8 + 4 + 4)), timestamp: key.getInt32(8))
indices.append(index)
if extractIntermediateEntryIsMessage(value: value) {
messages.append(index)
} else {
holes.append(index)
}
return true
}, limit: 0)
return indices
return (messages, holes)
}
func allMessageIndices(_ peerId: PeerId) -> [MessageIndex] {

View File

@ -14,7 +14,7 @@ public enum AdditionalMessageHistoryViewData {
case cachedPeerDataMessages(PeerId)
case peerChatState(PeerId)
case peerGroupState(PeerGroupId)
case totalUnreadCount
case totalUnreadState
case peerNotificationSettings(PeerId)
}
@ -23,7 +23,7 @@ public enum AdditionalMessageHistoryViewDataEntry {
case cachedPeerDataMessages(PeerId, [MessageId: Message]?)
case peerChatState(PeerId, PeerChatState?)
case peerGroupState(PeerGroupId, PeerGroupState?)
case totalUnreadCount(Int32)
case totalUnreadState(ChatListTotalUnreadState)
case peerNotificationSettings(PeerNotificationSettings?)
}
@ -423,7 +423,7 @@ private func monthUpperBoundIndex(peerId: PeerId, index: MessageMonthIndex) -> M
public enum MessageHistoryViewPeerIds: Equatable {
case single(PeerId)
case associated(PeerId, PeerId?)
case associated(PeerId, MessageId?)
case group(PeerGroupId)
public static func ==(lhs: MessageHistoryViewPeerIds, rhs: MessageHistoryViewPeerIds) -> Bool {
@ -450,6 +450,46 @@ public enum MessageHistoryViewPeerIds: Equatable {
}
}
private func clipMessages(peerIds: MessageHistoryViewPeerIds, entries: [MutableMessageHistoryEntry]) -> [MutableMessageHistoryEntry] {
switch peerIds {
case .single, .group:
return entries
case let .associated(_, associatedId):
if let associatedId = associatedId {
var result: [MutableMessageHistoryEntry] = []
for entry in entries {
switch entry {
case let .MessageEntry(message, _, _):
if message.id.peerId == associatedId.peerId {
if message.id.namespace == associatedId.namespace && message.id.id <= associatedId.id {
result.append(entry)
}
} else {
result.append(entry)
}
case let .IntermediateMessageEntry(message, _, _):
if message.id.peerId == associatedId.peerId {
if message.id.namespace == associatedId.namespace && message.id.id <= associatedId.id {
result.append(entry)
}
} else {
result.append(entry)
}
case .HoleEntry:
result.append(entry)
}
}
return result
} else {
return entries
}
}
}
private func clipAround(peerIds: MessageHistoryViewPeerIds, _ data: (entries: [MutableMessageHistoryEntry], lower: MutableMessageHistoryEntry?, upper: MutableMessageHistoryEntry?)) -> (entries: [MutableMessageHistoryEntry], lower: MutableMessageHistoryEntry?, upper: MutableMessageHistoryEntry?) {
return (entries: clipMessages(peerIds: peerIds, entries: data.entries), lower: data.lower, upper: data.upper)
}
private func fetchAround(postbox: Postbox, peerIds: MessageHistoryViewPeerIds, index: InternalMessageHistoryAnchorIndex, count: Int, tagMask: MessageTags?) -> (entries: [MutableMessageHistoryEntry], lower: MutableMessageHistoryEntry?, upper: MutableMessageHistoryEntry?) {
var ids: [PeerId] = []
switch peerIds {
@ -458,7 +498,7 @@ private func fetchAround(postbox: Postbox, peerIds: MessageHistoryViewPeerIds, i
case let .associated(mainId, associatedId):
ids.append(mainId)
if let associatedId = associatedId {
ids.append(associatedId)
ids.append(associatedId.peerId)
}
case let .group(groupId):
switch index {
@ -473,11 +513,11 @@ private func fetchAround(postbox: Postbox, peerIds: MessageHistoryViewPeerIds, i
switch index {
case let .message(index: index, _):
return postbox.fetchAroundHistoryEntries(peerIds: ids, index: index, count: count, tagMask: tagMask)
return clipAround(peerIds: peerIds, postbox.fetchAroundHistoryEntries(peerIds: ids, index: index, count: count, tagMask: tagMask))
case .upperBound:
return postbox.fetchAroundHistoryEntries(peerIds: ids, index: MessageIndex.absoluteUpperBound(), count: count, tagMask: tagMask)
return clipAround(peerIds: peerIds, postbox.fetchAroundHistoryEntries(peerIds: ids, index: MessageIndex.absoluteUpperBound(), count: count, tagMask: tagMask))
case .lowerBound:
return postbox.fetchAroundHistoryEntries(peerIds: ids, index: MessageIndex.absoluteLowerBound(), count: count, tagMask: tagMask)
return clipAround(peerIds: peerIds, postbox.fetchAroundHistoryEntries(peerIds: ids, index: MessageIndex.absoluteLowerBound(), count: count, tagMask: tagMask))
}
}
@ -690,12 +730,18 @@ final class MutableMessageHistoryView {
func updatePeerIds(transaction: PostboxTransaction) {
switch self.peerIds {
case .single, .group:
case .group:
break
case let .single(peerId):
if let updatedData = transaction.currentUpdatedCachedPeerData[peerId] {
if updatedData.associatedHistoryMessageId != nil {
self.peerIds = .associated(peerId, updatedData.associatedHistoryMessageId)
}
}
case let .associated(peerId, associatedId):
if let updatedData = transaction.currentUpdatedCachedPeerData[peerId] {
if updatedData.associatedHistoryPeerId != associatedId {
self.peerIds = .associated(peerId, updatedData.associatedHistoryPeerId)
if updatedData.associatedHistoryMessageId != associatedId {
self.peerIds = .associated(peerId, updatedData.associatedHistoryMessageId)
}
}
}
@ -722,7 +768,7 @@ final class MutableMessageHistoryView {
case let .associated(mainPeerId, associatedPeerId):
ids.insert(mainPeerId)
if let associatedPeerId = associatedPeerId {
ids.insert(associatedPeerId)
ids.insert(associatedPeerId.peerId)
}
case let .group(groupId):
if let operations = transaction.currentGroupFeedOperations[groupId] {
@ -1008,7 +1054,7 @@ final class MutableMessageHistoryView {
self.additionalDatas[i] = .peerGroupState(groupId, postbox.peerGroupStateTable.get(groupId))
hasChanges = true
}
case .totalUnreadCount:
case .totalUnreadState:
break
case .peerNotificationSettings:
break
@ -1205,13 +1251,13 @@ final class MutableMessageHistoryView {
case let .associated(mainId, associatedId):
ids.append(mainId)
if let associatedId = associatedId {
ids.append(associatedId)
ids.append(associatedId.peerId)
}
case let .group(groupId):
return postbox.fetchEarlierGroupFeedEntries(groupId: groupId, index: index, count: count)
}
return postbox.fetchEarlierHistoryEntries(peerIds: ids, index: index, count: count, tagMask: self.tagMask)
return clipMessages(peerIds: peerIds, entries: postbox.fetchEarlierHistoryEntries(peerIds: ids, index: index, count: count, tagMask: self.tagMask))
}
private func fetchLater(postbox: Postbox, index: MessageIndex?, count: Int) -> [MutableMessageHistoryEntry] {
@ -1222,13 +1268,13 @@ final class MutableMessageHistoryView {
case let .associated(mainId, associatedId):
ids.append(mainId)
if let associatedId = associatedId {
ids.append(associatedId)
ids.append(associatedId.peerId)
}
case let .group(groupId):
return postbox.fetchLaterGroupFeedEntries(groupId: groupId, index: index, count: count)
}
return postbox.fetchLaterHistoryEntries(ids, index: index, count: count, tagMask: self.tagMask)
return clipMessages(peerIds: peerIds, entries: postbox.fetchLaterHistoryEntries(ids, index: index, count: count, tagMask: self.tagMask))
}
func complete(postbox: Postbox, context: MutableMessageHistoryViewReplayContext) {
@ -1492,11 +1538,19 @@ public final class MessageHistoryView {
var laterId = mutableView.later?.index
var entries: [MessageHistoryEntry] = []
var removeUpperHolePeerId: PeerId?
if case let .associated(_, associatedId) = mutableView.peerIds {
removeUpperHolePeerId = associatedId?.peerId
}
if let transientReadStates = mutableView.transientReadStates, case let .peer(states) = transientReadStates {
for entry in mutableView.entries {
switch entry {
case let .HoleEntry(hole, location, _):
entries.append(.HoleEntry(hole, location))
if let removeUpperHolePeerId = removeUpperHolePeerId, removeUpperHolePeerId == hole.maxIndex.id.peerId, hole.maxIndex.timestamp >= Int32.max - 1 {
// skip hole
} else {
entries.append(.HoleEntry(hole, location))
}
case let .MessageEntry(message, location, monthLocation):
let read: Bool
if message.flags.contains(.Incoming) {
@ -1515,7 +1569,11 @@ public final class MessageHistoryView {
for entry in mutableView.entries {
switch entry {
case let .HoleEntry(hole, location, _):
entries.append(.HoleEntry(hole, location))
if let removeUpperHolePeerId = removeUpperHolePeerId, removeUpperHolePeerId == hole.maxIndex.id.peerId, hole.maxIndex.timestamp >= Int32.max - 1 {
// skip hole
} else {
entries.append(.HoleEntry(hole, location))
}
case let .MessageEntry(message, location, monthLocation):
entries.append(.MessageEntry(message, false, location, monthLocation))
case .IntermediateMessageEntry:

View File

@ -4,6 +4,7 @@ enum OrderedItemListOperation {
case replace([OrderedItemListEntry])
case addOrMoveToFirstPosition(OrderedItemListEntry, Int?)
case remove(MemoryBuffer)
case update(MemoryBuffer, OrderedItemListEntryContents)
}
private enum OrderedItemListKeyNamespace: UInt8 {
@ -85,6 +86,16 @@ final class OrderedItemListTable: Table {
}
}
func updateItem(collectionId: Int32, itemId: MemoryBuffer, item: OrderedItemListEntryContents, operations: inout [Int32: [OrderedItemListOperation]]) {
if let _ = self.indexTable.get(collectionId: collectionId, id: itemId) as? OrderedItemListEntryContents {
self.indexTable.set(collectionId: collectionId, id: itemId, content: item)
if operations[collectionId] == nil {
operations[collectionId] = []
}
operations[collectionId]!.append(.update(itemId, item))
}
}
func replaceItems(collectionId: Int32, items: [OrderedItemListEntry], operations: inout [Int32: [OrderedItemListOperation]]) {
if operations[collectionId] == nil {
operations[collectionId] = [.replace(items)]

View File

@ -37,6 +37,14 @@ final class MutableOrderedItemListView: MutablePostboxView {
break inner
}
}
case let .update(itemId, content):
inner: for i in 0 ..< self.items.count {
if self.items[i].id == itemId {
self.items[i] = OrderedItemListEntry(id: itemId, contents: content)
updated = true
break inner
}
}
}
}
}

View File

@ -522,6 +522,11 @@ public final class Modifier {
return self.postbox?.getOrderedItemListItem(collectionId: collectionId, itemId: itemId)
}
public func updateOrderedItemListItem(collectionId: Int32, itemId: MemoryBuffer, item: OrderedItemListEntryContents) {
assert(!self.disposed)
self.postbox?.updateOrderedItemListItem(collectionId: collectionId, itemId: itemId, item: item)
}
public func removeOrderedItemListItem(collectionId: Int32, itemId: MemoryBuffer) {
assert(!self.disposed)
self.postbox?.removeOrderedItemListItem(collectionId: collectionId, itemId: itemId)
@ -679,12 +684,12 @@ public final class Modifier {
}
}
public func getTotalUnreadCount() -> Int32 {
public func getTotalUnreadState() -> ChatListTotalUnreadState {
assert(!self.disposed)
if let postbox = self.postbox {
return postbox.messageHistoryMetadataTable.getChatListTotalUnreadCount()
return postbox.messageHistoryMetadataTable.getChatListTotalUnreadState()
} else {
return 0
return ChatListTotalUnreadState(absoluteCounters: ChatListTotalUnreadCounters(messageCount: 0), filteredCounters: ChatListTotalUnreadCounters(messageCount: 0))
}
}
@ -839,11 +844,15 @@ func debugSaveState(basePath:String, name: String) {
func debugRestoreState(basePath:String, name: String) {
let path = basePath + name
let _ = try? FileManager.default.removeItem(atPath: basePath)
do {
try FileManager.default.copyItem(atPath: path, toPath: basePath)
} catch (let e) {
print("(Postbox debugRestoreState: error \(e))")
if FileManager.default.fileExists(atPath: path) {
let _ = try? FileManager.default.removeItem(atPath: basePath)
do {
try FileManager.default.copyItem(atPath: path, toPath: basePath)
} catch (let e) {
print("(Postbox debugRestoreState: error \(e))")
}
} else {
print("(Postbox debugRestoreState: path doesn't exist")
}
}
@ -864,22 +873,26 @@ public func openPostbox(basePath: String, globalMessageIdsNamespace: MessageId.N
let metadataTable = MetadataTable(valueBox: valueBox, table: MetadataTable.tableSpec(0))
let userVersion: Int32? = metadataTable.userVersion()
let currentUserVersion: Int32 = 15
let currentUserVersion: Int32 = 16
if let userVersion = userVersion {
if userVersion != currentUserVersion {
if let operation = registeredUpgrades()[userVersion] {
switch operation {
case let .inplace(f):
valueBox.begin()
f(metadataTable, valueBox)
valueBox.commit()
}
continue loop
if userVersion > currentUserVersion {
postboxLog("Version \(userVersion) is newer than supported")
} else {
assertionFailure()
postboxLog("Couldn't find any upgrade for \(userVersion)")
valueBox.drop()
if let operation = registeredUpgrades()[userVersion] {
switch operation {
case let .inplace(f):
valueBox.begin()
f(metadataTable, valueBox)
valueBox.commit()
}
continue loop
} else {
assertionFailure()
postboxLog("Couldn't find any upgrade for \(userVersion)")
valueBox.drop()
}
}
}
} else {
@ -931,7 +944,7 @@ public final class Postbox {
private var currentUpdatedCachedPeerData: [PeerId: CachedPeerData] = [:]
private var currentUpdatedPeerPresences: [PeerId: PeerPresence] = [:]
private var currentUpdatedPeerChatListEmbeddedStates: [PeerId: PeerChatListEmbeddedInterfaceState?] = [:]
private var currentUpdatedTotalUnreadCount: Int32?
private var currentUpdatedTotalUnreadState: ChatListTotalUnreadState?
private var currentPeerMergedOperationLogOperations: [PeerMergedOperationLogOperation] = []
private var currentTimestampBasedMessageAttributesOperations: [TimestampBasedMessageAttributesOperation] = []
private var currentPreferencesOperations: [PreferencesOperation] = []
@ -1171,8 +1184,8 @@ public final class Postbox {
return self.cachedPeerDataTable.get(peerId)
}, getPeerPresence: { peerId in
return self.peerPresenceTable.get(peerId)
}, getTotalUnreadCount: {
return self.messageHistoryMetadataTable.getChatListTotalUnreadCount()
}, getTotalUnreadState: {
return self.messageHistoryMetadataTable.getChatListTotalUnreadState()
}, getPeerReadState: { peerId in
return self.readStateTable.getCombinedState(peerId)
}, operationLogGetOperations: { tag, fromIndex, limit in
@ -1710,9 +1723,19 @@ public final class Postbox {
let transactionParticipationInTotalUnreadCountUpdates = self.peerNotificationSettingsTable.transactionParticipationInTotalUnreadCountUpdates()
self.chatListIndexTable.commitWithTransactionUnreadCountDeltas(transactionUnreadCountDeltas, transactionParticipationInTotalUnreadCountUpdates: transactionParticipationInTotalUnreadCountUpdates, getPeer: { peerId in
return self.peerTable.get(peerId)
}, updatedTotalUnreadCount: &self.currentUpdatedTotalUnreadCount)
}, updatedTotalUnreadState: &self.currentUpdatedTotalUnreadState)
let transaction = PostboxTransaction(currentUpdatedState: self.currentUpdatedState, currentOperationsByPeerId: self.currentOperationsByPeerId, currentGroupFeedOperations: self.currentGroupFeedOperations, peerIdsWithFilledHoles: self.currentFilledHolesByPeerId, removedHolesByPeerId: self.currentRemovedHolesByPeerId, groupFeedIdsWithFilledHoles: self.currentGroupFeedIdsWithFilledHoles, removedHolesByPeerGroupId: self.currentRemovedHolesByPeerGroupId, chatListOperations: self.currentChatListOperations, currentUpdatedPeers: self.currentUpdatedPeers, currentUpdatedPeerNotificationSettings: self.currentUpdatedPeerNotificationSettings, currentUpdatedCachedPeerData: self.currentUpdatedCachedPeerData, currentUpdatedPeerPresences: currentUpdatedPeerPresences, currentUpdatedPeerChatListEmbeddedStates: self.currentUpdatedPeerChatListEmbeddedStates, currentUpdatedTotalUnreadCount: self.currentUpdatedTotalUnreadCount, peerIdsWithUpdatedUnreadCounts: Set(transactionUnreadCountDeltas.keys), peerIdsWithUpdatedCombinedReadStates: peerIdsWithUpdatedCombinedReadStates, currentPeerMergedOperationLogOperations: self.currentPeerMergedOperationLogOperations, currentTimestampBasedMessageAttributesOperations: self.currentTimestampBasedMessageAttributesOperations, unsentMessageOperations: self.currentUnsentOperations, updatedSynchronizePeerReadStateOperations: self.currentUpdatedSynchronizeReadStateOperations, currentPreferencesOperations: self.currentPreferencesOperations, currentOrderedItemListOperations: self.currentOrderedItemListOperations, currentItemCollectionItemsOperations: self.currentItemCollectionItemsOperations, currentItemCollectionInfosOperations: self.currentItemCollectionInfosOperations, currentUpdatedPeerChatStates: self.currentUpdatedPeerChatStates, currentUpdatedPeerGroupStates: self.currentUpdatedPeerGroupStates, updatedAccessChallengeData: self.currentUpdatedAccessChallengeData, 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, currentGroupFeedReadStateContext: self.currentGroupFeedReadStateContext, currentInitialPeerGroupIdsBeforeUpdate: self.currentInitialPeerGroupIdsBeforeUpdate, currentUpdatedMasterClientId: currentUpdatedMasterClientId)
#if DEBUG
/*if let updatedState = self.currentUpdatedTotalUnreadState {
let state = self.chatListIndexTable.debugReindexUnreadCounts(postbox: self)
if state != updatedState {
print("read state mismatch \(state) != \(updatedState)")
self.messageHistoryMetadataTable.setChatListTotalUnreadState(state)
}
}*/
#endif
let transaction = PostboxTransaction(currentUpdatedState: self.currentUpdatedState, currentOperationsByPeerId: self.currentOperationsByPeerId, currentGroupFeedOperations: self.currentGroupFeedOperations, peerIdsWithFilledHoles: self.currentFilledHolesByPeerId, removedHolesByPeerId: self.currentRemovedHolesByPeerId, groupFeedIdsWithFilledHoles: self.currentGroupFeedIdsWithFilledHoles, removedHolesByPeerGroupId: self.currentRemovedHolesByPeerGroupId, chatListOperations: self.currentChatListOperations, currentUpdatedPeers: self.currentUpdatedPeers, currentUpdatedPeerNotificationSettings: self.currentUpdatedPeerNotificationSettings, currentUpdatedCachedPeerData: self.currentUpdatedCachedPeerData, currentUpdatedPeerPresences: currentUpdatedPeerPresences, currentUpdatedPeerChatListEmbeddedStates: self.currentUpdatedPeerChatListEmbeddedStates, currentUpdatedTotalUnreadState: self.currentUpdatedTotalUnreadState, peerIdsWithUpdatedUnreadCounts: Set(transactionUnreadCountDeltas.keys), peerIdsWithUpdatedCombinedReadStates: peerIdsWithUpdatedCombinedReadStates, currentPeerMergedOperationLogOperations: self.currentPeerMergedOperationLogOperations, currentTimestampBasedMessageAttributesOperations: self.currentTimestampBasedMessageAttributesOperations, unsentMessageOperations: self.currentUnsentOperations, updatedSynchronizePeerReadStateOperations: self.currentUpdatedSynchronizeReadStateOperations, currentPreferencesOperations: self.currentPreferencesOperations, currentOrderedItemListOperations: self.currentOrderedItemListOperations, currentItemCollectionItemsOperations: self.currentItemCollectionItemsOperations, currentItemCollectionInfosOperations: self.currentItemCollectionInfosOperations, currentUpdatedPeerChatStates: self.currentUpdatedPeerChatStates, currentUpdatedPeerGroupStates: self.currentUpdatedPeerGroupStates, updatedAccessChallengeData: self.currentUpdatedAccessChallengeData, 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, currentGroupFeedReadStateContext: self.currentGroupFeedReadStateContext, currentInitialPeerGroupIdsBeforeUpdate: self.currentInitialPeerGroupIdsBeforeUpdate, currentUpdatedMasterClientId: currentUpdatedMasterClientId)
var updatedTransactionState: Int64?
var updatedMasterClientId: Int64?
if !transaction.isEmpty {
@ -1748,7 +1771,7 @@ public final class Postbox {
self.currentUpdatedCachedPeerData.removeAll()
self.currentUpdatedPeerPresences.removeAll()
self.currentUpdatedPeerChatListEmbeddedStates.removeAll()
self.currentUpdatedTotalUnreadCount = nil
self.currentUpdatedTotalUnreadState = nil
self.currentPeerMergedOperationLogOperations.removeAll()
self.currentTimestampBasedMessageAttributesOperations.removeAll()
self.currentPreferencesOperations.removeAll()
@ -2157,8 +2180,8 @@ public final class Postbox {
switch chatLocation {
case let .peer(peerId):
peerIds = .single(peerId)
if tagMask == nil, let associatedPeerId = self.cachedPeerDataTable.get(peerId)?.associatedHistoryPeerId, associatedPeerId != peerId {
peerIds = .associated(peerId, associatedPeerId)
if tagMask == nil, let associatedMessageId = self.cachedPeerDataTable.get(peerId)?.associatedHistoryMessageId, associatedMessageId.peerId != peerId {
peerIds = .associated(peerId, associatedMessageId)
}
case let .group(groupId):
peerIds = .group(groupId)
@ -2182,7 +2205,7 @@ public final class Postbox {
var ids: [PeerId] = []
ids.append(mainId)
if let associatedId = associatedId {
ids.append(associatedId)
ids.append(associatedId.peerId)
}
var minIndexWithUnreadMessages: InternalMessageHistoryAnchorIndex?
@ -2304,8 +2327,8 @@ public final class Postbox {
additionalDataEntries.append(.peerChatState(peerId, self.peerChatStateTable.get(peerId) as? PeerChatState))
case let .peerGroupState(groupId):
additionalDataEntries.append(.peerGroupState(groupId, self.peerGroupStateTable.get(groupId)))
case .totalUnreadCount:
additionalDataEntries.append(.totalUnreadCount(self.messageHistoryMetadataTable.getChatListTotalUnreadCount()))
case .totalUnreadState:
additionalDataEntries.append(.totalUnreadState(self.messageHistoryMetadataTable.getChatListTotalUnreadState()))
case let .peerNotificationSettings(peerId):
additionalDataEntries.append(.peerNotificationSettings(self.peerNotificationSettingsTable.getEffective(peerId)))
}
@ -2954,6 +2977,10 @@ public final class Postbox {
return self.orderedItemListTable.getItem(collectionId: collectionId, itemId: itemId)
}
fileprivate func updateOrderedItemListItem(collectionId: Int32, itemId: MemoryBuffer, item: OrderedItemListEntryContents) {
self.orderedItemListTable.updateItem(collectionId: collectionId, itemId: itemId, item: item, operations: &self.currentOrderedItemListOperations)
}
fileprivate func setAccessChallengeData(_ data: PostboxAccessChallengeData) {
self.currentUpdatedAccessChallengeData = data
self.metadataTable.setAccessChallengeData(data)

View File

@ -14,7 +14,7 @@ final class PostboxTransaction {
let currentUpdatedCachedPeerData: [PeerId: CachedPeerData]
let currentUpdatedPeerPresences: [PeerId: PeerPresence]
let currentUpdatedPeerChatListEmbeddedStates: [PeerId: PeerChatListEmbeddedInterfaceState?]
let currentUpdatedTotalUnreadCount: Int32?
let currentUpdatedTotalUnreadState: ChatListTotalUnreadState?
let peerIdsWithUpdatedUnreadCounts: Set<PeerId>
let peerIdsWithUpdatedCombinedReadStates: Set<PeerId>
let currentPeerMergedOperationLogOperations: [PeerMergedOperationLogOperation]
@ -101,7 +101,7 @@ final class PostboxTransaction {
if currentUpdatedMasterClientId != nil {
return false
}
if currentUpdatedTotalUnreadCount != nil {
if currentUpdatedTotalUnreadState != nil {
return false
}
if !peerIdsWithUpdatedCombinedReadStates.isEmpty {
@ -167,7 +167,7 @@ final class PostboxTransaction {
return true
}
init(currentUpdatedState: PostboxCoding?, currentOperationsByPeerId: [PeerId: [MessageHistoryOperation]], currentGroupFeedOperations: [PeerGroupId : [GroupFeedIndexOperation]], peerIdsWithFilledHoles: [PeerId: [MessageIndex: HoleFillDirection]], removedHolesByPeerId: [PeerId: [MessageIndex: HoleFillDirection]], groupFeedIdsWithFilledHoles: [PeerGroupId: [MessageIndex: HoleFillDirection]], removedHolesByPeerGroupId: [PeerGroupId: [MessageIndex: HoleFillDirection]], chatListOperations: [WrappedPeerGroupId: [ChatListOperation]], currentUpdatedPeers: [PeerId: Peer], currentUpdatedPeerNotificationSettings: [PeerId: PeerNotificationSettings], currentUpdatedCachedPeerData: [PeerId: CachedPeerData], currentUpdatedPeerPresences: [PeerId: PeerPresence], currentUpdatedPeerChatListEmbeddedStates: [PeerId: PeerChatListEmbeddedInterfaceState?], currentUpdatedTotalUnreadCount: Int32?, peerIdsWithUpdatedUnreadCounts: Set<PeerId>, peerIdsWithUpdatedCombinedReadStates: Set<PeerId>, currentPeerMergedOperationLogOperations: [PeerMergedOperationLogOperation], currentTimestampBasedMessageAttributesOperations: [TimestampBasedMessageAttributesOperation], unsentMessageOperations: [IntermediateMessageHistoryUnsentOperation], updatedSynchronizePeerReadStateOperations: [PeerId: PeerReadStateSynchronizationOperation?], currentPreferencesOperations: [PreferencesOperation], currentOrderedItemListOperations: [Int32: [OrderedItemListOperation]], currentItemCollectionItemsOperations: [ItemCollectionId: [ItemCollectionItemsOperation]], currentItemCollectionInfosOperations: [ItemCollectionInfosOperation], currentUpdatedPeerChatStates: Set<PeerId>, currentUpdatedPeerGroupStates: Set<PeerGroupId>, updatedAccessChallengeData: PostboxAccessChallengeData?, currentGlobalTagsOperations: [GlobalMessageHistoryTagsOperation], currentLocalTagsOperations: [IntermediateMessageHistoryLocalTagsOperation], updatedMedia: [MediaId: Media?], replaceRemoteContactCount: Int32?, replaceContactPeerIds: Set<PeerId>?, currentPendingMessageActionsOperations: [PendingMessageActionsOperation], currentUpdatedMessageActionsSummaries: [PendingMessageActionsSummaryKey: Int32], currentUpdatedMessageTagSummaries: [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], currentInvalidateMessageTagSummaries: [InvalidatedMessageHistoryTagsSummaryEntryOperation], currentUpdatedPendingPeerNotificationSettings: Set<PeerId>, currentGroupFeedReadStateContext: GroupFeedReadStateUpdateContext, currentInitialPeerGroupIdsBeforeUpdate: [PeerId: WrappedPeerGroupId], currentUpdatedMasterClientId: Int64?) {
init(currentUpdatedState: PostboxCoding?, currentOperationsByPeerId: [PeerId: [MessageHistoryOperation]], currentGroupFeedOperations: [PeerGroupId : [GroupFeedIndexOperation]], peerIdsWithFilledHoles: [PeerId: [MessageIndex: HoleFillDirection]], removedHolesByPeerId: [PeerId: [MessageIndex: HoleFillDirection]], groupFeedIdsWithFilledHoles: [PeerGroupId: [MessageIndex: HoleFillDirection]], removedHolesByPeerGroupId: [PeerGroupId: [MessageIndex: HoleFillDirection]], chatListOperations: [WrappedPeerGroupId: [ChatListOperation]], currentUpdatedPeers: [PeerId: Peer], currentUpdatedPeerNotificationSettings: [PeerId: PeerNotificationSettings], currentUpdatedCachedPeerData: [PeerId: CachedPeerData], currentUpdatedPeerPresences: [PeerId: PeerPresence], currentUpdatedPeerChatListEmbeddedStates: [PeerId: PeerChatListEmbeddedInterfaceState?], currentUpdatedTotalUnreadState: ChatListTotalUnreadState?, peerIdsWithUpdatedUnreadCounts: Set<PeerId>, peerIdsWithUpdatedCombinedReadStates: Set<PeerId>, currentPeerMergedOperationLogOperations: [PeerMergedOperationLogOperation], currentTimestampBasedMessageAttributesOperations: [TimestampBasedMessageAttributesOperation], unsentMessageOperations: [IntermediateMessageHistoryUnsentOperation], updatedSynchronizePeerReadStateOperations: [PeerId: PeerReadStateSynchronizationOperation?], currentPreferencesOperations: [PreferencesOperation], currentOrderedItemListOperations: [Int32: [OrderedItemListOperation]], currentItemCollectionItemsOperations: [ItemCollectionId: [ItemCollectionItemsOperation]], currentItemCollectionInfosOperations: [ItemCollectionInfosOperation], currentUpdatedPeerChatStates: Set<PeerId>, currentUpdatedPeerGroupStates: Set<PeerGroupId>, updatedAccessChallengeData: PostboxAccessChallengeData?, currentGlobalTagsOperations: [GlobalMessageHistoryTagsOperation], currentLocalTagsOperations: [IntermediateMessageHistoryLocalTagsOperation], updatedMedia: [MediaId: Media?], replaceRemoteContactCount: Int32?, replaceContactPeerIds: Set<PeerId>?, currentPendingMessageActionsOperations: [PendingMessageActionsOperation], currentUpdatedMessageActionsSummaries: [PendingMessageActionsSummaryKey: Int32], currentUpdatedMessageTagSummaries: [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], currentInvalidateMessageTagSummaries: [InvalidatedMessageHistoryTagsSummaryEntryOperation], currentUpdatedPendingPeerNotificationSettings: Set<PeerId>, currentGroupFeedReadStateContext: GroupFeedReadStateUpdateContext, currentInitialPeerGroupIdsBeforeUpdate: [PeerId: WrappedPeerGroupId], currentUpdatedMasterClientId: Int64?) {
self.currentUpdatedState = currentUpdatedState
self.currentOperationsByPeerId = currentOperationsByPeerId
self.currentGroupFeedOperations = currentGroupFeedOperations
@ -181,7 +181,7 @@ final class PostboxTransaction {
self.currentUpdatedCachedPeerData = currentUpdatedCachedPeerData
self.currentUpdatedPeerPresences = currentUpdatedPeerPresences
self.currentUpdatedPeerChatListEmbeddedStates = currentUpdatedPeerChatListEmbeddedStates
self.currentUpdatedTotalUnreadCount = currentUpdatedTotalUnreadCount
self.currentUpdatedTotalUnreadState = currentUpdatedTotalUnreadState
self.peerIdsWithUpdatedUnreadCounts = peerIdsWithUpdatedUnreadCounts
self.peerIdsWithUpdatedCombinedReadStates = peerIdsWithUpdatedCombinedReadStates
self.currentPeerMergedOperationLogOperations = currentPeerMergedOperationLogOperations

View File

@ -16,19 +16,6 @@ private func makeKeyValueForChatListPinningIndex(_ index: UInt16?) -> UInt16 {
}
}
/*
private func key(_ index: ChatListIndex, type: ChatListEntryType) -> ValueBoxKey {
let key = ValueBoxKey(length: 2 + 4 + 4 + 4 + 8 + 1)
key.setUInt16(0, value: keyValueForChatListPinningIndex(index.pinningIndex))
key.setInt32(2, value: index.messageIndex.timestamp)
key.setInt32(2 + 4, value: index.messageIndex.id.namespace)
key.setInt32(2 + 4 + 4, value: index.messageIndex.id.id)
key.setInt64(2 + 4 + 4 + 4, value: index.messageIndex.id.peerId.toInt64())
key.setInt8(2 + 4 + 4 + 4 + 8, value: type.rawValue)
return key
}
*/
private func extractPreviousKey(_ key: ValueBoxKey) -> (pinningIndex: UInt16?, index: MessageIndex, type: Int8) {
return (
pinningIndex: extractPinningIndexFromKeyValue(key.getUInt16(0)),

View File

@ -0,0 +1,248 @@
import Foundation
private struct UpgradeChatListIndexFlags: OptionSet {
var rawValue: Int8
init(rawValue: Int8) {
self.rawValue = rawValue
}
static let hasIndex = UpgradeChatListIndexFlags(rawValue: 1 << 0)
}
private enum UpgradePeerChatListInclusion {
case notSpecified
case never
case ifHasMessages
case ifHasMessagesOrOneOf(pinningIndex: UInt16?, minTimestamp: Int32?)
}
private struct UpgradeChatListPeerInclusionIndex {
let topMessageIndex: MessageIndex?
let inclusion: UpgradePeerChatListInclusion
func includedIndex(peerId: PeerId) -> Bool {
switch inclusion {
case .notSpecified, .never:
return false
case .ifHasMessages:
if let _ = self.topMessageIndex {
return true
} else {
return false
}
case let .ifHasMessagesOrOneOf(pinningIndex, minTimestamp):
if let _ = minTimestamp {
return true
} else if let _ = self.topMessageIndex {
return true
} else if let _ = pinningIndex {
return true
} else {
return false
}
}
}
}
private func parseInclusionIndex(peerId: PeerId, value: ReadBuffer) -> Bool {
let topMessageIndex: MessageIndex?
var flagsValue: Int8 = 0
value.read(&flagsValue, offset: 0, length: 1)
let flags = UpgradeChatListIndexFlags(rawValue: flagsValue)
if flags.contains(.hasIndex) {
var idNamespace: Int32 = 0
var idId: Int32 = 0
var idTimestamp: Int32 = 0
value.read(&idNamespace, offset: 0, length: 4)
value.read(&idId, offset: 0, length: 4)
value.read(&idTimestamp, offset: 0, length: 4)
topMessageIndex = MessageIndex(id: MessageId(peerId: peerId, namespace: idNamespace, id: idId), timestamp: idTimestamp)
} else {
topMessageIndex = nil
}
let inclusion: UpgradePeerChatListInclusion
var inclusionId: Int8 = 0
value.read(&inclusionId, offset: 0, length: 1)
if inclusionId == 0 {
inclusion = .notSpecified
} else if inclusionId == 1 {
inclusion = .never
} else if inclusionId == 2 {
inclusion = .ifHasMessages
} else if inclusionId == 3 {
var pinningIndexValue: UInt16 = 0
value.read(&pinningIndexValue, offset: 0, length: 2)
var hasMinTimestamp: Int8 = 0
value.read(&hasMinTimestamp, offset: 0, length: 1)
let minTimestamp: Int32?
if hasMinTimestamp != 0 {
var minTimestampValue: Int32 = 0
value.read(&minTimestampValue, offset: 0, length: 4)
minTimestamp = minTimestampValue
} else {
minTimestamp = nil
}
inclusion = .ifHasMessagesOrOneOf(pinningIndex: chatListPinningIndexFromKeyValue(pinningIndexValue), minTimestamp: minTimestamp)
} else {
assertionFailure()
return false
}
let inclusionIndex = UpgradeChatListPeerInclusionIndex(topMessageIndex: topMessageIndex, inclusion: inclusion)
return inclusionIndex.includedIndex(peerId: peerId)
}
private struct UpgradePeerNotificationSettingsTableEntryFlags: OptionSet {
var rawValue: Int32
init(rawValue: Int32) {
self.rawValue = rawValue
}
static let hasCurrent = UpgradePeerNotificationSettingsTableEntryFlags(rawValue: 1 << 0)
static let hasPending = UpgradePeerNotificationSettingsTableEntryFlags(rawValue: 1 << 1)
}
private func parseNotificationSettings(valueBox: ValueBox, table: ValueBoxTable, peerId: PeerId) -> Bool {
let key = ValueBoxKey(length: 8)
key.setInt64(0, value: peerId.toInt64())
if let value = valueBox.get(table, key: key) {
var flagsValue: Int32 = 0
value.read(&flagsValue, offset: 0, length: 4)
let flags = UpgradePeerNotificationSettingsTableEntryFlags(rawValue: flagsValue)
var current: PeerNotificationSettings?
if flags.contains(.hasCurrent) {
var length: Int32 = 0
value.read(&length, offset: 0, length: 4)
let object = PostboxDecoder(buffer: MemoryBuffer(memory: value.memory.advanced(by: value.offset), capacity: Int(length), length: Int(length), freeWhenDone: false)).decodeRootObject() as? PeerNotificationSettings
assert(object != nil)
current = object
value.skip(Int(length))
}
var pending: PeerNotificationSettings?
if flags.contains(.hasPending) {
var length: Int32 = 0
value.read(&length, offset: 0, length: 4)
let object = PostboxDecoder(buffer: MemoryBuffer(memory: value.memory.advanced(by: value.offset), capacity: Int(length), length: Int(length), freeWhenDone: false)).decodeRootObject() as? PeerNotificationSettings
assert(object != nil)
pending = object
value.skip(Int(length))
}
if let pending = pending {
return !pending.isRemovedFromTotalUnreadCount
} else if let current = current {
return !current.isRemovedFromTotalUnreadCount
} else {
return false
}
}
return false
}
private func getReadStateCount(valueBox: ValueBox, table: ValueBoxTable, peerId: PeerId) -> Int32 {
let key = ValueBoxKey(length: 8)
key.setInt64(0, value: peerId.toInt64())
var totalCount: Int32 = 0
if let value = valueBox.get(table, key: key) {
var count: Int32 = 0
value.read(&count, offset: 0, length: 4)
var stateByNamespace: [MessageId.Namespace: PeerReadState] = [:]
for _ in 0 ..< count {
var namespaceId: Int32 = 0
value.read(&namespaceId, offset: 0, length: 4)
let state: PeerReadState
var kind: Int8 = 0
value.read(&kind, offset: 0, length: 1)
if kind == 0 {
var maxIncomingReadId: Int32 = 0
var maxOutgoingReadId: Int32 = 0
var maxKnownId: Int32 = 0
var count: Int32 = 0
value.read(&maxIncomingReadId, offset: 0, length: 4)
value.read(&maxOutgoingReadId, offset: 0, length: 4)
value.read(&maxKnownId, offset: 0, length: 4)
value.read(&count, offset: 0, length: 4)
totalCount += count
} else {
var maxIncomingReadTimestamp: Int32 = 0
var maxIncomingReadIdPeerId: Int64 = 0
var maxIncomingReadIdNamespace: Int32 = 0
var maxIncomingReadIdId: Int32 = 0
var maxOutgoingReadTimestamp: Int32 = 0
var maxOutgoingReadIdPeerId: Int64 = 0
var maxOutgoingReadIdNamespace: Int32 = 0
var maxOutgoingReadIdId: Int32 = 0
var count: Int32 = 0
value.read(&maxIncomingReadTimestamp, offset: 0, length: 4)
value.read(&maxIncomingReadIdPeerId, offset: 0, length: 8)
value.read(&maxIncomingReadIdNamespace, offset: 0, length: 4)
value.read(&maxIncomingReadIdId, offset: 0, length: 4)
value.read(&maxOutgoingReadTimestamp, offset: 0, length: 4)
value.read(&maxOutgoingReadIdPeerId, offset: 0, length: 8)
value.read(&maxOutgoingReadIdNamespace, offset: 0, length: 4)
value.read(&maxOutgoingReadIdId, offset: 0, length: 4)
value.read(&count, offset: 0, length: 4)
totalCount += count
}
}
}
return totalCount
}
func postboxUpgrade_15to16(metadataTable: MetadataTable, valueBox: ValueBox) {
let chatListIndexTable = ValueBoxTable(id: 8, keyType: .int64)
let notificationSettingsTable = ValueBoxTable(id: 19, keyType: .int64)
let readStateTable = ValueBoxTable(id: 14, keyType: .int64)
let messageHistoryMetadataTable = ValueBoxTable(id: 10, keyType: .binary)
var includedPeerIds: [PeerId] = []
valueBox.scanInt64(chatListIndexTable, values: { key, value in
let peerId = PeerId(key)
if peerId.namespace != Int32.max {
if parseInclusionIndex(peerId: peerId, value: value) {
includedPeerIds.append(peerId)
}
}
return true
})
var state = ChatListTotalUnreadState(absoluteCounters: ChatListTotalUnreadCounters(messageCount: 0), filteredCounters: ChatListTotalUnreadCounters(messageCount: 0))
for peerId in includedPeerIds {
let count = getReadStateCount(valueBox: valueBox, table: readStateTable, peerId: peerId)
if count != 0 {
state.absoluteCounters.messageCount += count
if parseNotificationSettings(valueBox: valueBox, table: notificationSettingsTable, peerId: peerId) {
state.filteredCounters.messageCount += count
}
}
}
let key = ValueBoxKey(length: 1)
key.setInt8(0, value: 4)
let encoder = PostboxEncoder()
encoder.encodeObject(state, forKey: "_")
valueBox.set(messageHistoryMetadataTable, key: key, value: encoder.readBufferNoCopy())
metadataTable.setUserVersion(16)
}

View File

@ -1,14 +1,19 @@
import Foundation
public enum UnreadMessageCountsTotalItem {
case raw
case filtered
}
public enum UnreadMessageCountsItem: Equatable {
case total
case total(UnreadMessageCountsTotalItem)
case peer(PeerId)
case group(PeerGroupId)
public static func ==(lhs: UnreadMessageCountsItem, rhs: UnreadMessageCountsItem) -> Bool {
switch lhs {
case .total:
if case .total = rhs {
case let .total(value):
if case .total(value) = rhs {
return true
} else {
return false
@ -30,13 +35,13 @@ public enum UnreadMessageCountsItem: Equatable {
}
private enum MutableUnreadMessageCountsItemEntry {
case total(Int32)
case total(ChatListTotalUnreadState)
case peer(PeerId, Int32)
case group(PeerGroupId, ChatListGroupReferenceUnreadCounters)
}
enum UnreadMessageCountsItemEntry {
case total(Int32)
case total(ChatListTotalUnreadState)
case peer(PeerId, Int32)
case group(PeerGroupId, Int32)
}
@ -48,7 +53,7 @@ final class MutableUnreadMessageCountsView: MutablePostboxView {
self.entries = items.map { item in
switch item {
case .total:
return .total(postbox.messageHistoryMetadataTable.getChatListTotalUnreadCount())
return .total(postbox.messageHistoryMetadataTable.getChatListTotalUnreadState())
case let .peer(peerId):
var count: Int32 = 0
if let combinedState = postbox.readStateTable.getCombinedState(peerId) {
@ -64,14 +69,14 @@ final class MutableUnreadMessageCountsView: MutablePostboxView {
func replay(postbox: Postbox, transaction: PostboxTransaction) -> Bool {
var updated = false
if transaction.currentUpdatedTotalUnreadCount != nil || !transaction.peerIdsWithUpdatedUnreadCounts.isEmpty {
if transaction.currentUpdatedTotalUnreadState != nil || !transaction.peerIdsWithUpdatedUnreadCounts.isEmpty {
for i in 0 ..< self.entries.count {
switch self.entries[i] {
case let .total(count):
if transaction.currentUpdatedTotalUnreadCount != nil {
let updatedCount = postbox.messageHistoryMetadataTable.getChatListTotalUnreadCount()
if updatedCount != count {
self.entries[i] = .total(updatedCount)
case let .total(state):
if transaction.currentUpdatedTotalUnreadState != nil {
let updatedState = postbox.messageHistoryMetadataTable.getChatListTotalUnreadState()
if updatedState != state {
self.entries[i] = .total(updatedState)
updated = true
}
}
@ -120,9 +125,14 @@ public final class UnreadMessageCountsView: PostboxView {
public func count(for item: UnreadMessageCountsItem) -> Int32? {
for entry in self.entries {
switch entry {
case let .total(count):
if case .total = item {
return count
case let .total(state):
if case let .total(value) = item {
switch value {
case .raw:
return state.absoluteCounters.messageCount
case .filtered:
return state.filteredCounters.messageCount
}
}
case let .peer(peerId, count):
if case .peer(peerId) = item {

View File

@ -9,5 +9,6 @@ func registeredUpgrades() -> [Int32: PostboxUpgradeOperation] {
dict[12] = .inplace(postboxUpgrade_12to13)
dict[13] = .inplace(postboxUpgrade_13to14)
dict[14] = .inplace(postboxUpgrade_14to15)
dict[15] = .inplace(postboxUpgrade_15to16)
return dict
}

View File

@ -20,7 +20,7 @@ final class ViewTracker {
private let getPeerNotificationSettings: (PeerId) -> PeerNotificationSettings?
private let getCachedPeerData: (PeerId) -> CachedPeerData?
private let getPeerPresence: (PeerId) -> PeerPresence?
private let getTotalUnreadCount: () -> Int32
private let getTotalUnreadState: () -> ChatListTotalUnreadState
private let getPeerReadState: (PeerId) -> CombinedPeerReadState?
private let operationLogGetOperations: (PeerOperationLogTag, Int32, Int) -> [PeerMergedOperationLogEntry]
private let operationLogGetTailIndex: (PeerOperationLogTag) -> Int32?
@ -59,7 +59,7 @@ final class ViewTracker {
private var multiplePeersViews = Bag<(MutableMultiplePeersView, ValuePipe<MultiplePeersView>)>()
private var itemCollectionsViews = Bag<(MutableItemCollectionsView, ValuePipe<ItemCollectionsView>)>()
init(queue: Queue, fetchAnchorIndex: @escaping (MessageId) -> InternalMessageHistoryAnchorIndex?, renderMessage: @escaping (IntermediateMessage) -> Message, getPeer: @escaping (PeerId) -> Peer?, getPeerNotificationSettings: @escaping (PeerId) -> PeerNotificationSettings?, getCachedPeerData: @escaping (PeerId) -> CachedPeerData?, getPeerPresence: @escaping (PeerId) -> PeerPresence?, getTotalUnreadCount: @escaping () -> Int32, getPeerReadState: @escaping (PeerId) -> CombinedPeerReadState?, operationLogGetOperations: @escaping (PeerOperationLogTag, Int32, Int) -> [PeerMergedOperationLogEntry], operationLogGetTailIndex: @escaping (PeerOperationLogTag) -> Int32?, getTimestampBasedMessageAttributesHead: @escaping (UInt16) -> TimestampBasedMessageAttributesEntry?, getPreferencesEntry: @escaping (ValueBoxKey) -> PreferencesEntry?, unsentMessageIds: [MessageId], synchronizePeerReadStateOperations: [PeerId: PeerReadStateSynchronizationOperation]) {
init(queue: Queue, fetchAnchorIndex: @escaping (MessageId) -> InternalMessageHistoryAnchorIndex?, renderMessage: @escaping (IntermediateMessage) -> Message, getPeer: @escaping (PeerId) -> Peer?, getPeerNotificationSettings: @escaping (PeerId) -> PeerNotificationSettings?, getCachedPeerData: @escaping (PeerId) -> CachedPeerData?, getPeerPresence: @escaping (PeerId) -> PeerPresence?, getTotalUnreadState: @escaping () -> ChatListTotalUnreadState, getPeerReadState: @escaping (PeerId) -> CombinedPeerReadState?, operationLogGetOperations: @escaping (PeerOperationLogTag, Int32, Int) -> [PeerMergedOperationLogEntry], operationLogGetTailIndex: @escaping (PeerOperationLogTag) -> Int32?, getTimestampBasedMessageAttributesHead: @escaping (UInt16) -> TimestampBasedMessageAttributesEntry?, getPreferencesEntry: @escaping (ValueBoxKey) -> PreferencesEntry?, unsentMessageIds: [MessageId], synchronizePeerReadStateOperations: [PeerId: PeerReadStateSynchronizationOperation]) {
self.queue = queue
self.fetchAnchorIndex = fetchAnchorIndex
self.renderMessage = renderMessage
@ -67,7 +67,7 @@ final class ViewTracker {
self.getPeerNotificationSettings = getPeerNotificationSettings
self.getCachedPeerData = getCachedPeerData
self.getPeerPresence = getPeerPresence
self.getTotalUnreadCount = getTotalUnreadCount
self.getTotalUnreadState = getTotalUnreadState
self.getPeerReadState = getPeerReadState
self.operationLogGetOperations = operationLogGetOperations
self.operationLogGetTailIndex = operationLogGetTailIndex
@ -348,10 +348,10 @@ final class ViewTracker {
switch mutableView.peerIds {
case .single:
assertionFailure()
case let .associated(mainPeerId, associatedPeerId):
case let .associated(mainPeerId, associatedId):
ids.insert(mainPeerId)
if let associatedPeerId = associatedPeerId {
ids.insert(associatedPeerId)
if let associatedId = associatedId {
ids.insert(associatedId.peerId)
}
case let .group(groupId):
if let value = transaction.groupFeedIdsWithFilledHoles[groupId] {
@ -396,7 +396,7 @@ final class ViewTracker {
}
mutableView.updatePeerIds(transaction: transaction)
if case .associated = mutableView.peerIds, case .Generic = updateType, mutableView.peerIds != previousPeerIds {
if mutableView.peerIds != previousPeerIds {
updateType = .UpdateVisible
let _ = mutableView.refreshDueToExternalTransaction(postbox: postbox)