no message

This commit is contained in:
Peter 2017-09-19 15:16:58 +03:00
parent 7b4c119ec3
commit 2a1c6c5bee
19 changed files with 547 additions and 134 deletions

View File

@ -141,6 +141,7 @@
D0AB0B901D65D4AB002C78E7 /* UnsentMessageIndicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AB0B8F1D65D4AB002C78E7 /* UnsentMessageIndicesView.swift */; }; D0AB0B901D65D4AB002C78E7 /* UnsentMessageIndicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AB0B8F1D65D4AB002C78E7 /* UnsentMessageIndicesView.swift */; };
D0AD23271E194D1C00A7089A /* PeerOperationLogTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AD23261E194D1C00A7089A /* PeerOperationLogTable.swift */; }; D0AD23271E194D1C00A7089A /* PeerOperationLogTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AD23261E194D1C00A7089A /* PeerOperationLogTable.swift */; };
D0AD23291E196B6400A7089A /* PeerOperationLogMetadataTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AD23281E196B6400A7089A /* PeerOperationLogMetadataTable.swift */; }; D0AD23291E196B6400A7089A /* PeerOperationLogMetadataTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AD23281E196B6400A7089A /* PeerOperationLogMetadataTable.swift */; };
D0AE3EBC1F68261B0069BC90 /* PeerNotificationSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AE3EBB1F68261B0069BC90 /* PeerNotificationSettingsView.swift */; };
D0B418171D7DFAF3004562A4 /* PostboxMac.h in Headers */ = {isa = PBXBuildFile; fileRef = D0B418151D7DFAF3004562A4 /* PostboxMac.h */; settings = {ATTRIBUTES = (Public, ); }; }; D0B418171D7DFAF3004562A4 /* PostboxMac.h in Headers */ = {isa = PBXBuildFile; fileRef = D0B418151D7DFAF3004562A4 /* PostboxMac.h */; settings = {ATTRIBUTES = (Public, ); }; };
D0B4181C1D7DFDF1004562A4 /* SQLite-Bridging.m in Sources */ = {isa = PBXBuildFile; fileRef = D07516761B2EC90400AE42E0 /* SQLite-Bridging.m */; }; D0B4181C1D7DFDF1004562A4 /* SQLite-Bridging.m in Sources */ = {isa = PBXBuildFile; fileRef = D07516761B2EC90400AE42E0 /* SQLite-Bridging.m */; };
D0B4181D1D7DFDF4004562A4 /* sqlite3.c in Sources */ = {isa = PBXBuildFile; fileRef = D07516401B2D9CEF00AE42E0 /* sqlite3.c */; settings = {COMPILER_FLAGS = "-Wno-conversion -Wno-ambiguous-macro -Wno-conditional-uninitialized -Wno-unused-const-variable -Wno-unused-function -Wno-unreachable-code"; }; }; D0B4181D1D7DFDF4004562A4 /* sqlite3.c in Sources */ = {isa = PBXBuildFile; fileRef = D07516401B2D9CEF00AE42E0 /* sqlite3.c */; settings = {COMPILER_FLAGS = "-Wno-conversion -Wno-ambiguous-macro -Wno-conditional-uninitialized -Wno-unused-const-variable -Wno-unused-function -Wno-unreachable-code"; }; };
@ -198,8 +199,6 @@
D0C07F6A1B67DB4800966E43 /* SwiftSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0C07F691B67DB4800966E43 /* SwiftSignalKit.framework */; }; D0C07F6A1B67DB4800966E43 /* SwiftSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0C07F691B67DB4800966E43 /* SwiftSignalKit.framework */; };
D0C0B5AB1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B5AA1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift */; }; D0C0B5AB1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B5AA1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift */; };
D0C0B5AC1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B5AA1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift */; }; D0C0B5AC1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B5AA1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift */; };
D0C0B5AE1EE1B3F4000F4D2C /* PostboxUpgrade_13to14.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B5AD1EE1B3F4000F4D2C /* PostboxUpgrade_13to14.swift */; };
D0C0B5AF1EE1B3F4000F4D2C /* PostboxUpgrade_13to14.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B5AD1EE1B3F4000F4D2C /* PostboxUpgrade_13to14.swift */; };
D0C27B451F4B598200A4E170 /* CachedPeerDataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C27B441F4B598200A4E170 /* CachedPeerDataView.swift */; }; D0C27B451F4B598200A4E170 /* CachedPeerDataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C27B441F4B598200A4E170 /* CachedPeerDataView.swift */; };
D0C27B461F4B598200A4E170 /* CachedPeerDataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C27B441F4B598200A4E170 /* CachedPeerDataView.swift */; }; D0C27B461F4B598200A4E170 /* CachedPeerDataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C27B441F4B598200A4E170 /* CachedPeerDataView.swift */; };
D0C674C81CBB11C600183765 /* MessageHistoryReadStateTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C674C71CBB11C600183765 /* MessageHistoryReadStateTable.swift */; }; D0C674C81CBB11C600183765 /* MessageHistoryReadStateTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C674C71CBB11C600183765 /* MessageHistoryReadStateTable.swift */; };
@ -208,6 +207,10 @@
D0C8FCB71C5C2D200028C27F /* MessageHistoryViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C8FCB61C5C2D200028C27F /* MessageHistoryViewTests.swift */; }; D0C8FCB71C5C2D200028C27F /* MessageHistoryViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C8FCB61C5C2D200028C27F /* MessageHistoryViewTests.swift */; };
D0C9DA391C65782500855278 /* SimpleSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C9DA381C65782500855278 /* SimpleSet.swift */; }; D0C9DA391C65782500855278 /* SimpleSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C9DA381C65782500855278 /* SimpleSet.swift */; };
D0CE63F61CA1CCB2002BC462 /* MediaResource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CE63F51CA1CCB2002BC462 /* MediaResource.swift */; }; D0CE63F61CA1CCB2002BC462 /* MediaResource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CE63F51CA1CCB2002BC462 /* MediaResource.swift */; };
D0CE8CF31F70249400AA2DB0 /* PostboxUpgrade_13to14.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CE8CF21F70249400AA2DB0 /* PostboxUpgrade_13to14.swift */; };
D0CE8CF41F70249400AA2DB0 /* PostboxUpgrade_13to14.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CE8CF21F70249400AA2DB0 /* PostboxUpgrade_13to14.swift */; };
D0CE8CF61F703B1E00AA2DB0 /* PendingPeerNotificationSettingsIndexTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CE8CF51F703B1E00AA2DB0 /* PendingPeerNotificationSettingsIndexTable.swift */; };
D0CE8CF71F703B1E00AA2DB0 /* PendingPeerNotificationSettingsIndexTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CE8CF51F703B1E00AA2DB0 /* PendingPeerNotificationSettingsIndexTable.swift */; };
D0D510F41D63BA8400A97B8A /* PostboxTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D510F31D63BA8400A97B8A /* PostboxTransaction.swift */; }; D0D510F41D63BA8400A97B8A /* PostboxTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D510F31D63BA8400A97B8A /* PostboxTransaction.swift */; };
D0D510F61D63BBE100A97B8A /* MessageHistoryOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D510F51D63BBE100A97B8A /* MessageHistoryOperation.swift */; }; D0D510F61D63BBE100A97B8A /* MessageHistoryOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D510F51D63BBE100A97B8A /* MessageHistoryOperation.swift */; };
D0D510F91D63BCC200A97B8A /* IntermediateMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D510F81D63BCC200A97B8A /* IntermediateMessage.swift */; }; D0D510F91D63BCC200A97B8A /* IntermediateMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D510F81D63BCC200A97B8A /* IntermediateMessage.swift */; };
@ -216,6 +219,8 @@
D0D511041D64D91C00A97B8A /* IpcNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = D0D511031D64D75200A97B8A /* IpcNotifier.h */; settings = {ATTRIBUTES = (Public, ); }; }; D0D511041D64D91C00A97B8A /* IpcNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = D0D511031D64D75200A97B8A /* IpcNotifier.h */; settings = {ATTRIBUTES = (Public, ); }; };
D0D949F31D35302600740E02 /* RandomAccessResourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D949F21D35302600740E02 /* RandomAccessResourceTests.swift */; }; D0D949F31D35302600740E02 /* RandomAccessResourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D949F21D35302600740E02 /* RandomAccessResourceTests.swift */; };
D0D949F51D35353900740E02 /* MappedFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D949F41D35353900740E02 /* MappedFile.swift */; }; D0D949F51D35353900740E02 /* MappedFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D949F41D35353900740E02 /* MappedFile.swift */; };
D0DA1D2F1F70419D0034E892 /* PendingPeerNotificationSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DA1D2E1F70419D0034E892 /* PendingPeerNotificationSettingsView.swift */; };
D0DA1D301F70419D0034E892 /* PendingPeerNotificationSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DA1D2E1F70419D0034E892 /* PendingPeerNotificationSettingsView.swift */; };
D0DA44481E4C7D1E005FDCA7 /* PostboxAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DA44471E4C7D1E005FDCA7 /* PostboxAccess.swift */; }; D0DA44481E4C7D1E005FDCA7 /* PostboxAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DA44471E4C7D1E005FDCA7 /* PostboxAccess.swift */; };
D0DA44491E4C7D1E005FDCA7 /* PostboxAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DA44471E4C7D1E005FDCA7 /* PostboxAccess.swift */; }; D0DA44491E4C7D1E005FDCA7 /* PostboxAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DA44471E4C7D1E005FDCA7 /* PostboxAccess.swift */; };
D0DF0C8F1D81A350008AEB01 /* PeerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DF0C8E1D81A350008AEB01 /* PeerView.swift */; }; D0DF0C8F1D81A350008AEB01 /* PeerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DF0C8E1D81A350008AEB01 /* PeerView.swift */; };
@ -401,6 +406,7 @@
D0AB0B8F1D65D4AB002C78E7 /* UnsentMessageIndicesView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnsentMessageIndicesView.swift; sourceTree = "<group>"; }; D0AB0B8F1D65D4AB002C78E7 /* UnsentMessageIndicesView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnsentMessageIndicesView.swift; sourceTree = "<group>"; };
D0AD23261E194D1C00A7089A /* PeerOperationLogTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerOperationLogTable.swift; sourceTree = "<group>"; }; D0AD23261E194D1C00A7089A /* PeerOperationLogTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerOperationLogTable.swift; sourceTree = "<group>"; };
D0AD23281E196B6400A7089A /* PeerOperationLogMetadataTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerOperationLogMetadataTable.swift; sourceTree = "<group>"; }; D0AD23281E196B6400A7089A /* PeerOperationLogMetadataTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerOperationLogMetadataTable.swift; sourceTree = "<group>"; };
D0AE3EBB1F68261B0069BC90 /* PeerNotificationSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeerNotificationSettingsView.swift; sourceTree = "<group>"; };
D0B418131D7DFAF2004562A4 /* PostboxMac.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PostboxMac.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D0B418131D7DFAF2004562A4 /* PostboxMac.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PostboxMac.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D0B418151D7DFAF3004562A4 /* PostboxMac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PostboxMac.h; sourceTree = "<group>"; }; D0B418151D7DFAF3004562A4 /* PostboxMac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PostboxMac.h; sourceTree = "<group>"; };
D0B418161D7DFAF3004562A4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; D0B418161D7DFAF3004562A4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -416,7 +422,6 @@
D0BEAF6F1E54BC1E00BD963D /* AccountRecordsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountRecordsView.swift; sourceTree = "<group>"; }; D0BEAF6F1E54BC1E00BD963D /* AccountRecordsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountRecordsView.swift; sourceTree = "<group>"; };
D0C07F691B67DB4800966E43 /* SwiftSignalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SwiftSignalKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D0C07F691B67DB4800966E43 /* SwiftSignalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SwiftSignalKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D0C0B5AA1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReverseAssociatedPeerTable.swift; sourceTree = "<group>"; }; D0C0B5AA1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReverseAssociatedPeerTable.swift; sourceTree = "<group>"; };
D0C0B5AD1EE1B3F4000F4D2C /* PostboxUpgrade_13to14.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostboxUpgrade_13to14.swift; sourceTree = "<group>"; };
D0C27B441F4B598200A4E170 /* CachedPeerDataView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CachedPeerDataView.swift; sourceTree = "<group>"; }; D0C27B441F4B598200A4E170 /* CachedPeerDataView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CachedPeerDataView.swift; sourceTree = "<group>"; };
D0C674C71CBB11C600183765 /* MessageHistoryReadStateTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageHistoryReadStateTable.swift; sourceTree = "<group>"; }; D0C674C71CBB11C600183765 /* MessageHistoryReadStateTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageHistoryReadStateTable.swift; sourceTree = "<group>"; };
D0C674CB1CBB14A700183765 /* PeerReadState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerReadState.swift; sourceTree = "<group>"; }; D0C674CB1CBB14A700183765 /* PeerReadState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerReadState.swift; sourceTree = "<group>"; };
@ -424,6 +429,8 @@
D0C8FCB61C5C2D200028C27F /* MessageHistoryViewTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageHistoryViewTests.swift; sourceTree = "<group>"; }; D0C8FCB61C5C2D200028C27F /* MessageHistoryViewTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageHistoryViewTests.swift; sourceTree = "<group>"; };
D0C9DA381C65782500855278 /* SimpleSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimpleSet.swift; sourceTree = "<group>"; }; D0C9DA381C65782500855278 /* SimpleSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimpleSet.swift; sourceTree = "<group>"; };
D0CE63F51CA1CCB2002BC462 /* MediaResource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaResource.swift; sourceTree = "<group>"; }; D0CE63F51CA1CCB2002BC462 /* MediaResource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaResource.swift; sourceTree = "<group>"; };
D0CE8CF21F70249400AA2DB0 /* PostboxUpgrade_13to14.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostboxUpgrade_13to14.swift; sourceTree = "<group>"; };
D0CE8CF51F703B1E00AA2DB0 /* PendingPeerNotificationSettingsIndexTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PendingPeerNotificationSettingsIndexTable.swift; sourceTree = "<group>"; };
D0D510F31D63BA8400A97B8A /* PostboxTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostboxTransaction.swift; sourceTree = "<group>"; }; D0D510F31D63BA8400A97B8A /* PostboxTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostboxTransaction.swift; sourceTree = "<group>"; };
D0D510F51D63BBE100A97B8A /* MessageHistoryOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageHistoryOperation.swift; sourceTree = "<group>"; }; D0D510F51D63BBE100A97B8A /* MessageHistoryOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageHistoryOperation.swift; sourceTree = "<group>"; };
D0D510F81D63BCC200A97B8A /* IntermediateMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntermediateMessage.swift; sourceTree = "<group>"; }; D0D510F81D63BCC200A97B8A /* IntermediateMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntermediateMessage.swift; sourceTree = "<group>"; };
@ -432,6 +439,7 @@
D0D511031D64D75200A97B8A /* IpcNotifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IpcNotifier.h; sourceTree = "<group>"; }; D0D511031D64D75200A97B8A /* IpcNotifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IpcNotifier.h; sourceTree = "<group>"; };
D0D949F21D35302600740E02 /* RandomAccessResourceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RandomAccessResourceTests.swift; sourceTree = "<group>"; }; D0D949F21D35302600740E02 /* RandomAccessResourceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RandomAccessResourceTests.swift; sourceTree = "<group>"; };
D0D949F41D35353900740E02 /* MappedFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MappedFile.swift; sourceTree = "<group>"; }; D0D949F41D35353900740E02 /* MappedFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MappedFile.swift; sourceTree = "<group>"; };
D0DA1D2E1F70419D0034E892 /* PendingPeerNotificationSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PendingPeerNotificationSettingsView.swift; sourceTree = "<group>"; };
D0DA44471E4C7D1E005FDCA7 /* PostboxAccess.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostboxAccess.swift; sourceTree = "<group>"; }; D0DA44471E4C7D1E005FDCA7 /* PostboxAccess.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostboxAccess.swift; sourceTree = "<group>"; };
D0DF0C8E1D81A350008AEB01 /* PeerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerView.swift; sourceTree = "<group>"; }; D0DF0C8E1D81A350008AEB01 /* PeerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerView.swift; sourceTree = "<group>"; };
D0E1D30B1ECA1F5500FCEEF1 /* GlobalMessageHistoryTagsTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlobalMessageHistoryTagsTable.swift; sourceTree = "<group>"; }; D0E1D30B1ECA1F5500FCEEF1 /* GlobalMessageHistoryTagsTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlobalMessageHistoryTagsTable.swift; sourceTree = "<group>"; };
@ -578,7 +586,7 @@
children = ( children = (
D0F02CDE1E99223D0065DEE2 /* Upgrades.swift */, D0F02CDE1E99223D0065DEE2 /* Upgrades.swift */,
D0F02CE11E9922F50065DEE2 /* PostboxUpgrade_12to13.swift */, D0F02CE11E9922F50065DEE2 /* PostboxUpgrade_12to13.swift */,
D0C0B5AD1EE1B3F4000F4D2C /* PostboxUpgrade_13to14.swift */, D0CE8CF21F70249400AA2DB0 /* PostboxUpgrade_13to14.swift */,
); );
name = Upgrade; name = Upgrade;
sourceTree = "<group>"; sourceTree = "<group>";
@ -609,6 +617,7 @@
D0F9E86E1C5A0E7600037222 /* KeychainTable.swift */, D0F9E86E1C5A0E7600037222 /* KeychainTable.swift */,
D0F9E8701C5A0E9B00037222 /* PeerTable.swift */, D0F9E8701C5A0E9B00037222 /* PeerTable.swift */,
D03120FF1DA579A0006A2A60 /* PeerNotificationSettingsTable.swift */, D03120FF1DA579A0006A2A60 /* PeerNotificationSettingsTable.swift */,
D0CE8CF51F703B1E00AA2DB0 /* PendingPeerNotificationSettingsIndexTable.swift */,
D03120FD1DA562E9006A2A60 /* CachedPeerDataTable.swift */, D03120FD1DA562E9006A2A60 /* CachedPeerDataTable.swift */,
D03120F71DA53FF4006A2A60 /* PeerPresenceTable.swift */, D03120F71DA53FF4006A2A60 /* PeerPresenceTable.swift */,
D0C735271C864DF300BB3149 /* PeerChatStateTable.swift */, D0C735271C864DF300BB3149 /* PeerChatStateTable.swift */,
@ -726,6 +735,8 @@
D0A352F71F549D95001423DC /* InvalidatedMessageHistoryTagSummariesView.swift */, D0A352F71F549D95001423DC /* InvalidatedMessageHistoryTagSummariesView.swift */,
D07047B01F3DE40400F6A8D4 /* PendingMessageActionsSummaryView.swift */, D07047B01F3DE40400F6A8D4 /* PendingMessageActionsSummaryView.swift */,
D0C27B441F4B598200A4E170 /* CachedPeerDataView.swift */, D0C27B441F4B598200A4E170 /* CachedPeerDataView.swift */,
D0AE3EBB1F68261B0069BC90 /* PeerNotificationSettingsView.swift */,
D0DA1D2E1F70419D0034E892 /* PendingPeerNotificationSettingsView.swift */,
); );
name = Views; name = Views;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1029,6 +1040,7 @@
D0F82CFE1E4345D7007E499C /* OrderedItemListTable.swift in Sources */, D0F82CFE1E4345D7007E499C /* OrderedItemListTable.swift in Sources */,
D0F7B1C51E045C6A007EB8A5 /* MessageHistoryMetadataTable.swift in Sources */, D0F7B1C51E045C6A007EB8A5 /* MessageHistoryMetadataTable.swift in Sources */,
D073CE781DCBF3B4007511FD /* MessageHistoryHole.swift in Sources */, D073CE781DCBF3B4007511FD /* MessageHistoryHole.swift in Sources */,
D0CE8CF71F703B1E00AA2DB0 /* PendingPeerNotificationSettingsIndexTable.swift in Sources */,
D0E1D3101ECA53F900FCEEF1 /* GlobalMessageTagsView.swift in Sources */, D0E1D3101ECA53F900FCEEF1 /* GlobalMessageTagsView.swift in Sources */,
D08775071E3E3F2100A97350 /* PreferencesView.swift in Sources */, D08775071E3E3F2100A97350 /* PreferencesView.swift in Sources */,
D049EAF11E44D9B900A2CD3A /* PostboxStateView.swift in Sources */, D049EAF11E44D9B900A2CD3A /* PostboxStateView.swift in Sources */,
@ -1042,7 +1054,6 @@
D073CE7F1DCBF3B4007511FD /* ItemCollection.swift in Sources */, D073CE7F1DCBF3B4007511FD /* ItemCollection.swift in Sources */,
D07047B21F3DE40400F6A8D4 /* PendingMessageActionsSummaryView.swift in Sources */, D07047B21F3DE40400F6A8D4 /* PendingMessageActionsSummaryView.swift in Sources */,
D0F7B1D91E045C6A007EB8A5 /* OrderStatisticTable.swift in Sources */, D0F7B1D91E045C6A007EB8A5 /* OrderStatisticTable.swift in Sources */,
D0C0B5AF1EE1B3F4000F4D2C /* PostboxUpgrade_13to14.swift in Sources */,
D073CEA01DCBF3C1007511FD /* ItemCollectionsView.swift in Sources */, D073CEA01DCBF3C1007511FD /* ItemCollectionsView.swift in Sources */,
D0BE383A1E7C1FD4000079AF /* ItemCollectionInfoView.swift in Sources */, D0BE383A1E7C1FD4000079AF /* ItemCollectionInfoView.swift in Sources */,
D0B418491D7DFE20004562A4 /* ChatListView.swift in Sources */, D0B418491D7DFE20004562A4 /* ChatListView.swift in Sources */,
@ -1070,12 +1081,14 @@
D0B4185C1D7DFE2F004562A4 /* MurMurHash32.m in Sources */, D0B4185C1D7DFE2F004562A4 /* MurMurHash32.m in Sources */,
D0F7B1E01E045C6A007EB8A5 /* ItemCacheTable.swift in Sources */, D0F7B1E01E045C6A007EB8A5 /* ItemCacheTable.swift in Sources */,
D07047A91F3DA8D700F6A8D4 /* PendingMessageActionsMetadataTable.swift in Sources */, D07047A91F3DA8D700F6A8D4 /* PendingMessageActionsMetadataTable.swift in Sources */,
D0DA1D301F70419D0034E892 /* PendingPeerNotificationSettingsView.swift in Sources */,
D0F7B1E11E045C6A007EB8A5 /* ReverseIndexReferenceTable.swift in Sources */, D0F7B1E11E045C6A007EB8A5 /* ReverseIndexReferenceTable.swift in Sources */,
D0B418241D7DFE0C004562A4 /* SimpleSet.swift in Sources */, D0B418241D7DFE0C004562A4 /* SimpleSet.swift in Sources */,
D073CE7B1DCBF3B4007511FD /* PeerNameIndexRepresentation.swift in Sources */, D073CE7B1DCBF3B4007511FD /* PeerNameIndexRepresentation.swift in Sources */,
D073CE7D1DCBF3B4007511FD /* PeerPresence.swift in Sources */, D073CE7D1DCBF3B4007511FD /* PeerPresence.swift in Sources */,
D0B4184C1D7DFE20004562A4 /* ContactPeerIdsView.swift in Sources */, D0B4184C1D7DFE20004562A4 /* ContactPeerIdsView.swift in Sources */,
D0DA44491E4C7D1E005FDCA7 /* PostboxAccess.swift in Sources */, D0DA44491E4C7D1E005FDCA7 /* PostboxAccess.swift in Sources */,
D0CE8CF41F70249400AA2DB0 /* PostboxUpgrade_13to14.swift in Sources */,
D073CE751DCBF3B4007511FD /* Message.swift in Sources */, D073CE751DCBF3B4007511FD /* Message.swift in Sources */,
D087C20D1E43C11C00D686F8 /* OrderedItemListView.swift in Sources */, D087C20D1E43C11C00D686F8 /* OrderedItemListView.swift in Sources */,
D00C7CD51E365C4E0080C3D5 /* PeerChatListInclusion.swift in Sources */, D00C7CD51E365C4E0080C3D5 /* PeerChatListInclusion.swift in Sources */,
@ -1117,15 +1130,18 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
D08775061E3E3F2100A97350 /* PreferencesView.swift in Sources */, D08775061E3E3F2100A97350 /* PreferencesView.swift in Sources */,
D0CE8CF61F703B1E00AA2DB0 /* PendingPeerNotificationSettingsIndexTable.swift in Sources */,
D03229EE1E6B33FD0000AF9C /* SqliteInterface.swift in Sources */, D03229EE1E6B33FD0000AF9C /* SqliteInterface.swift in Sources */,
D01C7F071EFC1ED3008305F1 /* UnorderedItemListTable.swift in Sources */, D01C7F071EFC1ED3008305F1 /* UnorderedItemListTable.swift in Sources */,
D0F9E8631C579F0200037222 /* MediaCleanupTable.swift in Sources */, D0F9E8631C579F0200037222 /* MediaCleanupTable.swift in Sources */,
D0F3CC741DDE1EB9008148FA /* ItemCacheMetaTable.swift in Sources */, D0F3CC741DDE1EB9008148FA /* ItemCacheMetaTable.swift in Sources */,
D08D451F1D5D2CA700A7428A /* RatingTable.swift in Sources */, D08D451F1D5D2CA700A7428A /* RatingTable.swift in Sources */,
D07CFF831DCA909100761F81 /* PeerChatInterfaceStateTable.swift in Sources */, D07CFF831DCA909100761F81 /* PeerChatInterfaceStateTable.swift in Sources */,
D0DA1D2F1F70419D0034E892 /* PendingPeerNotificationSettingsView.swift in Sources */,
D0F9E86F1C5A0E7600037222 /* KeychainTable.swift in Sources */, D0F9E86F1C5A0E7600037222 /* KeychainTable.swift in Sources */,
D0E3A7821B28ADD000A402D9 /* Postbox.swift in Sources */, D0E3A7821B28ADD000A402D9 /* Postbox.swift in Sources */,
D0575AE31E9ECBB2006F2541 /* AccessChallengeDataView.swift in Sources */, D0575AE31E9ECBB2006F2541 /* AccessChallengeDataView.swift in Sources */,
D0CE8CF31F70249400AA2DB0 /* PostboxUpgrade_13to14.swift in Sources */,
D0E3A79E1B28B50400A402D9 /* Message.swift in Sources */, D0E3A79E1B28B50400A402D9 /* Message.swift in Sources */,
D0C674C81CBB11C600183765 /* MessageHistoryReadStateTable.swift in Sources */, D0C674C81CBB11C600183765 /* MessageHistoryReadStateTable.swift in Sources */,
D0DF0C8F1D81A350008AEB01 /* PeerView.swift in Sources */, D0DF0C8F1D81A350008AEB01 /* PeerView.swift in Sources */,
@ -1181,7 +1197,6 @@
D0BEAF631E54B2FA00BD963D /* AccountManager.swift in Sources */, D0BEAF631E54B2FA00BD963D /* AccountManager.swift in Sources */,
D0AD23271E194D1C00A7089A /* PeerOperationLogTable.swift in Sources */, D0AD23271E194D1C00A7089A /* PeerOperationLogTable.swift in Sources */,
D021E0D41DB4FAE100C6B04F /* ItemCollection.swift in Sources */, D021E0D41DB4FAE100C6B04F /* ItemCollection.swift in Sources */,
D0C0B5AE1EE1B3F4000F4D2C /* PostboxUpgrade_13to14.swift in Sources */,
D0D510F91D63BCC200A97B8A /* IntermediateMessage.swift in Sources */, D0D510F91D63BCC200A97B8A /* IntermediateMessage.swift in Sources */,
D0BE38391E7C1FD4000079AF /* ItemCollectionInfoView.swift in Sources */, D0BE38391E7C1FD4000079AF /* ItemCollectionInfoView.swift in Sources */,
D0F9E86B1C59719800037222 /* ChatListView.swift in Sources */, D0F9E86B1C59719800037222 /* ChatListView.swift in Sources */,
@ -1230,6 +1245,7 @@
D0BEAF6D1E54B77900BD963D /* AccountManagerRecordTable.swift in Sources */, D0BEAF6D1E54B77900BD963D /* AccountManagerRecordTable.swift in Sources */,
D03120F81DA53FF4006A2A60 /* PeerPresenceTable.swift in Sources */, D03120F81DA53FF4006A2A60 /* PeerPresenceTable.swift in Sources */,
D0F9E8731C5A1EE500037222 /* GlobalMessageIdsTable.swift in Sources */, D0F9E8731C5A1EE500037222 /* GlobalMessageIdsTable.swift in Sources */,
D0AE3EBC1F68261B0069BC90 /* PeerNotificationSettingsView.swift in Sources */,
D00EED1E1C81F28D00341DFF /* MessageHistoryTagsTable.swift in Sources */, D00EED1E1C81F28D00341DFF /* MessageHistoryTagsTable.swift in Sources */,
D044CA2C1C617E2D002160FF /* MessageHistoryMetadataTable.swift in Sources */, D044CA2C1C617E2D002160FF /* MessageHistoryMetadataTable.swift in Sources */,
D03120FC1DA55427006A2A60 /* PeerNotificationSettings.swift in Sources */, D03120FC1DA55427006A2A60 /* PeerNotificationSettings.swift in Sources */,

View File

@ -265,9 +265,9 @@ final class ChatListIndexTable: Table {
var notificationSettings: PeerNotificationSettings? var notificationSettings: PeerNotificationSettings?
if let peer = getPeer(peerId) { if let peer = getPeer(peerId) {
if let notificationSettingsPeerId = peer.notificationSettingsPeerId { if let notificationSettingsPeerId = peer.notificationSettingsPeerId {
notificationSettings = self.notificationSettingsTable.get(notificationSettingsPeerId) notificationSettings = self.notificationSettingsTable.getEffective(notificationSettingsPeerId)
} else { } else {
notificationSettings = self.notificationSettingsTable.get(peerId) notificationSettings = self.notificationSettingsTable.getEffective(peerId)
} }
} }
if let _ = self.get(peerId).includedIndex(peerId: peerId), let notificationSettings = notificationSettings, !notificationSettings.isRemovedFromTotalUnreadCount { if let _ = self.get(peerId).includedIndex(peerId: peerId), let notificationSettings = notificationSettings, !notificationSettings.isRemovedFromTotalUnreadCount {
@ -292,9 +292,9 @@ final class ChatListIndexTable: Table {
var notificationSettings: PeerNotificationSettings? var notificationSettings: PeerNotificationSettings?
if let peer = getPeer(peerId) { if let peer = getPeer(peerId) {
if let notificationSettingsPeerId = peer.notificationSettingsPeerId { if let notificationSettingsPeerId = peer.notificationSettingsPeerId {
notificationSettings = self.notificationSettingsTable.get(notificationSettingsPeerId) notificationSettings = self.notificationSettingsTable.getEffective(notificationSettingsPeerId)
} else { } else {
notificationSettings = self.notificationSettingsTable.get(peerId) notificationSettings = self.notificationSettingsTable.getEffective(peerId)
} }
} }
if let notificationSettings = notificationSettings, !notificationSettings.isRemovedFromTotalUnreadCount { if let notificationSettings = notificationSettings, !notificationSettings.isRemovedFromTotalUnreadCount {
@ -335,9 +335,9 @@ final class ChatListIndexTable: Table {
var notificationSettings: PeerNotificationSettings? var notificationSettings: PeerNotificationSettings?
if let peer = getPeer(peerId) { if let peer = getPeer(peerId) {
if let notificationSettingsPeerId = peer.notificationSettingsPeerId { if let notificationSettingsPeerId = peer.notificationSettingsPeerId {
notificationSettings = self.notificationSettingsTable.get(notificationSettingsPeerId) notificationSettings = self.notificationSettingsTable.getEffective(notificationSettingsPeerId)
} else { } else {
notificationSettings = self.notificationSettingsTable.get(peerId) notificationSettings = self.notificationSettingsTable.getEffective(peerId)
} }
} }
if let notificationSettings = notificationSettings, !notificationSettings.isRemovedFromTotalUnreadCount { if let notificationSettings = notificationSettings, !notificationSettings.isRemovedFromTotalUnreadCount {

View File

@ -159,6 +159,9 @@ final class ChatListTable: Table {
updatedTimestamp = max(updatedTimestamp, embeddedChatState.timestamp) updatedTimestamp = max(updatedTimestamp, embeddedChatState.timestamp)
} }
topMessageIndex = MessageIndex(id: topMessage.id, timestamp: updatedTimestamp) topMessageIndex = MessageIndex(id: topMessage.id, timestamp: updatedTimestamp)
} else if let embeddedChatState = embeddedChatState, embeddedChatState.timestamp != 0 {
topMessageIndex = MessageIndex(id: MessageId(peerId: peerId, namespace: 0, id: 1), timestamp: embeddedChatState.timestamp)
rawTopMessageIndex = nil
} else { } else {
topMessageIndex = nil topMessageIndex = nil
rawTopMessageIndex = nil rawTopMessageIndex = nil

View File

@ -4,12 +4,14 @@ public enum AdditionalMessageHistoryViewData {
case cachedPeerData(PeerId) case cachedPeerData(PeerId)
case peerChatState(PeerId) case peerChatState(PeerId)
case totalUnreadCount case totalUnreadCount
case peerNotificationSettings(PeerId)
} }
public enum AdditionalMessageHistoryViewDataEntry { public enum AdditionalMessageHistoryViewDataEntry {
case cachedPeerData(PeerId, CachedPeerData?) case cachedPeerData(PeerId, CachedPeerData?)
case peerChatState(PeerId, PeerChatState?) case peerChatState(PeerId, PeerChatState?)
case totalUnreadCount(Int32) case totalUnreadCount(Int32)
case peerNotificationSettings(PeerNotificationSettings?)
} }
public struct MessageHistoryViewId: Equatable { public struct MessageHistoryViewId: Equatable {
@ -373,11 +375,12 @@ final class MutableMessageHistoryView {
fileprivate var later: MutableMessageHistoryEntry? fileprivate var later: MutableMessageHistoryEntry?
fileprivate var entries: [MutableMessageHistoryEntry] fileprivate var entries: [MutableMessageHistoryEntry]
fileprivate let fillCount: Int fileprivate let fillCount: Int
fileprivate let clipHoles: Bool
fileprivate var topTaggedMessages: [MessageId.Namespace: MessageHistoryTopTaggedMessage?] fileprivate var topTaggedMessages: [MessageId.Namespace: MessageHistoryTopTaggedMessage?]
fileprivate var additionalDatas: [AdditionalMessageHistoryViewDataEntry] fileprivate var additionalDatas: [AdditionalMessageHistoryViewDataEntry]
init(id: MessageHistoryViewId, postbox: Postbox, orderStatistics: MessageHistoryViewOrderStatistics, peerId: PeerId, anchorIndex: MessageHistoryAnchorIndex, combinedReadState: CombinedPeerReadState?, earlier: MutableMessageHistoryEntry?, entries: [MutableMessageHistoryEntry], later: MutableMessageHistoryEntry?, tagMask: MessageTags?, count: Int, topTaggedMessages: [MessageId.Namespace: MessageHistoryTopTaggedMessage?], additionalDatas: [AdditionalMessageHistoryViewDataEntry], getMessageCountInRange: (MessageIndex, MessageIndex) -> Int32) { init(id: MessageHistoryViewId, postbox: Postbox, orderStatistics: MessageHistoryViewOrderStatistics, peerId: PeerId, anchorIndex: MessageHistoryAnchorIndex, combinedReadState: CombinedPeerReadState?, earlier: MutableMessageHistoryEntry?, entries: [MutableMessageHistoryEntry], later: MutableMessageHistoryEntry?, tagMask: MessageTags?, count: Int, clipHoles: Bool, topTaggedMessages: [MessageId.Namespace: MessageHistoryTopTaggedMessage?], additionalDatas: [AdditionalMessageHistoryViewDataEntry], getMessageCountInRange: (MessageIndex, MessageIndex) -> Int32) {
self.id = id self.id = id
self.orderStatistics = orderStatistics self.orderStatistics = orderStatistics
self.anchorIndex = anchorIndex self.anchorIndex = anchorIndex
@ -388,6 +391,7 @@ final class MutableMessageHistoryView {
self.later = later self.later = later
self.tagMask = tagMask self.tagMask = tagMask
self.fillCount = count self.fillCount = count
self.clipHoles = clipHoles
self.topTaggedMessages = topTaggedMessages self.topTaggedMessages = topTaggedMessages
self.additionalDatas = additionalDatas self.additionalDatas = additionalDatas
@ -692,6 +696,8 @@ final class MutableMessageHistoryView {
} }
case .totalUnreadCount: case .totalUnreadCount:
break break
case .peerNotificationSettings:
break
} }
} }
@ -1057,7 +1063,7 @@ public final class MessageHistoryView {
} }
} }
} }
if !entries.isEmpty { if !entries.isEmpty && mutableView.clipHoles {
var referenceIndex = entries.count - 1 var referenceIndex = entries.count - 1
for i in 0 ..< entries.count { for i in 0 ..< entries.count {
if entries[i].index > self.anchorIndex { if entries[i].index > self.anchorIndex {

View File

@ -1,42 +1,163 @@
import Foundation import Foundation
private struct PeerNotificationSettingsTableEntry: Equatable {
let current: PeerNotificationSettings?
let pending: PeerNotificationSettings?
static func ==(lhs: PeerNotificationSettingsTableEntry, rhs: PeerNotificationSettingsTableEntry) -> Bool {
if let lhsCurrent = lhs.current, let rhsCurrent = rhs.current {
if !lhsCurrent.isEqual(to: rhsCurrent) {
return false
}
} else if (lhs.current != nil) != (rhs.current != nil) {
return false
}
if let lhsPending = lhs.pending, let rhsPending = rhs.pending {
if !lhsPending.isEqual(to: rhsPending) {
return false
}
} else if (lhs.pending != nil) != (rhs.pending != nil) {
return false
}
return true
}
var effective: PeerNotificationSettings? {
if let pending = self.pending {
return pending
}
return self.current
}
func withUpdatedCurrent(_ current: PeerNotificationSettings?) -> PeerNotificationSettingsTableEntry {
return PeerNotificationSettingsTableEntry(current: current, pending: self.pending)
}
func withUpdatedPending(_ pending: PeerNotificationSettings?) -> PeerNotificationSettingsTableEntry {
return PeerNotificationSettingsTableEntry(current: self.current, pending: pending)
}
}
private struct PeerNotificationSettingsTableEntryFlags: OptionSet {
var rawValue: Int32
init(rawValue: Int32) {
self.rawValue = rawValue
}
static let hasCurrent = PeerNotificationSettingsTableEntryFlags(rawValue: 1 << 0)
static let hasPending = PeerNotificationSettingsTableEntryFlags(rawValue: 1 << 1)
}
final class PeerNotificationSettingsTable: Table { final class PeerNotificationSettingsTable: Table {
static func tableSpec(_ id: Int32) -> ValueBoxTable { static func tableSpec(_ id: Int32) -> ValueBoxTable {
return ValueBoxTable(id: id, keyType: .int64) return ValueBoxTable(id: id, keyType: .int64)
} }
private let pendingIndexTable: PendingPeerNotificationSettingsIndexTable
private let sharedEncoder = PostboxEncoder() private let sharedEncoder = PostboxEncoder()
private let sharedKey = ValueBoxKey(length: 8) private let sharedKey = ValueBoxKey(length: 8)
private var cachedSettings: [PeerId: PeerNotificationSettings] = [:] private var cachedSettings: [PeerId: PeerNotificationSettingsTableEntry] = [:]
private var updatedInitialSettings: [PeerId: PeerNotificationSettings?] = [:] private var updatedInitialSettings: [PeerId: PeerNotificationSettingsTableEntry] = [:]
init(valueBox: ValueBox, table: ValueBoxTable, pendingIndexTable: PendingPeerNotificationSettingsIndexTable) {
self.pendingIndexTable = pendingIndexTable
super.init(valueBox: valueBox, table: table)
}
private func key(_ id: PeerId) -> ValueBoxKey { private func key(_ id: PeerId) -> ValueBoxKey {
self.sharedKey.setInt64(0, value: id.toInt64()) self.sharedKey.setInt64(0, value: id.toInt64())
return self.sharedKey return self.sharedKey
} }
func set(id: PeerId, settings: PeerNotificationSettings) { private func getEntry(_ id: PeerId) -> PeerNotificationSettingsTableEntry {
let current = self.get(id) if let entry = self.cachedSettings[id] {
if current == nil || !current!.isEqual(to: settings) { return entry
if self.updatedInitialSettings[id] == nil { } else if let value = self.valueBox.get(self.table, key: self.key(id)) {
self.updatedInitialSettings[id] = current var flagsValue: Int32 = 0
value.read(&flagsValue, offset: 0, length: 4)
let flags = PeerNotificationSettingsTableEntryFlags(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))
} }
self.cachedSettings[id] = settings
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))
}
let entry = PeerNotificationSettingsTableEntry(current: current, pending: pending)
self.cachedSettings[id] = entry
return entry
} else {
let entry = PeerNotificationSettingsTableEntry(current: nil, pending: nil)
self.cachedSettings[id] = entry
return entry
} }
} }
func get(_ id: PeerId) -> PeerNotificationSettings? { func setCurrent(id: PeerId, settings: PeerNotificationSettings?) -> PeerNotificationSettings? {
if let settings = self.cachedSettings[id] { let currentEntry = self.getEntry(id)
return settings var updated = false
if let current = currentEntry.current, let settings = settings {
updated = !current.isEqual(to: settings)
} else if (currentEntry.current != nil) != (settings != nil) {
updated = true
} }
if let value = self.valueBox.get(self.table, key: self.key(id)) { if updated {
if let settings = PostboxDecoder(buffer: value).decodeRootObject() as? PeerNotificationSettings { if self.updatedInitialSettings[id] == nil {
self.cachedSettings[id] = settings self.updatedInitialSettings[id] = currentEntry
return settings
} }
let updatedEntry = currentEntry.withUpdatedCurrent(settings)
self.cachedSettings[id] = updatedEntry
return updatedEntry.effective
} else {
return nil
} }
return nil }
func setPending(id: PeerId, settings: PeerNotificationSettings?, updatedSettings: inout Set<PeerId>) -> PeerNotificationSettings? {
let currentEntry = self.getEntry(id)
var updated = false
if let pending = currentEntry.pending, let settings = settings {
updated = !pending.isEqual(to: settings)
} else if (currentEntry.pending != nil) != (settings != nil) {
updated = true
}
if updated {
if self.updatedInitialSettings[id] == nil {
self.updatedInitialSettings[id] = currentEntry
}
updatedSettings.insert(id)
let updatedEntry = currentEntry.withUpdatedPending(settings)
self.cachedSettings[id] = updatedEntry
self.pendingIndexTable.set(peerId: id, pending: updatedEntry.pending != nil)
return updatedEntry.effective
} else {
return nil
}
}
func getEffective(_ id: PeerId) -> PeerNotificationSettings? {
return self.getEntry(id).effective
}
func getPending(_ id: PeerId) -> PeerNotificationSettings? {
return self.getEntry(id).pending
} }
override func clearMemoryCache() { override func clearMemoryCache() {
@ -50,10 +171,13 @@ final class PeerNotificationSettingsTable: Table {
for (peerId, initialSettings) in self.updatedInitialSettings { for (peerId, initialSettings) in self.updatedInitialSettings {
var wasParticipating = false var wasParticipating = false
if let initialSettings = initialSettings { if let initialEffective = initialSettings.effective {
wasParticipating = !initialSettings.isRemovedFromTotalUnreadCount wasParticipating = !initialEffective.isRemovedFromTotalUnreadCount
}
var isParticipating = false
if let resultEffective = self.cachedSettings[peerId]?.effective {
isParticipating = !resultEffective.isRemovedFromTotalUnreadCount
} }
let isParticipating = !self.cachedSettings[peerId]!.isRemovedFromTotalUnreadCount
if wasParticipating != isParticipating { if wasParticipating != isParticipating {
if isParticipating { if isParticipating {
added.insert(peerId) added.insert(peerId)
@ -66,7 +190,7 @@ final class PeerNotificationSettingsTable: Table {
return (added, removed) return (added, removed)
} }
func resetAll(to settings: PeerNotificationSettings) -> [PeerId] { func resetAll(to settings: PeerNotificationSettings, updatedSettings: inout Set<PeerId>) -> [PeerId] {
let lowerBound = ValueBoxKey(length: 8) let lowerBound = ValueBoxKey(length: 8)
lowerBound.setInt64(0, value: 0) lowerBound.setInt64(0, value: 0)
let upperBound = ValueBoxKey(length: 8) let upperBound = ValueBoxKey(length: 8)
@ -79,9 +203,11 @@ final class PeerNotificationSettingsTable: Table {
var updatedPeerIds: [PeerId] = [] var updatedPeerIds: [PeerId] = []
for peerId in peerIds { for peerId in peerIds {
if let current = self.get(peerId), !current.isEqual(to: settings) { let entry = self.getEntry(peerId)
if let current = entry.current, !current.isEqual(to: settings) || entry.pending != nil {
let _ = self.setCurrent(id: peerId, settings: settings)
let _ = self.setPending(id: peerId, settings: nil, updatedSettings: &updatedSettings)
updatedPeerIds.append(peerId) updatedPeerIds.append(peerId)
self.set(id: peerId, settings: settings)
} }
} }
@ -90,12 +216,48 @@ final class PeerNotificationSettingsTable: Table {
override func beforeCommit() { override func beforeCommit() {
if !self.updatedInitialSettings.isEmpty { if !self.updatedInitialSettings.isEmpty {
let buffer = WriteBuffer()
let encoder = PostboxEncoder()
for (peerId, _) in self.updatedInitialSettings { for (peerId, _) in self.updatedInitialSettings {
if let settings = self.cachedSettings[peerId] { if let entry = self.cachedSettings[peerId] {
self.sharedEncoder.reset() buffer.reset()
self.sharedEncoder.encodeRootObject(settings)
self.valueBox.set(self.table, key: self.key(peerId), value: self.sharedEncoder.readBufferNoCopy()) var flags = PeerNotificationSettingsTableEntryFlags()
if entry.current != nil {
flags.insert(.hasCurrent)
}
if entry.pending != nil {
flags.insert(.hasPending)
}
var flagsValue: Int32 = flags.rawValue
buffer.write(&flagsValue, offset: 0, length: 4)
if let current = entry.current {
encoder.reset()
encoder.encodeRootObject(current)
let object = encoder.readBufferNoCopy()
withExtendedLifetime(object, {
var length: Int32 = Int32(object.length)
buffer.write(&length, offset: 0, length: 4)
buffer.write(object.memory, offset: 0, length: object.length)
})
}
if let pending = entry.pending {
encoder.reset()
encoder.encodeRootObject(pending)
let object = encoder.readBufferNoCopy()
withExtendedLifetime(object, {
var length: Int32 = Int32(object.length)
buffer.write(&length, offset: 0, length: 4)
buffer.write(object.memory, offset: 0, length: object.length)
})
}
self.valueBox.set(self.table, key: self.key(peerId), value: buffer.readBufferNoCopy())
} else {
assertionFailure()
} }
} }

View File

@ -0,0 +1,35 @@
import Foundation
final class MutablePeerNotificationSettingsView: MutablePostboxView {
let peerId: PeerId
var notificationSettings: PeerNotificationSettings?
init(postbox: Postbox, peerId: PeerId) {
self.peerId = peerId
self.notificationSettings = postbox.peerNotificationSettingsTable.getEffective(peerId)
}
func replay(postbox: Postbox, transaction: PostboxTransaction) -> Bool {
if let notificationSettings = transaction.currentUpdatedPeerNotificationSettings[self.peerId] {
self.notificationSettings = notificationSettings
return true
} else {
return false
}
}
func immutableView() -> PostboxView {
return PeerNotificationSettingsView(self)
}
}
public final class PeerNotificationSettingsView: PostboxView {
public let peerId: PeerId
public let notificationSettings: PeerNotificationSettings?
init(_ view: MutablePeerNotificationSettingsView) {
self.peerId = view.peerId
self.notificationSettings = view.notificationSettings
}
}

View File

@ -9,7 +9,7 @@ final class MutablePeerView: MutablePostboxView {
var peerIsContact: Bool var peerIsContact: Bool
init(postbox: Postbox, peerId: PeerId) { init(postbox: Postbox, peerId: PeerId) {
let notificationSettings = postbox.peerNotificationSettingsTable.get(peerId) let notificationSettings = postbox.peerNotificationSettingsTable.getEffective(peerId)
let cachedData = postbox.cachedPeerDataTable.get(peerId) let cachedData = postbox.cachedPeerDataTable.get(peerId)
let peerIsContact = postbox.contactsTable.isContact(peerId: peerId) let peerIsContact = postbox.contactsTable.isContact(peerId: peerId)

View File

@ -0,0 +1,40 @@
import Foundation
final class PendingPeerNotificationSettingsIndexTable: Table {
static func tableSpec(_ id: Int32) -> ValueBoxTable {
return ValueBoxTable(id: id, keyType: .int64)
}
private let sharedKey = ValueBoxKey(length: 8)
private var updatedPeerIds: [PeerId: Bool] = [:]
private func key(_ id: PeerId) -> ValueBoxKey {
self.sharedKey.setInt64(0, value: id.toInt64())
return self.sharedKey
}
private func get(peerId: PeerId) -> Bool {
if let _ = self.valueBox.get(self.table, key: self.key(peerId)) {
return true
} else {
return false
}
}
func getAll() -> [PeerId] {
var peerIds: [PeerId] = []
self.valueBox.scanInt64(self.table, values: { key, _ in
peerIds.append(PeerId(key))
return true
})
return peerIds
}
func set(peerId: PeerId, pending: Bool) {
if pending {
self.valueBox.set(self.table, key: self.key(peerId), value: MemoryBuffer())
} else {
self.valueBox.remove(self.table, key: self.key(peerId))
}
}
}

View File

@ -0,0 +1,41 @@
final class MutablePendingPeerNotificationSettingsView: MutablePostboxView {
var entries: [PeerId: PeerNotificationSettings] = [:]
init(postbox: Postbox) {
for peerId in postbox.pendingPeerNotificationSettingsIndexTable.getAll() {
if let value = postbox.peerNotificationSettingsTable.getPending(peerId) {
self.entries[peerId] = value
} else {
assertionFailure()
}
}
}
func replay(postbox: Postbox, transaction: PostboxTransaction) -> Bool {
var updated = false
for peerId in transaction.currentUpdatedPendingPeerNotificationSettings {
if let value = postbox.peerNotificationSettingsTable.getPending(peerId) {
self.entries[peerId] = value
updated = true
} else if self.entries[peerId] != nil {
self.entries.removeValue(forKey: peerId)
updated = true
}
}
return updated
}
func immutableView() -> PostboxView {
return PendingPeerNotificationSettingsView(self)
}
}
public final class PendingPeerNotificationSettingsView: PostboxView {
public let entries: [PeerId: PeerNotificationSettings]
init(_ view: MutablePendingPeerNotificationSettingsView) {
self.entries = view.entries
}
}

View File

@ -179,7 +179,12 @@ public final class Modifier {
public func getPeerNotificationSettings(_ id: PeerId) -> PeerNotificationSettings? { public func getPeerNotificationSettings(_ id: PeerId) -> PeerNotificationSettings? {
assert(!self.disposed) assert(!self.disposed)
return self.postbox?.peerNotificationSettingsTable.get(id) return self.postbox?.peerNotificationSettingsTable.getEffective(id)
}
public func getPendingPeerNotificationSettings(_ id: PeerId) -> PeerNotificationSettings? {
assert(!self.disposed)
return self.postbox?.peerNotificationSettingsTable.getPending(id)
} }
public func updatePeersInternal(_ peers: [Peer], update: (Peer?, Peer) -> Peer?) { public func updatePeersInternal(_ peers: [Peer], update: (Peer?, Peer) -> Peer?) {
@ -209,9 +214,14 @@ public final class Modifier {
self.postbox?.updatePeerChatListInclusion(id, inclusion: inclusion) self.postbox?.updatePeerChatListInclusion(id, inclusion: inclusion)
} }
public func updatePeerNotificationSettings(_ notificationSettings: [PeerId: PeerNotificationSettings]) { public func updateCurrentPeerNotificationSettings(_ notificationSettings: [PeerId: PeerNotificationSettings]) {
assert(!self.disposed) assert(!self.disposed)
self.postbox?.updatePeerNotificationSettings(notificationSettings) self.postbox?.updateCurrentPeerNotificationSettings(notificationSettings)
}
public func updatePendingPeerNotificationSettings(peerId: PeerId, settings: PeerNotificationSettings?) {
assert(!self.disposed)
self.postbox?.updatePendingPeerNotificationSettings(peerId: peerId, settings: settings)
} }
public func resetAllPeerNotificationSettings(_ notificationSettings: PeerNotificationSettings) { public func resetAllPeerNotificationSettings(_ notificationSettings: PeerNotificationSettings) {
@ -738,7 +748,7 @@ public func openPostbox(basePath: String, globalMessageIdsNamespace: MessageId.N
let metadataTable = MetadataTable(valueBox: valueBox, table: MetadataTable.tableSpec(0)) let metadataTable = MetadataTable(valueBox: valueBox, table: MetadataTable.tableSpec(0))
let userVersion: Int32? = metadataTable.userVersion() let userVersion: Int32? = metadataTable.userVersion()
let currentUserVersion: Int32 = 13 let currentUserVersion: Int32 = 14
if let userVersion = userVersion { if let userVersion = userVersion {
if userVersion != currentUserVersion { if userVersion != currentUserVersion {
@ -812,6 +822,7 @@ public final class Postbox {
private var currentUpdatedMessageActionsSummaries: [PendingMessageActionsSummaryKey: Int32] = [:] private var currentUpdatedMessageActionsSummaries: [PendingMessageActionsSummaryKey: Int32] = [:]
private var currentUpdatedMessageTagSummaries: [MessageHistoryTagsSummaryKey : MessageHistoryTagNamespaceSummary] = [:] private var currentUpdatedMessageTagSummaries: [MessageHistoryTagsSummaryKey : MessageHistoryTagNamespaceSummary] = [:]
private var currentInvalidateMessageTagSummaries: [InvalidatedMessageHistoryTagsSummaryEntryOperation] = [] private var currentInvalidateMessageTagSummaries: [InvalidatedMessageHistoryTagsSummaryEntryOperation] = []
private var currentUpdatedPendingPeerNotificationSettings = Set<PeerId>()
private var currentReplaceChatListHoles: [(MessageIndex, ChatListHole?)] = [] private var currentReplaceChatListHoles: [(MessageIndex, ChatListHole?)] = []
private var currentReplaceRemoteContactCount: Int32? private var currentReplaceRemoteContactCount: Int32?
@ -835,6 +846,7 @@ public final class Postbox {
let keychainTable: KeychainTable let keychainTable: KeychainTable
let peerTable: PeerTable let peerTable: PeerTable
let peerNotificationSettingsTable: PeerNotificationSettingsTable let peerNotificationSettingsTable: PeerNotificationSettingsTable
let pendingPeerNotificationSettingsIndexTable: PendingPeerNotificationSettingsIndexTable
let cachedPeerDataTable: CachedPeerDataTable let cachedPeerDataTable: CachedPeerDataTable
let peerPresenceTable: PeerPresenceTable let peerPresenceTable: PeerPresenceTable
let globalMessageIdsTable: GlobalMessageIdsTable let globalMessageIdsTable: GlobalMessageIdsTable
@ -938,7 +950,8 @@ public final class Postbox {
self.contactsTable = ContactTable(valueBox: self.valueBox, table: ContactTable.tableSpec(16), peerNameIndexTable: self.peerNameIndexTable) self.contactsTable = ContactTable(valueBox: self.valueBox, table: ContactTable.tableSpec(16), peerNameIndexTable: self.peerNameIndexTable)
self.peerRatingTable = RatingTable<PeerId>(valueBox: self.valueBox, table: RatingTable<PeerId>.tableSpec(17)) self.peerRatingTable = RatingTable<PeerId>(valueBox: self.valueBox, table: RatingTable<PeerId>.tableSpec(17))
self.cachedPeerDataTable = CachedPeerDataTable(valueBox: self.valueBox, table: CachedPeerDataTable.tableSpec(18)) self.cachedPeerDataTable = CachedPeerDataTable(valueBox: self.valueBox, table: CachedPeerDataTable.tableSpec(18))
self.peerNotificationSettingsTable = PeerNotificationSettingsTable(valueBox: self.valueBox, table: PeerNotificationSettingsTable.tableSpec(19)) self.pendingPeerNotificationSettingsIndexTable = PendingPeerNotificationSettingsIndexTable(valueBox: self.valueBox, table: PendingPeerNotificationSettingsIndexTable.tableSpec(48))
self.peerNotificationSettingsTable = PeerNotificationSettingsTable(valueBox: self.valueBox, table: PeerNotificationSettingsTable.tableSpec(19), pendingIndexTable: self.pendingPeerNotificationSettingsIndexTable)
self.peerPresenceTable = PeerPresenceTable(valueBox: self.valueBox, table: PeerPresenceTable.tableSpec(20)) self.peerPresenceTable = PeerPresenceTable(valueBox: self.valueBox, table: PeerPresenceTable.tableSpec(20))
self.itemCollectionInfoTable = ItemCollectionInfoTable(valueBox: self.valueBox, table: ItemCollectionInfoTable.tableSpec(21)) self.itemCollectionInfoTable = ItemCollectionInfoTable(valueBox: self.valueBox, table: ItemCollectionInfoTable.tableSpec(21))
self.itemCollectionReverseIndexTable = ReverseIndexReferenceTable<ItemCollectionItemReverseIndexReference>(valueBox: self.valueBox, table: ReverseIndexReferenceTable<ItemCollectionItemReverseIndexReference>.tableSpec(36)) self.itemCollectionReverseIndexTable = ReverseIndexReferenceTable<ItemCollectionItemReverseIndexReference>(valueBox: self.valueBox, table: ReverseIndexReferenceTable<ItemCollectionItemReverseIndexReference>.tableSpec(36))
@ -1013,7 +1026,7 @@ public final class Postbox {
self.viewTracker = ViewTracker(queue: self.queue, fetchEarlierHistoryEntries: self.fetchEarlierHistoryEntries, fetchLaterHistoryEntries: self.fetchLaterHistoryEntries, fetchEarlierChatEntries: self.fetchEarlierChatEntries, fetchLaterChatEntries: self.fetchLaterChatEntries, fetchAnchorIndex: self.fetchAnchorIndex, renderMessage: self.renderIntermediateMessage, getPeer: { peerId in self.viewTracker = ViewTracker(queue: self.queue, fetchEarlierHistoryEntries: self.fetchEarlierHistoryEntries, fetchLaterHistoryEntries: self.fetchLaterHistoryEntries, fetchEarlierChatEntries: self.fetchEarlierChatEntries, fetchLaterChatEntries: self.fetchLaterChatEntries, fetchAnchorIndex: self.fetchAnchorIndex, renderMessage: self.renderIntermediateMessage, getPeer: { peerId in
return self.peerTable.get(peerId) return self.peerTable.get(peerId)
}, getPeerNotificationSettings: { peerId in }, getPeerNotificationSettings: { peerId in
return self.peerNotificationSettingsTable.get(peerId) return self.peerNotificationSettingsTable.getEffective(peerId)
}, getCachedPeerData: { peerId in }, getCachedPeerData: { peerId in
return self.cachedPeerDataTable.get(peerId) return self.cachedPeerDataTable.get(peerId)
}, getPeerPresence: { peerId in }, getPeerPresence: { peerId in
@ -1425,7 +1438,7 @@ public final class Postbox {
private func beforeCommit() -> (updatedTransactionStateVersion: Int64?, updatedMasterClientId: Int64?) { private func beforeCommit() -> (updatedTransactionStateVersion: Int64?, updatedMasterClientId: Int64?) {
var chatListOperations: [ChatListOperation] = [] var chatListOperations: [ChatListOperation] = []
self.chatListTable.replay(historyOperationsByPeerId: self.currentOperationsByPeerId, updatedPeerChatListEmbeddedStates: currentUpdatedPeerChatListEmbeddedStates, updatedChatListInclusions: self.currentUpdatedChatListInclusions, messageHistoryTable: self.messageHistoryTable, peerChatInterfaceStateTable: self.peerChatInterfaceStateTable, operations: &chatListOperations) self.chatListTable.replay(historyOperationsByPeerId: self.currentOperationsByPeerId, updatedPeerChatListEmbeddedStates: self.currentUpdatedPeerChatListEmbeddedStates, updatedChatListInclusions: self.currentUpdatedChatListInclusions, messageHistoryTable: self.messageHistoryTable, peerChatInterfaceStateTable: self.peerChatInterfaceStateTable, operations: &chatListOperations)
for (index, hole) in self.currentReplaceChatListHoles { for (index, hole) in self.currentReplaceChatListHoles {
self.chatListTable.replaceHole(index, hole: hole, operations: &chatListOperations) self.chatListTable.replaceHole(index, hole: hole, operations: &chatListOperations)
} }
@ -1438,7 +1451,7 @@ public final class Postbox {
return self.peerTable.get(peerId) return self.peerTable.get(peerId)
}, updatedTotalUnreadCount: &self.currentUpdatedTotalUnreadCount) }, updatedTotalUnreadCount: &self.currentUpdatedTotalUnreadCount)
let transaction = PostboxTransaction(currentUpdatedState: self.currentUpdatedState, currentOperationsByPeerId: self.currentOperationsByPeerId, peerIdsWithFilledHoles: self.currentFilledHolesByPeerId, removedHolesByPeerId: self.currentRemovedHolesByPeerId, chatListOperations: chatListOperations, currentUpdatedPeers: self.currentUpdatedPeers, currentUpdatedPeerNotificationSettings: self.currentUpdatedPeerNotificationSettings, currentUpdatedCachedPeerData: self.currentUpdatedCachedPeerData, currentUpdatedPeerPresences: currentUpdatedPeerPresences, currentUpdatedPeerChatListEmbeddedStates: self.currentUpdatedPeerChatListEmbeddedStates, currentUpdatedTotalUnreadCount: self.currentUpdatedTotalUnreadCount, peerIdsWithUpdatedUnreadCounts: Set(transactionUnreadCountDeltas.keys), 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, updatedAccessChallengeData: self.currentUpdatedAccessChallengeData, currentGlobalTagsOperations: self.currentGlobalTagsOperations, updatedMedia: self.currentUpdatedMedia, replaceRemoteContactCount: self.currentReplaceRemoteContactCount, replaceContactPeerIds: self.currentReplacedContactPeerIds, currentPendingMessageActionsOperations: self.currentPendingMessageActionsOperations, currentUpdatedMessageActionsSummaries: self.currentUpdatedMessageActionsSummaries, currentUpdatedMessageTagSummaries: self.currentUpdatedMessageTagSummaries, currentInvalidateMessageTagSummaries: self.currentInvalidateMessageTagSummaries, currentUpdatedMasterClientId: currentUpdatedMasterClientId) let transaction = PostboxTransaction(currentUpdatedState: self.currentUpdatedState, currentOperationsByPeerId: self.currentOperationsByPeerId, peerIdsWithFilledHoles: self.currentFilledHolesByPeerId, removedHolesByPeerId: self.currentRemovedHolesByPeerId, chatListOperations: chatListOperations, currentUpdatedPeers: self.currentUpdatedPeers, currentUpdatedPeerNotificationSettings: self.currentUpdatedPeerNotificationSettings, currentUpdatedCachedPeerData: self.currentUpdatedCachedPeerData, currentUpdatedPeerPresences: currentUpdatedPeerPresences, currentUpdatedPeerChatListEmbeddedStates: self.currentUpdatedPeerChatListEmbeddedStates, currentUpdatedTotalUnreadCount: self.currentUpdatedTotalUnreadCount, peerIdsWithUpdatedUnreadCounts: Set(transactionUnreadCountDeltas.keys), 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, updatedAccessChallengeData: self.currentUpdatedAccessChallengeData, currentGlobalTagsOperations: self.currentGlobalTagsOperations, updatedMedia: self.currentUpdatedMedia, replaceRemoteContactCount: self.currentReplaceRemoteContactCount, replaceContactPeerIds: self.currentReplacedContactPeerIds, currentPendingMessageActionsOperations: self.currentPendingMessageActionsOperations, currentUpdatedMessageActionsSummaries: self.currentUpdatedMessageActionsSummaries, currentUpdatedMessageTagSummaries: self.currentUpdatedMessageTagSummaries, currentInvalidateMessageTagSummaries: self.currentInvalidateMessageTagSummaries, currentUpdatedPendingPeerNotificationSettings: self.currentUpdatedPendingPeerNotificationSettings, currentUpdatedMasterClientId: currentUpdatedMasterClientId)
var updatedTransactionState: Int64? var updatedTransactionState: Int64?
var updatedMasterClientId: Int64? var updatedMasterClientId: Int64?
if !transaction.isEmpty { if !transaction.isEmpty {
@ -1483,6 +1496,7 @@ public final class Postbox {
self.currentUpdatedMessageActionsSummaries.removeAll() self.currentUpdatedMessageActionsSummaries.removeAll()
self.currentUpdatedMessageTagSummaries.removeAll() self.currentUpdatedMessageTagSummaries.removeAll()
self.currentInvalidateMessageTagSummaries.removeAll() self.currentInvalidateMessageTagSummaries.removeAll()
self.currentUpdatedPendingPeerNotificationSettings.removeAll()
for table in self.tables { for table in self.tables {
table.beforeCommit() table.beforeCommit()
@ -1551,18 +1565,22 @@ public final class Postbox {
self.chatListTable.setPinnedPeerIds(peerIds: peerIds, updatedChatListInclusions: &self.currentUpdatedChatListInclusions) self.chatListTable.setPinnedPeerIds(peerIds: peerIds, updatedChatListInclusions: &self.currentUpdatedChatListInclusions)
} }
fileprivate func updatePeerNotificationSettings(_ notificationSettings: [PeerId: PeerNotificationSettings]) { fileprivate func updateCurrentPeerNotificationSettings(_ notificationSettings: [PeerId: PeerNotificationSettings]) {
for (peerId, settings) in notificationSettings { for (peerId, settings) in notificationSettings {
let currentSettings = self.peerNotificationSettingsTable.get(peerId) if let updated = self.peerNotificationSettingsTable.setCurrent(id: peerId, settings: settings) {
if currentSettings == nil || !(currentSettings!.isEqual(to: settings)) { self.currentUpdatedPeerNotificationSettings[peerId] = updated
self.peerNotificationSettingsTable.set(id: peerId, settings: settings)
self.currentUpdatedPeerNotificationSettings[peerId] = settings
} }
} }
} }
fileprivate func updatePendingPeerNotificationSettings(peerId: PeerId, settings: PeerNotificationSettings?) {
if let updated = self.peerNotificationSettingsTable.setPending(id: peerId, settings: settings, updatedSettings: &self.currentUpdatedPendingPeerNotificationSettings) {
self.currentUpdatedPeerNotificationSettings[peerId] = updated
}
}
fileprivate func resetAllPeerNotificationSettings(_ notificationSettings: PeerNotificationSettings) { fileprivate func resetAllPeerNotificationSettings(_ notificationSettings: PeerNotificationSettings) {
for peerId in self.peerNotificationSettingsTable.resetAll(to: notificationSettings) { for peerId in self.peerNotificationSettingsTable.resetAll(to: notificationSettings, updatedSettings: &self.currentUpdatedPendingPeerNotificationSettings) {
self.currentUpdatedPeerNotificationSettings[peerId] = notificationSettings self.currentUpdatedPeerNotificationSettings[peerId] = notificationSettings
} }
} }
@ -1782,7 +1800,7 @@ public final class Postbox {
} }
} }
public func aroundMessageOfInterestHistoryViewForPeerId(_ peerId: PeerId, count: Int, topTaggedMessageIdNamespaces: Set<MessageId.Namespace>, tagMask: MessageTags?, orderStatistics: MessageHistoryViewOrderStatistics, additionalData: [AdditionalMessageHistoryViewData]) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> { public func aroundMessageOfInterestHistoryViewForPeerId(_ peerId: PeerId, count: Int, clipHoles: Bool, topTaggedMessageIdNamespaces: Set<MessageId.Namespace>, tagMask: MessageTags?, orderStatistics: MessageHistoryViewOrderStatistics, additionalData: [AdditionalMessageHistoryViewData]) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> {
return self.modify(userInteractive: true, { modifier -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> in return self.modify(userInteractive: true, { modifier -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> in
var index = MessageHistoryAnchorIndex(index: MessageIndex.upperBound(peerId: peerId), exact: true) var index = MessageHistoryAnchorIndex(index: MessageIndex.upperBound(peerId: peerId), exact: true)
if let maxReadIndex = self.messageHistoryTable.maxReadIndex(peerId) { if let maxReadIndex = self.messageHistoryTable.maxReadIndex(peerId) {
@ -1790,27 +1808,27 @@ public final class Postbox {
} else if let scrollIndex = self.peerChatInterfaceStateTable.get(peerId)?.historyScrollMessageIndex { } else if let scrollIndex = self.peerChatInterfaceStateTable.get(peerId)?.historyScrollMessageIndex {
index = MessageHistoryAnchorIndex(index: scrollIndex, exact: true) index = MessageHistoryAnchorIndex(index: scrollIndex, exact: true)
} }
return self.syncAroundMessageHistoryViewForPeerId(peerId, index: index.index, count: count, anchorIndex: index, unreadIndex: index.index, fixedCombinedReadState: nil, topTaggedMessageIdNamespaces: topTaggedMessageIdNamespaces, tagMask: tagMask, orderStatistics: orderStatistics, additionalData: additionalData) return self.syncAroundMessageHistoryViewForPeerId(peerId, index: index.index, count: count, clipHoles: clipHoles, anchorIndex: index, unreadIndex: index.index, fixedCombinedReadState: nil, topTaggedMessageIdNamespaces: topTaggedMessageIdNamespaces, tagMask: tagMask, orderStatistics: orderStatistics, additionalData: additionalData)
}) |> switchToLatest }) |> switchToLatest
} }
public func aroundIdMessageHistoryViewForPeerId(_ peerId: PeerId, count: Int, messageId: MessageId, topTaggedMessageIdNamespaces: Set<MessageId.Namespace>, tagMask: MessageTags?, orderStatistics: MessageHistoryViewOrderStatistics, additionalData: [AdditionalMessageHistoryViewData] = []) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> { public func aroundIdMessageHistoryViewForPeerId(_ peerId: PeerId, count: Int, clipHoles: Bool, messageId: MessageId, topTaggedMessageIdNamespaces: Set<MessageId.Namespace>, tagMask: MessageTags?, orderStatistics: MessageHistoryViewOrderStatistics, additionalData: [AdditionalMessageHistoryViewData] = []) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> {
return self.modify { modifier -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> in return self.modify { modifier -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> in
var index = MessageHistoryAnchorIndex(index: MessageIndex.upperBound(peerId: peerId), exact: true) var index = MessageHistoryAnchorIndex(index: MessageIndex.upperBound(peerId: peerId), exact: true)
if let anchorIndex = self.messageHistoryTable.anchorIndex(messageId) { if let anchorIndex = self.messageHistoryTable.anchorIndex(messageId) {
index = anchorIndex index = anchorIndex
} }
return self.syncAroundMessageHistoryViewForPeerId(peerId, index: index.index, count: count, anchorIndex: index, unreadIndex: index.index, fixedCombinedReadState: nil, topTaggedMessageIdNamespaces: topTaggedMessageIdNamespaces, tagMask: tagMask, orderStatistics: orderStatistics, additionalData: additionalData) return self.syncAroundMessageHistoryViewForPeerId(peerId, index: index.index, count: count, clipHoles: clipHoles, anchorIndex: index, unreadIndex: index.index, fixedCombinedReadState: nil, topTaggedMessageIdNamespaces: topTaggedMessageIdNamespaces, tagMask: tagMask, orderStatistics: orderStatistics, additionalData: additionalData)
} |> switchToLatest } |> switchToLatest
} }
public func aroundMessageHistoryViewForPeerId(_ peerId: PeerId, index: MessageIndex, count: Int, anchorIndex: MessageIndex, fixedCombinedReadState: CombinedPeerReadState?, topTaggedMessageIdNamespaces: Set<MessageId.Namespace>, tagMask: MessageTags?, orderStatistics: MessageHistoryViewOrderStatistics, additionalData: [AdditionalMessageHistoryViewData] = []) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> { public func aroundMessageHistoryViewForPeerId(_ peerId: PeerId, index: MessageIndex, count: Int, clipHoles: Bool, anchorIndex: MessageIndex, fixedCombinedReadState: CombinedPeerReadState?, topTaggedMessageIdNamespaces: Set<MessageId.Namespace>, tagMask: MessageTags?, orderStatistics: MessageHistoryViewOrderStatistics, additionalData: [AdditionalMessageHistoryViewData] = []) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> {
return self.modify { modifier -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> in return self.modify { modifier -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> in
return self.syncAroundMessageHistoryViewForPeerId(peerId, index: index, count: count, anchorIndex: MessageHistoryAnchorIndex(index: anchorIndex, exact: true), unreadIndex: nil, fixedCombinedReadState: fixedCombinedReadState, topTaggedMessageIdNamespaces: topTaggedMessageIdNamespaces, tagMask: tagMask, orderStatistics: orderStatistics, additionalData: additionalData) return self.syncAroundMessageHistoryViewForPeerId(peerId, index: index, count: count, clipHoles: clipHoles, anchorIndex: MessageHistoryAnchorIndex(index: anchorIndex, exact: true), unreadIndex: nil, fixedCombinedReadState: fixedCombinedReadState, topTaggedMessageIdNamespaces: topTaggedMessageIdNamespaces, tagMask: tagMask, orderStatistics: orderStatistics, additionalData: additionalData)
} |> switchToLatest } |> switchToLatest
} }
private func syncAroundMessageHistoryViewForPeerId(_ peerId: PeerId, index: MessageIndex, count: Int, anchorIndex: MessageHistoryAnchorIndex, unreadIndex: MessageIndex?, fixedCombinedReadState: CombinedPeerReadState?, topTaggedMessageIdNamespaces: Set<MessageId.Namespace>, tagMask: MessageTags?, orderStatistics: MessageHistoryViewOrderStatistics, additionalData: [AdditionalMessageHistoryViewData]) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> { private func syncAroundMessageHistoryViewForPeerId(_ peerId: PeerId, index: MessageIndex, count: Int, clipHoles: Bool, anchorIndex: MessageHistoryAnchorIndex, unreadIndex: MessageIndex?, fixedCombinedReadState: CombinedPeerReadState?, topTaggedMessageIdNamespaces: Set<MessageId.Namespace>, tagMask: MessageTags?, orderStatistics: MessageHistoryViewOrderStatistics, additionalData: [AdditionalMessageHistoryViewData]) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> {
let startTime = CFAbsoluteTimeGetCurrent() let startTime = CFAbsoluteTimeGetCurrent()
let (entries, earlier, later) = self.fetchAroundHistoryEntries(index, count: count, tagMask: tagMask) let (entries, earlier, later) = self.fetchAroundHistoryEntries(index, count: count, tagMask: tagMask)
print("aroundMessageHistoryViewForPeerId fetchAroundHistoryEntries \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms") print("aroundMessageHistoryViewForPeerId fetchAroundHistoryEntries \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms")
@ -1842,10 +1860,12 @@ public final class Postbox {
additionalDataEntries.append(.peerChatState(peerId, self.peerChatStateTable.get(peerId) as? PeerChatState)) additionalDataEntries.append(.peerChatState(peerId, self.peerChatStateTable.get(peerId) as? PeerChatState))
case .totalUnreadCount: case .totalUnreadCount:
additionalDataEntries.append(.totalUnreadCount(self.messageHistoryMetadataTable.getChatListTotalUnreadCount())) additionalDataEntries.append(.totalUnreadCount(self.messageHistoryMetadataTable.getChatListTotalUnreadCount()))
case let .peerNotificationSettings(peerId):
additionalDataEntries.append(.peerNotificationSettings(self.peerNotificationSettingsTable.getEffective(peerId)))
} }
} }
let mutableView = MutableMessageHistoryView(id: MessageHistoryViewId(peerId: peerId, id: self.takeNextViewId()), postbox: self, orderStatistics: orderStatistics, peerId: peerId, anchorIndex: anchorIndex, combinedReadState: fixedCombinedReadState ?? self.readStateTable.getCombinedState(peerId), earlier: earlier, entries: entries, later: later, tagMask: tagMask, count: count, topTaggedMessages: topTaggedMessages, additionalDatas: additionalDataEntries, getMessageCountInRange: { lowerBound, upperBound in let mutableView = MutableMessageHistoryView(id: MessageHistoryViewId(peerId: peerId, id: self.takeNextViewId()), postbox: self, orderStatistics: orderStatistics, peerId: peerId, anchorIndex: anchorIndex, combinedReadState: fixedCombinedReadState ?? self.readStateTable.getCombinedState(peerId), earlier: earlier, entries: entries, later: later, tagMask: tagMask, count: count, clipHoles: clipHoles, topTaggedMessages: topTaggedMessages, additionalDatas: additionalDataEntries, getMessageCountInRange: { lowerBound, upperBound in
if let tagMask = tagMask { if let tagMask = tagMask {
return self.messageHistoryTable.getMessageCountInRange(peerId: peerId, tagMask: tagMask, lowerBound: lowerBound, upperBound: upperBound) return self.messageHistoryTable.getMessageCountInRange(peerId: peerId, tagMask: tagMask, lowerBound: lowerBound, upperBound: upperBound)
} else { } else {
@ -1933,7 +1953,7 @@ public final class Postbox {
let mutableView = MutableChatListView(earlier: earlier, entries: entries, later: later, count: count, summaryComponents: summaryComponents) let mutableView = MutableChatListView(earlier: earlier, entries: entries, later: later, count: count, summaryComponents: summaryComponents)
mutableView.render(postbox: self, renderMessage: self.renderIntermediateMessage, getPeer: { id in mutableView.render(postbox: self, renderMessage: self.renderIntermediateMessage, getPeer: { id in
return self.peerTable.get(id) return self.peerTable.get(id)
}, getPeerNotificationSettings: { self.peerNotificationSettingsTable.get($0) }) }, getPeerNotificationSettings: { self.peerNotificationSettingsTable.getEffective($0) })
let (index, signal) = self.viewTracker.addChatListView(mutableView) let (index, signal) = self.viewTracker.addChatListView(mutableView)
@ -2097,19 +2117,7 @@ public final class Postbox {
public func unreadMessageCountsView(items: [UnreadMessageCountsItem]) -> Signal<UnreadMessageCountsView, NoError> { public func unreadMessageCountsView(items: [UnreadMessageCountsItem]) -> Signal<UnreadMessageCountsView, NoError> {
return self.modify { modifier -> Signal<UnreadMessageCountsView, NoError> in return self.modify { modifier -> Signal<UnreadMessageCountsView, NoError> in
let entries: [UnreadMessageCountsItemEntry] = items.map { item in let view = MutableUnreadMessageCountsView(postbox: self, items: items)
switch item {
case .total:
return .total(self.messageHistoryMetadataTable.getChatListTotalUnreadCount())
case let .peer(peerId):
var count: Int32 = 0
if let combinedState = self.readStateTable.getCombinedState(peerId) {
count = combinedState.count
}
return .peer(peerId, count)
}
}
let view = MutableUnreadMessageCountsView(entries: entries)
let (index, signal) = self.viewTracker.addUnreadMessageCountsView(view) let (index, signal) = self.viewTracker.addUnreadMessageCountsView(view)
return (.single(UnreadMessageCountsView(view)) return (.single(UnreadMessageCountsView(view))

View File

@ -11824,6 +11824,11 @@ typedef INT16_TYPE LogEst;
# define SQLITE_MAX_MMAP_SIZE_xc 1 /* exclude from ctime.c */ # define SQLITE_MAX_MMAP_SIZE_xc 1 /* exclude from ctime.c */
#endif #endif
#ifdef SQLITE_MAX_MMAP_SIZE
#undef SQLITE_MAX_MMAP_SIZE
#endif
#define SQLITE_MAX_MMAP_SIZE 0
/* /*
** The default MMAP_SIZE is zero on all platforms. Or, even if a larger ** The default MMAP_SIZE is zero on all platforms. Or, even if a larger
** default MMAP_SIZE is specified at compile-time, make sure that it does ** default MMAP_SIZE is specified at compile-time, make sure that it does

View File

@ -26,6 +26,7 @@ final class PostboxTransaction {
let currentUpdatedMessageActionsSummaries: [PendingMessageActionsSummaryKey: Int32] let currentUpdatedMessageActionsSummaries: [PendingMessageActionsSummaryKey: Int32]
let currentUpdatedMessageTagSummaries: [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary] let currentUpdatedMessageTagSummaries: [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary]
let currentInvalidateMessageTagSummaries: [InvalidatedMessageHistoryTagsSummaryEntryOperation] let currentInvalidateMessageTagSummaries: [InvalidatedMessageHistoryTagsSummaryEntryOperation]
let currentUpdatedPendingPeerNotificationSettings: Set<PeerId>
let unsentMessageOperations: [IntermediateMessageHistoryUnsentOperation] let unsentMessageOperations: [IntermediateMessageHistoryUnsentOperation]
let updatedSynchronizePeerReadStateOperations: [PeerId: PeerReadStateSynchronizationOperation?] let updatedSynchronizePeerReadStateOperations: [PeerId: PeerReadStateSynchronizationOperation?]
@ -128,10 +129,13 @@ final class PostboxTransaction {
if !self.currentInvalidateMessageTagSummaries.isEmpty { if !self.currentInvalidateMessageTagSummaries.isEmpty {
return false return false
} }
if !self.currentUpdatedPendingPeerNotificationSettings.isEmpty {
return false
}
return true return true
} }
init(currentUpdatedState: PostboxCoding?, currentOperationsByPeerId: [PeerId: [MessageHistoryOperation]], peerIdsWithFilledHoles: [PeerId: [MessageIndex: HoleFillDirection]], removedHolesByPeerId: [PeerId: [MessageIndex: HoleFillDirection]], chatListOperations: [ChatListOperation], currentUpdatedPeers: [PeerId: Peer], currentUpdatedPeerNotificationSettings: [PeerId: PeerNotificationSettings], currentUpdatedCachedPeerData: [PeerId: CachedPeerData], currentUpdatedPeerPresences: [PeerId: PeerPresence], currentUpdatedPeerChatListEmbeddedStates: [PeerId: PeerChatListEmbeddedInterfaceState?], currentUpdatedTotalUnreadCount: Int32?, peerIdsWithUpdatedUnreadCounts: Set<PeerId>, currentPeerMergedOperationLogOperations: [PeerMergedOperationLogOperation], currentTimestampBasedMessageAttributesOperations: [TimestampBasedMessageAttributesOperation], unsentMessageOperations: [IntermediateMessageHistoryUnsentOperation], updatedSynchronizePeerReadStateOperations: [PeerId: PeerReadStateSynchronizationOperation?], currentPreferencesOperations: [PreferencesOperation], currentOrderedItemListOperations: [Int32: [OrderedItemListOperation]], currentItemCollectionItemsOperations: [ItemCollectionId: [ItemCollectionItemsOperation]], currentItemCollectionInfosOperations: [ItemCollectionInfosOperation], currentUpdatedPeerChatStates: Set<PeerId>, updatedAccessChallengeData: PostboxAccessChallengeData?, currentGlobalTagsOperations: [GlobalMessageHistoryTagsOperation], updatedMedia: [MediaId: Media?], replaceRemoteContactCount: Int32?, replaceContactPeerIds: Set<PeerId>?, currentPendingMessageActionsOperations: [PendingMessageActionsOperation], currentUpdatedMessageActionsSummaries: [PendingMessageActionsSummaryKey: Int32], currentUpdatedMessageTagSummaries: [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], currentInvalidateMessageTagSummaries: [InvalidatedMessageHistoryTagsSummaryEntryOperation], currentUpdatedMasterClientId: Int64?) { init(currentUpdatedState: PostboxCoding?, currentOperationsByPeerId: [PeerId: [MessageHistoryOperation]], peerIdsWithFilledHoles: [PeerId: [MessageIndex: HoleFillDirection]], removedHolesByPeerId: [PeerId: [MessageIndex: HoleFillDirection]], chatListOperations: [ChatListOperation], currentUpdatedPeers: [PeerId: Peer], currentUpdatedPeerNotificationSettings: [PeerId: PeerNotificationSettings], currentUpdatedCachedPeerData: [PeerId: CachedPeerData], currentUpdatedPeerPresences: [PeerId: PeerPresence], currentUpdatedPeerChatListEmbeddedStates: [PeerId: PeerChatListEmbeddedInterfaceState?], currentUpdatedTotalUnreadCount: Int32?, peerIdsWithUpdatedUnreadCounts: Set<PeerId>, currentPeerMergedOperationLogOperations: [PeerMergedOperationLogOperation], currentTimestampBasedMessageAttributesOperations: [TimestampBasedMessageAttributesOperation], unsentMessageOperations: [IntermediateMessageHistoryUnsentOperation], updatedSynchronizePeerReadStateOperations: [PeerId: PeerReadStateSynchronizationOperation?], currentPreferencesOperations: [PreferencesOperation], currentOrderedItemListOperations: [Int32: [OrderedItemListOperation]], currentItemCollectionItemsOperations: [ItemCollectionId: [ItemCollectionItemsOperation]], currentItemCollectionInfosOperations: [ItemCollectionInfosOperation], currentUpdatedPeerChatStates: Set<PeerId>, updatedAccessChallengeData: PostboxAccessChallengeData?, currentGlobalTagsOperations: [GlobalMessageHistoryTagsOperation], updatedMedia: [MediaId: Media?], replaceRemoteContactCount: Int32?, replaceContactPeerIds: Set<PeerId>?, currentPendingMessageActionsOperations: [PendingMessageActionsOperation], currentUpdatedMessageActionsSummaries: [PendingMessageActionsSummaryKey: Int32], currentUpdatedMessageTagSummaries: [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], currentInvalidateMessageTagSummaries: [InvalidatedMessageHistoryTagsSummaryEntryOperation], currentUpdatedPendingPeerNotificationSettings: Set<PeerId>, currentUpdatedMasterClientId: Int64?) {
self.currentUpdatedState = currentUpdatedState self.currentUpdatedState = currentUpdatedState
self.currentOperationsByPeerId = currentOperationsByPeerId self.currentOperationsByPeerId = currentOperationsByPeerId
self.peerIdsWithFilledHoles = peerIdsWithFilledHoles self.peerIdsWithFilledHoles = peerIdsWithFilledHoles
@ -162,6 +166,7 @@ final class PostboxTransaction {
self.currentUpdatedMessageActionsSummaries = currentUpdatedMessageActionsSummaries self.currentUpdatedMessageActionsSummaries = currentUpdatedMessageActionsSummaries
self.currentUpdatedMessageTagSummaries = currentUpdatedMessageTagSummaries self.currentUpdatedMessageTagSummaries = currentUpdatedMessageTagSummaries
self.currentInvalidateMessageTagSummaries = currentInvalidateMessageTagSummaries self.currentInvalidateMessageTagSummaries = currentInvalidateMessageTagSummaries
self.currentUpdatedPendingPeerNotificationSettings = currentUpdatedPendingPeerNotificationSettings
self.currentUpdatedMasterClientId = currentUpdatedMasterClientId self.currentUpdatedMasterClientId = currentUpdatedMasterClientId
} }
} }

View File

@ -1,40 +1,28 @@
import Foundation import Foundation
private func writePeerIds(_ buffer: WriteBuffer, _ peerIds: Set<PeerId>) {
for id in peerIds {
var value: Int64 = id.toInt64()
buffer.write(&value, offset: 0, length: 8)
}
}
func postboxUpgrade_13to14(metadataTable: MetadataTable, valueBox: ValueBox) { func postboxUpgrade_13to14(metadataTable: MetadataTable, valueBox: ValueBox) {
var reverseAssociations: [PeerId: Set<PeerId>] = [:] var peerSettings: [PeerId: Data] = [:]
let peerTable = ValueBoxTable(id: 2, keyType: .int64) let peerNotificationSettingsTable = ValueBoxTable(id: 19, keyType: .int64)
valueBox.scan(peerTable, values: { _, value in valueBox.scanInt64(peerNotificationSettingsTable, values: { key, value in
if let peer = PostboxDecoder(buffer: value).decodeRootObject() as? Peer { let peerId = PeerId(key)
if let association = peer.associatedPeerId { peerSettings[peerId] = value.makeData()
if reverseAssociations[association] == nil {
reverseAssociations[association] = Set()
}
reverseAssociations[association]!.insert(peer.id)
}
} else {
assertionFailure()
}
return true return true
}) })
let reverseAssociatedPeerTable = ValueBoxTable(id: 40, keyType: .int64) valueBox.dropTable(peerNotificationSettingsTable)
let key = ValueBoxKey(length: 8)
let buffer = WriteBuffer()
for (peerId, settings) in peerSettings {
buffer.reset()
let sharedKey = ValueBoxKey(length: 8) key.setInt64(0, value: peerId.toInt64())
let sharedBuffer = WriteBuffer() var flagsValue: Int32 = (1 << 0)
for (peerId, associations) in reverseAssociations { buffer.write(&flagsValue, offset: 0, length: 4)
sharedBuffer.reset() var length: Int32 = Int32(settings.count)
writePeerIds(sharedBuffer, associations) buffer.write(&length, offset: 0, length: 4)
buffer.write(settings)
sharedKey.setInt64(0, value: peerId.toInt64()) valueBox.set(peerNotificationSettingsTable, key: key, value: buffer)
valueBox.set(reverseAssociatedPeerTable, key: sharedKey, value: sharedBuffer)
} }
metadataTable.setUserVersion(14) metadataTable.setUserVersion(14)

View File

@ -102,6 +102,10 @@ private struct SqlitePreparedStatement {
return key return key
} }
func int64KeyValueAt(_ index: Int) -> Int64 {
return sqlite3_column_int64(statement, Int32(index))
}
func destroy() { func destroy() {
sqlite3_finalize(statement) sqlite3_finalize(statement)
} }
@ -177,10 +181,8 @@ final class SqliteValueBox: ValueBox {
var resultCode: Bool var resultCode: Bool
//database.execute("PRAGMA cache_size=-2097152") //database.execute("PRAGMA cache_size=-2097152")
resultCode = database.execute("PRAGMA mmap_size=0")
resultCode = database.execute("PRAGMA journal_mode=WAL") resultCode = database.execute("PRAGMA journal_mode=WAL")
if !resultCode {
resultCode = database.execute("PRAGMA VACUUM")
}
assert(resultCode) assert(resultCode)
resultCode = database.execute("PRAGMA synchronous=NORMAL") resultCode = database.execute("PRAGMA synchronous=NORMAL")
assert(resultCode) assert(resultCode)
@ -192,7 +194,7 @@ final class SqliteValueBox: ValueBox {
/*var statement: OpaquePointer? = nil /*var statement: OpaquePointer? = nil
sqlite3_prepare_v2(database.handle, "PRAGMA integrity_check", -1, &statement, nil) sqlite3_prepare_v2(database.handle, "PRAGMA integrity_check", -1, &statement, nil)
let preparedStatement = SqlitePreparedStatement(statement: statement) let preparedStatement = SqlitePreparedStatement(statement: statement)
while preparedStatement.step() { while preparedStatement.step(handle: database.handle) {
let value = preparedStatement.valueAt(0) let value = preparedStatement.valueAt(0)
let text = String(data: Data(bytes: value.memory.assumingMemoryBound(to: UInt8.self), count: value.length), encoding: .utf8) let text = String(data: Data(bytes: value.memory.assumingMemoryBound(to: UInt8.self), count: value.length), encoding: .utf8)
print("integrity_check: \(text ?? "")") print("integrity_check: \(text ?? "")")
@ -1186,6 +1188,37 @@ final class SqliteValueBox: ValueBox {
} }
} }
public func scanInt64(_ table: ValueBoxTable, values: (Int64, ReadBuffer) -> Bool) {
assert(self.queue.isCurrent())
if let _ = self.tables[table.id] {
let statement: SqlitePreparedStatement = self.scanStatement(table)
var startTime = CFAbsoluteTimeGetCurrent()
var currentTime = CFAbsoluteTimeGetCurrent()
self.readQueryTime += currentTime - startTime
startTime = currentTime
while statement.step(handle: self.database.handle) {
startTime = CFAbsoluteTimeGetCurrent()
let key = statement.int64KeyValueAt(0)
let value = statement.valueAt(1)
currentTime = CFAbsoluteTimeGetCurrent()
self.readQueryTime += currentTime - startTime
if !values(key, value) {
break
}
}
statement.reset()
}
}
public func set(_ table: ValueBoxTable, key: ValueBoxKey, value: MemoryBuffer) { public func set(_ table: ValueBoxTable, key: ValueBoxKey, value: MemoryBuffer) {
assert(self.queue.isCurrent()) assert(self.queue.isCurrent())
self.checkTable(table) self.checkTable(table)

View File

@ -1,8 +1,25 @@
import Foundation import Foundation
public enum UnreadMessageCountsItem { public enum UnreadMessageCountsItem: Equatable {
case total case total
case peer(PeerId) case peer(PeerId)
public static func ==(lhs: UnreadMessageCountsItem, rhs: UnreadMessageCountsItem) -> Bool {
switch lhs {
case .total:
if case .total = rhs {
return true
} else {
return false
}
case let .peer(peerId):
if case .peer(peerId) = rhs {
return true
} else {
return false
}
}
}
} }
enum UnreadMessageCountsItemEntry { enum UnreadMessageCountsItemEntry {
@ -10,41 +27,60 @@ enum UnreadMessageCountsItemEntry {
case peer(PeerId, Int32) case peer(PeerId, Int32)
} }
final class MutableUnreadMessageCountsView { final class MutableUnreadMessageCountsView: MutablePostboxView {
fileprivate var entries: [UnreadMessageCountsItemEntry] fileprivate var entries: [UnreadMessageCountsItemEntry]
init(entries: [UnreadMessageCountsItemEntry]) { init(postbox: Postbox, items: [UnreadMessageCountsItem]) {
self.entries = entries self.entries = items.map { item in
switch item {
case .total:
return .total(postbox.messageHistoryMetadataTable.getChatListTotalUnreadCount())
case let .peer(peerId):
var count: Int32 = 0
if let combinedState = postbox.readStateTable.getCombinedState(peerId) {
count = combinedState.count
}
return .peer(peerId, count)
}
}
} }
func replay(peerIdsWithUpdatedUnreadCounts: Set<PeerId>, getTotalUnreadCount: () -> Int32, getPeerReadState: (PeerId) -> CombinedPeerReadState?) -> Bool { func replay(postbox: Postbox, transaction: PostboxTransaction) -> Bool {
var updated = false var updated = false
for i in 0 ..< self.entries.count { if transaction.currentUpdatedTotalUnreadCount != nil || !transaction.peerIdsWithUpdatedUnreadCounts.isEmpty {
switch self.entries[i] { for i in 0 ..< self.entries.count {
case let .total(count): switch self.entries[i] {
let updatedCount = getTotalUnreadCount() case let .total(count):
if updatedCount != count { if transaction.currentUpdatedTotalUnreadCount != nil {
self.entries[i] = .total(updatedCount) let updatedCount = postbox.messageHistoryMetadataTable.getChatListTotalUnreadCount()
updated = true if updatedCount != count {
} self.entries[i] = .total(updatedCount)
case let .peer(peerId, count): updated = true
if peerIdsWithUpdatedUnreadCounts.contains(peerId) { }
var updatedCount: Int32 = 0
if let combinedState = getPeerReadState(peerId) {
updatedCount = combinedState.count
} }
self.entries[i] = .peer(peerId, updatedCount) case let .peer(peerId, count):
updated = true if transaction.peerIdsWithUpdatedUnreadCounts.contains(peerId) {
} var updatedCount: Int32 = 0
if let combinedState = postbox.readStateTable.getCombinedState(peerId) {
updatedCount = combinedState.count
}
self.entries[i] = .peer(peerId, updatedCount)
updated = true
}
}
} }
} }
return updated return updated
} }
func immutableView() -> PostboxView {
return UnreadMessageCountsView(self)
}
} }
public final class UnreadMessageCountsView { public final class UnreadMessageCountsView: PostboxView {
private let entries: [UnreadMessageCountsItemEntry] private let entries: [UnreadMessageCountsItemEntry]
init(_ view: MutableUnreadMessageCountsView) { init(_ view: MutableUnreadMessageCountsView) {

View File

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

View File

@ -24,6 +24,7 @@ protocol ValueBox {
func range(_ table: ValueBoxTable, start: ValueBoxKey, end: ValueBoxKey, values: (ValueBoxKey, ReadBuffer) -> Bool, limit: Int) func range(_ table: ValueBoxTable, start: ValueBoxKey, end: ValueBoxKey, values: (ValueBoxKey, ReadBuffer) -> Bool, limit: Int)
func range(_ table: ValueBoxTable, start: ValueBoxKey, end: ValueBoxKey, keys: (ValueBoxKey) -> Bool, limit: Int) func range(_ table: ValueBoxTable, start: ValueBoxKey, end: ValueBoxKey, keys: (ValueBoxKey) -> Bool, limit: Int)
func scan(_ table: ValueBoxTable, values: (ValueBoxKey, ReadBuffer) -> Bool) func scan(_ table: ValueBoxTable, values: (ValueBoxKey, ReadBuffer) -> Bool)
func scanInt64(_ table: ValueBoxTable, values: (Int64, ReadBuffer) -> Bool)
func get(_ table: ValueBoxTable, key: ValueBoxKey) -> ReadBuffer? func get(_ table: ValueBoxTable, key: ValueBoxKey) -> ReadBuffer?
func exists(_ table: ValueBoxTable, key: ValueBoxKey) -> Bool func exists(_ table: ValueBoxTable, key: ValueBoxKey) -> Bool
func set(_ table: ValueBoxTable, key: ValueBoxKey, value: MemoryBuffer) func set(_ table: ValueBoxTable, key: ValueBoxKey, value: MemoryBuffer)

View File

@ -435,7 +435,7 @@ final class ViewTracker {
} }
for (view, pipe) in self.unreadMessageCountsViews.copyItems() { for (view, pipe) in self.unreadMessageCountsViews.copyItems() {
if view.replay(peerIdsWithUpdatedUnreadCounts: transaction.peerIdsWithUpdatedUnreadCounts, getTotalUnreadCount: self.getTotalUnreadCount, getPeerReadState: self.getPeerReadState) { if view.replay(postbox: postbox, transaction: transaction) {
pipe.putNext(UnreadMessageCountsView(view)) pipe.putNext(UnreadMessageCountsView(view))
} }
} }

View File

@ -15,6 +15,9 @@ public enum PostboxViewKey: Hashable {
case pendingMessageActionsSummary(type: PendingMessageActionType, peerId: PeerId, namespace: MessageId.Namespace) case pendingMessageActionsSummary(type: PendingMessageActionType, peerId: PeerId, namespace: MessageId.Namespace)
case historyTagSummaryView(tag: MessageTags, peerId: PeerId, namespace: MessageId.Namespace) case historyTagSummaryView(tag: MessageTags, peerId: PeerId, namespace: MessageId.Namespace)
case cachedPeerData(peerId: PeerId) case cachedPeerData(peerId: PeerId)
case unreadCounts(items: [UnreadMessageCountsItem])
case peerNotificationSettings(peerId: PeerId)
case pendingPeerNotificationSettings
public var hashValue: Int { public var hashValue: Int {
switch self { switch self {
@ -46,6 +49,12 @@ public enum PostboxViewKey: Hashable {
return tag.rawValue.hashValue ^ peerId.hashValue ^ namespace.hashValue return tag.rawValue.hashValue ^ peerId.hashValue ^ namespace.hashValue
case let .cachedPeerData(peerId): case let .cachedPeerData(peerId):
return peerId.hashValue return peerId.hashValue
case .unreadCounts:
return 5
case let .peerNotificationSettings(peerId):
return 6 &+ 31 &* peerId.hashValue
case .pendingPeerNotificationSettings:
return 7
} }
} }
@ -135,6 +144,24 @@ public enum PostboxViewKey: Hashable {
} else { } else {
return false return false
} }
case let .unreadCounts(lhsItems):
if case let .unreadCounts(rhsItems) = rhs, lhsItems == rhsItems {
return true
} else {
return false
}
case let .peerNotificationSettings(peerId):
if case .peerNotificationSettings(peerId) = rhs {
return true
} else {
return false
}
case .pendingPeerNotificationSettings:
if case .pendingPeerNotificationSettings = rhs {
return true
} else {
return false
}
} }
} }
} }
@ -169,5 +196,11 @@ func postboxViewForKey(postbox: Postbox, key: PostboxViewKey) -> MutablePostboxV
return MutableMessageHistoryTagSummaryView(postbox: postbox, tag: tag, peerId: peerId, namespace: namespace) return MutableMessageHistoryTagSummaryView(postbox: postbox, tag: tag, peerId: peerId, namespace: namespace)
case let .cachedPeerData(peerId): case let .cachedPeerData(peerId):
return MutableCachedPeerDataView(postbox: postbox, peerId: peerId) return MutableCachedPeerDataView(postbox: postbox, peerId: peerId)
case let .unreadCounts(items):
return MutableUnreadMessageCountsView(postbox: postbox, items: items)
case let .peerNotificationSettings(peerId):
return MutablePeerNotificationSettingsView(postbox: postbox, peerId: peerId)
case .pendingPeerNotificationSettings:
return MutablePendingPeerNotificationSettingsView(postbox: postbox)
} }
} }